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}