chartml_core/scales/
mod.rs1mod linear;
2mod band;
3mod time;
4mod ordinal;
5mod sqrt;
6
7pub use linear::ScaleLinear;
8pub use band::ScaleBand;
9pub use time::ScaleTime;
10pub use ordinal::ScaleOrdinal;
11pub use sqrt::ScaleSqrt;
12
13pub trait ContinuousScale {
16 fn map(&self, value: f64) -> f64;
18 fn domain(&self) -> (f64, f64);
20 fn range(&self) -> (f64, f64);
22 fn ticks(&self, count: usize) -> Vec<f64>;
24 fn clamp(&self, value: f64) -> f64;
26}
27
28pub(crate) fn tick_step(min: f64, max: f64, count: usize) -> f64 {
31 let raw_step = (max - min) / count as f64;
32 let magnitude = 10_f64.powf(raw_step.log10().floor());
33 let error = raw_step / magnitude;
34
35 if error >= 50_f64.sqrt() {
36 10.0 * magnitude
37 } else if error >= 10_f64.sqrt() {
38 5.0 * magnitude
39 } else if error >= 2_f64.sqrt() {
40 2.0 * magnitude
41 } else {
42 magnitude
43 }
44}
45
46pub(crate) fn round_to_precision(value: f64, step: f64) -> f64 {
48 if step == 0.0 {
49 return value;
50 }
51 let decimals = (-step.log10().floor()).max(0.0) as i32;
52 let factor = 10_f64.powi(decimals);
53 (value * factor).round() / factor
54}