plotly_patched/
box_plot.rs

1//! Box plot
2
3use 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}