Skip to main content

ggplot_rs/coord/
cartesian.rs

1use crate::render::Rect;
2
3use super::Coord;
4
5/// Standard Cartesian coordinate system, with optional zoom limits.
6///
7/// Unlike `xlim()`/`ylim()` on scales, zoom limits do NOT filter data —
8/// they only clip the viewport. Data outside the limits is still computed
9/// by stats and positions, just not visible.
10pub struct CoordCartesian {
11    xlim: Option<(f64, f64)>,
12    ylim: Option<(f64, f64)>,
13}
14
15impl CoordCartesian {
16    pub fn new() -> Self {
17        CoordCartesian {
18            xlim: None,
19            ylim: None,
20        }
21    }
22
23    /// Set x-axis zoom limits (data coordinates).
24    pub fn xlim(mut self, min: f64, max: f64) -> Self {
25        self.xlim = Some((min, max));
26        self
27    }
28
29    /// Set y-axis zoom limits (data coordinates).
30    pub fn ylim(mut self, min: f64, max: f64) -> Self {
31        self.ylim = Some((min, max));
32        self
33    }
34
35    /// Get x zoom limits for use by the renderer.
36    pub fn get_xlim(&self) -> Option<(f64, f64)> {
37        self.xlim
38    }
39
40    /// Get y zoom limits for use by the renderer.
41    pub fn get_ylim(&self) -> Option<(f64, f64)> {
42        self.ylim
43    }
44}
45
46impl Default for CoordCartesian {
47    fn default() -> Self {
48        Self::new()
49    }
50}
51
52impl Coord for CoordCartesian {
53    fn transform(&self, point: (f64, f64), plot_area: &Rect) -> (f64, f64) {
54        let (nx, ny) = point;
55        let px = plot_area.x + nx * plot_area.width;
56        // Y is flipped: 0 at bottom, 1 at top
57        let py = plot_area.y + (1.0 - ny) * plot_area.height;
58        (px, py)
59    }
60
61    fn zoom_x(&self) -> Option<(f64, f64)> {
62        self.xlim
63    }
64
65    fn zoom_y(&self) -> Option<(f64, f64)> {
66        self.ylim
67    }
68}