Skip to main content

mdbook_plotly/code_handler/plot_obj_parser/
box_plot_parser.rs

1use super::common::parse_marker;
2use super::until::{Color, must_translate_from_context};
3use crate::code_handler::parse_context::ParseContext;
4use crate::{translate_enum_with_config, translate_with_config};
5use anyhow::Result;
6use plotly::Trace;
7use plotly::BoxPlot;
8
9pub fn parse_box_plot_data(
10    box_obj: &mut serde_json::Value,
11    context: &ParseContext<'_>,
12) -> Result<Box<dyn Trace>> {
13    let box_plot = if box_obj.get("y").is_some() {
14        let y: Vec<f64> = must_translate_from_context(box_obj, context, "y")?;
15        if box_obj.get("x").is_some() {
16            let x: Vec<f64> = must_translate_from_context(box_obj, context, "x")?;
17            BoxPlot::new_xy(x, y)
18        } else {
19            BoxPlot::new(y)
20        }
21    } else {
22        let y: Vec<f64> = Vec::new();
23        BoxPlot::new(y)
24    };
25
26    let box_plot = translate_with_config! {
27        box_plot,
28        box_obj,
29        context.map(),
30        context.map_eval(),
31        (name, String),
32        (opacity, f64),
33        (ids, Vec<String>),
34        (text, String),
35        (text_array, Vec<String>),
36        (hover_text, String),
37        (hover_text_array, Vec<String>),
38        (hover_template, String),
39        (hover_template_array, Vec<String>),
40        (x_axis, String),
41        (y_axis, String),
42        (alignment_group, String),
43        (offset_group, String),
44        (show_legend, bool),
45        (legend_group, String),
46        (fill_color, Color),
47        (notched, bool),
48        (notch_width, f64),
49        (whisker_width, f64),
50        (q1, Vec<f64>),
51        (median, Vec<f64>),
52        (q3, Vec<f64>),
53        (upper_fence, Vec<f64>),
54        (lower_fence, Vec<f64>),
55        (notch_span, Vec<f64>),
56        (mean, Vec<f64>),
57        (standard_deviation, Vec<f64>),
58        (point_pos, f64),
59        (jitter, f64),
60    }?;
61
62    use plotly::common::Orientation;
63    let box_plot = translate_enum_with_config! {
64        box_plot,
65        box_obj,
66        context.map(),
67        context.map_eval(),
68        (orientation, {
69            "v" => Orientation::Vertical,
70            "h" => Orientation::Horizontal,
71        }),
72    }?;
73
74    use plotly::traces::box_plot::{BoxMean, BoxPoints, HoverOn, QuartileMethod};
75    let box_plot = translate_enum_with_config! {
76        box_plot,
77        box_obj,
78        context.map(),
79        context.map_eval(),
80        (box_mean, {
81            "true"    => BoxMean::True,
82            "false"   => BoxMean::False,
83            "sd"      => BoxMean::StandardDeviation,
84        }),
85        (box_points, {
86            "all"           => BoxPoints::All,
87            "outliers"      => BoxPoints::Outliers,
88            "suspectedoutliers" => BoxPoints::SuspectedOutliers,
89            "false"         => BoxPoints::False,
90        }),
91        (quartile_method, {
92            "linear"        => QuartileMethod::Linear,
93            "exclusive"     => QuartileMethod::Exclusive,
94            "inclusive"     => QuartileMethod::Inclusive,
95        }),
96        (hover_on, {
97            "points"  => HoverOn::Points,
98            "boxes"   => HoverOn::Boxes,
99            "boxes+points" => HoverOn::BoxesAndPoints,
100        }),
101    }?;
102
103    let box_plot = if let Some(marker_obj) = box_obj.get_mut("marker")
104        && marker_obj.is_object()
105    {
106        let marker = parse_marker(marker_obj, context)?;
107        box_plot.marker(marker)
108    } else {
109        box_plot
110    };
111
112    let box_plot = if let Some(line_obj) = box_obj.get_mut("line")
113        && line_obj.is_object()
114    {
115        use plotly::common::Line;
116        let line = translate_with_config! {
117            Line::new(),
118            line_obj,
119            context.map(),
120            context.map_eval(),
121            (color, Color),
122            (width, f64),
123        }?;
124        use plotly::common::DashType;
125        let line = translate_enum_with_config! {
126            line,
127            line_obj,
128            context.map(),
129            context.map_eval(),
130            (dash, {
131                "solid" => DashType::Solid,
132                "dot" => DashType::Dot,
133                "dash" => DashType::Dash,
134                "longdash" => DashType::LongDash,
135                "dashdot" => DashType::DashDot,
136                "longdashdot" => DashType::LongDashDot,
137            }),
138        }?;
139        box_plot.line(line)
140    } else {
141        box_plot
142    };
143
144    Ok(box_plot)
145}