feat(chart)!: accept IntoIterator for axis labels (#1283)

BREAKING CHANGES: #1273 is already breaking and this only advances the
already breaking part
This commit is contained in:
EdJoPaTo 2024-08-06 11:39:44 +02:00 committed by GitHub
parent fe4eeab676
commit afe15349c8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 29 additions and 25 deletions

View file

@ -14,7 +14,7 @@ This is a quick summary of the sections below:
- Ratatui now requires Crossterm 0.28.0 - Ratatui now requires Crossterm 0.28.0
- `Layout::init_cache` no longer returns bool and takes a `NonZeroUsize` instead of `usize` - `Layout::init_cache` no longer returns bool and takes a `NonZeroUsize` instead of `usize`
- `ratatui::terminal` module is now private - `ratatui::terminal` module is now private
- `Axis::labels` now accepts `Vec<T: Into<Line>>` - `Axis::labels` now accepts `IntoIterator<Into<Line>>`
- `ToText` no longer has a lifetime - `ToText` no longer has a lifetime
- [v0.27.0](#v0270) - [v0.27.0](#v0270)
- List no clamps the selected index to list - List no clamps the selected index to list
@ -79,16 +79,17 @@ Crossterm is updated to version 0.28.0, which is a semver incompatible version w
version (0.27.0). Ratatui re-exports the version of crossterm that it is compatible with under version (0.27.0). Ratatui re-exports the version of crossterm that it is compatible with under
`ratatui::crossterm`, which can be used to avoid incompatible versions in your dependency list. `ratatui::crossterm`, which can be used to avoid incompatible versions in your dependency list.
### `Axis::labels()` now accepts `Vec<T: Into<Line>>` ([#1273]) ### `Axis::labels()` now accepts `IntoIterator<Into<Line>>` ([#1273] and [#1283])
[#1273]: https://github.com/ratatui-org/ratatui/pull/1173 [#1273]: https://github.com/ratatui-org/ratatui/pull/1173
[#1283]: https://github.com/ratatui-org/ratatui/pull/1283
Previously Axis::labels accepted `Vec<Span>`. Any code that uses conversion methods that infer the Previously Axis::labels accepted `Vec<Span>`. Any code that uses conversion methods that infer the
type will need to be rewritten as the compiler cannot infer the correct type. type will need to be rewritten as the compiler cannot infer the correct type.
```diff ```diff
- Axis::default().labels("a".into(), "b".into()) - Axis::default().labels(vec!["a".into(), "b".into()])
+ Axis::default().labels("a", "b") + Axis::default().labels(["a", "b"])
``` ```
### `Layout::init_cache` no longer returns bool and takes a `NonZeroUsize` instead of `usize` ([#1245]) ### `Layout::init_cache` no longer returns bool and takes a `NonZeroUsize` instead of `usize` ([#1245])

View file

@ -200,7 +200,7 @@ fn render_animated_chart(f: &mut Frame, area: Rect, app: &App) {
Axis::default() Axis::default()
.title("Y Axis") .title("Y Axis")
.style(Style::default().fg(Color::Gray)) .style(Style::default().fg(Color::Gray))
.labels(vec!["-20".bold(), "0".into(), "20".bold()]) .labels(["-20".bold(), "0".into(), "20".bold()])
.bounds([-20.0, 20.0]), .bounds([-20.0, 20.0]),
); );
@ -239,13 +239,13 @@ fn render_barchart(frame: &mut Frame, bar_chart: Rect) {
Axis::default() Axis::default()
.style(Style::default().gray()) .style(Style::default().gray())
.bounds([0.0, 100.0]) .bounds([0.0, 100.0])
.labels(vec!["0".bold(), "50".into(), "100.0".bold()]), .labels(["0".bold(), "50".into(), "100.0".bold()]),
) )
.y_axis( .y_axis(
Axis::default() Axis::default()
.style(Style::default().gray()) .style(Style::default().gray())
.bounds([0.0, 100.0]) .bounds([0.0, 100.0])
.labels(vec!["0".bold(), "50".into(), "100.0".bold()]), .labels(["0".bold(), "50".into(), "100.0".bold()]),
) )
.hidden_legend_constraints((Constraint::Ratio(1, 2), Constraint::Ratio(1, 2))); .hidden_legend_constraints((Constraint::Ratio(1, 2), Constraint::Ratio(1, 2)));
@ -273,14 +273,14 @@ fn render_line_chart(f: &mut Frame, area: Rect) {
.title("X Axis") .title("X Axis")
.style(Style::default().gray()) .style(Style::default().gray())
.bounds([0.0, 5.0]) .bounds([0.0, 5.0])
.labels(vec!["0".bold(), "2.5".into(), "5.0".bold()]), .labels(["0".bold(), "2.5".into(), "5.0".bold()]),
) )
.y_axis( .y_axis(
Axis::default() Axis::default()
.title("Y Axis") .title("Y Axis")
.style(Style::default().gray()) .style(Style::default().gray())
.bounds([0.0, 5.0]) .bounds([0.0, 5.0])
.labels(vec!["0".bold(), "2.5".into(), "5.0".bold()]), .labels(["0".bold(), "2.5".into(), "5.0".bold()]),
) )
.legend_position(Some(LegendPosition::TopLeft)) .legend_position(Some(LegendPosition::TopLeft))
.hidden_legend_constraints((Constraint::Ratio(1, 2), Constraint::Ratio(1, 2))); .hidden_legend_constraints((Constraint::Ratio(1, 2), Constraint::Ratio(1, 2)));
@ -323,14 +323,14 @@ fn render_scatter(f: &mut Frame, area: Rect) {
.title("Year") .title("Year")
.bounds([1960., 2020.]) .bounds([1960., 2020.])
.style(Style::default().fg(Color::Gray)) .style(Style::default().fg(Color::Gray))
.labels(vec!["1960", "1990", "2020"]), .labels(["1960", "1990", "2020"]),
) )
.y_axis( .y_axis(
Axis::default() Axis::default()
.title("Cost") .title("Cost")
.bounds([0., 75000.]) .bounds([0., 75000.])
.style(Style::default().fg(Color::Gray)) .style(Style::default().fg(Color::Gray))
.labels(vec!["0", "37 500", "75 000"]), .labels(["0", "37 500", "75 000"]),
) )
.hidden_legend_constraints((Constraint::Ratio(1, 2), Constraint::Ratio(1, 2))); .hidden_legend_constraints((Constraint::Ratio(1, 2), Constraint::Ratio(1, 2)));

View file

@ -221,7 +221,7 @@ fn draw_charts(f: &mut Frame, app: &mut App, area: Rect) {
.title("Y Axis") .title("Y Axis")
.style(Style::default().fg(Color::Gray)) .style(Style::default().fg(Color::Gray))
.bounds([-20.0, 20.0]) .bounds([-20.0, 20.0])
.labels(vec![ .labels([
Span::styled("-20", Style::default().add_modifier(Modifier::BOLD)), Span::styled("-20", Style::default().add_modifier(Modifier::BOLD)),
Span::raw("0"), Span::raw("0"),
Span::styled("20", Style::default().add_modifier(Modifier::BOLD)), Span::styled("20", Style::default().add_modifier(Modifier::BOLD)),

View file

@ -30,7 +30,7 @@ use crate::{
/// .title("X Axis") /// .title("X Axis")
/// .style(Style::default().gray()) /// .style(Style::default().gray())
/// .bounds([0.0, 50.0]) /// .bounds([0.0, 50.0])
/// .labels(vec!["0".bold(), "25".into(), "50".bold()]); /// .labels(["0".bold(), "25".into(), "50".bold()]);
/// ``` /// ```
#[derive(Debug, Default, Clone, PartialEq)] #[derive(Debug, Default, Clone, PartialEq)]
pub struct Axis<'a> { pub struct Axis<'a> {
@ -95,13 +95,16 @@ impl<'a> Axis<'a> {
/// ///
/// ```rust /// ```rust
/// # use ratatui::{prelude::*, widgets::*}; /// # use ratatui::{prelude::*, widgets::*};
/// let axis = /// let axis = Axis::default()
/// Axis::default()
/// .bounds([0.0, 50.0]) /// .bounds([0.0, 50.0])
/// .labels(vec!["0".bold(), "25".into(), "50".bold()]); /// .labels(["0".bold(), "25".into(), "50".bold()]);
/// ``` /// ```
#[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 labels<T: Into<Line<'a>>>(mut self, labels: Vec<T>) -> Self { pub fn labels<Labels>(mut self, labels: Labels) -> Self
where
Labels: IntoIterator,
Labels::Item: Into<Line<'a>>,
{
self.labels = labels.into_iter().map(Into::into).collect(); self.labels = labels.into_iter().map(Into::into).collect();
self self
} }
@ -474,14 +477,14 @@ struct ChartLayout {
/// .title("X Axis".red()) /// .title("X Axis".red())
/// .style(Style::default().white()) /// .style(Style::default().white())
/// .bounds([0.0, 10.0]) /// .bounds([0.0, 10.0])
/// .labels(vec!["0.0", "5.0", "10.0"]); /// .labels(["0.0", "5.0", "10.0"]);
/// ///
/// // Create the Y axis and define its properties /// // Create the Y axis and define its properties
/// let y_axis = Axis::default() /// let y_axis = Axis::default()
/// .title("Y Axis".red()) /// .title("Y Axis".red())
/// .style(Style::default().white()) /// .style(Style::default().white())
/// .bounds([0.0, 10.0]) /// .bounds([0.0, 10.0])
/// .labels(vec!["0.0", "5.0", "10.0"]); /// .labels(["0.0", "5.0", "10.0"]);
/// ///
/// // Create the chart and link all the parts together /// // Create the chart and link all the parts together
/// let chart = Chart::new(datasets) /// let chart = Chart::new(datasets)
@ -583,7 +586,7 @@ impl<'a> Chart<'a> {
/// Axis::default() /// Axis::default()
/// .title("X Axis") /// .title("X Axis")
/// .bounds([0.0, 20.0]) /// .bounds([0.0, 20.0])
/// .labels(vec!["0", "20"]), /// .labels(["0", "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"]
@ -606,7 +609,7 @@ impl<'a> Chart<'a> {
/// Axis::default() /// Axis::default()
/// .title("Y Axis") /// .title("Y Axis")
/// .bounds([0.0, 20.0]) /// .bounds([0.0, 20.0])
/// .labels(vec!["0", "20"]), /// .labels(["0", "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"]

View file

@ -165,12 +165,12 @@ fn widgets_chart_handles_long_labels<'line, Lines>(
let mut x_axis = Axis::default().bounds([0.0, 1.0]); let mut x_axis = Axis::default().bounds([0.0, 1.0]);
if let Some((left_label, right_label)) = x_labels { if let Some((left_label, right_label)) = x_labels {
x_axis = x_axis x_axis = x_axis
.labels(vec![Span::from(left_label), Span::from(right_label)]) .labels([left_label, right_label])
.labels_alignment(x_alignment); .labels_alignment(x_alignment);
} }
let mut y_axis = Axis::default().bounds([0.0, 1.0]); let mut y_axis = Axis::default().bounds([0.0, 1.0]);
if let Some((left_label, right_label)) = y_labels { if let Some((left_label, right_label)) = y_labels {
y_axis = y_axis.labels(vec![Span::from(left_label), Span::from(right_label)]); y_axis = y_axis.labels([left_label, right_label]);
} }
axis_test_case(10, 5, x_axis, y_axis, expected); axis_test_case(10, 5, x_axis, y_axis, expected);
} }
@ -214,7 +214,7 @@ fn widgets_chart_handles_x_axis_labels_alignments<'line, Lines>(
Lines::Item: Into<text::Line<'line>>, Lines::Item: Into<text::Line<'line>>,
{ {
let x_axis = Axis::default() let x_axis = Axis::default()
.labels(vec![Span::from("AAAA"), Span::from("B"), Span::from("C")]) .labels(["AAAA", "B", "C"])
.labels_alignment(y_alignment); .labels_alignment(y_alignment);
let y_axis = Axis::default(); let y_axis = Axis::default();
axis_test_case(10, 5, x_axis, y_axis, expected); axis_test_case(10, 5, x_axis, y_axis, expected);