diff --git a/crates/ui/src/input/rope_ext.rs b/crates/ui/src/input/rope_ext.rs index 44cf111c..dc140d13 100644 --- a/crates/ui/src/input/rope_ext.rs +++ b/crates/ui/src/input/rope_ext.rs @@ -101,7 +101,7 @@ mod tests { #[test] fn test_lines() { let rope = Rope::from("Hello\nWorld\r\nThis is a test 中文\nRope"); - let lines: Vec<_> = rope.lines().into_iter().map(|r| r.to_string()).collect(); + let lines: Vec<_> = rope.lines().map(|r| r.to_string()).collect(); assert_eq!( lines, vec!["Hello", "World\r", "This is a test 中文", "Rope"] diff --git a/crates/ui/src/plot/scale.rs b/crates/ui/src/plot/scale.rs index dfd0ecff..9befebd3 100644 --- a/crates/ui/src/plot/scale.rs +++ b/crates/ui/src/plot/scale.rs @@ -13,5 +13,12 @@ pub trait Scale { fn tick(&self, value: &T) -> Option; /// Get the least index of the scale. - fn least_index(&self, tick: f32) -> usize; + fn least_index(&self, _tick: f32) -> usize { + 0 + } + + /// Get the least index of the scale with the domain. + fn least_index_with_domain(&self, _tick: f32, _domain: &[T]) -> (usize, f32) { + (0, 0.) + } } diff --git a/crates/ui/src/plot/scale/linear.rs b/crates/ui/src/plot/scale/linear.rs index 6b9a1c36..24360c6f 100644 --- a/crates/ui/src/plot/scale/linear.rs +++ b/crates/ui/src/plot/scale/linear.rs @@ -65,13 +65,22 @@ where Some(ratio * self.range_diff + self.range_start) } - fn least_index(&self, tick: f32) -> usize { - if self.domain_len == 0 { - return 0; + fn least_index_with_domain(&self, tick: f32, domain: &[T]) -> (usize, f32) { + if self.domain_len == 0 || domain.is_empty() { + return (0, 0.); } - let index = (tick / self.range_diff).round() as usize; - index.min(self.domain_len.saturating_sub(1)) + domain + .iter() + .flat_map(|v| self.tick(v)) + .enumerate() + .min_by(|(_, a), (_, b)| { + ((*a) - tick) + .abs() + .partial_cmp(&((*b) - tick).abs()) + .unwrap_or(std::cmp::Ordering::Equal) + }) + .unwrap_or((0, 0.)) } } @@ -127,4 +136,15 @@ mod tests { assert_eq!(scale.tick(&2.), Some(0.)); assert_eq!(scale.tick(&3.), Some(0.)); } + + #[test] + fn test_scale_linear_least_index_with_domain() { + let scale = ScaleLinear::new(vec![1., 2., 3.], vec![0., 100.]); + assert_eq!(scale.least_index_with_domain(0., &[1., 2., 3.]), (0, 0.)); + assert_eq!(scale.least_index_with_domain(50., &[1., 2., 3.]), (1, 50.)); + assert_eq!( + scale.least_index_with_domain(100., &[1., 2., 3.]), + (2, 100.) + ); + } }