From c3155a24895ec4dfb1a8e580fb9ee3d31e9af139 Mon Sep 17 00:00:00 2001 From: Valentin271 <36198422+Valentin271@users.noreply.github.com> Date: Fri, 22 Sep 2023 09:38:58 +0200 Subject: [PATCH] fix(barchart): add horizontal labels(#518) Labels were missed in the initial implementation of the horizontal mode for the BarChart widget. This adds them. Fixes https://github.com/ratatui-org/ratatui/issues/499 --- src/widgets/barchart.rs | 43 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/src/widgets/barchart.rs b/src/widgets/barchart.rs index 0e361ec4c..19408054a 100644 --- a/src/widgets/barchart.rs +++ b/src/widgets/barchart.rs @@ -335,6 +335,26 @@ impl<'a> BarChart<'a> { } fn render_horizontal_bars(self, buf: &mut Buffer, bars_area: Rect, max: u64) { + // get the longest label + let label_size = self + .data + .iter() + .flat_map(|group| group.bars.iter().map(|bar| &bar.label)) + .flatten() // bar.label is an Option + .map(|label| label.width()) + .max() + .unwrap_or(0) as u16; + + let label_x = bars_area.x; + let bars_area = { + let margin = if label_size == 0 { 0 } else { 1 }; + Rect { + x: bars_area.x + label_size + margin, + width: bars_area.width - label_size - margin, + ..bars_area + } + }; + // convert the bar values to ratatui::symbols::bar::Set let groups: Vec> = self .data @@ -348,7 +368,7 @@ impl<'a> BarChart<'a> { }) .collect(); - // print all visible bars + // print all visible bars, label and values let mut bar_y = bars_area.top(); for (group_data, mut group) in groups.into_iter().zip(self.data) { let bars = std::mem::take(&mut group.bars); @@ -374,6 +394,12 @@ impl<'a> BarChart<'a> { y: bar_y + (self.bar_width >> 1), ..bars_area }; + + // label + if let Some(label) = &bar.label { + buf.set_line(label_x, bar_value_area.top(), label, label_size); + } + bar.render_value_with_different_styles( buf, bar_value_area, @@ -1098,6 +1124,21 @@ mod tests { test_horizontal_bars_label_width_greater_than_bar(Some(Color::White)) } + /// Tests horizontal bars label are presents + #[test] + fn test_horizontal_label() { + let chart = BarChart::default() + .direction(Direction::Horizontal) + .bar_gap(0) + .data(&[("Jan", 10), ("Feb", 20), ("Mar", 5)]); + + let mut buffer = Buffer::empty(Rect::new(0, 0, 10, 3)); + chart.render(buffer.area, &mut buffer); + let expected = Buffer::with_lines(vec!["Jan 10█ ", "Feb 20████", "Mar 5 "]); + + assert_buffer_eq!(buffer, expected); + } + #[test] fn test_group_label_style() { let chart: BarChart<'_> = BarChart::default()