plotly/common/
mod.rs

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