rustial_engine/visualization/
legend.rs1use super::ColorRamp;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7pub enum NormalizationMode {
8 Absolute,
10 ZeroToOne,
12 Percentage,
14}
15
16#[derive(Debug, Clone)]
18pub struct LabeledStop {
19 pub position: f32,
21 pub label: String,
23}
24
25#[derive(Debug, Clone)]
31pub struct LegendSpec {
32 pub title: String,
34 pub units: String,
36 pub ramp: ColorRamp,
38 pub min_value: f64,
40 pub max_value: f64,
42 pub labeled_stops: Vec<LabeledStop>,
44 pub normalization: NormalizationMode,
46}
47
48impl LegendSpec {
49 pub fn new(title: impl Into<String>, ramp: ColorRamp, min: f64, max: f64) -> Self {
51 Self {
52 title: title.into(),
53 units: String::new(),
54 ramp,
55 min_value: min,
56 max_value: max,
57 labeled_stops: Vec::new(),
58 normalization: NormalizationMode::Absolute,
59 }
60 }
61
62 pub fn with_units(mut self, units: impl Into<String>) -> Self {
64 self.units = units.into();
65 self
66 }
67
68 pub fn with_stop(mut self, position: f32, label: impl Into<String>) -> Self {
70 self.labeled_stops.push(LabeledStop {
71 position,
72 label: label.into(),
73 });
74 self
75 }
76}
77
78#[cfg(test)]
79mod tests {
80 use super::*;
81 use crate::visualization::{ColorStop, ColorRamp};
82
83 #[test]
84 fn legend_spec_builder() {
85 let ramp = ColorRamp::new(vec![
86 ColorStop { value: 0.0, color: [0.0, 0.0, 1.0, 1.0] },
87 ColorStop { value: 1.0, color: [1.0, 0.0, 0.0, 1.0] },
88 ]);
89 let legend = LegendSpec::new("Test", ramp, 0.0, 100.0)
90 .with_units("m/s")
91 .with_stop(0.0, "Low")
92 .with_stop(1.0, "High");
93
94 assert_eq!(legend.title, "Test");
95 assert_eq!(legend.units, "m/s");
96 assert_eq!(legend.labeled_stops.len(), 2);
97 assert!((legend.min_value - 0.0).abs() < 1e-9);
98 assert!((legend.max_value - 100.0).abs() < 1e-9);
99 }
100}