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())
|
/// .bar_style(Style::new().yellow().on_red())
|
||||||
/// .value_style(Style::new().red().bold())
|
/// .value_style(Style::new().red().bold())
|
||||||
/// .label_style(Style::new().white())
|
/// .label_style(Style::new().white())
|
||||||
/// .data(&[("B0", 0), ("B1", 2), ("B2", 4), ("B3", 3)])
|
/// .data(&[("A0", 0), ("A1", 2), ("A2", 4), ("A3", 3)])
|
||||||
/// .data(BarGroup::default().bars(&[Bar::default().value(10), Bar::default().value(20)]))
|
/// .data(BarGroup::new([
|
||||||
|
/// Bar::with_label("B0", 10),
|
||||||
|
/// Bar::with_label("B2", 20),
|
||||||
|
/// ]))
|
||||||
/// .max(4);
|
/// .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)]
|
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
|
||||||
pub struct BarChart<'a> {
|
pub struct BarChart<'a> {
|
||||||
/// Block to wrap the widget in
|
/// Block to wrap the widget in
|
||||||
@ -117,6 +128,52 @@ impl<'a> Default for BarChart<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> 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`
|
/// Add group of bars to the `BarChart`
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
@ -129,7 +186,10 @@ impl<'a> BarChart<'a> {
|
|||||||
///
|
///
|
||||||
/// BarChart::default()
|
/// BarChart::default()
|
||||||
/// .data(&[("B0", 0), ("B1", 2), ("B2", 4), ("B3", 3)])
|
/// .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"]
|
#[must_use = "method moves the value of self and returns the modified value"]
|
||||||
pub fn data(mut self, data: impl Into<BarGroup<'a>>) -> Self {
|
pub fn data(mut self, data: impl Into<BarGroup<'a>>) -> Self {
|
||||||
@ -1345,4 +1405,19 @@ mod tests {
|
|||||||
]);
|
]);
|
||||||
assert_eq!(buffer, expected);
|
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,
|
/// widgets::Bar,
|
||||||
/// };
|
/// };
|
||||||
///
|
///
|
||||||
/// Bar::default()
|
/// Bar::with_label("Bar 1", 10)
|
||||||
/// .label("Bar 1")
|
|
||||||
/// .value(10)
|
|
||||||
/// .red()
|
/// .red()
|
||||||
/// .value_style(Style::new().red().on_white())
|
/// .value_style(Style::new().red().on_white())
|
||||||
/// .text_value("10°C");
|
/// .text_value("10°C");
|
||||||
@ -49,14 +47,54 @@ pub struct Bar<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> 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.
|
/// Set the value of this bar.
|
||||||
///
|
///
|
||||||
/// The value will be displayed inside the bar.
|
/// The value will be displayed inside the bar.
|
||||||
///
|
///
|
||||||
/// # See also
|
/// # See also
|
||||||
///
|
///
|
||||||
/// [`Bar::value_style`] to style the value.
|
/// - [`Bar::value_style`] to style the value.
|
||||||
/// [`Bar::text_value`] to set the displayed value.
|
/// - [`Bar::text_value`] to set the displayed value.
|
||||||
#[must_use = "method moves the value of self and returns the modified value"]
|
#[must_use = "method moves the value of self and returns the modified value"]
|
||||||
pub const fn value(mut self, value: u64) -> Self {
|
pub const fn value(mut self, value: u64) -> Self {
|
||||||
self.value = value;
|
self.value = value;
|
||||||
@ -266,6 +304,20 @@ mod tests {
|
|||||||
|
|
||||||
use super::*;
|
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]
|
#[test]
|
||||||
fn test_bar_stylized() {
|
fn test_bar_stylized() {
|
||||||
let bar = Bar::default().red().bold();
|
let bar = Bar::default().red().bold();
|
||||||
|
@ -15,9 +15,7 @@ use crate::barchart::Bar;
|
|||||||
/// ```
|
/// ```
|
||||||
/// use ratatui::widgets::{Bar, BarGroup};
|
/// use ratatui::widgets::{Bar, BarGroup};
|
||||||
///
|
///
|
||||||
/// BarGroup::default()
|
/// let group = BarGroup::new([Bar::with_label("Red", 20), Bar::with_label("Blue", 15)]);
|
||||||
/// .label("Group 1")
|
|
||||||
/// .bars(&[Bar::default().value(200), Bar::default().value(150)]);
|
|
||||||
/// ```
|
/// ```
|
||||||
#[derive(Debug, Default, Clone, Eq, PartialEq, Hash)]
|
#[derive(Debug, Default, Clone, Eq, PartialEq, Hash)]
|
||||||
pub struct BarGroup<'a> {
|
pub struct BarGroup<'a> {
|
||||||
@ -28,6 +26,25 @@ pub struct BarGroup<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> 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
|
/// Set the group label
|
||||||
///
|
///
|
||||||
/// `label` can be a [`&str`], [`String`] or anything that can be converted into [`Line`].
|
/// `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,
|
label: None,
|
||||||
bars: value
|
bars: value
|
||||||
.iter()
|
.iter()
|
||||||
.map(|&(text, v)| Bar::default().value(v).label(text))
|
.map(|&(text, v)| Bar::with_label(text, v))
|
||||||
.collect(),
|
.collect(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -117,3 +134,16 @@ impl<'a> From<&Vec<(&'a str, u64)>> for BarGroup<'a> {
|
|||||||
Self::from(array)
|
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