use crate::app::{PanelState, YAxisMode};
pub(crate) fn calculate_y_bounds(p: &PanelState) -> [f64; 2] {
let mut min = f64::MAX;
let mut max = f64::MIN;
let mut has_data = false;
for s in &p.series {
if !s.visible {
continue;
}
for &(_, v) in &s.points {
if !v.is_finite() {
continue;
}
if v < min {
min = v;
}
if v > max {
max = v;
}
has_data = true;
}
}
if !has_data {
return [0.0, 1.0];
}
if min == max {
min -= 1.0;
max += 1.0;
}
if p.y_axis_mode == YAxisMode::ZeroBased {
if min > 0.0 {
min = 0.0;
} else if max < 0.0 {
max = 0.0;
}
}
let range = max - min;
[min - range * 0.05, max + range * 0.05]
}
#[cfg(test)]
mod tests {
use super::*;
use crate::app::SeriesView;
fn create_test_panel() -> PanelState {
PanelState {
title: "test".to_string(),
exprs: vec![],
legends: vec![],
series: vec![],
last_error: None,
last_url: None,
last_samples: 0,
grid: None,
y_axis_mode: YAxisMode::Auto,
panel_type: crate::app::PanelType::Graph,
thresholds: None,
min: None,
max: None,
autogrid: None,
}
}
#[test]
fn test_calculate_y_bounds_basic() {
let mut p = create_test_panel();
p.series.push(SeriesView {
name: "test".to_string(),
value: None,
points: vec![(0.0, 10.0), (1.0, 20.0)],
visible: true,
});
let bounds = calculate_y_bounds(&p);
assert!(bounds[0] < 10.0);
assert!(bounds[1] > 20.0);
}
#[test]
fn test_calculate_y_bounds_nan() {
let mut p = create_test_panel();
p.series.push(SeriesView {
name: "test".to_string(),
value: None,
points: vec![(0.0, 10.0), (1.0, f64::NAN), (2.0, 20.0)],
visible: true,
});
let bounds = calculate_y_bounds(&p);
assert!(bounds[0] < 10.0); assert!(bounds[1] > 20.0);
}
#[test]
fn test_calculate_y_bounds_infinity() {
let mut p = create_test_panel();
p.series.push(SeriesView {
name: "test".to_string(),
value: None,
points: vec![(0.0, 10.0), (1.0, f64::INFINITY), (2.0, 20.0)],
visible: true,
});
let bounds = calculate_y_bounds(&p);
assert!(bounds[0] < 10.0); assert!(bounds[1] > 20.0);
}
#[test]
fn test_calculate_y_bounds_zero_based() {
let mut p = create_test_panel();
p.y_axis_mode = YAxisMode::ZeroBased;
p.series.push(SeriesView {
name: "test".to_string(),
value: None,
points: vec![(0.0, 10.0), (1.0, 20.0)],
visible: true,
});
let bounds = calculate_y_bounds(&p);
assert_eq!(bounds[0], -1.0);
assert!(bounds[1] > 20.0);
}
}