1use crate::common::color::{Color, ColorWrapper};
4use crate::common::{Calendar, Dim, HoverInfo, Label, Line, Marker, Orientation, PlotType};
5use crate::private;
6use crate::Trace;
7use serde::Serialize;
8
9#[derive(Serialize, Debug)]
10pub enum BoxMean {
11 #[serde(rename = "true")]
12 True,
13 #[serde(rename = "false")]
14 False,
15 #[serde(rename = "sd")]
16 StandardDeviation,
17}
18
19#[derive(Serialize, Debug)]
20pub enum BoxPoints {
21 #[serde(rename = "all")]
22 All,
23 #[serde(rename = "outliers")]
24 Outliers,
25 #[serde(rename = "suspectedoutliers")]
26 SuspectedOutliers,
27 #[serde(rename = "false")]
28 False,
29}
30
31#[derive(Serialize, Debug)]
32pub enum QuartileMethod {
33 #[serde(rename = "linear")]
34 Linear,
35 #[serde(rename = "exclusive")]
36 Exclusive,
37 #[serde(rename = "inclusive")]
38 Inclusive,
39}
40
41#[derive(Serialize, Debug, Default)]
42pub struct BoxPlot<Y, X>
43where
44 Y: Serialize + Default,
45 X: Serialize + Default,
46{
47 r#type: PlotType,
48 #[serde(skip_serializing_if = "Option::is_none")]
49 x: Option<Vec<X>>,
50 #[serde(skip_serializing_if = "Option::is_none")]
51 y: Option<Vec<Y>>,
52 #[serde(skip_serializing_if = "Option::is_none")]
53 name: Option<String>,
54 #[serde(skip_serializing_if = "Option::is_none")]
55 visible: Option<bool>,
56 #[serde(skip_serializing_if = "Option::is_none", rename = "showlegend")]
57 show_legend: Option<bool>,
58 #[serde(skip_serializing_if = "Option::is_none", rename = "legendgroup")]
59 legend_group: Option<String>,
60 #[serde(skip_serializing_if = "Option::is_none")]
61 opacity: Option<f64>,
62 #[serde(skip_serializing_if = "Option::is_none")]
63 ids: Option<Vec<String>>,
64 #[serde(skip_serializing_if = "Option::is_none")]
65 width: Option<usize>,
66 #[serde(skip_serializing_if = "Option::is_none")]
67 text: Option<Dim<String>>,
68 #[serde(skip_serializing_if = "Option::is_none", rename = "hovertext")]
69 hover_text: Option<Dim<String>>,
70 #[serde(skip_serializing_if = "Option::is_none", rename = "hoverinfo")]
71 hover_info: Option<HoverInfo>,
72 #[serde(skip_serializing_if = "Option::is_none", rename = "hovertemplate")]
73 hover_template: Option<Dim<String>>,
74 #[serde(skip_serializing_if = "Option::is_none", rename = "xaxis")]
75 x_axis: Option<String>,
76 #[serde(skip_serializing_if = "Option::is_none", rename = "yaxis")]
77 y_axis: Option<String>,
78 #[serde(skip_serializing_if = "Option::is_none")]
79 orientation: Option<Orientation>,
80 #[serde(skip_serializing_if = "Option::is_none", rename = "alignmentgroup")]
81 alignment_group: Option<String>,
82 #[serde(skip_serializing_if = "Option::is_none", rename = "offsetgroup")]
83 offset_group: Option<String>,
84 #[serde(skip_serializing_if = "Option::is_none")]
85 marker: Option<Marker>,
86 #[serde(skip_serializing_if = "Option::is_none")]
87 line: Option<Line>,
88 #[serde(skip_serializing_if = "Option::is_none", rename = "boxmean")]
89 box_mean: Option<private::TruthyEnum<BoxMean>>,
90 #[serde(skip_serializing_if = "Option::is_none", rename = "boxpoints")]
91 box_points: Option<private::TruthyEnum<BoxPoints>>,
92 #[serde(skip_serializing_if = "Option::is_none")]
93 notched: Option<bool>,
94 #[serde(skip_serializing_if = "Option::is_none", rename = "notchwidth")]
95 notch_width: Option<f64>,
96 #[serde(skip_serializing_if = "Option::is_none", rename = "whiskerwidth")]
97 whisker_width: Option<f64>,
98 #[serde(skip_serializing_if = "Option::is_none")]
99 q1: Option<Vec<f64>>,
100 #[serde(skip_serializing_if = "Option::is_none")]
101 median: Option<Vec<f64>>,
102 #[serde(skip_serializing_if = "Option::is_none")]
103 q3: Option<Vec<f64>>,
104 #[serde(skip_serializing_if = "Option::is_none", rename = "lowerfence")]
105 lower_fence: Option<Vec<f64>>,
106 #[serde(skip_serializing_if = "Option::is_none", rename = "notchspan")]
107 notch_span: Option<Vec<f64>>,
108 #[serde(skip_serializing_if = "Option::is_none")]
109 mean: Option<Vec<f64>>,
110 #[serde(skip_serializing_if = "Option::is_none", rename = "sd")]
111 standard_deviation: Option<Vec<f64>>,
112 #[serde(skip_serializing_if = "Option::is_none", rename = "quartilemethod")]
113 quartile_method: Option<QuartileMethod>,
114 #[serde(skip_serializing_if = "Option::is_none", rename = "fillcolor")]
115 fill_color: Option<ColorWrapper>,
116 #[serde(skip_serializing_if = "Option::is_none", rename = "hoverlabel")]
117 hover_label: Option<Label>,
118 #[serde(skip_serializing_if = "Option::is_none", rename = "hoveron")]
119 hover_on: Option<String>,
120 #[serde(skip_serializing_if = "Option::is_none", rename = "pointpos")]
121 point_pos: Option<f64>,
122 #[serde(skip_serializing_if = "Option::is_none")]
123 jitter: Option<f64>,
124 #[serde(skip_serializing_if = "Option::is_none", rename = "xcalendar")]
125 x_calendar: Option<Calendar>,
126 #[serde(skip_serializing_if = "Option::is_none", rename = "ycalendar")]
127 y_calendar: Option<Calendar>,
128}
129
130impl<Y> BoxPlot<Y, f64>
131where
132 Y: Serialize + Default,
133{
134 pub fn new(y: Vec<Y>) -> Box<BoxPlot<Y, f64>> {
135 Box::new(BoxPlot {
136 r#type: PlotType::Box,
137 x: None,
138 y: Some(y),
139 ..Default::default()
140 })
141 }
142}
143
144impl<Y, X> BoxPlot<Y, X>
145where
146 Y: Serialize + Default,
147 X: Serialize + Default,
148{
149 pub fn new_xy(x: Vec<X>, y: Vec<Y>) -> Box<BoxPlot<Y, X>> {
150 Box::new(BoxPlot {
151 r#type: PlotType::Box,
152 x: Some(x),
153 y: Some(y),
154 ..Default::default()
155 })
156 }
157
158 pub fn horizontal(x: Vec<X>) -> Box<BoxPlot<f64, X>> {
159 Box::new(BoxPlot {
160 r#type: PlotType::Box,
161 x: Some(x),
162 y: None,
163 ..Default::default()
164 })
165 }
166
167 pub fn name(mut self, name: &str) -> Box<BoxPlot<Y, X>> {
168 self.name = Some(name.to_owned());
169 Box::new(self)
170 }
171
172 pub fn visible(mut self, visible: bool) -> Box<BoxPlot<Y, X>> {
173 self.visible = Some(visible);
174 Box::new(self)
175 }
176
177 pub fn show_legend(mut self, show_legend: bool) -> Box<BoxPlot<Y, X>> {
178 self.show_legend = Some(show_legend);
179 Box::new(self)
180 }
181
182 pub fn legend_group(mut self, legend_group: &str) -> Box<BoxPlot<Y, X>> {
183 self.legend_group = Some(legend_group.to_owned());
184 Box::new(self)
185 }
186
187 pub fn opacity(mut self, opacity: f64) -> Box<BoxPlot<Y, X>> {
188 self.opacity = Some(opacity);
189 Box::new(self)
190 }
191
192 pub fn ids<S: AsRef<str>>(mut self, ids: Vec<S>) -> Box<BoxPlot<Y, X>> {
193 let ids = private::owned_string_vector(ids);
194 self.ids = Some(ids);
195 Box::new(self)
196 }
197
198 pub fn width(mut self, width: usize) -> Box<BoxPlot<Y, X>> {
199 self.width = Some(width);
200 Box::new(self)
201 }
202
203 pub fn text(mut self, text: &str) -> Box<BoxPlot<Y, X>> {
204 self.text = Some(Dim::Scalar(text.to_owned()));
205 Box::new(self)
206 }
207
208 pub fn text_array<S: AsRef<str>>(mut self, text: Vec<S>) -> Box<BoxPlot<Y, X>> {
209 let text = private::owned_string_vector(text);
210 self.text = Some(Dim::Vector(text));
211 Box::new(self)
212 }
213
214 pub fn hover_text(mut self, hover_text: &str) -> Box<BoxPlot<Y, X>> {
215 self.hover_text = Some(Dim::Scalar(hover_text.to_owned()));
216 Box::new(self)
217 }
218
219 pub fn hover_text_array<S: AsRef<str>>(mut self, hover_text: Vec<S>) -> Box<BoxPlot<Y, X>> {
220 let hover_text = private::owned_string_vector(hover_text);
221 self.hover_text = Some(Dim::Vector(hover_text));
222 Box::new(self)
223 }
224
225 pub fn hover_info(mut self, hover_info: HoverInfo) -> Box<BoxPlot<Y, X>> {
226 self.hover_info = Some(hover_info);
227 Box::new(self)
228 }
229
230 pub fn hover_template(mut self, hover_template: &str) -> Box<BoxPlot<Y, X>> {
231 self.hover_template = Some(Dim::Scalar(hover_template.to_owned()));
232 Box::new(self)
233 }
234
235 pub fn x_axis(mut self, axis: &str) -> Box<BoxPlot<Y, X>> {
236 self.x_axis = Some(axis.to_owned());
237 Box::new(self)
238 }
239
240 pub fn y_axis(mut self, axis: &str) -> Box<BoxPlot<Y, X>> {
241 self.y_axis = Some(axis.to_owned());
242 Box::new(self)
243 }
244
245 pub fn hover_template_array<S: AsRef<str>>(
246 mut self,
247 hover_template: Vec<S>,
248 ) -> Box<BoxPlot<Y, X>> {
249 let hover_template = private::owned_string_vector(hover_template);
250 self.hover_template = Some(Dim::Vector(hover_template));
251 Box::new(self)
252 }
253
254 pub fn orientation(mut self, orientation: Orientation) -> Box<BoxPlot<Y, X>> {
255 self.orientation = Some(orientation);
256 Box::new(self)
257 }
258
259 pub fn alignment_group(mut self, alignment_group: &str) -> Box<BoxPlot<Y, X>> {
260 self.alignment_group = Some(alignment_group.to_owned());
261 Box::new(self)
262 }
263
264 pub fn offset_group(mut self, offset_group: &str) -> Box<BoxPlot<Y, X>> {
265 self.offset_group = Some(offset_group.to_owned());
266 Box::new(self)
267 }
268
269 pub fn marker(mut self, marker: Marker) -> Box<BoxPlot<Y, X>> {
270 self.marker = Some(marker);
271 Box::new(self)
272 }
273
274 pub fn line(mut self, line: Line) -> Box<BoxPlot<Y, X>> {
275 self.line = Some(line);
276 Box::new(self)
277 }
278
279 pub fn box_mean(mut self, box_mean: BoxMean) -> Box<BoxPlot<Y, X>> {
280 self.box_mean = Some(private::TruthyEnum { e: box_mean });
281 Box::new(self)
282 }
283
284 pub fn box_points(mut self, box_points: BoxPoints) -> Box<BoxPlot<Y, X>> {
285 self.box_points = Some(private::TruthyEnum { e: box_points });
286 Box::new(self)
287 }
288
289 pub fn notched(mut self, notched: bool) -> Box<BoxPlot<Y, X>> {
290 self.notched = Some(notched);
291 Box::new(self)
292 }
293
294 pub fn notch_width(mut self, notch_width: f64) -> Box<BoxPlot<Y, X>> {
295 self.notch_width = Some(notch_width);
296 Box::new(self)
297 }
298
299 pub fn whisker_width(mut self, whisker_width: f64) -> Box<BoxPlot<Y, X>> {
300 self.whisker_width = Some(whisker_width);
301 Box::new(self)
302 }
303
304 pub fn q1(mut self, q1: Vec<f64>) -> Box<BoxPlot<Y, X>> {
305 self.q1 = Some(q1);
306 Box::new(self)
307 }
308
309 pub fn median(mut self, median: Vec<f64>) -> Box<BoxPlot<Y, X>> {
310 self.median = Some(median);
311 Box::new(self)
312 }
313
314 pub fn q3(mut self, q3: Vec<f64>) -> Box<BoxPlot<Y, X>> {
315 self.q3 = Some(q3);
316 Box::new(self)
317 }
318
319 pub fn lower_fence(mut self, lower_fence: Vec<f64>) -> Box<BoxPlot<Y, X>> {
320 self.lower_fence = Some(lower_fence);
321 Box::new(self)
322 }
323
324 pub fn notch_span(mut self, notch_span: Vec<f64>) -> Box<BoxPlot<Y, X>> {
325 self.notch_span = Some(notch_span);
326 Box::new(self)
327 }
328
329 pub fn mean(mut self, mean: Vec<f64>) -> Box<BoxPlot<Y, X>> {
330 self.mean = Some(mean);
331 Box::new(self)
332 }
333
334 pub fn standard_deviation(mut self, standard_deviation: Vec<f64>) -> Box<BoxPlot<Y, X>> {
335 self.standard_deviation = Some(standard_deviation);
336 Box::new(self)
337 }
338
339 pub fn quartile_method(mut self, quartile_method: QuartileMethod) -> Box<BoxPlot<Y, X>> {
340 self.quartile_method = Some(quartile_method);
341 Box::new(self)
342 }
343
344 pub fn fill_color<C: Color>(mut self, fill_color: C) -> Box<BoxPlot<Y, X>> {
345 self.fill_color = Some(fill_color.to_color());
346 Box::new(self)
347 }
348
349 pub fn hover_label(mut self, hover_label: Label) -> Box<BoxPlot<Y, X>> {
350 self.hover_label = Some(hover_label);
351 Box::new(self)
352 }
353
354 pub fn hover_on(mut self, hover_on: &str) -> Box<BoxPlot<Y, X>> {
355 self.hover_on = Some(hover_on.to_owned());
356 Box::new(self)
357 }
358
359 pub fn point_pos(mut self, point_pos: f64) -> Box<BoxPlot<Y, X>> {
360 self.point_pos = Some(point_pos);
361 Box::new(self)
362 }
363
364 pub fn jitter(mut self, jitter: f64) -> Box<BoxPlot<Y, X>> {
365 self.jitter = Some(jitter);
366 Box::new(self)
367 }
368
369 pub fn x_calendar(mut self, x_calendar: Calendar) -> Box<BoxPlot<Y, X>> {
370 self.x_calendar = Some(x_calendar);
371 Box::new(self)
372 }
373
374 pub fn y_calendar(mut self, y_calendar: Calendar) -> Box<BoxPlot<Y, X>> {
375 self.y_calendar = Some(y_calendar);
376 Box::new(self)
377 }
378}
379
380impl<X, Y> Trace for BoxPlot<X, Y>
381where
382 X: Serialize + Default,
383 Y: Serialize + Default,
384{
385 fn serialize(&self) -> String {
386 serde_json::to_string(&self).unwrap()
387 }
388}