diff --git a/crates/story/src/fixtures/monthly-devices.json b/crates/story/src/fixtures/monthly-devices.json index 770e83f4..c741a863 100644 --- a/crates/story/src/fixtures/monthly-devices.json +++ b/crates/story/src/fixtures/monthly-devices.json @@ -29,4 +29,4 @@ "desktop": 214.0, "color_alpha": 1.0 } -] +] \ No newline at end of file diff --git a/crates/ui/src/chart/area_chart.rs b/crates/ui/src/chart/area_chart.rs index 7ab82e35..046fe264 100644 --- a/crates/ui/src/chart/area_chart.rs +++ b/crates/ui/src/chart/area_chart.rs @@ -115,7 +115,13 @@ where if (i + 1) % self.tick_margin == 0 { x.tick(&x_fn(d)).map(|x_tick| { let align = match i { - 0 => TextAlign::Left, + 0 => { + if data_len == 1 { + TextAlign::Center + } else { + TextAlign::Left + } + } i if i == data_len - 1 => TextAlign::Right, _ => TextAlign::Center, }; diff --git a/crates/ui/src/chart/line_chart.rs b/crates/ui/src/chart/line_chart.rs index 96f589a6..8de85c66 100644 --- a/crates/ui/src/chart/line_chart.rs +++ b/crates/ui/src/chart/line_chart.rs @@ -107,7 +107,13 @@ where if (i + 1) % self.tick_margin == 0 { x.tick(&x_fn(d)).map(|x_tick| { let align = match i { - 0 => TextAlign::Left, + 0 => { + if data_len == 1 { + TextAlign::Center + } else { + TextAlign::Left + } + } i if i == data_len - 1 => TextAlign::Right, _ => TextAlign::Center, }; diff --git a/crates/ui/src/plot/scale/point.rs b/crates/ui/src/plot/scale/point.rs index 74f45e95..185f4faf 100644 --- a/crates/ui/src/plot/scale/point.rs +++ b/crates/ui/src/plot/scale/point.rs @@ -27,7 +27,14 @@ where .into_option() .map_or(0., |(min, max)| max - min); - (range_diff / (len - 1) as f32, range_diff / len as f32) + if len == 1 { + (range_diff, range_diff) + } else { + ( + range_diff / len.saturating_sub(1) as f32, + range_diff / len as f32, + ) + } }; Self { @@ -43,8 +50,12 @@ where T: PartialEq, { fn tick(&self, value: &T) -> Option { - let index = self.domain.iter().position(|v| v == value)?; - Some(index as f32 * self.range_tick) + if self.domain.len() == 1 { + Some(self.range_tick / 2.) + } else { + let index = self.domain.iter().position(|v| v == value)?; + Some(index as f32 * self.range_tick) + } } fn least_index(&self, tick: f32) -> usize { @@ -62,7 +73,7 @@ mod tests { use super::*; #[test] - fn test_scale_point_1() { + fn test_scale_point() { let scale = ScalePoint::new(vec![1, 2, 3], vec![0., 100.]); assert_eq!(scale.tick(&1), Some(0.)); assert_eq!(scale.tick(&2), Some(50.)); @@ -70,7 +81,7 @@ mod tests { } #[test] - fn test_scale_point_2() { + fn test_scale_point_empty() { let scale = ScalePoint::new(vec![], vec![0., 100.]); assert_eq!(scale.tick(&1), None); assert_eq!(scale.tick(&2), None); @@ -81,4 +92,10 @@ mod tests { assert_eq!(scale.tick(&2), Some(0.)); assert_eq!(scale.tick(&3), Some(0.)); } + + #[test] + fn test_scale_point_single() { + let scale = ScalePoint::new(vec![1], vec![0., 100.]); + assert_eq!(scale.tick(&1), Some(50.)); + } }