Skip to main content

ggplot_rs/coord/
fixed.rs

1use crate::render::Rect;
2
3use super::Coord;
4
5/// Fixed-ratio coordinate system — maintains aspect ratio.
6pub struct CoordFixed {
7    pub ratio: f64,
8}
9
10impl CoordFixed {
11    pub fn new(ratio: f64) -> Self {
12        CoordFixed { ratio }
13    }
14}
15
16impl Coord for CoordFixed {
17    fn fixed_aspect(&self) -> Option<f64> {
18        (self.ratio.is_finite() && self.ratio > 0.0).then_some(self.ratio)
19    }
20
21    fn transform(&self, point: (f64, f64), plot_area: &Rect) -> (f64, f64) {
22        // Compute the effective area that maintains the aspect ratio
23        let data_aspect = self.ratio; // data units_y / units_x
24        let pixel_aspect = plot_area.height / plot_area.width;
25
26        let (eff_w, eff_h, off_x, off_y) = if pixel_aspect > data_aspect {
27            // Too tall — use full width, reduce height
28            let h = plot_area.width * data_aspect;
29            (plot_area.width, h, 0.0, (plot_area.height - h) / 2.0)
30        } else {
31            // Too wide — use full height, reduce width
32            let w = plot_area.height / data_aspect;
33            (w, plot_area.height, (plot_area.width - w) / 2.0, 0.0)
34        };
35
36        let (nx, ny) = point;
37        let px = plot_area.x + off_x + nx * eff_w;
38        let py = plot_area.y + off_y + (1.0 - ny) * eff_h;
39        (px, py)
40    }
41}