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