plotters/chart/context/cartesian2d/
mod.rs

1use std::ops::Range;
2
3use plotters_backend::{BackendCoord, DrawingBackend};
4
5use crate::chart::{ChartContext, DualCoordChartContext, MeshStyle};
6use crate::coord::{
7    cartesian::Cartesian2d,
8    ranged1d::{AsRangedCoord, Ranged, ValueFormatter},
9    Shift,
10};
11use crate::drawing::DrawingArea;
12
13mod draw_impl;
14
15impl<'a, DB, XT, YT, X, Y> ChartContext<'a, DB, Cartesian2d<X, Y>>
16where
17    DB: DrawingBackend,
18    X: Ranged<ValueType = XT> + ValueFormatter<XT>,
19    Y: Ranged<ValueType = YT> + ValueFormatter<YT>,
20{
21    pub(crate) fn is_overlapping_drawing_area(
22        &self,
23        area: Option<&DrawingArea<DB, Shift>>,
24    ) -> bool {
25        if let Some(area) = area {
26            let (x0, y0) = area.get_base_pixel();
27            let (w, h) = area.dim_in_pixel();
28            let (x1, y1) = (x0 + w as i32, y0 + h as i32);
29            let (dx0, dy0) = self.drawing_area.get_base_pixel();
30            let (w, h) = self.drawing_area.dim_in_pixel();
31            let (dx1, dy1) = (dx0 + w as i32, dy0 + h as i32);
32
33            let (ox0, ox1) = (x0.max(dx0), x1.min(dx1));
34            let (oy0, oy1) = (y0.max(dy0), y1.min(dy1));
35
36            ox1 > ox0 && oy1 > oy0
37        } else {
38            false
39        }
40    }
41
42    /// Initialize a mesh configuration object and mesh drawing can be finalized by calling
43    /// the function `MeshStyle::draw`.
44    pub fn configure_mesh(&mut self) -> MeshStyle<'a, '_, X, Y, DB> {
45        MeshStyle::new(self)
46    }
47}
48
49impl<'a, DB: DrawingBackend, X: Ranged, Y: Ranged> ChartContext<'a, DB, Cartesian2d<X, Y>> {
50    /// Get the range of X axis
51    pub fn x_range(&self) -> Range<X::ValueType> {
52        self.drawing_area.get_x_range()
53    }
54
55    /// Get range of the Y axis
56    pub fn y_range(&self) -> Range<Y::ValueType> {
57        self.drawing_area.get_y_range()
58    }
59
60    /// Maps the coordinate to the backend coordinate. This is typically used
61    /// with an interactive chart.
62    pub fn backend_coord(&self, coord: &(X::ValueType, Y::ValueType)) -> BackendCoord {
63        self.drawing_area.map_coordinate(coord)
64    }
65}
66
67impl<'a, DB: DrawingBackend, X: Ranged, Y: Ranged> ChartContext<'a, DB, Cartesian2d<X, Y>> {
68    /// Convert this chart context into a dual axis chart context and attach a second coordinate spec
69    /// on the chart context. For more detailed information, see documentation for [struct DualCoordChartContext](struct.DualCoordChartContext.html)
70    ///
71    /// - `x_coord`: The coordinate spec for the X axis
72    /// - `y_coord`: The coordinate spec for the Y axis
73    /// - **returns** The newly created dual spec chart context
74    #[allow(clippy::type_complexity)]
75    pub fn set_secondary_coord<SX: AsRangedCoord, SY: AsRangedCoord>(
76        self,
77        x_coord: SX,
78        y_coord: SY,
79    ) -> DualCoordChartContext<
80        'a,
81        DB,
82        Cartesian2d<X, Y>,
83        Cartesian2d<SX::CoordDescType, SY::CoordDescType>,
84    > {
85        let mut pixel_range = self.drawing_area.get_pixel_range();
86        pixel_range.1 = pixel_range.1.end..pixel_range.1.start;
87
88        DualCoordChartContext::new(self, Cartesian2d::new(x_coord, y_coord, pixel_range))
89    }
90}