Coverage Report

Created: 2026-03-28 06:33

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/plotters-0.3.7/src/chart/state.rs
Line
Count
Source
1
use std::sync::Arc;
2
3
use super::ChartContext;
4
use crate::coord::{CoordTranslate, Shift};
5
use crate::drawing::DrawingArea;
6
use plotters_backend::DrawingBackend;
7
8
/// A chart context state - This is the data that is needed to reconstruct the chart context
9
/// without actually drawing the chart. This is useful when we want to do realtime rendering and
10
/// want to incrementally update the chart.
11
///
12
/// For each frame, instead of updating the entire backend, we are able to keep the keep the figure
13
/// component like axis, labels untouched and make updates only in the plotting drawing area.
14
/// This is very useful for incremental render.
15
/// ```rust
16
///   use plotters::prelude::*;
17
///    let mut buffer = vec![0u8;1024*768*3];
18
///    let area = BitMapBackend::with_buffer(&mut buffer[..], (1024, 768))
19
///        .into_drawing_area()
20
///        .split_evenly((1,2));
21
///    let chart = ChartBuilder::on(&area[0])
22
///        .caption("Incremental Example", ("sans-serif", 20))
23
///        .set_all_label_area_size(30)
24
///        .build_cartesian_2d(0..10, 0..10)
25
///        .expect("Unable to build ChartContext");
26
///    // Draw the first frame at this point
27
///    area[0].present().expect("Present");
28
///    let state = chart.into_chart_state();
29
///    // Let's draw the second frame
30
///    let chart = state.restore(&area[0]);
31
///    chart.plotting_area().fill(&WHITE).unwrap(); // Clear the previously drawn graph
32
///    // At this point, you are able to draw next frame
33
///```
34
#[derive(Clone)]
35
pub struct ChartState<CT: CoordTranslate> {
36
    drawing_area_pos: (i32, i32),
37
    drawing_area_size: (u32, u32),
38
    coord: CT,
39
}
40
41
impl<'a, DB: DrawingBackend, CT: CoordTranslate> From<ChartContext<'a, DB, CT>> for ChartState<CT> {
42
0
    fn from(chart: ChartContext<'a, DB, CT>) -> ChartState<CT> {
43
0
        ChartState {
44
0
            drawing_area_pos: chart.drawing_area_pos,
45
0
            drawing_area_size: chart.drawing_area.dim_in_pixel(),
46
0
            coord: chart.drawing_area.into_coord_spec(),
47
0
        }
48
0
    }
49
}
50
51
impl<'a, DB: DrawingBackend, CT: CoordTranslate> ChartContext<'a, DB, CT> {
52
    /// Convert a chart context into a chart state, by doing so, the chart context is consumed and
53
    /// a saved chart state is created for later use. This is typically used in incremental rendering. See documentation of `ChartState` for more detailed example.
54
0
    pub fn into_chart_state(self) -> ChartState<CT> {
55
0
        self.into()
56
0
    }
57
58
    /// Convert the chart context into a sharable chart state.
59
    /// Normally a chart state can not be clone, since the coordinate spec may not be able to be
60
    /// cloned. In this case, we can use an `Arc` get the coordinate wrapped thus the state can be
61
    /// cloned and shared by multiple chart context
62
0
    pub fn into_shared_chart_state(self) -> ChartState<Arc<CT>> {
63
0
        ChartState {
64
0
            drawing_area_pos: self.drawing_area_pos,
65
0
            drawing_area_size: self.drawing_area.dim_in_pixel(),
66
0
            coord: Arc::new(self.drawing_area.into_coord_spec()),
67
0
        }
68
0
    }
69
}
70
71
impl<'a, DB, CT> From<&ChartContext<'a, DB, CT>> for ChartState<CT>
72
where
73
    DB: DrawingBackend,
74
    CT: CoordTranslate + Clone,
75
{
76
0
    fn from(chart: &ChartContext<'a, DB, CT>) -> ChartState<CT> {
77
0
        ChartState {
78
0
            drawing_area_pos: chart.drawing_area_pos,
79
0
            drawing_area_size: chart.drawing_area.dim_in_pixel(),
80
0
            coord: chart.drawing_area.as_coord_spec().clone(),
81
0
        }
82
0
    }
83
}
84
85
impl<'a, DB: DrawingBackend, CT: CoordTranslate + Clone> ChartContext<'a, DB, CT> {
86
    /// Make the chart context, do not consume the chart context and clone the coordinate spec
87
0
    pub fn to_chart_state(&self) -> ChartState<CT> {
88
0
        self.into()
89
0
    }
90
}
91
92
impl<CT: CoordTranslate> ChartState<CT> {
93
    /// Restore the chart context on the given drawing area
94
    ///
95
    /// - `area`: The given drawing area where we want to restore the chart context
96
    /// - **returns** The newly created chart context
97
0
    pub fn restore<'a, DB: DrawingBackend>(
98
0
        self,
99
0
        area: &DrawingArea<DB, Shift>,
100
0
    ) -> ChartContext<'a, DB, CT> {
101
0
        let area = area
102
0
            .clone()
103
0
            .shrink(self.drawing_area_pos, self.drawing_area_size);
104
0
        ChartContext {
105
0
            x_label_area: [None, None],
106
0
            y_label_area: [None, None],
107
0
            drawing_area: area.apply_coord_spec(self.coord),
108
0
            series_anno: vec![],
109
0
            drawing_area_pos: self.drawing_area_pos,
110
0
        }
111
0
    }
112
}