mirror of
https://github.com/ratatui/ratatui.git
synced 2025-09-27 04:50:46 +00:00
feat(barchart): reduce barchart creation verbosity (#1453)
Adds constructor methods for BarChart, BarGroup, and Bar
This commit is contained in:
parent
2ce958e38c
commit
369b18eef2
@ -64,10 +64,21 @@ mod bar_group;
|
||||
/// .bar_style(Style::new().yellow().on_red())
|
||||
/// .value_style(Style::new().red().bold())
|
||||
/// .label_style(Style::new().white())
|
||||
/// .data(&[("B0", 0), ("B1", 2), ("B2", 4), ("B3", 3)])
|
||||
/// .data(BarGroup::default().bars(&[Bar::default().value(10), Bar::default().value(20)]))
|
||||
/// .data(&[("A0", 0), ("A1", 2), ("A2", 4), ("A3", 3)])
|
||||
/// .data(BarGroup::new([
|
||||
/// Bar::with_label("B0", 10),
|
||||
/// Bar::with_label("B2", 20),
|
||||
/// ]))
|
||||
/// .max(4);
|
||||
/// ```
|
||||
///
|
||||
/// For simpler usages, you can also create a `BarChart` simply by
|
||||
///
|
||||
/// ```rust
|
||||
/// use ratatui::widgets::{Bar, BarChart};
|
||||
///
|
||||
/// BarChart::new([Bar::with_label("A", 10), Bar::with_label("B", 20)]);
|
||||
/// ```
|
||||
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
|
||||
pub struct BarChart<'a> {
|
||||
/// Block to wrap the widget in
|
||||
@ -117,6 +128,52 @@ impl<'a> Default for BarChart<'a> {
|
||||
}
|
||||
|
||||
impl<'a> BarChart<'a> {
|
||||
/// Creates a new vertical `BarChart` widget with the given bars.
|
||||
///
|
||||
/// The `bars` parameter accepts any type that can be converted into a `Vec<Bar>`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// use ratatui::{
|
||||
/// layout::Direction,
|
||||
/// widgets::{Bar, BarChart},
|
||||
/// };
|
||||
///
|
||||
/// BarChart::new(vec![Bar::with_label("A", 10), Bar::with_label("B", 10)]);
|
||||
/// ```
|
||||
pub fn new<T: Into<Vec<Bar<'a>>>>(bars: T) -> Self {
|
||||
Self {
|
||||
data: vec![BarGroup::new(bars.into())],
|
||||
direction: Direction::Vertical,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a new `BarChart` widget with a vertical direction.
|
||||
///
|
||||
/// This function is equivalent to `BarChart::new()`.
|
||||
pub fn vertical(bars: impl Into<Vec<Bar<'a>>>) -> Self {
|
||||
Self::new(bars)
|
||||
}
|
||||
|
||||
/// Creates a new `BarChart` widget with a horizontal direction.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// use ratatui::widgets::{Bar, BarChart};
|
||||
///
|
||||
/// BarChart::horizontal(vec![Bar::with_label("A", 10), Bar::with_label("B", 20)]);
|
||||
/// ```
|
||||
pub fn horizontal(bars: impl Into<Vec<Bar<'a>>>) -> Self {
|
||||
Self {
|
||||
data: vec![BarGroup::new(bars.into())],
|
||||
direction: Direction::Horizontal,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
/// Add group of bars to the `BarChart`
|
||||
///
|
||||
/// # Examples
|
||||
@ -129,7 +186,10 @@ impl<'a> BarChart<'a> {
|
||||
///
|
||||
/// BarChart::default()
|
||||
/// .data(&[("B0", 0), ("B1", 2), ("B2", 4), ("B3", 3)])
|
||||
/// .data(BarGroup::default().bars(&[Bar::default().value(10), Bar::default().value(20)]));
|
||||
/// .data(BarGroup::new([
|
||||
/// Bar::with_label("A", 10),
|
||||
/// Bar::with_label("B", 20),
|
||||
/// ]));
|
||||
/// ```
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn data(mut self, data: impl Into<BarGroup<'a>>) -> Self {
|
||||
@ -1345,4 +1405,19 @@ mod tests {
|
||||
]);
|
||||
assert_eq!(buffer, expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_barchart_new() {
|
||||
let bars = [Bar::with_label("Red", 1), Bar::with_label("Green", 2)];
|
||||
|
||||
let chart = BarChart::new(bars.clone());
|
||||
assert_eq!(chart.data.len(), 1);
|
||||
assert_eq!(chart.data[0].bars, bars);
|
||||
|
||||
let bars2 = [("Blue", 3)];
|
||||
|
||||
let updated_chart = chart.data(&bars2);
|
||||
assert_eq!(updated_chart.data.len(), 2);
|
||||
assert_eq!(updated_chart.data[1].bars, [Bar::with_label("Blue", 3)]);
|
||||
}
|
||||
}
|
||||
|
@ -27,9 +27,7 @@ use unicode_width::UnicodeWidthStr;
|
||||
/// widgets::Bar,
|
||||
/// };
|
||||
///
|
||||
/// Bar::default()
|
||||
/// .label("Bar 1")
|
||||
/// .value(10)
|
||||
/// Bar::with_label("Bar 1", 10)
|
||||
/// .red()
|
||||
/// .value_style(Style::new().red().on_white())
|
||||
/// .text_value("10°C");
|
||||
@ -49,14 +47,54 @@ pub struct Bar<'a> {
|
||||
}
|
||||
|
||||
impl<'a> Bar<'a> {
|
||||
/// Creates a new `Bar` with the given value.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use ratatui::widgets::Bar;
|
||||
///
|
||||
/// let bar = Bar::new(42);
|
||||
/// ```
|
||||
pub const fn new(value: u64) -> Self {
|
||||
Self {
|
||||
value,
|
||||
label: None,
|
||||
style: Style::new(),
|
||||
value_style: Style::new(),
|
||||
text_value: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a new `Bar` with the given `label` and value.
|
||||
///
|
||||
/// a `label` can be a [`&str`], [`String`] or anything that can be converted into [`Line`].
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use ratatui::widgets::Bar;
|
||||
///
|
||||
/// let bar = Bar::with_label("Label", 42);
|
||||
/// ```
|
||||
pub fn with_label<T: Into<Line<'a>>>(label: T, value: u64) -> Self {
|
||||
Self {
|
||||
value,
|
||||
label: Some(label.into()),
|
||||
style: Style::new(),
|
||||
value_style: Style::new(),
|
||||
text_value: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the value of this bar.
|
||||
///
|
||||
/// The value will be displayed inside the bar.
|
||||
///
|
||||
/// # See also
|
||||
///
|
||||
/// [`Bar::value_style`] to style the value.
|
||||
/// [`Bar::text_value`] to set the displayed value.
|
||||
/// - [`Bar::value_style`] to style the value.
|
||||
/// - [`Bar::text_value`] to set the displayed value.
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub const fn value(mut self, value: u64) -> Self {
|
||||
self.value = value;
|
||||
@ -266,6 +304,20 @@ mod tests {
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_bar_new() {
|
||||
let bar = Bar::new(42).label(Line::from("Label"));
|
||||
assert_eq!(bar.label, Some(Line::from("Label")));
|
||||
assert_eq!(bar.value, 42);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bar_with_label() {
|
||||
let bar = Bar::with_label("Label", 42);
|
||||
assert_eq!(bar.label, Some(Line::from("Label")));
|
||||
assert_eq!(bar.value, 42);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bar_stylized() {
|
||||
let bar = Bar::default().red().bold();
|
||||
|
@ -15,9 +15,7 @@ use crate::barchart::Bar;
|
||||
/// ```
|
||||
/// use ratatui::widgets::{Bar, BarGroup};
|
||||
///
|
||||
/// BarGroup::default()
|
||||
/// .label("Group 1")
|
||||
/// .bars(&[Bar::default().value(200), Bar::default().value(150)]);
|
||||
/// let group = BarGroup::new([Bar::with_label("Red", 20), Bar::with_label("Blue", 15)]);
|
||||
/// ```
|
||||
#[derive(Debug, Default, Clone, Eq, PartialEq, Hash)]
|
||||
pub struct BarGroup<'a> {
|
||||
@ -28,6 +26,25 @@ pub struct BarGroup<'a> {
|
||||
}
|
||||
|
||||
impl<'a> BarGroup<'a> {
|
||||
/// Creates a new `BarGroup` with the given bars.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use ratatui::{
|
||||
/// style::{Style, Stylize},
|
||||
/// widgets::{Bar, BarGroup},
|
||||
/// };
|
||||
///
|
||||
/// let group = BarGroup::new(vec![Bar::with_label("A", 10), Bar::with_label("B", 20)]);
|
||||
/// ```
|
||||
pub fn new<T: Into<Vec<Bar<'a>>>>(bars: T) -> Self {
|
||||
Self {
|
||||
bars: bars.into(),
|
||||
..Self::default()
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the group label
|
||||
///
|
||||
/// `label` can be a [`&str`], [`String`] or anything that can be converted into [`Line`].
|
||||
@ -98,7 +115,7 @@ impl<'a> From<&[(&'a str, u64)]> for BarGroup<'a> {
|
||||
label: None,
|
||||
bars: value
|
||||
.iter()
|
||||
.map(|&(text, v)| Bar::default().value(v).label(text))
|
||||
.map(|&(text, v)| Bar::with_label(text, v))
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
@ -117,3 +134,16 @@ impl<'a> From<&Vec<(&'a str, u64)>> for BarGroup<'a> {
|
||||
Self::from(array)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_bargroup_new() {
|
||||
let group = BarGroup::new([Bar::with_label("Label1", 1), Bar::with_label("Label2", 2)])
|
||||
.label(Line::from("Group1"));
|
||||
assert_eq!(group.label, Some(Line::from("Group1")));
|
||||
assert_eq!(group.bars.len(), 2);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user