plotters_unsable/series/
histogram.rs

1use std::collections::{hash_map::IntoIter, HashMap};
2use std::hash::Hash;
3use std::marker::PhantomData;
4use std::ops::AddAssign;
5
6use crate::coord::DescreteRanged;
7use crate::element::Rectangle;
8use crate::style::ShapeStyle;
9
10/// The series that aggregate data into a histogram
11pub struct Histogram<'a, XR: DescreteRanged, Y: AddAssign<Y> + Default>
12where
13    XR::ValueType: Eq + Hash + Default,
14{
15    style: ShapeStyle<'a>,
16    x_margin: u32,
17    iter: IntoIter<XR::ValueType, Y>,
18    _p: PhantomData<XR>,
19}
20
21impl<'a, XR: DescreteRanged, Y: AddAssign<Y> + Default> Histogram<'a, XR, Y>
22where
23    XR::ValueType: Eq + Hash + Default,
24{
25    pub fn new<S: Into<ShapeStyle<'a>>, I: IntoIterator<Item = (XR::ValueType, Y)>>(
26        iter: I,
27        x_margin: u32,
28        style: S,
29    ) -> Self {
30        let mut buffer = HashMap::<XR::ValueType, Y>::new();
31        for (x, y) in iter.into_iter() {
32            *buffer.entry(x).or_insert_with(Default::default) += y;
33        }
34        Self {
35            style: style.into(),
36            x_margin,
37            iter: buffer.into_iter(),
38            _p: PhantomData,
39        }
40    }
41}
42
43impl<'a, XR: DescreteRanged, Y: AddAssign<Y> + Default> Iterator for Histogram<'a, XR, Y>
44where
45    XR::ValueType: Eq + Hash + Default,
46{
47    type Item = Rectangle<'a, (XR::ValueType, Y)>;
48    fn next(&mut self) -> Option<Self::Item> {
49        if let Some((x, y)) = self.iter.next() {
50            let nx = XR::next_value(&x);
51            let mut rect = Rectangle::new([(x, y), (nx, Y::default())], self.style.clone());
52            rect.set_margin(0, 0, self.x_margin, self.x_margin);
53            return Some(rect);
54        }
55        None
56    }
57}