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}
91