chartml_core/scales/
ordinal.rs1pub struct ScaleOrdinal {
4 domain: Vec<String>,
5 range: Vec<String>,
6}
7
8impl ScaleOrdinal {
9 pub fn new(domain: Vec<String>, range: Vec<String>) -> Self {
11 Self { domain, range }
12 }
13
14 pub fn map(&self, value: &str) -> Option<&str> {
18 if self.range.is_empty() {
19 return None;
20 }
21 let index = self.domain.iter().position(|d| d == value)?;
22 Some(&self.range[index % self.range.len()])
23 }
24
25 pub fn map_index(&self, index: usize) -> Option<&str> {
28 if self.range.is_empty() {
29 return None;
30 }
31 Some(&self.range[index % self.range.len()])
32 }
33
34 pub fn domain(&self) -> &[String] {
36 &self.domain
37 }
38
39 pub fn range(&self) -> &[String] {
41 &self.range
42 }
43}
44
45#[cfg(test)]
46mod tests {
47 use super::*;
48
49 #[test]
50 fn ordinal_basic_mapping() {
51 let scale = ScaleOrdinal::new(
52 vec!["a".into(), "b".into(), "c".into()],
53 vec!["red".into(), "green".into(), "blue".into()],
54 );
55 assert_eq!(scale.map("a"), Some("red"));
56 assert_eq!(scale.map("b"), Some("green"));
57 assert_eq!(scale.map("c"), Some("blue"));
58 }
59
60 #[test]
61 fn ordinal_cycling() {
62 let scale = ScaleOrdinal::new(
63 vec!["a".into(), "b".into(), "c".into(), "d".into()],
64 vec!["red".into(), "green".into()],
65 );
66 assert_eq!(scale.map("a"), Some("red"));
67 assert_eq!(scale.map("b"), Some("green"));
68 assert_eq!(scale.map("c"), Some("red")); assert_eq!(scale.map("d"), Some("green")); }
71
72 #[test]
73 fn ordinal_unknown_returns_none() {
74 let scale = ScaleOrdinal::new(
75 vec!["a".into(), "b".into()],
76 vec!["red".into(), "green".into()],
77 );
78 assert_eq!(scale.map("unknown"), None);
79 }
80
81 #[test]
82 fn ordinal_empty_range() {
83 let scale = ScaleOrdinal::new(
84 vec!["a".into(), "b".into()],
85 vec![],
86 );
87 assert_eq!(scale.map("a"), None);
88 }
89
90 #[test]
91 fn ordinal_map_index() {
92 let scale = ScaleOrdinal::new(
93 vec!["a".into(), "b".into()],
94 vec!["red".into(), "green".into(), "blue".into()],
95 );
96 assert_eq!(scale.map_index(0), Some("red"));
97 assert_eq!(scale.map_index(1), Some("green"));
98 assert_eq!(scale.map_index(2), Some("blue"));
99 assert_eq!(scale.map_index(3), Some("red")); }
101}