Skip to main content

ggplot_rs/scale/
mod.rs

1pub mod alpha;
2pub mod color;
3pub mod continuous;
4pub mod datetime;
5pub mod discrete;
6pub mod format;
7pub mod gradient;
8pub mod gradient_n;
9pub mod grey;
10pub mod linetype;
11pub mod linetype_manual;
12pub mod manual;
13pub mod modified;
14pub mod palettes;
15pub mod scale_set;
16pub mod sec_axis;
17pub mod shape;
18pub mod shape_manual;
19pub mod size;
20pub mod steps;
21pub mod transform;
22pub mod util;
23
24pub use scale_set::ScaleSet;
25
26use crate::aes::Aesthetic;
27use crate::data::Value;
28use crate::render::backend::{Linetype, PointShape};
29
30/// Trait for scales that map data values to visual properties.
31pub trait Scale: Send + Sync {
32    /// Which aesthetic this scale is for.
33    fn aesthetic(&self) -> Aesthetic;
34
35    /// Incorporate data values to determine domain.
36    fn train(&mut self, values: &[Value]);
37
38    /// Map a data value to a [0, 1] normalized position (position scales)
39    /// or to a concrete visual value index (color/size scales).
40    fn map(&self, value: &Value) -> f64;
41
42    /// Generate break positions and labels for axis/legend.
43    fn breaks(&self) -> Vec<(f64, String)>;
44
45    /// Human-readable name (axis title).
46    fn name(&self) -> &str;
47
48    /// Set the scale name.
49    fn set_name(&mut self, name: &str);
50
51    /// Apply transformation to raw data (e.g., log10).
52    fn transform(&self, value: &Value) -> Value {
53        value.clone()
54    }
55
56    /// Whether this is a discrete scale.
57    fn is_discrete(&self) -> bool {
58        false
59    }
60
61    /// Map a data value to an RGB color. Default returns None.
62    fn map_to_color(&self, _value: &Value) -> Option<(u8, u8, u8)> {
63        None
64    }
65
66    /// Map a data value to a point shape. Default returns None.
67    fn map_to_shape(&self, _value: &Value) -> Option<PointShape> {
68        None
69    }
70
71    /// Map a data value to a linetype. Default returns None.
72    fn map_to_linetype(&self, _value: &Value) -> Option<Linetype> {
73        None
74    }
75
76    /// Map a data value to a point size (radius in pixels). Default returns None.
77    fn map_to_size(&self, _value: &Value) -> Option<f64> {
78        None
79    }
80
81    /// Map a data value to an alpha (opacity) value. Default returns None.
82    fn map_to_alpha(&self, _value: &Value) -> Option<f64> {
83        None
84    }
85
86    /// Get the secondary axis specification, if any.
87    fn sec_axis(&self) -> Option<&sec_axis::SecAxis> {
88        None
89    }
90
91    /// Adopt a plot-level default [`Locale`](crate::locale::Locale) for the
92    /// default break labels (number marks, month names, date formats), unless
93    /// the scale already has its own. Called by the plot builder when
94    /// [`GGPlot::locale`](crate::GGPlot::locale) is set. Default: ignored
95    /// (scales without numeric/date labels).
96    fn set_default_locale(&mut self, _locale: &crate::locale::Locale) {}
97
98    /// The locale this scale's default labels are rendered with, if any.
99    fn locale(&self) -> Option<&crate::locale::Locale> {
100        None
101    }
102
103    /// Override the trained domain limits (used by coord_cartesian zoom).
104    fn set_limits(&mut self, _min: f64, _max: f64) {
105        // Default no-op. Continuous scales override this.
106    }
107
108    /// Return OOB filter limits if this scale was created with explicit limits
109    /// (e.g., via xlim/ylim). Data outside these limits should be removed before stats.
110    fn filter_limits(&self) -> Option<(f64, f64)> {
111        None
112    }
113
114    /// Return the trained data domain (min, max) for continuous scales.
115    /// Used by the colorbar legend to pass data-space values to map_to_color().
116    fn domain(&self) -> Option<(f64, f64)> {
117        None
118    }
119
120    /// The data values at the panel edges (normalized 0 and 1) for a trained
121    /// continuous position scale — the limits after expansion, in the scale's
122    /// transformed space. `None` for discrete / untrained / non-position scales.
123    fn expanded_domain(&self) -> Option<(f64, f64)> {
124        None
125    }
126
127    /// Whether this axis is drawn on the opposite side (x → top, y → right).
128    fn axis_position_opposite(&self) -> bool {
129        false
130    }
131
132    /// Clone this scale into a boxed trait object.
133    fn clone_box(&self) -> Box<dyn Scale>;
134
135    /// Reset training state so the scale can be retrained on new data.
136    fn reset_training(&mut self) {}
137}