• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use crate::element::{DynElement, IntoDynElement, PathElement, Polygon};
2 use crate::style::colors::TRANSPARENT;
3 use crate::style::ShapeStyle;
4 use plotters_backend::DrawingBackend;
5 
6 /// An area series is similar to a line series but use a filled polygon
7 pub struct AreaSeries<DB: DrawingBackend, X: Clone, Y: Clone> {
8     area_style: ShapeStyle,
9     border_style: ShapeStyle,
10     baseline: Y,
11     data: Vec<(X, Y)>,
12     state: u32,
13     _p: std::marker::PhantomData<DB>,
14 }
15 
16 impl<DB: DrawingBackend, X: Clone, Y: Clone> AreaSeries<DB, X, Y> {
new<S: Into<ShapeStyle>, I: IntoIterator<Item = (X, Y)>>( iter: I, baseline: Y, area_style: S, ) -> Self17     pub fn new<S: Into<ShapeStyle>, I: IntoIterator<Item = (X, Y)>>(
18         iter: I,
19         baseline: Y,
20         area_style: S,
21     ) -> Self {
22         Self {
23             area_style: area_style.into(),
24             baseline,
25             data: iter.into_iter().collect(),
26             state: 0,
27             border_style: (&TRANSPARENT).into(),
28             _p: std::marker::PhantomData,
29         }
30     }
31 
border_style<S: Into<ShapeStyle>>(mut self, style: S) -> Self32     pub fn border_style<S: Into<ShapeStyle>>(mut self, style: S) -> Self {
33         self.border_style = style.into();
34         self
35     }
36 }
37 
38 impl<DB: DrawingBackend, X: Clone + 'static, Y: Clone + 'static> Iterator for AreaSeries<DB, X, Y> {
39     type Item = DynElement<'static, DB, (X, Y)>;
next(&mut self) -> Option<Self::Item>40     fn next(&mut self) -> Option<Self::Item> {
41         if self.state == 0 {
42             let mut data: Vec<_> = self.data.clone();
43 
44             if !data.is_empty() {
45                 data.push((data[data.len() - 1].0.clone(), self.baseline.clone()));
46                 data.push((data[0].0.clone(), self.baseline.clone()));
47             }
48 
49             self.state = 1;
50 
51             Some(Polygon::new(data, self.area_style.clone()).into_dyn())
52         } else if self.state == 1 {
53             let data: Vec<_> = self.data.clone();
54 
55             self.state = 2;
56 
57             Some(PathElement::new(data, self.border_style.clone()).into_dyn())
58         } else {
59             None
60         }
61     }
62 }
63