Skip to main content

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}