1
/*!
2

3
Box plot
4

5
# Examples
6

7
```
8
# use plotlib::repr::BoxPlot;
9
# use plotlib::view::CategoricalView;
10
let b1 = BoxPlot::from_slice(&[0., 2., 3., 4.]);
11
let b2 = BoxPlot::from_vec(vec![0., 2., 3., 4.]);
12
let v = CategoricalView::new().add(b1);
13
```
14
*/
15

16
use std::f64;
17

18
use svg;
19

20
use crate::axis;
21
use crate::repr::CategoricalRepresentation;
22
use crate::style::BoxStyle;
23
use crate::svg_render;
24
use crate::utils;
25

26
enum BoxData<'a> {
27
    Owned(Vec<f64>),
28
    Ref(&'a [f64]),
29
}
30

31
pub struct BoxPlot<'a> {
32
    data: BoxData<'a>,
33
    label: String,
34
    style: BoxStyle,
35
}
36

37
impl<'a> BoxPlot<'a> {
38 0
    pub fn from_slice(v: &'a [f64]) -> Self {
39
        BoxPlot {
40 0
            data: BoxData::Ref(v),
41 0
            style: BoxStyle::new(),
42 0
            label: String::new(),
43
        }
44
    }
45

46 0
    pub fn from_vec(v: Vec<f64>) -> Self {
47
        BoxPlot {
48 0
            data: BoxData::Owned(v),
49 0
            style: BoxStyle::new(),
50 0
            label: String::new(),
51
        }
52
    }
53

54 0
    pub fn style(mut self, style: &BoxStyle) -> Self {
55 0
        self.style.overlay(style);
56 0
        self
57
    }
58

59 0
    pub fn get_style(&self) -> &BoxStyle {
60 0
        &self.style
61
    }
62

63
    pub fn label<T>(mut self, label: T) -> Self
64
    where
65
        T: Into<String>,
66
    {
67 0
        self.label = label.into();
68 0
        self
69
    }
70

71 0
    pub fn get_label(&self) -> &String {
72 0
        &self.label
73
    }
74

75 0
    fn get_data(&'a self) -> &'a [f64] {
76 0
        match self.data {
77 0
            BoxData::Owned(ref v) => v,
78 0
            BoxData::Ref(v) => v,
79
        }
80
    }
81

82 0
    fn range(&self) -> (f64, f64) {
83 0
        match self.data {
84 0
            BoxData::Owned(ref v) => utils::range(v),
85 0
            BoxData::Ref(v) => utils::range(v),
86
        }
87
    }
88
}
89

90
impl<'a> CategoricalRepresentation for BoxPlot<'a> {
91
    /// The maximum range. Used for auto-scaling axis
92 0
    fn range(&self) -> (f64, f64) {
93 0
        self.range()
94
    }
95

96
    /// The ticks that this representation covers. Used to collect all ticks for display
97 0
    fn ticks(&self) -> Vec<String> {
98 0
        vec![self.label.clone()]
99
    }
100

101 0
    fn to_svg(
102
        &self,
103
        x_axis: &axis::CategoricalAxis,
104
        y_axis: &axis::ContinuousAxis,
105
        face_width: f64,
106
        face_height: f64,
107
    ) -> svg::node::element::Group {
108
        svg_render::draw_face_boxplot(
109 0
            self.get_data(),
110 0
            &self.label,
111 0
            x_axis,
112 0
            y_axis,
113 0
            face_width,
114 0
            face_height,
115 0
            &self.style,
116
        )
117
    }
118

119 0
    fn to_text(
120
        &self,
121
        _x_axis: &axis::CategoricalAxis,
122
        _y_axis: &axis::ContinuousAxis,
123
        _face_width: u32,
124
        _face_height: u32,
125
    ) -> String {
126 0
        "".into()
127
    }
128
}

Read our documentation on viewing source code .

Loading