theta_chart/series/
series_number.rs

1use std::vec;
2
3use crate::{chart::*, coord::*, utils::cal_step::*, TAU};
4
5#[derive(Debug, Clone, Default)]
6/// A series of numbers represented on a chart
7pub struct SNumber {
8    series: Vec<f64>,
9    is_float: bool,
10    stick: usize,
11    origin: f64,
12    // For range of axis
13    range: Option<(f64, f64)>,
14}
15
16impl SNumber {
17    pub fn new(series: Vec<f64>) -> Self {
18        SNumber {
19            series,
20            is_float: true,
21            stick: 0,
22            origin: 0.,
23            range: None,
24        }
25    }
26
27    pub fn set_stick(&self, stick: usize) -> Self {
28        Self {
29            series: self.series.clone(),
30            is_float: self.is_float,
31            stick: stick,
32            origin: self.origin,
33            range: self.range,
34        }
35    }
36
37    pub fn series(&self) -> Vec<f64> {
38        self.series.clone()
39    }
40
41    pub fn merge(&self, other: SNumber) -> Self {
42        let mut series = self.series.clone();
43        series.extend(other.series);
44        Self {
45            series,
46            is_float: self.is_float,
47            stick: self.stick,
48            origin: self.origin,
49            range: self.range,
50        }
51    }
52
53    pub fn set_range(&self, min: f64, max: f64) -> Self {
54        Self {
55            series: self.series.clone(),
56            is_float: self.is_float,
57            stick: self.stick,
58            origin: self.origin,
59            range: Some((min, max)),
60        }
61    }
62}
63
64impl From<Vec<i64>> for SNumber {
65    fn from(value: Vec<i64>) -> Self {
66        let mut series: Vec<f64> = vec![];
67        for i in value {
68            series.push(i as f64)
69        }
70        Self {
71            series,
72            is_float: false,
73            stick: 0,
74            origin: 0.,
75            range: None,
76        }
77    }
78}
79
80impl From<Vec<u64>> for SNumber {
81    fn from(value: Vec<u64>) -> Self {
82        let mut series: Vec<f64> = vec![];
83        for i in value {
84            series.push(i as f64)
85        }
86
87        Self {
88            series,
89            is_float: false,
90            stick: 0,
91            origin: 0.,
92            range: None,
93        }
94    }
95}
96
97impl ScaleNumber for SNumber {
98    fn domain(&self) -> (f64, f64) {
99        let mut all = self.series();
100        if let Some(range) = self.range {
101            all.push(range.0);
102            all.push(range.1);
103        } else {
104            all.push(self.origin);
105        }
106
107        min_max_vec(&all)
108    }
109
110    fn count_distance_step(&self) -> (f64, f64, f64) {
111        let (min, max) = self.domain();
112        let count_distance = if self.stick == 0 {
113            10.
114        } else {
115            self.stick as f64 - 1.
116        };
117        let (distance_up, step, distance_down) = if min >= 0. && max >= 0. {
118            let mut step = max / count_distance;
119            step = CalStep::new(step).cal_scale();
120            (max / step, step, 0.)
121        } else if min < 0. && max < 0. {
122            let mut step = min / count_distance;
123            step = CalStep::new(step).cal_scale();
124            (0., step, min.abs() / step)
125        } else {
126            let mut step = (max - min) / count_distance;
127            step = CalStep::new(step).cal_scale();
128            (max / step, step, min.abs() / step)
129        };
130        (distance_up.ceil(), step, distance_down.ceil())
131    }
132
133    fn to_percent(&self) -> Vec<f64> {
134        let total: f64 = self.series.iter().sum();
135        self.series.clone().into_iter().map(|f| f / total).collect()
136    }
137
138    fn to_percent_radar(&self) -> Vec<f64> {
139        let total = 100.;
140        self.series.clone().into_iter().map(|f| f / total).collect()
141    }
142
143    fn gen_pie(&self) -> Vec<Arc> {
144        let series = self.series.clone();
145        let total: f64 = series.iter().sum();
146        let percent: Vec<f64> = series.clone().into_iter().map(|f| f / total).collect();
147        let mut vector_begin = Vector::new(0., -1.);
148        let mut vec_arc: Vec<Arc> = vec![];
149        for p in percent {
150            let arc = Arc::new_polar(Point::default(), vector_begin.clone(), p * TAU);
151            vector_begin = arc.end.clone();
152            vec_arc.push(arc);
153        }
154        vec_arc
155    }
156
157    fn gen_radar_grid(&self, count: usize) -> Vec<Vector> {
158        let mut vector_begin = Vector::new(0., -1.);
159        let mut vectors: Vec<Vector> = vec![];
160        vectors.push(vector_begin);
161        for index in 1..count {
162            vector_begin = vectors[index - 1].clone();
163            vectors.push(vector_begin.az_rotate_tau(TAU / count as f64));
164        }
165        vectors
166    }
167
168    fn gen_axes(&self) -> Axes {
169        let style = "number".to_string();
170        let (distance_up, step, distance_down) = self.count_distance_step();
171        let (_, precision) = count_precision(step.clone(), 0);
172        let mut vec_value: Vec<f64> = vec![];
173        let mut vec_stick: Vec<Stick> = vec![];
174        for index in 1..(distance_down as i64 + 1) {
175            vec_value.push(-index as f64 * step);
176        }
177
178        for index in 0..(distance_up as i64 + 1) {
179            vec_value.push(index as f64 * step);
180        }
181
182        vec_value.sort_by(|a, b| a.partial_cmp(b).unwrap());
183
184        for index in 0..(vec_value.len()) {
185            let value = vec_value[index];
186            let label = format!("{:.prec$}", value, prec = precision);
187            let stick = Stick::new(label, self.scale(value));
188            vec_stick.push(stick);
189        }
190        let sticks = vec_stick
191            .into_iter()
192            .filter(|stick| stick.value >= -0.0000001 && stick.value <= 1.0000001)
193            .collect::<Vec<_>>();
194
195        Axes {
196            sticks: sticks,
197            step: step,
198            style,
199        }
200    }
201
202    fn scale(&self, value: f64) -> f64 {
203        let (min, max) = self.domain();
204        let range = max - min;
205
206        let diff = value - min;
207        diff / range
208    }
209
210    fn to_stick(&self) -> Vec<Stick> {
211        let mut vec_stick: Vec<Stick> = vec![];
212        let len = self.series().len();
213        for index in 0..len {
214            let stick = Stick::new(format!("{}", self.series()[index]), self.series()[index]);
215            vec_stick.push(stick);
216        }
217        vec_stick
218    }
219}
220
221fn count_precision(mut number: f64, mut count: usize) -> (f64, usize) {
222    let floor = number - number.floor();
223    if floor == 0. {
224        return (number, count);
225    } else {
226        number *= 10.;
227        count += 1;
228        count_precision(number, count)
229    }
230}