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