Deprecated: The each() function is deprecated. This message will be suppressed on further calls in /home/zhenxiangba/zhenxiangba.com/public_html/phproxy-improved-master/index.php on line 456
curve.rs - source
[go: Go Back, main page]

criterion_plot/
curve.rs

1//! Simple "curve" like plots
2
3use std::borrow::Cow;
4
5use crate::data::Matrix;
6use crate::traits::{self, Data, Set};
7use crate::{
8    Axes, Color, CurveDefault, Display, Figure, Label, LineType, LineWidth, Plot, PointSize,
9    PointType, Script,
10};
11
12/// Properties common to simple "curve" like plots
13pub struct Properties {
14    axes: Option<Axes>,
15    color: Option<Color>,
16    label: Option<Cow<'static, str>>,
17    line_type: LineType,
18    linewidth: Option<f64>,
19    point_type: Option<PointType>,
20    point_size: Option<f64>,
21    style: Style,
22}
23
24impl CurveDefault<Style> for Properties {
25    fn default(style: Style) -> Properties {
26        Properties {
27            axes: None,
28            color: None,
29            label: None,
30            line_type: LineType::Solid,
31            linewidth: None,
32            point_size: None,
33            point_type: None,
34            style,
35        }
36    }
37}
38
39impl Script for Properties {
40    fn script(&self) -> String {
41        let mut script = if let Some(axes) = self.axes {
42            format!("axes {} ", axes.display())
43        } else {
44            String::new()
45        };
46
47        script.push_str(&format!("with {} ", self.style.display()));
48        script.push_str(&format!("lt {} ", self.line_type.display()));
49
50        if let Some(lw) = self.linewidth {
51            script.push_str(&format!("lw {} ", lw))
52        }
53
54        if let Some(color) = self.color {
55            script.push_str(&format!("lc rgb '{}' ", color.display()))
56        }
57
58        if let Some(pt) = self.point_type {
59            script.push_str(&format!("pt {} ", pt.display()))
60        }
61
62        if let Some(ps) = self.point_size {
63            script.push_str(&format!("ps {} ", ps))
64        }
65
66        if let Some(ref label) = self.label {
67            script.push_str("title '");
68            script.push_str(label);
69            script.push('\'')
70        } else {
71            script.push_str("notitle")
72        }
73
74        script
75    }
76}
77
78impl Set<Axes> for Properties {
79    /// Select the axes to plot against
80    ///
81    /// **Note** By default, the `BottomXLeftY` axes are used
82    fn set(&mut self, axes: Axes) -> &mut Properties {
83        self.axes = Some(axes);
84        self
85    }
86}
87
88impl Set<Color> for Properties {
89    /// Sets the line color
90    fn set(&mut self, color: Color) -> &mut Properties {
91        self.color = Some(color);
92        self
93    }
94}
95
96impl Set<Label> for Properties {
97    /// Sets the legend label
98    fn set(&mut self, label: Label) -> &mut Properties {
99        self.label = Some(label.0);
100        self
101    }
102}
103
104impl Set<LineType> for Properties {
105    /// Changes the line type
106    ///
107    /// **Note** By default `Solid` lines are used
108    fn set(&mut self, lt: LineType) -> &mut Properties {
109        self.line_type = lt;
110        self
111    }
112}
113
114impl Set<LineWidth> for Properties {
115    /// Changes the width of the line
116    ///
117    /// # Panics
118    ///
119    /// Panics if `width` is a non-positive value
120    fn set(&mut self, lw: LineWidth) -> &mut Properties {
121        let lw = lw.0;
122
123        assert!(lw > 0.);
124
125        self.linewidth = Some(lw);
126        self
127    }
128}
129
130impl Set<PointSize> for Properties {
131    /// Changes the size of the points
132    ///
133    /// # Panics
134    ///
135    /// Panics if `size` is a non-positive value
136    fn set(&mut self, ps: PointSize) -> &mut Properties {
137        let ps = ps.0;
138
139        assert!(ps > 0.);
140
141        self.point_size = Some(ps);
142        self
143    }
144}
145
146impl Set<PointType> for Properties {
147    /// Changes the point type
148    fn set(&mut self, pt: PointType) -> &mut Properties {
149        self.point_type = Some(pt);
150        self
151    }
152}
153
154/// Types of "curve" plots
155pub enum Curve<X, Y> {
156    /// A minimally sized dot on each data point
157    Dots {
158        /// X coordinate of the data points
159        x: X,
160        /// Y coordinate of the data points
161        y: Y,
162    },
163    /// A vertical "impulse" on each data point
164    Impulses {
165        /// X coordinate of the data points
166        x: X,
167        /// Y coordinate of the data points
168        y: Y,
169    },
170    /// Line that joins the data points
171    Lines {
172        /// X coordinate of the data points
173        x: X,
174        /// Y coordinate of the data points
175        y: Y,
176    },
177    /// Line with a point on each data point
178    LinesPoints {
179        /// X coordinate of the data points
180        x: X,
181        /// Y coordinate of the data points
182        y: Y,
183    },
184    /// A point on each data point
185    Points {
186        /// X coordinate of the data points
187        x: X,
188        /// Y coordinate of the data points
189        y: Y,
190    },
191    /// An step `_|` between each data point
192    Steps {
193        /// X coordinate of the data points
194        x: X,
195        /// Y coordinate of the data points
196        y: Y,
197    },
198}
199
200impl<X, Y> Curve<X, Y> {
201    fn style(&self) -> Style {
202        match *self {
203            Curve::Dots { .. } => Style::Dots,
204            Curve::Impulses { .. } => Style::Impulses,
205            Curve::Lines { .. } => Style::Lines,
206            Curve::LinesPoints { .. } => Style::LinesPoints,
207            Curve::Points { .. } => Style::Points,
208            Curve::Steps { .. } => Style::Steps,
209        }
210    }
211}
212
213#[derive(Clone, Copy)]
214enum Style {
215    Dots,
216    Impulses,
217    Lines,
218    LinesPoints,
219    Points,
220    Steps,
221}
222
223impl Display<&'static str> for Style {
224    fn display(&self) -> &'static str {
225        match *self {
226            Style::Dots => "dots",
227            Style::Impulses => "impulses",
228            Style::Lines => "lines",
229            Style::LinesPoints => "linespoints",
230            Style::Points => "points",
231            Style::Steps => "steps",
232        }
233    }
234}
235
236impl<X, Y> traits::Plot<Curve<X, Y>> for Figure
237where
238    X: IntoIterator,
239    X::Item: Data,
240    Y: IntoIterator,
241    Y::Item: Data,
242{
243    type Properties = Properties;
244
245    fn plot<F>(&mut self, curve: Curve<X, Y>, configure: F) -> &mut Figure
246    where
247        F: FnOnce(&mut Properties) -> &mut Properties,
248    {
249        let style = curve.style();
250        let (x, y) = match curve {
251            Curve::Dots { x, y }
252            | Curve::Impulses { x, y }
253            | Curve::Lines { x, y }
254            | Curve::LinesPoints { x, y }
255            | Curve::Points { x, y }
256            | Curve::Steps { x, y } => (x, y),
257        };
258
259        let mut props = CurveDefault::default(style);
260        configure(&mut props);
261
262        let (x_factor, y_factor) =
263            crate::scale_factor(&self.axes, props.axes.unwrap_or(crate::Axes::BottomXLeftY));
264
265        let data = Matrix::new(itertools::izip!(x, y), (x_factor, y_factor));
266        self.plots.push(Plot::new(data, &props));
267        self
268    }
269}