ggplot_rs/scale/
transform.rs1use crate::data::Value;
2
3#[derive(Clone, Debug)]
5pub enum ScaleTransform {
6 Identity,
7 Log10,
8 Log2,
9 Ln,
10 Sqrt,
11 Reverse,
12}
13
14impl ScaleTransform {
15 pub fn apply(&self, value: f64) -> f64 {
17 match self {
18 ScaleTransform::Identity => value,
19 ScaleTransform::Log10 => {
20 if value > 0.0 {
21 value.log10()
22 } else {
23 f64::NEG_INFINITY
24 }
25 }
26 ScaleTransform::Log2 => {
27 if value > 0.0 {
28 value.log2()
29 } else {
30 f64::NEG_INFINITY
31 }
32 }
33 ScaleTransform::Ln => {
34 if value > 0.0 {
35 value.ln()
36 } else {
37 f64::NEG_INFINITY
38 }
39 }
40 ScaleTransform::Sqrt => {
41 if value >= 0.0 {
42 value.sqrt()
43 } else {
44 f64::NAN
45 }
46 }
47 ScaleTransform::Reverse => -value,
48 }
49 }
50
51 pub fn inverse(&self, value: f64) -> f64 {
53 match self {
54 ScaleTransform::Identity => value,
55 ScaleTransform::Log10 => 10f64.powf(value),
56 ScaleTransform::Log2 => 2f64.powf(value),
57 ScaleTransform::Ln => value.exp(),
58 ScaleTransform::Sqrt => value * value,
59 ScaleTransform::Reverse => -value,
60 }
61 }
62
63 pub fn transform_value(&self, value: &Value) -> Value {
65 match value.as_f64() {
66 Some(f) => {
67 let t = self.apply(f);
68 if t.is_finite() {
69 Value::Float(t)
70 } else {
71 Value::Na
72 }
73 }
74 None => value.clone(),
75 }
76 }
77
78 pub fn is_identity(&self) -> bool {
79 matches!(self, ScaleTransform::Identity)
80 }
81}