ggplot_rs/coord/mod.rs
1pub mod cartesian;
2pub mod fixed;
3pub mod flip;
4pub mod polar;
5#[cfg(feature = "sf")]
6pub mod sf;
7pub mod trans;
8
9use crate::render::Rect;
10
11/// A trained axis domain together with the normalized panel positions of its
12/// endpoints. `pmin`/`pmax` are `scale.map(min)`/`scale.map(max)`, so a coord can
13/// invert the (linear, expanded) scale mapping exactly: given a normalized
14/// position `n`, the data value is `min + (n - pmin)/(pmax - pmin) * (max - min)`.
15#[derive(Clone, Copy, Debug)]
16pub struct AxisSpan {
17 pub min: f64,
18 pub max: f64,
19 pub pmin: f64,
20 pub pmax: f64,
21}
22
23/// Trait for coordinate systems.
24pub trait Coord: Send + Sync {
25 /// Transform normalized (0..1, 0..1) coordinates to pixel coordinates.
26 fn transform(&self, point: (f64, f64), plot_area: &Rect) -> (f64, f64);
27
28 /// Whether to draw grid lines.
29 fn gridlines(&self) -> bool {
30 true
31 }
32
33 /// Whether this coordinate system flips X and Y.
34 fn is_flipped(&self) -> bool {
35 false
36 }
37
38 /// Whether this is a non-linear polar system (bars become radial sectors,
39 /// so geoms that draw rectangles must tessellate their edges into an arc).
40 fn is_polar(&self) -> bool {
41 false
42 }
43
44 /// For a polar system, whether the *x* aesthetic maps to angle (`theta="x"`).
45 /// When false (`theta="y"`, pies), the *y* aesthetic is the angle, so sector
46 /// tessellation must sweep the y edge instead of the x edge.
47 fn polar_theta_is_x(&self) -> bool {
48 true
49 }
50
51 /// Zoom limits for x-axis (data coordinates). Clips viewport without filtering data.
52 fn zoom_x(&self) -> Option<(f64, f64)> {
53 None
54 }
55
56 /// Zoom limits for y-axis (data coordinates). Clips viewport without filtering data.
57 fn zoom_y(&self) -> Option<(f64, f64)> {
58 None
59 }
60
61 /// Supply the trained x/y axis spans after scale training. Coordinate systems
62 /// that warp the axis (e.g. `coord_trans`) need this to map a normalized
63 /// position back to a data value. Default is a no-op.
64 fn set_domains(&mut self, _x: Option<AxisSpan>, _y: Option<AxisSpan>) {}
65}