feat(barchart): set custom text value in the bar (#309)

for now the value is converted to a string and then printed. in many
cases the values are too wide or double values. so it make sense
to set a custom value text instead of the default behavior.

this patch suggests to add a method
"fn text_value(mut self, text_value: String)"
to the Bar, which allows to override the value printed in the bar

Signed-off-by: Ben Fekih, Hichem <hichem.f@live.de>
This commit is contained in:
Hichem 2023-07-14 06:38:54 +02:00 committed by GitHub
parent 2889c7d084
commit 60150f6236
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 37 additions and 30 deletions

View file

@ -57,17 +57,17 @@ impl<'a> App<'a> {
companies: [
Company {
label: "Comp.A",
revenue: [9, 12, 5, 8],
revenue: [9500, 12500, 5300, 8500],
bar_style: Style::default().fg(Color::Green),
},
Company {
label: "Comp.B",
revenue: [1, 2, 3, 4],
revenue: [1500, 2500, 3000, 4100],
bar_style: Style::default().fg(Color::Yellow),
},
Company {
label: "Comp.C",
revenue: [10, 10, 9, 4],
revenue: [10500, 10600, 9000, 4200],
bar_style: Style::default().fg(Color::White),
},
],
@ -182,7 +182,8 @@ where
Style::default()
.bg(c.bar_style.fg.unwrap())
.fg(Color::Black),
);
)
.text_value(format!("{:.1}", (c.revenue[i] as f64) / 1000.));
if bar_labels {
bar = bar.label(c.label.into());
}

View file

@ -12,7 +12,8 @@ use crate::{buffer::Buffer, style::Style, text::Line};
/// .label("Bar 1".into())
/// .value(10)
/// .style(Style::default().fg(Color::Red))
/// .value_style(Style::default().bg(Color::Red).fg(Color::White));
/// .value_style(Style::default().bg(Color::Red).fg(Color::White))
/// .text_value("10°C".to_string());
/// ```
#[derive(Debug, Clone, Default)]
pub struct Bar<'a> {
@ -24,6 +25,8 @@ pub struct Bar<'a> {
pub(super) style: Style,
/// style of the value printed at the bottom of the bar.
pub(super) value_style: Style,
/// optional text_value to be shown on the bar instead of the actual value
pub(super) text_value: Option<String>,
}
impl<'a> Bar<'a> {
@ -47,43 +50,46 @@ impl<'a> Bar<'a> {
self
}
/// render the bar's value
pub(super) fn render_value(
&self,
/// set the text value printed in the bar. (By default self.value is printed)
pub fn text_value(mut self, text_value: String) -> Bar<'a> {
self.text_value = Some(text_value);
self
}
pub(super) fn render_label_and_value(
self,
buf: &mut Buffer,
max_width: u16,
x: u16,
y: u16,
default_style: Style,
default_value_style: Style,
default_label_style: Style,
) {
// render the value
if self.value != 0 {
let value_label = format!("{}", self.value);
let value_label = if let Some(text) = self.text_value {
text
} else {
self.value.to_string()
};
let width = value_label.len() as u16;
if width < max_width {
buf.set_string(
x + (max_width.saturating_sub(value_label.len() as u16) >> 1),
y,
value_label,
self.value_style.patch(default_style),
self.value_style.patch(default_value_style),
);
}
}
}
/// render the bar's label
pub(super) fn render_label(
self,
buf: &mut Buffer,
max_width: u16,
x: u16,
y: u16,
default_style: Style,
) {
// render the label
if let Some(mut label) = self.label {
label.patch_style(default_style);
label.patch_style(default_label_style);
buf.set_line(
x + (max_width.saturating_sub(label.width() as u16) >> 1),
y,
y + 1,
&label,
max_width,
);

View file

@ -264,7 +264,7 @@ impl<'a> BarChart<'a> {
fn render_labels_and_values(self, area: Rect, buf: &mut Buffer, label_height: u16) {
// print labels and values in one go
let mut bar_x = area.left();
let y_value_offset = area.bottom() - label_height - 1;
let bar_y = area.bottom() - label_height - 1;
for group in self.data.into_iter() {
// print group labels under the bars or the previous labels
if let Some(mut label) = group.label {
@ -282,13 +282,12 @@ impl<'a> BarChart<'a> {
// print the bar values and numbers
for bar in group.bars.into_iter() {
bar.render_value(buf, self.bar_width, bar_x, y_value_offset, self.value_style);
bar.render_label(
bar.render_label_and_value(
buf,
self.bar_width,
bar_x,
y_value_offset + 1,
bar_y,
self.value_style,
self.label_style,
);

View file

@ -63,7 +63,8 @@ fn widgets_barchart_group() {
.value_style(Style::default().fg(Color::Blue)),
Bar::default()
.value(20)
.style(Style::default().fg(Color::Green)),
.style(Style::default().fg(Color::Green))
.text_value("20M".to_string()),
]),
)
.data(&vec![("C1", 50u64), ("C2", 40u64)])
@ -86,7 +87,7 @@ fn widgets_barchart_group() {
"│ ▇▇▇▇ ████ ████│",
"│ ████ ████ ████ ████│",
"│ ▄▄▄▄ ████ ████ ████ ████│",
"│▆10▆ 20█ █50█ █40█ █60█ █90█│",
"│▆10▆ 20M█ █50█ █40█ █60█ █90█│",
"│ C1 C1 C2 C1 C2 │",
"│ Mar │",
"└─────────────────────────────────┘",