plot(scale): Add least index support for linear (#1225)

This commit is contained in:
Floyd Wang 2025-09-09 11:40:09 +08:00 committed by GitHub
parent d71a32d0e4
commit 84b2d2a6f5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 34 additions and 7 deletions

View file

@ -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"]

View file

@ -13,5 +13,12 @@ pub trait Scale<T> {
fn tick(&self, value: &T) -> Option<f32>;
/// 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.)
}
}

View file

@ -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.)
);
}
}