plotters/series/
line_series.rs
1use crate::element::{Circle, DynElement, IntoDynElement, PathElement};
2use crate::style::ShapeStyle;
3use plotters_backend::DrawingBackend;
4use std::marker::PhantomData;
5
6pub struct LineSeries<DB: DrawingBackend, Coord> {
9 style: ShapeStyle,
10 data: Vec<Coord>,
11 point_idx: usize,
12 point_size: u32,
13 phantom: PhantomData<DB>,
14}
15
16impl<DB: DrawingBackend, Coord: Clone + 'static> Iterator for LineSeries<DB, Coord> {
17 type Item = DynElement<'static, DB, Coord>;
18 fn next(&mut self) -> Option<Self::Item> {
19 if !self.data.is_empty() {
20 if self.point_size > 0 && self.point_idx < self.data.len() {
21 let idx = self.point_idx;
22 self.point_idx += 1;
23 return Some(
24 Circle::new(self.data[idx].clone(), self.point_size, self.style.clone())
25 .into_dyn(),
26 );
27 }
28 let mut data = vec![];
29 std::mem::swap(&mut self.data, &mut data);
30 Some(PathElement::new(data, self.style.clone()).into_dyn())
31 } else {
32 None
33 }
34 }
35}
36
37impl<DB: DrawingBackend, Coord> LineSeries<DB, Coord> {
38 pub fn new<I: IntoIterator<Item = Coord>, S: Into<ShapeStyle>>(iter: I, style: S) -> Self {
39 Self {
40 style: style.into(),
41 data: iter.into_iter().collect(),
42 point_size: 0,
43 point_idx: 0,
44 phantom: PhantomData,
45 }
46 }
47
48 pub fn point_size(mut self, size: u32) -> Self {
49 self.point_size = size;
50 self
51 }
52}
53
54#[cfg(test)]
55mod test {
56 use crate::prelude::*;
57
58 #[test]
59 fn test_line_series() {
60 let drawing_area = create_mocked_drawing_area(200, 200, |m| {
61 m.check_draw_path(|c, s, path| {
62 assert_eq!(c, RED.to_rgba());
63 assert_eq!(s, 3);
64 for i in 0..100 {
65 assert_eq!(path[i], (i as i32 * 2, 200 - i as i32 * 2 - 1));
66 }
67 });
68
69 m.drop_check(|b| {
70 assert_eq!(b.num_draw_path_call, 1);
71 assert_eq!(b.draw_count, 1);
72 });
73 });
74
75 let mut chart = ChartBuilder::on(&drawing_area)
76 .build_cartesian_2d(0..100, 0..100)
77 .expect("Build chart error");
78
79 chart
80 .draw_series(LineSeries::new(
81 (0..100).map(|x| (x, x)),
82 Into::<ShapeStyle>::into(&RED).stroke_width(3),
83 ))
84 .expect("Drawing Error");
85 }
86}