use super::ColorRamp;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum NormalizationMode {
Absolute,
ZeroToOne,
Percentage,
}
#[derive(Debug, Clone)]
pub struct LabeledStop {
pub position: f32,
pub label: String,
}
#[derive(Debug, Clone)]
pub struct LegendSpec {
pub title: String,
pub units: String,
pub ramp: ColorRamp,
pub min_value: f64,
pub max_value: f64,
pub labeled_stops: Vec<LabeledStop>,
pub normalization: NormalizationMode,
}
impl LegendSpec {
pub fn new(title: impl Into<String>, ramp: ColorRamp, min: f64, max: f64) -> Self {
Self {
title: title.into(),
units: String::new(),
ramp,
min_value: min,
max_value: max,
labeled_stops: Vec::new(),
normalization: NormalizationMode::Absolute,
}
}
pub fn with_units(mut self, units: impl Into<String>) -> Self {
self.units = units.into();
self
}
pub fn with_stop(mut self, position: f32, label: impl Into<String>) -> Self {
self.labeled_stops.push(LabeledStop {
position,
label: label.into(),
});
self
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::visualization::{ColorRamp, ColorStop};
#[test]
fn legend_spec_builder() {
let ramp = ColorRamp::new(vec![
ColorStop {
value: 0.0,
color: [0.0, 0.0, 1.0, 1.0],
},
ColorStop {
value: 1.0,
color: [1.0, 0.0, 0.0, 1.0],
},
]);
let legend = LegendSpec::new("Test", ramp, 0.0, 100.0)
.with_units("m/s")
.with_stop(0.0, "Low")
.with_stop(1.0, "High");
assert_eq!(legend.title, "Test");
assert_eq!(legend.units, "m/s");
assert_eq!(legend.labeled_stops.len(), 2);
assert!((legend.min_value - 0.0).abs() < 1e-9);
assert!((legend.max_value - 100.0).abs() < 1e-9);
}
}