Struct ratatui::widgets::Bar

source ·
pub struct Bar<'a> { /* private fields */ }
Expand description

A bar to be shown by the BarChart widget.

Here is an explanation of a Bar’s components.

███                          ┐
█2█  <- text_value or value  │ bar
foo  <- label                ┘

Note that every element can be styled individually.

§Example

The following example creates a bar with the label “Bar 1”, a value “10”, red background and a white value foreground.

use ratatui::{prelude::*, widgets::*};

Bar::default()
    .label("Bar 1".into())
    .value(10)
    .style(Style::default().fg(Color::Red))
    .value_style(Style::default().bg(Color::Red).fg(Color::White))
    .text_value("10°C".to_string());

Implementations§

source§

impl<'a> Bar<'a>

source

pub const fn value(self, value: u64) -> Self

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.

Examples found in repository?
examples/demo2/tabs/weather.rs (line 83)
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
fn render_simple_barchart(area: Rect, buf: &mut Buffer) {
    let data = [
        ("Sat", 76),
        ("Sun", 69),
        ("Mon", 65),
        ("Tue", 67),
        ("Wed", 65),
        ("Thu", 69),
        ("Fri", 73),
    ];
    let data = data
        .into_iter()
        .map(|(label, value)| {
            Bar::default()
                .value(value)
                // This doesn't actually render correctly as the text is too wide for the bar
                // See https://github.com/ratatui-org/ratatui/issues/513 for more info
                // (the demo GIFs hack around this by hacking the calculation in bars.rs)
                .text_value(format!("{value}°"))
                .style(if value > 70 {
                    Style::new().fg(Color::Red)
                } else {
                    Style::new().fg(Color::Yellow)
                })
                .value_style(if value > 70 {
                    Style::new().fg(Color::Gray).bg(Color::Red).bold()
                } else {
                    Style::new().fg(Color::DarkGray).bg(Color::Yellow).bold()
                })
                .label(label.into())
        })
        .collect_vec();
    let group = BarGroup::default().bars(&data);
    BarChart::default()
        .data(group)
        .bar_width(3)
        .bar_gap(1)
        .render(area, buf);
}

fn render_horizontal_barchart(area: Rect, buf: &mut Buffer) {
    let bg = Color::Rgb(32, 48, 96);
    let data = [
        Bar::default().text_value("Winter 37-51".into()).value(51),
        Bar::default().text_value("Spring 40-65".into()).value(65),
        Bar::default().text_value("Summer 54-77".into()).value(77),
        Bar::default()
            .text_value("Fall 41-71".into())
            .value(71)
            .value_style(Style::new().bold()), // current season
    ];
    let group = BarGroup::default().label("GPU".into()).bars(&data);
    BarChart::default()
        .block(Block::new().padding(Padding::new(0, 0, 2, 0)))
        .direction(Direction::Horizontal)
        .data(group)
        .bar_gap(1)
        .bar_style(Style::new().fg(bg))
        .value_style(Style::new().bg(bg).fg(Color::Gray))
        .render(area, buf);
}
More examples
Hide additional examples
examples/barchart.rs (line 184)
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
fn create_groups<'a>(app: &'a App, combine_values_and_labels: bool) -> Vec<BarGroup<'a>> {
    app.months
        .iter()
        .enumerate()
        .map(|(i, &month)| {
            let bars: Vec<Bar> = app
                .companies
                .iter()
                .map(|c| {
                    let mut bar = Bar::default()
                        .value(c.revenue[i])
                        .style(c.bar_style)
                        .value_style(
                            Style::default()
                                .bg(c.bar_style.fg.unwrap())
                                .fg(Color::Black),
                        );

                    if combine_values_and_labels {
                        bar = bar.text_value(format!(
                            "{} ({:.1} M)",
                            c.label,
                            (c.revenue[i] as f64) / 1000.
                        ));
                    } else {
                        bar = bar
                            .text_value(format!("{:.1}", (c.revenue[i] as f64) / 1000.))
                            .label(c.label.into());
                    }
                    bar
                })
                .collect();
            BarGroup::default()
                .label(Line::from(month).centered())
                .bars(&bars)
        })
        .collect()
}
source

pub fn label(self, label: Line<'a>) -> Self

Set the label of the bar.

For Vertical bars, display the label under the bar. For Horizontal bars, display the label in the bar. See BarChart::direction to set the direction.

Examples found in repository?
examples/demo2/tabs/weather.rs (line 98)
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
fn render_simple_barchart(area: Rect, buf: &mut Buffer) {
    let data = [
        ("Sat", 76),
        ("Sun", 69),
        ("Mon", 65),
        ("Tue", 67),
        ("Wed", 65),
        ("Thu", 69),
        ("Fri", 73),
    ];
    let data = data
        .into_iter()
        .map(|(label, value)| {
            Bar::default()
                .value(value)
                // This doesn't actually render correctly as the text is too wide for the bar
                // See https://github.com/ratatui-org/ratatui/issues/513 for more info
                // (the demo GIFs hack around this by hacking the calculation in bars.rs)
                .text_value(format!("{value}°"))
                .style(if value > 70 {
                    Style::new().fg(Color::Red)
                } else {
                    Style::new().fg(Color::Yellow)
                })
                .value_style(if value > 70 {
                    Style::new().fg(Color::Gray).bg(Color::Red).bold()
                } else {
                    Style::new().fg(Color::DarkGray).bg(Color::Yellow).bold()
                })
                .label(label.into())
        })
        .collect_vec();
    let group = BarGroup::default().bars(&data);
    BarChart::default()
        .data(group)
        .bar_width(3)
        .bar_gap(1)
        .render(area, buf);
}
More examples
Hide additional examples
examples/barchart.rs (line 201)
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
fn create_groups<'a>(app: &'a App, combine_values_and_labels: bool) -> Vec<BarGroup<'a>> {
    app.months
        .iter()
        .enumerate()
        .map(|(i, &month)| {
            let bars: Vec<Bar> = app
                .companies
                .iter()
                .map(|c| {
                    let mut bar = Bar::default()
                        .value(c.revenue[i])
                        .style(c.bar_style)
                        .value_style(
                            Style::default()
                                .bg(c.bar_style.fg.unwrap())
                                .fg(Color::Black),
                        );

                    if combine_values_and_labels {
                        bar = bar.text_value(format!(
                            "{} ({:.1} M)",
                            c.label,
                            (c.revenue[i] as f64) / 1000.
                        ));
                    } else {
                        bar = bar
                            .text_value(format!("{:.1}", (c.revenue[i] as f64) / 1000.))
                            .label(c.label.into());
                    }
                    bar
                })
                .collect();
            BarGroup::default()
                .label(Line::from(month).centered())
                .bars(&bars)
        })
        .collect()
}
source

pub fn style<S: Into<Style>>(self, style: S) -> Self

Set the style of the bar.

style accepts any type that is convertible to Style (e.g. Style, Color, or your own type that implements Into<Style>).

This will apply to every non-styled element. It can be seen and used as a default value.

Examples found in repository?
examples/demo2/tabs/weather.rs (lines 88-92)
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
fn render_simple_barchart(area: Rect, buf: &mut Buffer) {
    let data = [
        ("Sat", 76),
        ("Sun", 69),
        ("Mon", 65),
        ("Tue", 67),
        ("Wed", 65),
        ("Thu", 69),
        ("Fri", 73),
    ];
    let data = data
        .into_iter()
        .map(|(label, value)| {
            Bar::default()
                .value(value)
                // This doesn't actually render correctly as the text is too wide for the bar
                // See https://github.com/ratatui-org/ratatui/issues/513 for more info
                // (the demo GIFs hack around this by hacking the calculation in bars.rs)
                .text_value(format!("{value}°"))
                .style(if value > 70 {
                    Style::new().fg(Color::Red)
                } else {
                    Style::new().fg(Color::Yellow)
                })
                .value_style(if value > 70 {
                    Style::new().fg(Color::Gray).bg(Color::Red).bold()
                } else {
                    Style::new().fg(Color::DarkGray).bg(Color::Yellow).bold()
                })
                .label(label.into())
        })
        .collect_vec();
    let group = BarGroup::default().bars(&data);
    BarChart::default()
        .data(group)
        .bar_width(3)
        .bar_gap(1)
        .render(area, buf);
}
More examples
Hide additional examples
examples/barchart.rs (line 185)
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
fn create_groups<'a>(app: &'a App, combine_values_and_labels: bool) -> Vec<BarGroup<'a>> {
    app.months
        .iter()
        .enumerate()
        .map(|(i, &month)| {
            let bars: Vec<Bar> = app
                .companies
                .iter()
                .map(|c| {
                    let mut bar = Bar::default()
                        .value(c.revenue[i])
                        .style(c.bar_style)
                        .value_style(
                            Style::default()
                                .bg(c.bar_style.fg.unwrap())
                                .fg(Color::Black),
                        );

                    if combine_values_and_labels {
                        bar = bar.text_value(format!(
                            "{} ({:.1} M)",
                            c.label,
                            (c.revenue[i] as f64) / 1000.
                        ));
                    } else {
                        bar = bar
                            .text_value(format!("{:.1}", (c.revenue[i] as f64) / 1000.))
                            .label(c.label.into());
                    }
                    bar
                })
                .collect();
            BarGroup::default()
                .label(Line::from(month).centered())
                .bars(&bars)
        })
        .collect()
}
source

pub fn value_style<S: Into<Style>>(self, style: S) -> Self

Set the style of the value.

style accepts any type that is convertible to Style (e.g. Style, Color, or your own type that implements Into<Style>).

§See also

Bar::value to set the value.

Examples found in repository?
examples/demo2/tabs/weather.rs (lines 93-97)
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
fn render_simple_barchart(area: Rect, buf: &mut Buffer) {
    let data = [
        ("Sat", 76),
        ("Sun", 69),
        ("Mon", 65),
        ("Tue", 67),
        ("Wed", 65),
        ("Thu", 69),
        ("Fri", 73),
    ];
    let data = data
        .into_iter()
        .map(|(label, value)| {
            Bar::default()
                .value(value)
                // This doesn't actually render correctly as the text is too wide for the bar
                // See https://github.com/ratatui-org/ratatui/issues/513 for more info
                // (the demo GIFs hack around this by hacking the calculation in bars.rs)
                .text_value(format!("{value}°"))
                .style(if value > 70 {
                    Style::new().fg(Color::Red)
                } else {
                    Style::new().fg(Color::Yellow)
                })
                .value_style(if value > 70 {
                    Style::new().fg(Color::Gray).bg(Color::Red).bold()
                } else {
                    Style::new().fg(Color::DarkGray).bg(Color::Yellow).bold()
                })
                .label(label.into())
        })
        .collect_vec();
    let group = BarGroup::default().bars(&data);
    BarChart::default()
        .data(group)
        .bar_width(3)
        .bar_gap(1)
        .render(area, buf);
}

fn render_horizontal_barchart(area: Rect, buf: &mut Buffer) {
    let bg = Color::Rgb(32, 48, 96);
    let data = [
        Bar::default().text_value("Winter 37-51".into()).value(51),
        Bar::default().text_value("Spring 40-65".into()).value(65),
        Bar::default().text_value("Summer 54-77".into()).value(77),
        Bar::default()
            .text_value("Fall 41-71".into())
            .value(71)
            .value_style(Style::new().bold()), // current season
    ];
    let group = BarGroup::default().label("GPU".into()).bars(&data);
    BarChart::default()
        .block(Block::new().padding(Padding::new(0, 0, 2, 0)))
        .direction(Direction::Horizontal)
        .data(group)
        .bar_gap(1)
        .bar_style(Style::new().fg(bg))
        .value_style(Style::new().bg(bg).fg(Color::Gray))
        .render(area, buf);
}
More examples
Hide additional examples
examples/barchart.rs (lines 186-190)
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
fn create_groups<'a>(app: &'a App, combine_values_and_labels: bool) -> Vec<BarGroup<'a>> {
    app.months
        .iter()
        .enumerate()
        .map(|(i, &month)| {
            let bars: Vec<Bar> = app
                .companies
                .iter()
                .map(|c| {
                    let mut bar = Bar::default()
                        .value(c.revenue[i])
                        .style(c.bar_style)
                        .value_style(
                            Style::default()
                                .bg(c.bar_style.fg.unwrap())
                                .fg(Color::Black),
                        );

                    if combine_values_and_labels {
                        bar = bar.text_value(format!(
                            "{} ({:.1} M)",
                            c.label,
                            (c.revenue[i] as f64) / 1000.
                        ));
                    } else {
                        bar = bar
                            .text_value(format!("{:.1}", (c.revenue[i] as f64) / 1000.))
                            .label(c.label.into());
                    }
                    bar
                })
                .collect();
            BarGroup::default()
                .label(Line::from(month).centered())
                .bars(&bars)
        })
        .collect()
}
source

pub fn text_value(self, text_value: String) -> Self

Set the text value printed in the bar.

If text_value is not set, then the ToString representation of value will be shown on the bar.

§See also

Bar::value to set the value.

Examples found in repository?
examples/demo2/tabs/weather.rs (line 87)
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
fn render_simple_barchart(area: Rect, buf: &mut Buffer) {
    let data = [
        ("Sat", 76),
        ("Sun", 69),
        ("Mon", 65),
        ("Tue", 67),
        ("Wed", 65),
        ("Thu", 69),
        ("Fri", 73),
    ];
    let data = data
        .into_iter()
        .map(|(label, value)| {
            Bar::default()
                .value(value)
                // This doesn't actually render correctly as the text is too wide for the bar
                // See https://github.com/ratatui-org/ratatui/issues/513 for more info
                // (the demo GIFs hack around this by hacking the calculation in bars.rs)
                .text_value(format!("{value}°"))
                .style(if value > 70 {
                    Style::new().fg(Color::Red)
                } else {
                    Style::new().fg(Color::Yellow)
                })
                .value_style(if value > 70 {
                    Style::new().fg(Color::Gray).bg(Color::Red).bold()
                } else {
                    Style::new().fg(Color::DarkGray).bg(Color::Yellow).bold()
                })
                .label(label.into())
        })
        .collect_vec();
    let group = BarGroup::default().bars(&data);
    BarChart::default()
        .data(group)
        .bar_width(3)
        .bar_gap(1)
        .render(area, buf);
}

fn render_horizontal_barchart(area: Rect, buf: &mut Buffer) {
    let bg = Color::Rgb(32, 48, 96);
    let data = [
        Bar::default().text_value("Winter 37-51".into()).value(51),
        Bar::default().text_value("Spring 40-65".into()).value(65),
        Bar::default().text_value("Summer 54-77".into()).value(77),
        Bar::default()
            .text_value("Fall 41-71".into())
            .value(71)
            .value_style(Style::new().bold()), // current season
    ];
    let group = BarGroup::default().label("GPU".into()).bars(&data);
    BarChart::default()
        .block(Block::new().padding(Padding::new(0, 0, 2, 0)))
        .direction(Direction::Horizontal)
        .data(group)
        .bar_gap(1)
        .bar_style(Style::new().fg(bg))
        .value_style(Style::new().bg(bg).fg(Color::Gray))
        .render(area, buf);
}
More examples
Hide additional examples
examples/barchart.rs (lines 193-197)
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
fn create_groups<'a>(app: &'a App, combine_values_and_labels: bool) -> Vec<BarGroup<'a>> {
    app.months
        .iter()
        .enumerate()
        .map(|(i, &month)| {
            let bars: Vec<Bar> = app
                .companies
                .iter()
                .map(|c| {
                    let mut bar = Bar::default()
                        .value(c.revenue[i])
                        .style(c.bar_style)
                        .value_style(
                            Style::default()
                                .bg(c.bar_style.fg.unwrap())
                                .fg(Color::Black),
                        );

                    if combine_values_and_labels {
                        bar = bar.text_value(format!(
                            "{} ({:.1} M)",
                            c.label,
                            (c.revenue[i] as f64) / 1000.
                        ));
                    } else {
                        bar = bar
                            .text_value(format!("{:.1}", (c.revenue[i] as f64) / 1000.))
                            .label(c.label.into());
                    }
                    bar
                })
                .collect();
            BarGroup::default()
                .label(Line::from(month).centered())
                .bars(&bars)
        })
        .collect()
}

Trait Implementations§

source§

impl<'a> Clone for Bar<'a>

source§

fn clone(&self) -> Bar<'a>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<'a> Debug for Bar<'a>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'a> Default for Bar<'a>

source§

fn default() -> Bar<'a>

Returns the “default value” for a type. Read more
source§

impl<'a> Hash for Bar<'a>

source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl<'a> PartialEq for Bar<'a>

source§

fn eq(&self, other: &Bar<'a>) -> bool

This method tests for self and other values to be equal, and is used by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
source§

impl<'a> Eq for Bar<'a>

source§

impl<'a> StructuralPartialEq for Bar<'a>

Auto Trait Implementations§

§

impl<'a> Freeze for Bar<'a>

§

impl<'a> RefUnwindSafe for Bar<'a>

§

impl<'a> Send for Bar<'a>

§

impl<'a> Sync for Bar<'a>

§

impl<'a> Unpin for Bar<'a>

§

impl<'a> UnwindSafe for Bar<'a>

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

source§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> IntoEither for T

source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.