1use crate::error::{ChartError, Result};
4
5pub fn calculate_price_levels(price_min: f64, price_max: f64, content_height: f32) -> Vec<f64> {
7 let price_range = price_max - price_min;
8 let target_label_count = (content_height / 20.0) as i32; let raw_step = price_range / target_label_count as f64;
10 let nice_step = find_nice_number(raw_step);
11
12 let start_price = (price_min / nice_step).floor() * nice_step;
14 let mut levels = Vec::new();
15 let mut current_price = start_price;
16
17 while current_price <= price_max {
18 if current_price >= price_min {
19 levels.push(current_price);
20 }
21 current_price += nice_step;
22 }
23
24 levels
25}
26
27pub fn find_nice_number(value: f64) -> f64 {
29 let magnitude = 10.0_f64.powf(value.log10().floor());
30 let normalized = value / magnitude;
31
32 let nice_normalized = if normalized < 1.5 {
33 1.0
34 } else if normalized < 2.5 {
35 2.0
36 } else if normalized < 3.0 {
37 2.5
38 } else if normalized < 7.0 {
39 5.0
40 } else {
41 10.0
42 };
43
44 nice_normalized * magnitude
45}
46
47pub fn compare_image_mse(
54 generated_rgba: &[u8],
55 width: u32,
56 height: u32,
57 reference_path: &str,
58) -> Result<f64> {
59 let reference_img = image::open(reference_path)
60 .map_err(|e| {
61 ChartError::internal(format!(
62 "Failed to open reference image {}: {}",
63 reference_path, e
64 ))
65 })?
66 .to_rgba8();
67
68 if reference_img.width() != width || reference_img.height() != height {
70 return Err(ChartError::internal(format!(
71 "Reference image dimensions {}x{} do not match generated {}x{}",
72 reference_img.width(),
73 reference_img.height(),
74 width,
75 height
76 )));
77 }
78
79 let ref_pixels = reference_img.as_raw();
80 if ref_pixels.len() != generated_rgba.len() {
81 return Err(ChartError::internal(
82 "Pixel data length mismatch between images",
83 ));
84 }
85
86 let mut mse: f64 = 0.0;
87 for (a, b) in generated_rgba.iter().zip(ref_pixels.iter()) {
88 let diff = (*a as f64) - (*b as f64);
89 mse += diff * diff;
90 }
91
92 mse /= generated_rgba.len() as f64;
93 Ok(mse)
94}