diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-18 02:49:50 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-18 02:49:50 +0000 |
commit | 9835e2ae736235810b4ea1c162ca5e65c547e770 (patch) | |
tree | 3fcebf40ed70e581d776a8a4c65923e8ec20e026 /vendor/plotters/src/chart/state.rs | |
parent | Releasing progress-linux version 1.70.0+dfsg2-1~progress7.99u1. (diff) | |
download | rustc-9835e2ae736235810b4ea1c162ca5e65c547e770.tar.xz rustc-9835e2ae736235810b4ea1c162ca5e65c547e770.zip |
Merging upstream version 1.71.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/plotters/src/chart/state.rs')
-rw-r--r-- | vendor/plotters/src/chart/state.rs | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/vendor/plotters/src/chart/state.rs b/vendor/plotters/src/chart/state.rs new file mode 100644 index 000000000..1ce2f8285 --- /dev/null +++ b/vendor/plotters/src/chart/state.rs @@ -0,0 +1,112 @@ +use std::sync::Arc; + +use super::ChartContext; +use crate::coord::{CoordTranslate, Shift}; +use crate::drawing::DrawingArea; +use plotters_backend::DrawingBackend; + +/// A chart context state - This is the data that is needed to reconstruct the chart context +/// without actually drawing the chart. This is useful when we want to do realtime rendering and +/// want to incrementally update the chart. +/// +/// For each frame, instead of updating the entire backend, we are able to keep the keep the figure +/// component like axis, labels untouched and make updates only in the plotting drawing area. +/// This is very useful for incremental render. +/// ```rust +/// use plotters::prelude::*; +/// let mut buffer = vec![0u8;1024*768*3]; +/// let area = BitMapBackend::with_buffer(&mut buffer[..], (1024, 768)) +/// .into_drawing_area() +/// .split_evenly((1,2)); +/// let chart = ChartBuilder::on(&area[0]) +/// .caption("Incremental Example", ("sans-serif", 20)) +/// .set_all_label_area_size(30) +/// .build_cartesian_2d(0..10, 0..10) +/// .expect("Unable to build ChartContext"); +/// // Draw the first frame at this point +/// area[0].present().expect("Present"); +/// let state = chart.into_chart_state(); +/// // Let's draw the second frame +/// let chart = state.restore(&area[0]); +/// chart.plotting_area().fill(&WHITE).unwrap(); // Clear the previously drawn graph +/// // At this point, you are able to draw next frame +///``` +#[derive(Clone)] +pub struct ChartState<CT: CoordTranslate> { + drawing_area_pos: (i32, i32), + drawing_area_size: (u32, u32), + coord: CT, +} + +impl<'a, DB: DrawingBackend, CT: CoordTranslate> From<ChartContext<'a, DB, CT>> for ChartState<CT> { + fn from(chart: ChartContext<'a, DB, CT>) -> ChartState<CT> { + ChartState { + drawing_area_pos: chart.drawing_area_pos, + drawing_area_size: chart.drawing_area.dim_in_pixel(), + coord: chart.drawing_area.into_coord_spec(), + } + } +} + +impl<'a, DB: DrawingBackend, CT: CoordTranslate> ChartContext<'a, DB, CT> { + /// Convert a chart context into a chart state, by doing so, the chart context is consumed and + /// a saved chart state is created for later use. This is typically used in incrmental rendering. See documentation of `ChartState` for more detailed example. + pub fn into_chart_state(self) -> ChartState<CT> { + self.into() + } + + /// Convert the chart context into a sharable chart state. + /// Normally a chart state can not be clone, since the coordinate spec may not be able to be + /// cloned. In this case, we can use an `Arc` get the coordinate wrapped thus the state can be + /// cloned and shared by multiple chart context + pub fn into_shared_chart_state(self) -> ChartState<Arc<CT>> { + ChartState { + drawing_area_pos: self.drawing_area_pos, + drawing_area_size: self.drawing_area.dim_in_pixel(), + coord: Arc::new(self.drawing_area.into_coord_spec()), + } + } +} + +impl<'a, DB, CT> From<&ChartContext<'a, DB, CT>> for ChartState<CT> +where + DB: DrawingBackend, + CT: CoordTranslate + Clone, +{ + fn from(chart: &ChartContext<'a, DB, CT>) -> ChartState<CT> { + ChartState { + drawing_area_pos: chart.drawing_area_pos, + drawing_area_size: chart.drawing_area.dim_in_pixel(), + coord: chart.drawing_area.as_coord_spec().clone(), + } + } +} + +impl<'a, DB: DrawingBackend, CT: CoordTranslate + Clone> ChartContext<'a, DB, CT> { + /// Make the chart context, do not consume the chart context and clone the coordinate spec + pub fn to_chart_state(&self) -> ChartState<CT> { + self.into() + } +} + +impl<CT: CoordTranslate> ChartState<CT> { + /// Restore the chart context on the given drawing area + /// + /// - `area`: The given drawing area where we want to restore the chart context + /// - **returns** The newly created chart context + pub fn restore<'a, DB: DrawingBackend>( + self, + area: &DrawingArea<DB, Shift>, + ) -> ChartContext<'a, DB, CT> { + let area = area + .clone() + .shrink(self.drawing_area_pos, self.drawing_area_size); + ChartContext { + x_label_area: [None, None], + y_label_area: [None, None], + drawing_area: area.apply_coord_spec(self.coord), + series_anno: vec![], + drawing_area_pos: self.drawing_area_pos, + } + } +} |