ggplot_rs/scale/sec_axis.rs
1/// A secondary axis specification — defines a transformation from the primary axis domain.
2///
3/// # Example
4/// ```
5/// use ggplot_rs::prelude::*;
6///
7/// // Temperature in Celsius on primary, Fahrenheit on secondary
8/// let sec = SecAxis::new(|c| c * 9.0 / 5.0 + 32.0).with_name("Fahrenheit");
9/// ```
10#[derive(Clone)]
11pub struct SecAxis {
12 /// Transformation from primary axis values to secondary axis values.
13 pub transform: fn(f64) -> f64,
14 /// Name / title for the secondary axis.
15 pub name: String,
16 /// Custom break positions in primary axis coordinates.
17 pub breaks: Option<Vec<f64>>,
18}
19
20impl SecAxis {
21 /// Create a secondary axis with the given transformation function.
22 pub fn new(transform: fn(f64) -> f64) -> Self {
23 SecAxis {
24 transform,
25 name: String::new(),
26 breaks: None,
27 }
28 }
29
30 pub fn with_name(mut self, name: &str) -> Self {
31 self.name = name.to_string();
32 self
33 }
34
35 pub fn with_breaks(mut self, breaks: Vec<f64>) -> Self {
36 self.breaks = Some(breaks);
37 self
38 }
39
40 /// Transform a primary axis value to the secondary axis value.
41 pub fn transform_value(&self, v: f64) -> f64 {
42 (self.transform)(v)
43 }
44}
45
46impl std::fmt::Debug for SecAxis {
47 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
48 f.debug_struct("SecAxis")
49 .field("name", &self.name)
50 .field("breaks", &self.breaks)
51 .finish()
52 }
53}