Skip to main content

mdbook_plotly/code_handler/plot_obj_parser/
box_plot_parser.rs

1use super::until::{Color, Map, must_translate};
2use crate::{translate, translate_enum};
3use anyhow::Result;
4use plotly::BoxPlot;
5
6pub fn parse_box_plot_data(
7    box_obj: &mut serde_json::Value,
8    map: &Map,
9) -> Result<Box<BoxPlot<f64, f64>>> {
10    let box_plot = if box_obj.get("y").is_some() {
11        let y: Vec<f64> = must_translate(box_obj, map, "y")?;
12        if box_obj.get("x").is_some() {
13            let x: Vec<f64> = must_translate(box_obj, map, "x")?;
14            BoxPlot::new_xy(x, y)
15        } else {
16            BoxPlot::new(y)
17        }
18    } else {
19        let y: Vec<f64> = Vec::new();
20        BoxPlot::new(y)
21    };
22
23    let box_plot = translate! {
24        box_plot,
25        box_obj,
26        map,
27        (name, String),
28        (opacity, f64),
29        (ids, Vec<String>),
30        (text, String),
31        (text_array, Vec<String>),
32        (hover_text, String),
33        (hover_text_array, Vec<String>),
34        (hover_template, String),
35        (hover_template_array, Vec<String>),
36        (x_axis, String),
37        (y_axis, String),
38        (alignment_group, String),
39        (offset_group, String),
40        (show_legend, bool),
41        (legend_group, String),
42        (fill_color, Color),
43        (notched, bool),
44        (notch_width, f64),
45        (whisker_width, f64),
46        (q1, Vec<f64>),
47        (median, Vec<f64>),
48        (q3, Vec<f64>),
49        (upper_fence, Vec<f64>),
50        (lower_fence, Vec<f64>),
51        (notch_span, Vec<f64>),
52        (mean, Vec<f64>),
53        (standard_deviation, Vec<f64>),
54        (point_pos, f64),
55        (jitter, f64),
56    }?;
57
58    use plotly::common::Orientation;
59    let box_plot = translate_enum! {
60        box_plot,
61        box_obj,
62        map,
63        (orientation, {
64            "v" => Orientation::Vertical,
65            "h" => Orientation::Horizontal,
66        }),
67    }?;
68
69    use plotly::traces::box_plot::{BoxMean, BoxPoints, HoverOn, QuartileMethod};
70    let box_plot = translate_enum! {
71        box_plot,
72        box_obj,
73        map,
74        (box_mean, {
75            "true"    => BoxMean::True,
76            "false"   => BoxMean::False,
77            "sd"      => BoxMean::StandardDeviation,
78        }),
79        (box_points, {
80            "all"           => BoxPoints::All,
81            "outliers"      => BoxPoints::Outliers,
82            "suspectedoutliers" => BoxPoints::SuspectedOutliers,
83            "false"         => BoxPoints::False,
84        }),
85        (quartile_method, {
86            "linear"        => QuartileMethod::Linear,
87            "exclusive"     => QuartileMethod::Exclusive,
88            "inclusive"     => QuartileMethod::Inclusive,
89        }),
90        (hover_on, {
91            "points"  => HoverOn::Points,
92            "boxes"   => HoverOn::Boxes,
93            "boxes+points" => HoverOn::BoxesAndPoints,
94        }),
95    }?;
96
97    let box_plot = if let Some(marker_obj) = box_obj.get_mut("marker")
98        && marker_obj.is_object()
99    {
100        let marker = plotly::common::Marker::new();
101        let marker = translate! {
102            marker,
103            marker_obj,
104            map,
105            (color, Color),
106            (opacity, f64),
107            (size, usize),
108            (size_array, Vec<usize>),
109            (max_displayed, usize),
110            (size_ref, usize),
111            (size_min, usize),
112            (cauto, bool),
113            (cmax, f64),
114            (cmin, f64),
115            (cmid, f64),
116            (auto_color_scale, bool),
117            (reverse_scale, bool),
118            (show_scale, bool),
119            (outlier_color, Color),
120        }?;
121
122        use plotly::common::{MarkerSymbol, SizeMode};
123        let marker = translate_enum! {
124            marker,
125            marker_obj,
126            map,
127            (symbol, {
128                "circle" =>         MarkerSymbol::Circle,
129                "square" =>         MarkerSymbol::Square,
130                "diamond" =>        MarkerSymbol::Diamond,
131                "cross" =>          MarkerSymbol::Cross,
132                "x" =>              MarkerSymbol::X,
133                "triangle-up" =>    MarkerSymbol::TriangleUp,
134                "triangle-down" =>  MarkerSymbol::TriangleDown,
135                "triangle-left" =>  MarkerSymbol::TriangleLeft,
136                "triangle-right" => MarkerSymbol::TriangleRight,
137                "pentagon" =>       MarkerSymbol::Pentagon,
138                "hexagon" =>        MarkerSymbol::Hexagon,
139            }),
140            (size_mode, {
141                "area" => SizeMode::Area,
142                "diameter" => SizeMode::Diameter,
143            }),
144        }?;
145        box_plot.marker(marker)
146    } else {
147        box_plot
148    };
149
150    let box_plot = if let Some(line_obj) = box_obj.get_mut("line")
151        && line_obj.is_object()
152    {
153        use plotly::common::Line;
154        let line = translate! {
155            Line::new(),
156            line_obj,
157            map,
158            (color, Color),
159            (width, f64),
160        }?;
161        use plotly::common::DashType;
162        let line = translate_enum! {
163            line,
164            line_obj,
165            map,
166            (dash, {
167                "solid" => DashType::Solid,
168                "dot" => DashType::Dot,
169                "dash" => DashType::Dash,
170                "longdash" => DashType::LongDash,
171                "dashdot" => DashType::DashDot,
172                "longdashdot" => DashType::LongDashDot,
173            }),
174        }?;
175        box_plot.line(line)
176    } else {
177        box_plot
178    };
179
180    Ok(box_plot)
181}