1pub mod color;
2
3use plotly_derive::FieldSetter;
4use serde::{Serialize, Serializer};
5
6use crate::{
7 color::{Color, ColorArray},
8 private,
9};
10
11#[derive(Serialize, Clone, Debug)]
12#[serde(untagged)]
13pub enum Direction {
14 Increasing { line: Line },
15 Decreasing { line: Line },
16}
17
18#[derive(Clone, Debug)]
19pub enum Visible {
20 True,
21 False,
22 LegendOnly,
23}
24
25impl Serialize for Visible {
26 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
27 where
28 S: Serializer,
29 {
30 match *self {
31 Self::True => serializer.serialize_bool(true),
32 Self::False => serializer.serialize_bool(false),
33 Self::LegendOnly => serializer.serialize_str("legendonly"),
34 }
35 }
36}
37
38#[derive(Serialize, Clone, Debug)]
39#[serde(rename_all = "lowercase")]
40pub enum HoverInfo {
41 X,
42 Y,
43 Z,
44 #[serde(rename = "x+y")]
45 XAndY,
46 #[serde(rename = "x+z")]
47 XAndZ,
48 #[serde(rename = "y+z")]
49 YAndZ,
50 #[serde(rename = "x+y+z")]
51 XAndYAndZ,
52 Text,
53 Name,
54 All,
55 None,
56 Skip,
57}
58
59#[serde_with::skip_serializing_none]
60#[derive(Serialize, Clone, Debug, FieldSetter)]
61pub struct LegendGroupTitle {
62 text: Option<String>,
63 font: Option<Font>,
64}
65
66impl From<&str> for LegendGroupTitle {
67 fn from(title: &str) -> Self {
68 LegendGroupTitle::with_text(title)
69 }
70}
71
72impl From<String> for LegendGroupTitle {
73 fn from(value: String) -> Self {
74 LegendGroupTitle::with_text(value)
75 }
76}
77
78impl From<&String> for LegendGroupTitle {
79 fn from(value: &String) -> Self {
80 LegendGroupTitle::with_text(value)
81 }
82}
83
84impl LegendGroupTitle {
85 pub fn new() -> Self {
86 Default::default()
87 }
88
89 pub fn with_text<S: Into<String>>(text: S) -> Self {
90 LegendGroupTitle {
91 text: Some(text.into()),
92 ..Default::default()
93 }
94 }
95}
96
97#[serde_with::skip_serializing_none]
98#[derive(Serialize, Clone, Debug, Default)]
99pub struct Domain {
100 column: Option<usize>,
101 row: Option<usize>,
102 x: Option<[f64; 2]>,
103 y: Option<[f64; 2]>,
104}
105
106impl Domain {
107 pub fn new() -> Self {
108 Default::default()
109 }
110
111 pub fn column(mut self, column: usize) -> Self {
112 self.column = Some(column);
113 self
114 }
115
116 pub fn row(mut self, row: usize) -> Self {
117 self.row = Some(row);
118 self
119 }
120
121 pub fn x(mut self, x: &[f64; 2]) -> Self {
122 self.x = Some(x.to_owned());
123 self
124 }
125
126 pub fn y(mut self, y: &[f64; 2]) -> Self {
127 self.y = Some(y.to_owned());
128 self
129 }
130}
131
132#[derive(Serialize, Clone, Debug)]
133#[serde(rename_all = "lowercase")]
134pub enum TextPosition {
135 Inside,
136 Outside,
137 Auto,
138 None,
139}
140
141#[derive(Serialize, Clone, Debug)]
142#[serde(rename_all = "lowercase")]
143pub enum ConstrainText {
144 Inside,
145 Outside,
146 Both,
147 None,
148}
149
150#[derive(Serialize, Clone, Debug)]
151pub enum Orientation {
152 #[serde(rename = "a")]
153 Auto,
154 #[serde(rename = "v")]
155 Vertical,
156 #[serde(rename = "h")]
157 Horizontal,
158 #[serde(rename = "r")]
159 Radial,
160 #[serde(rename = "t")]
161 Tangential,
162}
163
164#[derive(Serialize, Clone, Debug)]
165#[serde(rename_all = "lowercase")]
166pub enum Fill {
167 ToZeroY,
168 ToZeroX,
169 ToNextY,
170 ToNextX,
171 ToSelf,
172 ToNext,
173 None,
174}
175
176#[derive(Serialize, Clone, Debug)]
177#[serde(rename_all = "lowercase")]
178pub enum Calendar {
179 Gregorian,
180 Chinese,
181 Coptic,
182 DiscWorld,
183 Ethiopian,
184 Hebrew,
185 Islamic,
186 Julian,
187 Mayan,
188 Nanakshahi,
189 Nepali,
190 Persian,
191 Jalali,
192 Taiwan,
193 Thai,
194 Ummalqura,
195}
196
197#[derive(Serialize, Clone, Debug)]
198#[serde(untagged)]
199pub enum Dim<T>
200where
201 T: Serialize,
202{
203 Scalar(T),
204 Vector(Vec<T>),
205 Matrix(Vec<Vec<T>>),
206}
207
208#[derive(Serialize, Clone, Debug, PartialEq, Eq)]
209#[serde(rename_all = "lowercase")]
210pub enum PlotType {
211 Scatter,
212 ScatterGL,
213 Scatter3D,
214 ScatterMapbox,
215 ScatterGeo,
216 ScatterPolar,
217 ScatterPolarGL,
218 Bar,
219 Box,
220 Candlestick,
221 Contour,
222 HeatMap,
223 Histogram,
224 Histogram2dContour,
225 Image,
226 Mesh3D,
227 Ohlc,
228 Sankey,
229 Surface,
230 DensityMapbox,
231 Table,
232 Pie,
233}
234
235#[derive(Serialize, Clone, Debug)]
236#[serde(rename_all = "lowercase")]
237pub enum Mode {
238 Lines,
239 Markers,
240 Text,
241 #[serde(rename = "lines+markers")]
242 LinesMarkers,
243 #[serde(rename = "lines+text")]
244 LinesText,
245 #[serde(rename = "markers+text")]
246 MarkersText,
247 #[serde(rename = "lines+markers+text")]
248 LinesMarkersText,
249 None,
250}
251
252#[derive(Serialize, Clone, Debug)]
253#[serde(rename_all = "lowercase")]
254pub enum Ticks {
255 Outside,
256 Inside,
257 #[serde(rename = "")]
258 None,
259}
260
261#[derive(Serialize, Clone, Debug)]
262pub enum Position {
263 #[serde(rename = "top left")]
264 TopLeft,
265 #[serde(rename = "top center")]
266 TopCenter,
267 #[serde(rename = "top right")]
268 TopRight,
269 #[serde(rename = "middle left")]
270 MiddleLeft,
271 #[serde(rename = "middle center")]
272 MiddleCenter,
273 #[serde(rename = "middle right")]
274 MiddleRight,
275 #[serde(rename = "bottom left")]
276 BottomLeft,
277 #[serde(rename = "bottom center")]
278 BottomCenter,
279 #[serde(rename = "bottom right")]
280 BottomRight,
281 #[serde(rename = "inside")]
282 Inside,
283 #[serde(rename = "outside")]
284 Outside,
285}
286
287#[derive(Serialize, Clone, Debug)]
288#[serde(rename_all = "kebab-case")]
289pub enum MarkerSymbol {
290 Circle,
291 CircleOpen,
292 CircleDot,
293 CircleOpenDot,
294 Square,
295 SquareOpen,
296 SquareDot,
297 SquareOpenDot,
298 Diamond,
299 DiamondOpen,
300 DiamondDot,
301 DiamondOpenDot,
302 Cross,
303 CrossOpen,
304 CrossDot,
305 CrossOpenDot,
306 X,
307 XOpen,
308 XDot,
309 XOpenDot,
310 TriangleUp,
311 TriangleUpOpen,
312 TriangleUpDot,
313 TriangleUpOpenDot,
314 TriangleDown,
315 TriangleDownOpen,
316 TriangleDownDot,
317 TriangleDownOpenDot,
318 TriangleLeft,
319 TriangleLeftOpen,
320 TriangleLeftDot,
321 TriangleLeftOpenDot,
322 TriangleRight,
323 TriangleRightOpen,
324 TriangleRightDot,
325 TriangleRightOpenDot,
326 #[serde(rename = "triangle-ne")]
327 TriangleNE,
328 #[serde(rename = "triangle-ne-open")]
329 TriangleNEOpen,
330 #[serde(rename = "triangle-ne-dot")]
331 TriangleNEDot,
332 #[serde(rename = "triangle-ne-open-dot")]
333 TriangleNEOpenDot,
334 #[serde(rename = "triangle-se")]
335 TriangleSE,
336 #[serde(rename = "triangle-se-open")]
337 TriangleSEOpen,
338 #[serde(rename = "triangle-se-dot")]
339 TriangleSEDot,
340 #[serde(rename = "triangle-se-open-dot")]
341 TriangleSEOpenDot,
342 #[serde(rename = "triangle-sw")]
343 TriangleSW,
344 #[serde(rename = "triangle-sw-open")]
345 TriangleSWOpen,
346 #[serde(rename = "triangle-sw-dot")]
347 TriangleSWDot,
348 #[serde(rename = "triangle-sw-open-dot")]
349 TriangleSWOpenDot,
350 #[serde(rename = "triangle-nw")]
351 TriangleNW,
352 #[serde(rename = "triangle-nw-open")]
353 TriangleNWOpen,
354 #[serde(rename = "triangle-nw-dot")]
355 TriangleNWDot,
356 #[serde(rename = "triangle-nw-open-dot")]
357 TriangleNWOpenDot,
358 Pentagon,
359 PentagonOpen,
360 PentagonDot,
361 PentagonOpenDot,
362 Hexagon,
363 HexagonOpen,
364 HexagonDot,
365 HexagonOpenDot,
366 Hexagon2,
367 Hexagon2Open,
368 Hexagon2Dot,
369 Hexagon2OpenDot,
370 Octagon,
371 OctagonOpen,
372 OctagonDot,
373 OctagonOpenDot,
374 Star,
375 StarOpen,
376 StarDot,
377 StarOpenDot,
378 Hexagram,
379 HexagramOpen,
380 HexagramDot,
381 HexagramOpenDot,
382 StarTriangleUp,
383 StarTriangleUpOpen,
384 StarTriangleUpDot,
385 StarTriangleUpOpenDot,
386 StarTriangleDown,
387 StarTriangleDownOpen,
388 StarTriangleDownDot,
389 StarTriangleDownOpenDot,
390 StarSquare,
391 StarSquareOpen,
392 StarSquareDot,
393 StarSquareOpenDot,
394 StarDiamond,
395 StarDiamondOpen,
396 StarDiamondDot,
397 StarDiamondOpenDot,
398 DiamondTall,
399 DiamondTallOpen,
400 DiamondTallDot,
401 DiamondTallOpenDot,
402 DiamondWide,
403 DiamondWideOpen,
404 DiamondWideDot,
405 DiamondWideOpenDot,
406 Hourglass,
407 HourglassOpen,
408 #[serde(rename = "bowtie")]
409 BowTie,
410 #[serde(rename = "bowtie-open")]
411 BowTieOpen,
412 CircleCross,
413 CircleCrossOpen,
414 CircleX,
415 CircleXOpen,
416 SquareCross,
417 SquareCrossOpen,
418 SquareX,
419 SquareXOpen,
420 DiamondCross,
421 DiamondCrossOpen,
422 DiamondX,
423 DiamondXOpen,
424 CrossThin,
425 CrossThinOpen,
426 XThin,
427 XThinOpen,
428 Asterisk,
429 AsteriskOpen,
430 Hash,
431 HashOpen,
432 HashDot,
433 HashOpenDot,
434 YUp,
435 YUpOpen,
436 YDown,
437 YDownOpen,
438 YLeft,
439 YLeftOpen,
440 YRight,
441 YRightOpen,
442 #[serde(rename = "line-ew")]
443 LineEW,
444 #[serde(rename = "line-ew-open")]
445 LineEWOpen,
446 #[serde(rename = "line-ns")]
447 LineNS,
448 #[serde(rename = "line-ns-open")]
449 LineNSOpen,
450 #[serde(rename = "line-ne")]
451 LineNE,
452 #[serde(rename = "line-ne-open")]
453 LineNEOpen,
454 #[serde(rename = "line-nw")]
455 LineNW,
456 #[serde(rename = "line-nw-open")]
457 LineNWOpen,
458}
459
460#[derive(Serialize, Clone, Debug)]
461#[serde(rename_all = "lowercase")]
462pub enum TickMode {
463 Auto,
464 Linear,
465 Array,
466}
467
468#[derive(Serialize, Clone, Debug)]
469#[serde(rename_all = "lowercase")]
470pub enum DashType {
471 Solid,
472 Dot,
473 Dash,
474 LongDash,
475 DashDot,
476 LongDashDot,
477}
478
479#[derive(Serialize, Clone, Debug)]
480pub struct ColorScaleElement(pub f64, pub String);
481
482#[derive(Serialize, Clone, Debug)]
483pub enum ColorScalePalette {
484 Greys,
485 YlGnBu,
486 Greens,
487 YlOrRd,
488 Bluered,
489 RdBu,
490 Reds,
491 Blues,
492 Picnic,
493 Rainbow,
494 Portland,
495 Jet,
496 Hot,
497 Blackbody,
498 Earth,
499 Electric,
500 Viridis,
501 Cividis,
502}
503
504#[derive(Serialize, Clone, Debug)]
505#[serde(untagged)]
506pub enum ColorScale {
507 Palette(ColorScalePalette),
508 Vector(Vec<ColorScaleElement>),
509}
510
511impl From<ColorScalePalette> for ColorScale {
512 fn from(src: ColorScalePalette) -> Self {
513 ColorScale::Palette(src)
514 }
515}
516
517#[derive(Serialize, Clone, Debug)]
518#[serde(rename_all = "lowercase")]
519pub enum LineShape {
520 Linear,
521 Spline,
522 Hv,
523 Vh,
524 Hvh,
525 Vhv,
526}
527
528#[serde_with::skip_serializing_none]
529#[derive(Serialize, Clone, Debug, FieldSetter)]
530pub struct Line {
531 width: Option<f64>,
532 shape: Option<LineShape>,
533 smoothing: Option<f64>,
534 dash: Option<DashType>,
535 simplify: Option<bool>,
536 color: Option<Box<dyn Color>>,
537 cauto: Option<bool>,
538 cmin: Option<f64>,
539 cmax: Option<f64>,
540 cmid: Option<f64>,
541 #[serde(rename = "colorscale")]
542 color_scale: Option<ColorScale>,
543 #[serde(rename = "autocolorscale")]
544 auto_color_scale: Option<bool>,
545 #[serde(rename = "reversescale")]
546 reverse_scale: Option<bool>,
547 #[serde(rename = "outliercolor")]
548 outlier_color: Option<Box<dyn Color>>,
549 #[serde(rename = "outlierwidth")]
550 outlier_width: Option<usize>,
551}
552
553impl Line {
554 pub fn new() -> Self {
555 Default::default()
556 }
557}
558
559#[derive(Serialize, Clone, Debug)]
560#[serde(rename_all = "lowercase")]
561pub enum GradientType {
562 Radial,
563 Horizontal,
564 Vertical,
565 None,
566}
567
568#[derive(Serialize, Clone, Debug)]
569#[serde(rename_all = "lowercase")]
570pub enum SizeMode {
571 Diameter,
572 Area,
573}
574
575#[derive(Serialize, Clone, Debug)]
576#[serde(rename_all = "lowercase")]
577pub enum ThicknessMode {
578 Fraction,
579 Pixels,
580}
581
582#[derive(Serialize, Clone, Debug)]
583#[serde(rename_all = "lowercase")]
584pub enum Anchor {
585 Auto,
586 Left,
587 Center,
588 Right,
589 Top,
590 Middle,
591 Bottom,
592}
593
594#[derive(Serialize, Clone, Debug)]
595#[serde(rename_all = "lowercase")]
596pub enum TextAnchor {
597 Start,
598 Middle,
599 End,
600}
601
602#[derive(Serialize, Clone, Debug)]
603#[serde(rename_all = "lowercase")]
604pub enum ExponentFormat {
605 None,
606 #[serde(rename = "e")]
607 SmallE,
608 #[serde(rename = "E")]
609 CapitalE,
610 Power,
611 #[serde(rename = "SI")]
612 SI,
613 #[serde(rename = "B")]
614 B,
615}
616
617#[derive(Serialize, Clone, Debug)]
618pub struct Gradient {
619 r#type: GradientType,
620 color: Dim<Box<dyn Color>>,
621}
622
623impl Gradient {
624 pub fn new<C: Color>(gradient_type: GradientType, color: C) -> Self {
625 Gradient {
626 r#type: gradient_type,
627 color: Dim::Scalar(Box::new(color)),
628 }
629 }
630
631 pub fn new_array<C: Color>(gradient_type: GradientType, colors: Vec<C>) -> Self {
632 Gradient {
633 r#type: gradient_type,
634 color: Dim::Vector(ColorArray(colors).into()),
635 }
636 }
637}
638
639#[serde_with::skip_serializing_none]
640#[derive(Serialize, Clone, Debug, FieldSetter)]
641pub struct TickFormatStop {
642 #[field_setter(default = "true")]
643 enabled: bool,
644 #[serde(rename = "dtickrange")]
645 dtick_range: Option<private::NumOrStringCollection>,
646 value: Option<String>,
647 name: Option<String>,
648 #[serde(rename = "templateitemname")]
649 template_item_name: Option<String>,
650}
651
652impl TickFormatStop {
653 pub fn new() -> Self {
654 TickFormatStop {
655 enabled: true,
656 ..Default::default()
657 }
658 }
659
660 pub fn enabled(mut self, enabled: bool) -> Self {
661 self.enabled = enabled;
662 self
663 }
664}
665
666#[derive(Serialize, Debug, Clone)]
667#[serde(rename_all = "lowercase")]
668pub enum Show {
669 All,
670 First,
671 Last,
672 None,
673}
674
675#[serde_with::skip_serializing_none]
676#[derive(Serialize, Clone, Debug, FieldSetter)]
677pub struct ColorBar {
678 #[serde(rename = "bgcolor")]
679 background_color: Option<Box<dyn Color>>,
680 #[serde(rename = "bordercolor")]
681 border_color: Option<Box<dyn Color>>,
682 #[serde(rename = "borderwidth")]
683 border_width: Option<usize>,
684 dtick: Option<f64>,
685 #[serde(rename = "exponentformat")]
686 exponent_format: Option<ExponentFormat>,
687 len: Option<usize>,
688 #[serde(rename = "lenmode")]
689 len_mode: Option<ThicknessMode>,
690 #[serde(rename = "nticks")]
691 n_ticks: Option<usize>,
692 orientation: Option<Orientation>,
693 #[serde(rename = "outlinecolor")]
694 outline_color: Option<Box<dyn Color>>,
695 #[serde(rename = "outlinewidth")]
696 outline_width: Option<usize>,
697 #[serde(rename = "separatethousands")]
698 separate_thousands: Option<bool>,
699 #[serde(rename = "showexponent")]
700 show_exponent: Option<Show>,
701 #[serde(rename = "showticklabels")]
702 show_tick_labels: Option<bool>,
703 #[serde(rename = "showtickprefix")]
704 show_tick_prefix: Option<Show>,
705 #[serde(rename = "showticksuffix")]
706 show_tick_suffix: Option<Show>,
707 thickness: Option<usize>,
708 #[serde(rename = "thicknessmode")]
709 thickness_mode: Option<ThicknessMode>,
710 #[serde(rename = "tickangle")]
711 tick_angle: Option<f64>,
712 #[serde(rename = "tickcolor")]
713 tick_color: Option<Box<dyn Color>>,
714 #[serde(rename = "tickfont")]
715 tick_font: Option<Font>,
716 #[serde(rename = "tickformat")]
717 tick_format: Option<String>,
718 #[serde(rename = "tickformatstops")]
719 tick_format_stops: Option<Vec<TickFormatStop>>,
720 #[serde(rename = "ticklen")]
721 tick_len: Option<usize>,
722 #[serde(rename = "tickmode")]
723 tick_mode: Option<TickMode>,
724 #[serde(rename = "tickprefix")]
725 tick_prefix: Option<String>,
726 #[serde(rename = "ticksuffix")]
727 tick_suffix: Option<String>,
728 #[serde(rename = "ticktext")]
729 tick_text: Option<Vec<String>>,
730 #[serde(rename = "tickvals")]
731 tick_vals: Option<Vec<f64>>,
732 #[serde(rename = "tickwidth")]
733 tick_width: Option<usize>,
734 tick0: Option<f64>,
735 ticks: Option<Ticks>,
736 title: Option<Title>,
737 x: Option<f64>,
738 #[serde(rename = "xanchor")]
739 x_anchor: Option<Anchor>,
740 #[serde(rename = "xpad")]
741 x_pad: Option<f64>,
742 y: Option<f64>,
743 #[serde(rename = "yanchor")]
744 y_anchor: Option<Anchor>,
745 #[serde(rename = "ypad")]
746 y_pad: Option<f64>,
747}
748
749impl ColorBar {
750 pub fn new() -> Self {
751 Default::default()
752 }
753}
754
755#[derive(Serialize, Debug, Clone)]
756#[serde(rename_all = "lowercase")]
757pub enum AxisSide {
758 Top,
759 Bottom,
760 Left,
761 Right,
762}
763
764#[derive(Serialize, Debug, Clone)]
765pub enum PatternShape {
766 #[serde(rename = "")]
767 None,
768 #[serde(rename = "-")]
769 HorizontalLine,
770 #[serde(rename = "|")]
771 VerticalLine,
772 #[serde(rename = "/")]
773 RightDiagonalLine,
774 #[serde(rename = "\\")]
775 LeftDiagonalLine,
776 #[serde(rename = "+")]
777 Cross,
778 #[serde(rename = "x")]
779 DiagonalCross,
780 #[serde(rename = ".")]
781 Dot,
782}
783
784#[derive(Serialize, Debug, Clone)]
785#[serde(rename_all = "lowercase")]
786pub enum PatternFillMode {
787 Replace,
788 Overlay,
789}
790
791#[serde_with::skip_serializing_none]
792#[derive(Serialize, Clone, Debug, FieldSetter)]
793pub struct Pattern {
794 shape: Option<Dim<PatternShape>>,
795 #[serde(rename = "fillmode")]
796 fill_mode: Option<PatternFillMode>,
797 #[serde(rename = "bgcolor")]
798 background_color: Option<Dim<Box<dyn Color>>>,
799 #[serde(rename = "fgcolor")]
800 foreground_color: Option<Dim<Box<dyn Color>>>,
801 #[serde(rename = "fgopacity")]
802 foreground_opacity: Option<f64>,
803 size: Option<Dim<f64>>,
804 solidity: Option<Dim<f64>>,
805}
806
807impl Pattern {
808 pub fn new() -> Self {
809 Default::default()
810 }
811}
812
813#[serde_with::skip_serializing_none]
814#[derive(Serialize, Clone, Debug, FieldSetter)]
815pub struct Marker {
816 symbol: Option<MarkerSymbol>,
817 opacity: Option<f64>,
818 size: Option<Dim<usize>>,
819 #[serde(rename = "maxdisplayed")]
820 max_displayed: Option<usize>,
821 #[serde(rename = "sizeref")]
822 size_ref: Option<usize>,
823 #[serde(rename = "sizemin")]
824 size_min: Option<usize>,
825 #[serde(rename = "sizemode")]
826 size_mode: Option<SizeMode>,
827 line: Option<Line>,
828 gradient: Option<Gradient>,
829 color: Option<Dim<Box<dyn Color>>>,
831 #[field_setter(skip)]
833 colors: Option<Vec<Box<dyn Color>>>,
834 cauto: Option<bool>,
835 cmin: Option<f64>,
836 cmax: Option<f64>,
837 cmid: Option<f64>,
838 #[serde(rename = "colorscale")]
839 color_scale: Option<ColorScale>,
840 #[serde(rename = "autocolorscale")]
841 auto_color_scale: Option<bool>,
842 #[serde(rename = "reversescale")]
843 reverse_scale: Option<bool>,
844 #[serde(rename = "showscale")]
845 show_scale: Option<bool>,
846 #[serde(rename = "colorbar")]
847 color_bar: Option<ColorBar>,
848 #[serde(rename = "outliercolor")]
849 outlier_color: Option<Box<dyn Color>>,
850 pattern: Option<Pattern>,
851}
852
853impl Marker {
854 pub fn new() -> Self {
855 Default::default()
856 }
857
858 pub fn colors<C: Color>(mut self, colors: Vec<C>) -> Self {
859 self.colors = Some(ColorArray(colors).into());
860 self
861 }
862}
863
864#[serde_with::skip_serializing_none]
865#[derive(Serialize, Clone, Debug, FieldSetter)]
866pub struct Font {
867 family: Option<String>,
868 size: Option<usize>,
869 color: Option<Box<dyn Color>>,
870}
871
872impl Font {
873 pub fn new() -> Self {
874 Default::default()
875 }
876}
877
878#[derive(Serialize, Clone, Debug)]
879#[serde(rename_all = "lowercase")]
880pub enum Side {
881 Right,
882 Top,
883 Bottom,
884 Left,
885 #[serde(rename = "top left")]
886 TopLeft,
887}
888
889#[derive(Serialize, Clone, Debug)]
890#[serde(rename_all = "lowercase")]
891pub enum Reference {
892 Container,
893 Paper,
894}
895
896#[derive(Serialize, Clone, Debug)]
897pub struct Pad {
898 t: usize,
899 b: usize,
900 l: usize,
901}
902
903impl Pad {
904 pub fn new(t: usize, b: usize, l: usize) -> Self {
905 Pad { t, b, l }
906 }
907}
908
909#[serde_with::skip_serializing_none]
910#[derive(Serialize, Clone, Debug, FieldSetter)]
911pub struct Title {
912 text: Option<String>,
913 font: Option<Font>,
914 side: Option<Side>,
915 #[serde(rename = "xref")]
916 x_ref: Option<Reference>,
917 #[serde(rename = "yref")]
918 y_ref: Option<Reference>,
919 x: Option<f64>,
920 y: Option<f64>,
921 #[serde(rename = "xanchor")]
922 x_anchor: Option<Anchor>,
923 #[serde(rename = "yanchor")]
924 y_anchor: Option<Anchor>,
925 pad: Option<Pad>,
926}
927
928impl From<&str> for Title {
929 fn from(title: &str) -> Self {
930 Title::with_text(title)
931 }
932}
933
934impl From<String> for Title {
935 fn from(value: String) -> Self {
936 Title::with_text(value)
937 }
938}
939
940impl From<&String> for Title {
941 fn from(value: &String) -> Self {
942 Title::with_text(value)
943 }
944}
945
946impl Title {
947 pub fn new() -> Self {
948 Default::default()
949 }
950
951 pub fn with_text<S: Into<String>>(text: S) -> Self {
952 Title {
953 text: Some(text.into()),
954 ..Default::default()
955 }
956 }
957}
958
959#[serde_with::skip_serializing_none]
960#[derive(Serialize, Clone, Debug, FieldSetter)]
961pub struct Label {
962 #[serde(rename = "bgcolor")]
963 background_color: Option<Box<dyn Color>>,
964 #[serde(rename = "bordercolor")]
965 border_color: Option<Box<dyn Color>>,
966 font: Option<Font>,
967 align: Option<String>,
968 #[serde(rename = "namelength")]
969 name_length: Option<Dim<i32>>,
970}
971
972impl Label {
973 pub fn new() -> Self {
974 Default::default()
975 }
976}
977
978#[derive(Serialize, Clone, Debug, Default)]
979#[serde(rename_all = "lowercase")]
980pub enum ErrorType {
981 #[default]
982 Percent,
983 Constant,
984 #[serde(rename = "sqrt")]
985 SquareRoot,
986 Data,
987}
988
989#[serde_with::skip_serializing_none]
990#[derive(Serialize, Clone, Debug, FieldSetter)]
991pub struct ErrorData {
992 #[field_setter(default = "ErrorType::Percent")]
993 r#type: ErrorType,
994 array: Option<Vec<f64>>,
995 visible: Option<bool>,
996 symmetric: Option<bool>,
997 #[serde(rename = "arrayminus")]
998 array_minus: Option<Vec<f64>>,
999 value: Option<f64>,
1000 #[serde(rename = "valueminus")]
1001 value_minus: Option<f64>,
1002 #[serde(rename = "traceref")]
1003 trace_ref: Option<usize>,
1004 #[serde(rename = "tracerefminus")]
1005 trace_ref_minus: Option<usize>,
1006 copy_ystyle: Option<bool>,
1007 color: Option<Box<dyn Color>>,
1008 thickness: Option<f64>,
1009 width: Option<usize>,
1010}
1011
1012impl ErrorData {
1013 pub fn new(error_type: ErrorType) -> Self {
1014 ErrorData {
1015 r#type: error_type,
1016 ..Default::default()
1017 }
1018 }
1019}
1020
1021#[derive(Serialize, Clone, Debug)]
1022#[serde(rename_all = "lowercase")]
1023pub enum HoverOn {
1024 Points,
1025 Fills,
1026 #[serde(rename = "points+fills")]
1027 PointsAndFills,
1028}
1029
1030#[cfg(test)]
1031mod tests {
1032 use serde_json::{json, to_value};
1033
1034 use super::*;
1035 use crate::color::NamedColor;
1036
1037 #[test]
1038 fn serialize_domain() {
1039 let domain = Domain::new().column(0).row(0).x(&[0., 1.]).y(&[0., 1.]);
1040 let expected = json!({
1041 "column": 0,
1042 "row": 0,
1043 "x": [0.0, 1.0],
1044 "y": [0.0, 1.0],
1045 });
1046
1047 assert_eq!(to_value(domain).unwrap(), expected);
1048 }
1049
1050 #[test]
1051 fn serialize_direction() {
1052 let inc = Direction::Increasing { line: Line::new() };
1055 let expected = json!({"line": {}});
1056 assert_eq!(to_value(inc).unwrap(), expected);
1057
1058 let dec = Direction::Decreasing { line: Line::new() };
1059 let expected = json!({"line": {}});
1060 assert_eq!(to_value(dec).unwrap(), expected);
1061 }
1062
1063 #[test]
1064 fn serialize_hover_info() {
1065 assert_eq!(to_value(HoverInfo::X).unwrap(), json!("x"));
1066 assert_eq!(to_value(HoverInfo::Y).unwrap(), json!("y"));
1067 assert_eq!(to_value(HoverInfo::Z).unwrap(), json!("z"));
1068 assert_eq!(to_value(HoverInfo::XAndY).unwrap(), json!("x+y"));
1069 assert_eq!(to_value(HoverInfo::XAndZ).unwrap(), json!("x+z"));
1070 assert_eq!(to_value(HoverInfo::YAndZ).unwrap(), json!("y+z"));
1071 assert_eq!(to_value(HoverInfo::XAndYAndZ).unwrap(), json!("x+y+z"));
1072 assert_eq!(to_value(HoverInfo::Text).unwrap(), json!("text"));
1073 assert_eq!(to_value(HoverInfo::Name).unwrap(), json!("name"));
1074 assert_eq!(to_value(HoverInfo::All).unwrap(), json!("all"));
1075 assert_eq!(to_value(HoverInfo::None).unwrap(), json!("none"));
1076 assert_eq!(to_value(HoverInfo::Skip).unwrap(), json!("skip"));
1077 }
1078
1079 #[test]
1080 fn serialize_text_position() {
1081 assert_eq!(to_value(TextPosition::Inside).unwrap(), json!("inside"));
1082 assert_eq!(to_value(TextPosition::Outside).unwrap(), json!("outside"));
1083 assert_eq!(to_value(TextPosition::Auto).unwrap(), json!("auto"));
1084 assert_eq!(to_value(TextPosition::None).unwrap(), json!("none"));
1085 }
1086
1087 #[test]
1088 fn serialize_constrain_text() {
1089 assert_eq!(to_value(ConstrainText::Inside).unwrap(), json!("inside"));
1090 assert_eq!(to_value(ConstrainText::Outside).unwrap(), json!("outside"));
1091 assert_eq!(to_value(ConstrainText::Both).unwrap(), json!("both"));
1092 assert_eq!(to_value(ConstrainText::None).unwrap(), json!("none"));
1093 }
1094
1095 #[test]
1096 #[rustfmt::skip]
1097 fn serialize_orientation() {
1098 assert_eq!(to_value(Orientation::Vertical).unwrap(), json!("v"));
1099 assert_eq!(to_value(Orientation::Horizontal).unwrap(), json!("h"));
1100 }
1101
1102 #[test]
1103 fn serialize_fill() {
1104 assert_eq!(to_value(Fill::ToZeroY).unwrap(), json!("tozeroy"));
1105 assert_eq!(to_value(Fill::ToZeroX).unwrap(), json!("tozerox"));
1106 assert_eq!(to_value(Fill::ToNextY).unwrap(), json!("tonexty"));
1107 assert_eq!(to_value(Fill::ToNextX).unwrap(), json!("tonextx"));
1108 assert_eq!(to_value(Fill::ToSelf).unwrap(), json!("toself"));
1109 assert_eq!(to_value(Fill::ToNext).unwrap(), json!("tonext"));
1110 assert_eq!(to_value(Fill::None).unwrap(), json!("none"));
1111 }
1112
1113 #[test]
1114 fn serialize_calendar() {
1115 assert_eq!(to_value(Calendar::Gregorian).unwrap(), json!("gregorian"));
1116 assert_eq!(to_value(Calendar::Chinese).unwrap(), json!("chinese"));
1117 assert_eq!(to_value(Calendar::Coptic).unwrap(), json!("coptic"));
1118 assert_eq!(to_value(Calendar::DiscWorld).unwrap(), json!("discworld"));
1119 assert_eq!(to_value(Calendar::Ethiopian).unwrap(), json!("ethiopian"));
1120 assert_eq!(to_value(Calendar::Hebrew).unwrap(), json!("hebrew"));
1121 assert_eq!(to_value(Calendar::Islamic).unwrap(), json!("islamic"));
1122 assert_eq!(to_value(Calendar::Julian).unwrap(), json!("julian"));
1123 assert_eq!(to_value(Calendar::Mayan).unwrap(), json!("mayan"));
1124 assert_eq!(to_value(Calendar::Nanakshahi).unwrap(), json!("nanakshahi"));
1125 assert_eq!(to_value(Calendar::Nepali).unwrap(), json!("nepali"));
1126 assert_eq!(to_value(Calendar::Persian).unwrap(), json!("persian"));
1127 assert_eq!(to_value(Calendar::Jalali).unwrap(), json!("jalali"));
1128 assert_eq!(to_value(Calendar::Taiwan).unwrap(), json!("taiwan"));
1129 assert_eq!(to_value(Calendar::Thai).unwrap(), json!("thai"));
1130 assert_eq!(to_value(Calendar::Ummalqura).unwrap(), json!("ummalqura"));
1131 }
1132
1133 #[test]
1134 fn serialize_dim() {
1135 assert_eq!(to_value(Dim::Scalar(0)).unwrap(), json!(0));
1136 assert_eq!(to_value(Dim::Vector(vec![0])).unwrap(), json!([0]));
1137 }
1138
1139 #[test]
1140 #[rustfmt::skip]
1141 fn serialize_plot_type() {
1142 assert_eq!(to_value(PlotType::Scatter).unwrap(), json!("scatter"));
1143 assert_eq!(to_value(PlotType::ScatterGL).unwrap(), json!("scattergl"));
1144 assert_eq!(to_value(PlotType::Scatter3D).unwrap(), json!("scatter3d"));
1145 assert_eq!(to_value(PlotType::ScatterGeo).unwrap(), json!("scattergeo"));
1146 assert_eq!(to_value(PlotType::ScatterPolar).unwrap(), json!("scatterpolar"));
1147 assert_eq!(to_value(PlotType::ScatterPolarGL).unwrap(), json!("scatterpolargl"));
1148 assert_eq!(to_value(PlotType::Bar).unwrap(), json!("bar"));
1149 assert_eq!(to_value(PlotType::Box).unwrap(), json!("box"));
1150 assert_eq!(to_value(PlotType::Candlestick).unwrap(), json!("candlestick"));
1151 assert_eq!(to_value(PlotType::Contour).unwrap(), json!("contour"));
1152 assert_eq!(to_value(PlotType::HeatMap).unwrap(), json!("heatmap"));
1153 assert_eq!(to_value(PlotType::Histogram).unwrap(), json!("histogram"));
1154 assert_eq!(to_value(PlotType::Histogram2dContour).unwrap(), json!("histogram2dcontour"));
1155 assert_eq!(to_value(PlotType::Ohlc).unwrap(), json!("ohlc"));
1156 assert_eq!(to_value(PlotType::Sankey).unwrap(), json!("sankey"));
1157 assert_eq!(to_value(PlotType::Surface).unwrap(), json!("surface"));
1158 }
1159
1160 #[test]
1161 #[rustfmt::skip]
1162 fn serialize_mode() {
1163 assert_eq!(to_value(Mode::Lines).unwrap(), json!("lines"));
1164 assert_eq!(to_value(Mode::Markers).unwrap(), json!("markers"));
1165 assert_eq!(to_value(Mode::Text).unwrap(), json!("text"));
1166 assert_eq!(to_value(Mode::LinesMarkers).unwrap(), json!("lines+markers"));
1167 assert_eq!(to_value(Mode::LinesText).unwrap(), json!("lines+text"));
1168 assert_eq!(to_value(Mode::MarkersText).unwrap(), json!("markers+text"));
1169 assert_eq!(to_value(Mode::LinesMarkersText).unwrap(), json!("lines+markers+text"));
1170 assert_eq!(to_value(Mode::None).unwrap(), json!("none"));
1171 }
1172
1173 #[test]
1174 #[rustfmt::skip]
1175 fn serialize_axis_side() {
1176 assert_eq!(to_value(AxisSide::Left).unwrap(), json!("left"));
1177 assert_eq!(to_value(AxisSide::Top).unwrap(), json!("top"));
1178 assert_eq!(to_value(AxisSide::Right).unwrap(), json!("right"));
1179 assert_eq!(to_value(AxisSide::Bottom).unwrap(), json!("bottom"));
1180 }
1181
1182 #[test]
1183 #[rustfmt::skip]
1184 fn serialize_position() {
1185 assert_eq!(to_value(Position::TopLeft).unwrap(), json!("top left"));
1186 assert_eq!(to_value(Position::TopCenter).unwrap(), json!("top center"));
1187 assert_eq!(to_value(Position::TopRight).unwrap(), json!("top right"));
1188 assert_eq!(to_value(Position::MiddleLeft).unwrap(), json!("middle left"));
1189 assert_eq!(to_value(Position::MiddleCenter).unwrap(), json!("middle center"));
1190 assert_eq!(to_value(Position::MiddleRight).unwrap(), json!("middle right"));
1191 assert_eq!(to_value(Position::BottomLeft).unwrap(), json!("bottom left"));
1192 assert_eq!(to_value(Position::BottomCenter).unwrap(), json!("bottom center"));
1193 assert_eq!(to_value(Position::BottomRight).unwrap(), json!("bottom right"));
1194 }
1195
1196 #[test]
1197 fn serialize_ticks() {
1198 assert_eq!(to_value(Ticks::Outside).unwrap(), json!("outside"));
1199 assert_eq!(to_value(Ticks::Inside).unwrap(), json!("inside"));
1200 assert_eq!(to_value(Ticks::None).unwrap(), json!(""));
1201 }
1202
1203 #[test]
1204 fn serialize_show() {
1205 assert_eq!(to_value(Show::All).unwrap(), json!("all"));
1206 assert_eq!(to_value(Show::First).unwrap(), json!("first"));
1207 assert_eq!(to_value(Show::Last).unwrap(), json!("last"));
1208 assert_eq!(to_value(Show::None).unwrap(), json!("none"));
1209 }
1210
1211 #[test]
1212 fn serialize_default_color_bar() {
1213 let color_bar = ColorBar::new();
1214 let expected = json!({});
1215
1216 assert_eq!(to_value(color_bar).unwrap(), expected);
1217 }
1218
1219 #[test]
1220 fn serialize_color_bar() {
1221 let color_bar = ColorBar::new()
1222 .background_color("#123456")
1223 .border_color("#123456")
1224 .border_width(19)
1225 .dtick(1.0)
1226 .exponent_format(ExponentFormat::CapitalE)
1227 .len(99)
1228 .len_mode(ThicknessMode::Pixels)
1229 .n_ticks(500)
1230 .orientation(Orientation::Horizontal)
1231 .outline_color("#789456")
1232 .outline_width(7)
1233 .separate_thousands(true)
1234 .show_exponent(Show::All)
1235 .show_tick_labels(true)
1236 .show_tick_prefix(Show::First)
1237 .show_tick_suffix(Show::Last)
1238 .thickness(5)
1239 .thickness_mode(ThicknessMode::Fraction)
1240 .tick_angle(90.0)
1241 .tick_color("#777999")
1242 .tick_font(Font::new())
1243 .tick_format("tick_format")
1244 .tick_format_stops(vec![TickFormatStop::new()])
1245 .tick_len(1)
1246 .tick_mode(TickMode::Auto)
1247 .tick_prefix("prefix")
1248 .tick_suffix("suffix")
1249 .tick_text(vec!["txt"])
1250 .tick_vals(vec![1.0, 2.0])
1251 .tick_width(55)
1252 .tick0(0.0)
1253 .ticks(Ticks::Outside)
1254 .title(Title::new())
1255 .x(5.0)
1256 .x_anchor(Anchor::Bottom)
1257 .x_pad(2.2)
1258 .y(1.0)
1259 .y_anchor(Anchor::Auto)
1260 .y_pad(8.8);
1261
1262 let expected = json!({
1263 "bgcolor": "#123456",
1264 "bordercolor": "#123456",
1265 "borderwidth": 19,
1266 "dtick": 1.0,
1267 "exponentformat": "E",
1268 "len": 99,
1269 "lenmode": "pixels",
1270 "nticks": 500,
1271 "orientation": "h",
1272 "outlinecolor": "#789456",
1273 "outlinewidth": 7,
1274 "separatethousands": true,
1275 "showexponent": "all",
1276 "showticklabels": true,
1277 "showtickprefix": "first",
1278 "showticksuffix": "last",
1279 "thickness": 5,
1280 "thicknessmode": "fraction",
1281 "tickangle": 90.0,
1282 "tickcolor": "#777999",
1283 "tickfont": {},
1284 "tickformat": "tick_format",
1285 "tickformatstops": [{"enabled": true}],
1286 "ticklen": 1,
1287 "tickmode": "auto",
1288 "tickprefix": "prefix",
1289 "ticksuffix": "suffix",
1290 "ticktext": ["txt"],
1291 "tickvals": [1.0, 2.0],
1292 "tickwidth": 55,
1293 "tick0": 0.0,
1294 "ticks": "outside",
1295 "title": {},
1296 "x": 5.0,
1297 "xanchor": "bottom",
1298 "xpad": 2.2,
1299 "y": 1.0,
1300 "yanchor": "auto",
1301 "ypad": 8.8
1302 });
1303
1304 assert_eq!(to_value(color_bar).unwrap(), expected);
1305 }
1306
1307 #[test]
1308 #[rustfmt::skip]
1309 fn serialize_marker_symbol() {
1310 assert_eq!(to_value(MarkerSymbol::Circle).unwrap(), json!("circle"));
1311 assert_eq!(to_value(MarkerSymbol::CircleOpen).unwrap(), json!("circle-open"));
1312 assert_eq!(to_value(MarkerSymbol::CircleDot).unwrap(), json!("circle-dot"));
1313 assert_eq!(to_value(MarkerSymbol::CircleOpenDot).unwrap(), json!("circle-open-dot"));
1314 assert_eq!(to_value(MarkerSymbol::Square).unwrap(), json!("square"));
1315 assert_eq!(to_value(MarkerSymbol::SquareOpen).unwrap(), json!("square-open"));
1316 assert_eq!(to_value(MarkerSymbol::SquareDot).unwrap(), json!("square-dot"));
1317 assert_eq!(to_value(MarkerSymbol::SquareOpenDot).unwrap(), json!("square-open-dot"));
1318 assert_eq!(to_value(MarkerSymbol::Diamond).unwrap(), json!("diamond"));
1319 assert_eq!(to_value(MarkerSymbol::DiamondOpen).unwrap(), json!("diamond-open"));
1320 assert_eq!(to_value(MarkerSymbol::DiamondDot).unwrap(), json!("diamond-dot"));
1321 assert_eq!(to_value(MarkerSymbol::DiamondOpenDot).unwrap(), json!("diamond-open-dot"));
1322 assert_eq!(to_value(MarkerSymbol::Cross).unwrap(), json!("cross"));
1323 assert_eq!(to_value(MarkerSymbol::CrossOpen).unwrap(), json!("cross-open"));
1324 assert_eq!(to_value(MarkerSymbol::CrossDot).unwrap(), json!("cross-dot"));
1325 assert_eq!(to_value(MarkerSymbol::CrossOpenDot).unwrap(), json!("cross-open-dot"));
1326 assert_eq!(to_value(MarkerSymbol::X).unwrap(), json!("x"));
1327 assert_eq!(to_value(MarkerSymbol::XOpen).unwrap(), json!("x-open"));
1328 assert_eq!(to_value(MarkerSymbol::XDot).unwrap(), json!("x-dot"));
1329 assert_eq!(to_value(MarkerSymbol::XOpenDot).unwrap(), json!("x-open-dot"));
1330 assert_eq!(to_value(MarkerSymbol::TriangleUp).unwrap(), json!("triangle-up"));
1331 assert_eq!(to_value(MarkerSymbol::TriangleUpOpen).unwrap(), json!("triangle-up-open"));
1332 assert_eq!(to_value(MarkerSymbol::TriangleUpDot).unwrap(), json!("triangle-up-dot"));
1333 assert_eq!(to_value(MarkerSymbol::TriangleUpOpenDot).unwrap(), json!("triangle-up-open-dot"));
1334 assert_eq!(to_value(MarkerSymbol::TriangleDown).unwrap(), json!("triangle-down"));
1335 assert_eq!(to_value(MarkerSymbol::TriangleDownOpen).unwrap(), json!("triangle-down-open"));
1336 assert_eq!(to_value(MarkerSymbol::TriangleDownDot).unwrap(), json!("triangle-down-dot"));
1337 assert_eq!(to_value(MarkerSymbol::TriangleDownOpenDot).unwrap(), json!("triangle-down-open-dot"));
1338 assert_eq!(to_value(MarkerSymbol::TriangleLeft).unwrap(), json!("triangle-left"));
1339 assert_eq!(to_value(MarkerSymbol::TriangleLeftOpen).unwrap(), json!("triangle-left-open"));
1340 assert_eq!(to_value(MarkerSymbol::TriangleLeftDot).unwrap(), json!("triangle-left-dot"));
1341 assert_eq!(to_value(MarkerSymbol::TriangleLeftOpenDot).unwrap(), json!("triangle-left-open-dot"));
1342 assert_eq!(to_value(MarkerSymbol::TriangleRight).unwrap(), json!("triangle-right"));
1343 assert_eq!(to_value(MarkerSymbol::TriangleRightOpen).unwrap(), json!("triangle-right-open"));
1344 assert_eq!(to_value(MarkerSymbol::TriangleRightDot).unwrap(), json!("triangle-right-dot"));
1345 assert_eq!(to_value(MarkerSymbol::TriangleRightOpenDot).unwrap(), json!("triangle-right-open-dot"));
1346 assert_eq!(to_value(MarkerSymbol::TriangleNE).unwrap(), json!("triangle-ne"));
1347 assert_eq!(to_value(MarkerSymbol::TriangleNEOpen).unwrap(), json!("triangle-ne-open"));
1348 assert_eq!(to_value(MarkerSymbol::TriangleNEDot).unwrap(), json!("triangle-ne-dot"));
1349 assert_eq!(to_value(MarkerSymbol::TriangleNEOpenDot).unwrap(), json!("triangle-ne-open-dot"));
1350 assert_eq!(to_value(MarkerSymbol::TriangleSE).unwrap(), json!("triangle-se"));
1351 assert_eq!(to_value(MarkerSymbol::TriangleSEOpen).unwrap(), json!("triangle-se-open"));
1352 assert_eq!(to_value(MarkerSymbol::TriangleSEDot).unwrap(), json!("triangle-se-dot"));
1353 assert_eq!(to_value(MarkerSymbol::TriangleSEOpenDot).unwrap(), json!("triangle-se-open-dot"));
1354 assert_eq!(to_value(MarkerSymbol::TriangleSW).unwrap(), json!("triangle-sw"));
1355 assert_eq!(to_value(MarkerSymbol::TriangleSWOpen).unwrap(), json!("triangle-sw-open"));
1356 assert_eq!(to_value(MarkerSymbol::TriangleSWDot).unwrap(), json!("triangle-sw-dot"));
1357 assert_eq!(to_value(MarkerSymbol::TriangleSWOpenDot).unwrap(), json!("triangle-sw-open-dot"));
1358 assert_eq!(to_value(MarkerSymbol::TriangleNW).unwrap(), json!("triangle-nw"));
1359 assert_eq!(to_value(MarkerSymbol::TriangleNWOpen).unwrap(), json!("triangle-nw-open"));
1360 assert_eq!(to_value(MarkerSymbol::TriangleNWDot).unwrap(), json!("triangle-nw-dot"));
1361 assert_eq!(to_value(MarkerSymbol::TriangleNWOpenDot).unwrap(), json!("triangle-nw-open-dot"));
1362 assert_eq!(to_value(MarkerSymbol::Pentagon).unwrap(), json!("pentagon"));
1363 assert_eq!(to_value(MarkerSymbol::PentagonOpen).unwrap(), json!("pentagon-open"));
1364 assert_eq!(to_value(MarkerSymbol::PentagonDot).unwrap(), json!("pentagon-dot"));
1365 assert_eq!(to_value(MarkerSymbol::PentagonOpenDot).unwrap(), json!("pentagon-open-dot"));
1366 assert_eq!(to_value(MarkerSymbol::Hexagon).unwrap(), json!("hexagon"));
1367 assert_eq!(to_value(MarkerSymbol::HexagonOpen).unwrap(), json!("hexagon-open"));
1368 assert_eq!(to_value(MarkerSymbol::HexagonDot).unwrap(), json!("hexagon-dot"));
1369 assert_eq!(to_value(MarkerSymbol::HexagonOpenDot).unwrap(), json!("hexagon-open-dot"));
1370 assert_eq!(to_value(MarkerSymbol::Hexagon2).unwrap(), json!("hexagon2"));
1371 assert_eq!(to_value(MarkerSymbol::Hexagon2Open).unwrap(), json!("hexagon2-open"));
1372 assert_eq!(to_value(MarkerSymbol::Hexagon2Dot).unwrap(), json!("hexagon2-dot"));
1373 assert_eq!(to_value(MarkerSymbol::Hexagon2OpenDot).unwrap(), json!("hexagon2-open-dot"));
1374 assert_eq!(to_value(MarkerSymbol::Octagon).unwrap(), json!("octagon"));
1375 assert_eq!(to_value(MarkerSymbol::OctagonOpen).unwrap(), json!("octagon-open"));
1376 assert_eq!(to_value(MarkerSymbol::OctagonDot).unwrap(), json!("octagon-dot"));
1377 assert_eq!(to_value(MarkerSymbol::OctagonOpenDot).unwrap(), json!("octagon-open-dot"));
1378 assert_eq!(to_value(MarkerSymbol::Star).unwrap(), json!("star"));
1379 assert_eq!(to_value(MarkerSymbol::StarOpen).unwrap(), json!("star-open"));
1380 assert_eq!(to_value(MarkerSymbol::StarDot).unwrap(), json!("star-dot"));
1381 assert_eq!(to_value(MarkerSymbol::StarOpenDot).unwrap(), json!("star-open-dot"));
1382 assert_eq!(to_value(MarkerSymbol::Hexagram).unwrap(), json!("hexagram"));
1383 assert_eq!(to_value(MarkerSymbol::HexagramOpen).unwrap(), json!("hexagram-open"));
1384 assert_eq!(to_value(MarkerSymbol::HexagramDot).unwrap(), json!("hexagram-dot"));
1385 assert_eq!(to_value(MarkerSymbol::HexagramOpenDot).unwrap(), json!("hexagram-open-dot"));
1386 assert_eq!(to_value(MarkerSymbol::StarTriangleUp).unwrap(), json!("star-triangle-up"));
1387 assert_eq!(to_value(MarkerSymbol::StarTriangleUpOpen).unwrap(), json!("star-triangle-up-open"));
1388 assert_eq!(to_value(MarkerSymbol::StarTriangleUpDot).unwrap(), json!("star-triangle-up-dot"));
1389 assert_eq!(to_value(MarkerSymbol::StarTriangleUpOpenDot).unwrap(), json!("star-triangle-up-open-dot"));
1390 assert_eq!(to_value(MarkerSymbol::StarTriangleDown).unwrap(), json!("star-triangle-down"));
1391 assert_eq!(to_value(MarkerSymbol::StarTriangleDownOpen).unwrap(), json!("star-triangle-down-open"));
1392 assert_eq!(to_value(MarkerSymbol::StarTriangleDownDot).unwrap(), json!("star-triangle-down-dot"));
1393 assert_eq!(to_value(MarkerSymbol::StarTriangleDownOpenDot).unwrap(), json!("star-triangle-down-open-dot"));
1394 assert_eq!(to_value(MarkerSymbol::StarSquare).unwrap(), json!("star-square"));
1395 assert_eq!(to_value(MarkerSymbol::StarSquareOpen).unwrap(), json!("star-square-open"));
1396 assert_eq!(to_value(MarkerSymbol::StarSquareDot).unwrap(), json!("star-square-dot"));
1397 assert_eq!(to_value(MarkerSymbol::StarSquareOpenDot).unwrap(), json!("star-square-open-dot"));
1398 assert_eq!(to_value(MarkerSymbol::StarDiamond).unwrap(), json!("star-diamond"));
1399 assert_eq!(to_value(MarkerSymbol::StarDiamondOpen).unwrap(), json!("star-diamond-open"));
1400 assert_eq!(to_value(MarkerSymbol::StarDiamondDot).unwrap(), json!("star-diamond-dot"));
1401 assert_eq!(to_value(MarkerSymbol::StarDiamondOpenDot).unwrap(), json!("star-diamond-open-dot"));
1402 assert_eq!(to_value(MarkerSymbol::DiamondTall).unwrap(), json!("diamond-tall"));
1403 assert_eq!(to_value(MarkerSymbol::DiamondTallOpen).unwrap(), json!("diamond-tall-open"));
1404 assert_eq!(to_value(MarkerSymbol::DiamondTallDot).unwrap(), json!("diamond-tall-dot"));
1405 assert_eq!(to_value(MarkerSymbol::DiamondTallOpenDot).unwrap(), json!("diamond-tall-open-dot"));
1406 assert_eq!(to_value(MarkerSymbol::DiamondWide).unwrap(), json!("diamond-wide"));
1407 assert_eq!(to_value(MarkerSymbol::DiamondWideOpen).unwrap(), json!("diamond-wide-open"));
1408 assert_eq!(to_value(MarkerSymbol::DiamondWideDot).unwrap(), json!("diamond-wide-dot"));
1409 assert_eq!(to_value(MarkerSymbol::DiamondWideOpenDot).unwrap(), json!("diamond-wide-open-dot"));
1410 assert_eq!(to_value(MarkerSymbol::Hourglass).unwrap(), json!("hourglass"));
1411 assert_eq!(to_value(MarkerSymbol::HourglassOpen).unwrap(), json!("hourglass-open"));
1412 assert_eq!(to_value(MarkerSymbol::BowTie).unwrap(), json!("bowtie"));
1413 assert_eq!(to_value(MarkerSymbol::BowTieOpen).unwrap(), json!("bowtie-open"));
1414 assert_eq!(to_value(MarkerSymbol::CircleCross).unwrap(), json!("circle-cross"));
1415 assert_eq!(to_value(MarkerSymbol::CircleCrossOpen).unwrap(), json!("circle-cross-open"));
1416 assert_eq!(to_value(MarkerSymbol::CircleX).unwrap(), json!("circle-x"));
1417 assert_eq!(to_value(MarkerSymbol::CircleXOpen).unwrap(), json!("circle-x-open"));
1418 assert_eq!(to_value(MarkerSymbol::SquareCross).unwrap(), json!("square-cross"));
1419 assert_eq!(to_value(MarkerSymbol::SquareCrossOpen).unwrap(), json!("square-cross-open"));
1420 assert_eq!(to_value(MarkerSymbol::SquareX).unwrap(), json!("square-x"));
1421 assert_eq!(to_value(MarkerSymbol::SquareXOpen).unwrap(), json!("square-x-open"));
1422 assert_eq!(to_value(MarkerSymbol::DiamondCross).unwrap(), json!("diamond-cross"));
1423 assert_eq!(to_value(MarkerSymbol::DiamondCrossOpen).unwrap(), json!("diamond-cross-open"));
1424 assert_eq!(to_value(MarkerSymbol::DiamondX).unwrap(), json!("diamond-x"));
1425 assert_eq!(to_value(MarkerSymbol::DiamondXOpen).unwrap(), json!("diamond-x-open"));
1426 assert_eq!(to_value(MarkerSymbol::CrossThin).unwrap(), json!("cross-thin"));
1427 assert_eq!(to_value(MarkerSymbol::CrossThinOpen).unwrap(), json!("cross-thin-open"));
1428 assert_eq!(to_value(MarkerSymbol::XThin).unwrap(), json!("x-thin"));
1429 assert_eq!(to_value(MarkerSymbol::XThinOpen).unwrap(), json!("x-thin-open"));
1430 assert_eq!(to_value(MarkerSymbol::Asterisk).unwrap(), json!("asterisk"));
1431 assert_eq!(to_value(MarkerSymbol::AsteriskOpen).unwrap(), json!("asterisk-open"));
1432 assert_eq!(to_value(MarkerSymbol::Hash).unwrap(), json!("hash"));
1433 assert_eq!(to_value(MarkerSymbol::HashOpen).unwrap(), json!("hash-open"));
1434 assert_eq!(to_value(MarkerSymbol::HashDot).unwrap(), json!("hash-dot"));
1435 assert_eq!(to_value(MarkerSymbol::HashOpenDot).unwrap(), json!("hash-open-dot"));
1436 assert_eq!(to_value(MarkerSymbol::YUp).unwrap(), json!("y-up"));
1437 assert_eq!(to_value(MarkerSymbol::YUpOpen).unwrap(), json!("y-up-open"));
1438 assert_eq!(to_value(MarkerSymbol::YDown).unwrap(), json!("y-down"));
1439 assert_eq!(to_value(MarkerSymbol::YDownOpen).unwrap(), json!("y-down-open"));
1440 assert_eq!(to_value(MarkerSymbol::YLeft).unwrap(), json!("y-left"));
1441 assert_eq!(to_value(MarkerSymbol::YLeftOpen).unwrap(), json!("y-left-open"));
1442 assert_eq!(to_value(MarkerSymbol::YRight).unwrap(), json!("y-right"));
1443 assert_eq!(to_value(MarkerSymbol::YRightOpen).unwrap(), json!("y-right-open"));
1444 assert_eq!(to_value(MarkerSymbol::LineEW).unwrap(), json!("line-ew"));
1445 assert_eq!(to_value(MarkerSymbol::LineEWOpen).unwrap(), json!("line-ew-open"));
1446 assert_eq!(to_value(MarkerSymbol::LineNS).unwrap(), json!("line-ns"));
1447 assert_eq!(to_value(MarkerSymbol::LineNSOpen).unwrap(), json!("line-ns-open"));
1448 assert_eq!(to_value(MarkerSymbol::LineNE).unwrap(), json!("line-ne"));
1449 assert_eq!(to_value(MarkerSymbol::LineNEOpen).unwrap(), json!("line-ne-open"));
1450 assert_eq!(to_value(MarkerSymbol::LineNW).unwrap(), json!("line-nw"));
1451 assert_eq!(to_value(MarkerSymbol::LineNWOpen).unwrap(), json!("line-nw-open"));
1452 }
1453
1454 #[test]
1455 fn serialize_tick_mode() {
1456 assert_eq!(to_value(TickMode::Auto).unwrap(), json!("auto"));
1457 assert_eq!(to_value(TickMode::Linear).unwrap(), json!("linear"));
1458 assert_eq!(to_value(TickMode::Array).unwrap(), json!("array"));
1459 }
1460
1461 #[test]
1462 #[rustfmt::skip]
1463 fn serialize_dash_type() {
1464 assert_eq!(to_value(DashType::Solid).unwrap(), json!("solid"));
1465 assert_eq!(to_value(DashType::Dot).unwrap(), json!("dot"));
1466 assert_eq!(to_value(DashType::Dash).unwrap(), json!("dash"));
1467 assert_eq!(to_value(DashType::LongDash).unwrap(), json!("longdash"));
1468 assert_eq!(to_value(DashType::DashDot).unwrap(), json!("dashdot"));
1469 assert_eq!(to_value(DashType::LongDashDot).unwrap(), json!("longdashdot"));
1470 }
1471
1472 #[test]
1473 #[rustfmt::skip]
1474 fn serialize_color_scale_element() {
1475 assert_eq!(to_value(ColorScaleElement(0., "red".to_string())).unwrap(), json!([0.0, "red"]));
1476 }
1477
1478 #[test]
1479 #[rustfmt::skip]
1480 fn serialize_color_scale_palette() {
1481 assert_eq!(to_value(ColorScalePalette::Greys).unwrap(), json!("Greys"));
1482 assert_eq!(to_value(ColorScalePalette::YlGnBu).unwrap(), json!("YlGnBu"));
1483 assert_eq!(to_value(ColorScalePalette::Greens).unwrap(), json!("Greens"));
1484 assert_eq!(to_value(ColorScalePalette::YlOrRd).unwrap(), json!("YlOrRd"));
1485 assert_eq!(to_value(ColorScalePalette::Bluered).unwrap(), json!("Bluered"));
1486 assert_eq!(to_value(ColorScalePalette::RdBu).unwrap(), json!("RdBu"));
1487 assert_eq!(to_value(ColorScalePalette::Reds).unwrap(), json!("Reds"));
1488 assert_eq!(to_value(ColorScalePalette::Blues).unwrap(), json!("Blues"));
1489 assert_eq!(to_value(ColorScalePalette::Picnic).unwrap(), json!("Picnic"));
1490 assert_eq!(to_value(ColorScalePalette::Rainbow).unwrap(), json!("Rainbow"));
1491 assert_eq!(to_value(ColorScalePalette::Portland).unwrap(), json!("Portland"));
1492 assert_eq!(to_value(ColorScalePalette::Jet).unwrap(), json!("Jet"));
1493 assert_eq!(to_value(ColorScalePalette::Hot).unwrap(), json!("Hot"));
1494 assert_eq!(to_value(ColorScalePalette::Blackbody).unwrap(), json!("Blackbody"));
1495 assert_eq!(to_value(ColorScalePalette::Earth).unwrap(), json!("Earth"));
1496 assert_eq!(to_value(ColorScalePalette::Electric).unwrap(), json!("Electric"));
1497 assert_eq!(to_value(ColorScalePalette::Viridis).unwrap(), json!("Viridis"));
1498 assert_eq!(to_value(ColorScalePalette::Cividis).unwrap(), json!("Cividis"));
1499 }
1500
1501 #[test]
1502 fn serialize_color_scale() {
1503 assert_eq!(
1504 to_value(ColorScale::Palette(ColorScalePalette::Greys)).unwrap(),
1505 json!("Greys")
1506 );
1507 assert_eq!(
1508 to_value(ColorScale::Vector(vec![ColorScaleElement(
1509 0.0,
1510 "red".to_string()
1511 )]))
1512 .unwrap(),
1513 json!([[0.0, "red"]])
1514 );
1515 }
1516
1517 #[test]
1518 fn serialize_line_shape() {
1519 assert_eq!(to_value(LineShape::Linear).unwrap(), json!("linear"));
1520 assert_eq!(to_value(LineShape::Spline).unwrap(), json!("spline"));
1521 assert_eq!(to_value(LineShape::Hv).unwrap(), json!("hv"));
1522 assert_eq!(to_value(LineShape::Vh).unwrap(), json!("vh"));
1523 assert_eq!(to_value(LineShape::Hvh).unwrap(), json!("hvh"));
1524 assert_eq!(to_value(LineShape::Vhv).unwrap(), json!("vhv"));
1525 }
1526
1527 #[test]
1528 fn serialize_line() {
1529 let line = Line::new()
1530 .width(0.1)
1531 .shape(LineShape::Linear)
1532 .smoothing(1.0)
1533 .dash(DashType::Dash)
1534 .simplify(true)
1535 .color("#FFFFFF")
1536 .cauto(true)
1537 .cmin(0.0)
1538 .cmax(1.0)
1539 .cmid(0.5)
1540 .color_scale(ColorScale::Palette(ColorScalePalette::Greys))
1541 .auto_color_scale(true)
1542 .reverse_scale(true)
1543 .outlier_color("#111111")
1544 .outlier_width(1);
1545
1546 let expected = json!({
1547 "width": 0.1,
1548 "shape": "linear",
1549 "smoothing": 1.0,
1550 "dash": "dash",
1551 "simplify": true,
1552 "color": "#FFFFFF",
1553 "cauto": true,
1554 "cmin": 0.0,
1555 "cmax": 1.0,
1556 "cmid": 0.5,
1557 "colorscale": "Greys",
1558 "autocolorscale": true,
1559 "reversescale": true,
1560 "outliercolor": "#111111",
1561 "outlierwidth": 1
1562 });
1563
1564 assert_eq!(to_value(line).unwrap(), expected);
1565 }
1566
1567 #[test]
1568 #[rustfmt::skip]
1569 fn serialize_gradient_type() {
1570 assert_eq!(to_value(GradientType::Radial).unwrap(), json!("radial"));
1571 assert_eq!(to_value(GradientType::Horizontal).unwrap(), json!("horizontal"));
1572 assert_eq!(to_value(GradientType::Vertical).unwrap(), json!("vertical"));
1573 assert_eq!(to_value(GradientType::None).unwrap(), json!("none"));
1574 }
1575
1576 #[test]
1577 fn serialize_size_mode() {
1578 assert_eq!(to_value(SizeMode::Diameter).unwrap(), json!("diameter"));
1579 assert_eq!(to_value(SizeMode::Area).unwrap(), json!("area"));
1580 }
1581
1582 #[test]
1583 #[rustfmt::skip]
1584 fn serialize_thickness_mode() {
1585 assert_eq!(to_value(ThicknessMode::Fraction).unwrap(), json!("fraction"));
1586 assert_eq!(to_value(ThicknessMode::Pixels).unwrap(), json!("pixels"));
1587 }
1588
1589 #[test]
1590 fn serialize_anchor() {
1591 assert_eq!(to_value(Anchor::Auto).unwrap(), json!("auto"));
1592 assert_eq!(to_value(Anchor::Left).unwrap(), json!("left"));
1593 assert_eq!(to_value(Anchor::Center).unwrap(), json!("center"));
1594 assert_eq!(to_value(Anchor::Right).unwrap(), json!("right"));
1595 assert_eq!(to_value(Anchor::Top).unwrap(), json!("top"));
1596 assert_eq!(to_value(Anchor::Middle).unwrap(), json!("middle"));
1597 assert_eq!(to_value(Anchor::Bottom).unwrap(), json!("bottom"));
1598 }
1599
1600 #[test]
1601 fn serialize_text_anchor() {
1602 assert_eq!(to_value(TextAnchor::Start).unwrap(), json!("start"));
1603 assert_eq!(to_value(TextAnchor::Middle).unwrap(), json!("middle"));
1604 assert_eq!(to_value(TextAnchor::End).unwrap(), json!("end"));
1605 }
1606
1607 #[test]
1608 fn serialize_exponent_format() {
1609 assert_eq!(to_value(ExponentFormat::None).unwrap(), json!("none"));
1610 assert_eq!(to_value(ExponentFormat::SmallE).unwrap(), json!("e"));
1611 assert_eq!(to_value(ExponentFormat::CapitalE).unwrap(), json!("E"));
1612 assert_eq!(to_value(ExponentFormat::Power).unwrap(), json!("power"));
1613 assert_eq!(to_value(ExponentFormat::SI).unwrap(), json!("SI"));
1614 assert_eq!(to_value(ExponentFormat::B).unwrap(), json!("B"));
1615 }
1616
1617 #[test]
1618 #[rustfmt::skip]
1619 fn serialize_gradient() {
1620 let gradient = Gradient::new(GradientType::Horizontal, "#FFFFFF");
1621 let expected = json!({"color": "#FFFFFF", "type": "horizontal"});
1622 assert_eq!(to_value(gradient).unwrap(), expected);
1623
1624 let gradient = Gradient::new_array(GradientType::Horizontal, vec!["#FFFFFF"]);
1625 let expected = json!({"color": ["#FFFFFF"], "type": "horizontal"});
1626 assert_eq!(to_value(gradient).unwrap(), expected);
1627 }
1628
1629 #[test]
1630 fn serialize_tick_format_stop_default() {
1631 let tick_format_stop = TickFormatStop::new();
1632 let expected = json!({"enabled": true});
1633 assert_eq!(to_value(tick_format_stop).unwrap(), expected);
1634 }
1635
1636 #[test]
1637 fn serialize_tick_format_stop() {
1638 let tick_format_stop = TickFormatStop::new()
1639 .enabled(false)
1640 .dtick_range(vec![0.0, 1.0])
1641 .value("value")
1642 .name("name")
1643 .template_item_name("template_item_name");
1644 let expected = json!({
1645 "enabled": false,
1646 "dtickrange": [0.0, 1.0],
1647 "value": "value",
1648 "name": "name",
1649 "templateitemname": "template_item_name"
1650 });
1651 assert_eq!(to_value(tick_format_stop).unwrap(), expected);
1652 }
1653
1654 #[test]
1655 fn serialize_pattern_shape() {
1656 assert_eq!(to_value(PatternShape::None).unwrap(), json!(""));
1657 assert_eq!(to_value(PatternShape::HorizontalLine).unwrap(), json!("-"));
1658 assert_eq!(to_value(PatternShape::VerticalLine).unwrap(), json!("|"));
1659 assert_eq!(
1660 to_value(PatternShape::RightDiagonalLine).unwrap(),
1661 json!("/")
1662 );
1663 assert_eq!(
1664 to_value(PatternShape::LeftDiagonalLine).unwrap(),
1665 json!("\\")
1666 );
1667 assert_eq!(to_value(PatternShape::Cross).unwrap(), json!("+"));
1668 assert_eq!(to_value(PatternShape::DiagonalCross).unwrap(), json!("x"));
1669 assert_eq!(to_value(PatternShape::Dot).unwrap(), json!("."));
1670 }
1671
1672 #[test]
1673 fn serialize_pattern_fill_mode() {
1674 assert_eq!(
1675 to_value(PatternFillMode::Replace).unwrap(),
1676 json!("replace")
1677 );
1678 assert_eq!(
1679 to_value(PatternFillMode::Overlay).unwrap(),
1680 json!("overlay")
1681 );
1682 }
1683
1684 #[test]
1685 fn serialize_pattern() {
1686 let pattern = Pattern::new()
1687 .shape_array(vec![
1688 PatternShape::HorizontalLine,
1689 PatternShape::VerticalLine,
1690 ])
1691 .fill_mode(PatternFillMode::Overlay)
1692 .background_color_array(vec![NamedColor::Black, NamedColor::Blue])
1693 .foreground_color_array(vec![NamedColor::Red, NamedColor::Green])
1694 .foreground_opacity(0.9)
1695 .size_array(vec![10.0, 20.0])
1696 .solidity_array(vec![0.1, 0.2]);
1697
1698 let expected = json!({
1699 "shape": ["-", "|"],
1700 "fillmode": "overlay",
1701 "bgcolor": ["black", "blue"],
1702 "fgcolor": ["red", "green"],
1703 "fgopacity": 0.9,
1704 "size": [10.0, 20.0],
1705 "solidity": [0.1, 0.2]
1706 });
1707
1708 assert_eq!(to_value(pattern).unwrap(), expected);
1709 }
1710
1711 #[test]
1712 fn serialize_marker() {
1713 let marker = Marker::new()
1714 .symbol(MarkerSymbol::Circle)
1715 .opacity(0.1)
1716 .size(1)
1717 .max_displayed(5)
1718 .size_ref(5)
1719 .size_min(1)
1720 .size_mode(SizeMode::Area)
1721 .line(Line::new())
1722 .gradient(Gradient::new(GradientType::Radial, "#FFFFFF"))
1723 .color(NamedColor::Blue)
1724 .colors(vec![NamedColor::Black, NamedColor::Blue])
1725 .color_array(vec![NamedColor::Black, NamedColor::Blue])
1726 .cauto(true)
1727 .cmin(0.0)
1728 .cmax(1.0)
1729 .cmid(0.5)
1730 .color_scale(ColorScale::Palette(ColorScalePalette::Earth))
1731 .auto_color_scale(true)
1732 .reverse_scale(true)
1733 .show_scale(true)
1734 .color_bar(ColorBar::new())
1735 .outlier_color("#FFFFFF")
1736 .pattern(
1737 Pattern::new()
1738 .shape(PatternShape::Cross)
1739 .foreground_color(NamedColor::Red)
1740 .size(10.0),
1741 );
1742
1743 let expected = json!({
1744 "symbol": "circle",
1745 "opacity": 0.1,
1746 "size": 1,
1747 "maxdisplayed": 5,
1748 "sizeref": 5,
1749 "sizemin": 1,
1750 "sizemode": "area",
1751 "line": {},
1752 "gradient": {"type": "radial", "color": "#FFFFFF"},
1753 "color": ["black", "blue"],
1754 "colors": ["black", "blue"],
1755 "colorbar": {},
1756 "cauto": true,
1757 "cmin": 0.0,
1758 "cmax": 1.0,
1759 "cmid": 0.5,
1760 "colorscale": "Earth",
1761 "autocolorscale": true,
1762 "reversescale": true,
1763 "showscale": true,
1764 "outliercolor": "#FFFFFF",
1765 "pattern": {
1766 "shape": "+",
1767 "fgcolor": "red",
1768 "size": 10.0
1769 }
1770 });
1771
1772 assert_eq!(to_value(marker).unwrap(), expected);
1773 }
1774
1775 #[test]
1776 fn serialize_font() {
1777 let font = Font::new().family("family").size(100).color("#FFFFFF");
1778 let expected = json!({
1779 "family": "family",
1780 "size": 100,
1781 "color": "#FFFFFF"
1782 });
1783
1784 assert_eq!(to_value(font).unwrap(), expected);
1785 }
1786
1787 #[test]
1788 fn serialize_side() {
1789 assert_eq!(to_value(Side::Right).unwrap(), json!("right"));
1790 assert_eq!(to_value(Side::Top).unwrap(), json!("top"));
1791 assert_eq!(to_value(Side::Bottom).unwrap(), json!("bottom"));
1792 assert_eq!(to_value(Side::Left).unwrap(), json!("left"));
1793 assert_eq!(to_value(Side::TopLeft).unwrap(), json!("top left"));
1794 }
1795
1796 #[test]
1797 fn serialize_reference() {
1798 assert_eq!(to_value(Reference::Container).unwrap(), json!("container"));
1799 assert_eq!(to_value(Reference::Paper).unwrap(), json!("paper"));
1800 }
1801
1802 #[test]
1803 #[rustfmt::skip]
1804 fn serialize_legend_group_title() {
1805 assert_eq!(to_value(LegendGroupTitle::new()).unwrap(), json!({}));
1806 assert_eq!(to_value(LegendGroupTitle::with_text("title_str").font(Font::default())).unwrap(), json!({"font": {}, "text": "title_str"}));
1807 assert_eq!(to_value(LegendGroupTitle::from(String::from("title_string"))).unwrap(), json!({"text" : "title_string"}));
1808 assert_eq!(to_value(LegendGroupTitle::from(&String::from("title_string"))).unwrap(), json!({"text" : "title_string"}));
1809 }
1810
1811 #[test]
1812 fn serialize_pad() {
1813 let pad = Pad::new(1, 2, 3);
1814 let expected = json!({
1815 "t": 1,
1816 "b": 2,
1817 "l": 3
1818 });
1819
1820 assert_eq!(to_value(pad).unwrap(), expected);
1821 }
1822
1823 #[test]
1824 fn serialize_title() {
1825 let title = Title::with_text("title")
1826 .font(Font::new())
1827 .side(Side::Top)
1828 .x_ref(Reference::Paper)
1829 .y_ref(Reference::Paper)
1830 .x(0.5)
1831 .y(0.5)
1832 .x_anchor(Anchor::Auto)
1833 .y_anchor(Anchor::Auto)
1834 .pad(Pad::new(0, 0, 0));
1835 let expected = json!({
1836 "text": "title",
1837 "font": {},
1838 "side": "top",
1839 "xref": "paper",
1840 "yref": "paper",
1841 "x": 0.5,
1842 "y": 0.5,
1843 "xanchor": "auto",
1844 "yanchor": "auto",
1845 "pad": {"t": 0, "b": 0, "l": 0}
1846 });
1847
1848 assert_eq!(to_value(title).unwrap(), expected);
1849 }
1850
1851 #[test]
1852 fn serialize_title_from_str() {
1853 let title = Title::from("from");
1854 let expected = json!({"text": "from"});
1855
1856 assert_eq!(to_value(title).unwrap(), expected);
1857
1858 let title: Title = "into".into();
1859 let expected = json!({"text": "into"});
1860
1861 assert_eq!(to_value(title).unwrap(), expected);
1862 }
1863
1864 #[test]
1865 fn serialize_label() {
1866 let label = Label::new()
1867 .background_color("#FFFFFF")
1868 .border_color("#000000")
1869 .font(Font::new())
1870 .align("something")
1871 .name_length_array(vec![5, 10])
1872 .name_length(6);
1873 let expected = json!({
1874 "bgcolor": "#FFFFFF",
1875 "bordercolor": "#000000",
1876 "font": {},
1877 "align": "something",
1878 "namelength": 6,
1879 });
1880
1881 assert_eq!(to_value(label).unwrap(), expected);
1882 }
1883
1884 #[test]
1885 fn serialize_error_type() {
1886 assert_eq!(to_value(ErrorType::Percent).unwrap(), json!("percent"));
1887 assert_eq!(to_value(ErrorType::Constant).unwrap(), json!("constant"));
1888 assert_eq!(to_value(ErrorType::SquareRoot).unwrap(), json!("sqrt"));
1889 assert_eq!(to_value(ErrorType::Data).unwrap(), json!("data"));
1890 }
1891
1892 #[test]
1893 fn serialize_error_type_default() {
1894 assert_eq!(to_value(ErrorType::default()).unwrap(), json!("percent"));
1895 }
1896
1897 #[test]
1898 fn serialize_error_data() {
1899 let error_data = ErrorData::new(ErrorType::Constant)
1900 .array(vec![0.1, 0.2])
1901 .visible(true)
1902 .symmetric(false)
1903 .array_minus(vec![0.05, 0.1])
1904 .value(5.0)
1905 .value_minus(2.5)
1906 .trace_ref(1)
1907 .trace_ref_minus(1)
1908 .copy_ystyle(true)
1909 .color("#AAAAAA")
1910 .thickness(2.0)
1911 .width(5);
1912 let expected = json!({
1913 "type": "constant",
1914 "array": [0.1, 0.2],
1915 "visible": true,
1916 "symmetric": false,
1917 "arrayminus": [0.05, 0.1],
1918 "value": 5.0,
1919 "valueminus": 2.5,
1920 "traceref": 1,
1921 "tracerefminus": 1,
1922 "copy_ystyle": true,
1923 "color": "#AAAAAA",
1924 "thickness": 2.0,
1925 "width": 5,
1926 });
1927
1928 assert_eq!(to_value(error_data).unwrap(), expected)
1929 }
1930
1931 #[test]
1932 fn serialize_visible() {
1933 assert_eq!(to_value(Visible::True).unwrap(), json!(true));
1934 assert_eq!(to_value(Visible::False).unwrap(), json!(false));
1935 assert_eq!(to_value(Visible::LegendOnly).unwrap(), json!("legendonly"));
1936 }
1937
1938 #[test]
1939 #[rustfmt::skip]
1940 fn serialize_hover_on() {
1941 assert_eq!(to_value(HoverOn::Points).unwrap(), json!("points"));
1942 assert_eq!(to_value(HoverOn::Fills).unwrap(), json!("fills"));
1943 assert_eq!(to_value(HoverOn::PointsAndFills).unwrap(), json!("points+fills"));
1944
1945 }
1946
1947 #[test]
1948 fn serialize_slider_anchor() {
1949 assert_eq!(to_value(Anchor::Auto).unwrap(), json!("auto"));
1950 assert_eq!(to_value(Anchor::Left).unwrap(), json!("left"));
1951 assert_eq!(to_value(Anchor::Center).unwrap(), json!("center"));
1952 assert_eq!(to_value(Anchor::Right).unwrap(), json!("right"));
1953 assert_eq!(to_value(Anchor::Top).unwrap(), json!("top"));
1954 assert_eq!(to_value(Anchor::Middle).unwrap(), json!("middle"));
1955 assert_eq!(to_value(Anchor::Bottom).unwrap(), json!("bottom"));
1956 }
1957
1958 #[test]
1959 #[allow(clippy::needless_borrows_for_generic_args)]
1960 fn title_method_can_take_string() {
1961 ColorBar::new().title("Title");
1962 ColorBar::new().title(String::from("Title"));
1963 ColorBar::new().title(&String::from("Title"));
1964 ColorBar::new().title(Title::with_text("Title"));
1965 }
1966}