mirror of
https://github.com/ratatui-org/ratatui
synced 2024-11-21 20:23:11 +00:00
feat(barchart)!: allow axes to accept Lines (#1273)
Fixes: https://github.com/ratatui-org/ratatui/issues/1272
This commit is contained in:
parent
edc2af9822
commit
8d4a1026ab
4 changed files with 36 additions and 23 deletions
|
@ -13,6 +13,7 @@ This is a quick summary of the sections below:
|
|||
- [v0.28.0](#v0280) (unreleased)
|
||||
- `Layout::init_cache` no longer returns bool and takes a `NonZeroUsize` instead of `usize`
|
||||
- `ratatui::terminal` module is now private
|
||||
- `Axis::labels` now accepts `Vec<T: Into<Line>>`
|
||||
- [v0.27.0](#v0270)
|
||||
- List no clamps the selected index to list
|
||||
- Prelude items added / removed
|
||||
|
@ -61,6 +62,17 @@ This is a quick summary of the sections below:
|
|||
|
||||
## v0.28.0 (unreleased)
|
||||
|
||||
### `Axis::labels()` now accepts `Vec<T: Into<Line>>` ([#1273])
|
||||
|
||||
[#1273]: https://github.com/ratatui-org/ratatui/pull/1173
|
||||
|
||||
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.
|
||||
|
||||
```diff
|
||||
- Axis::default().labels("a".into(), "b".into())
|
||||
+ Axis::default().labels("a", "b")
|
||||
|
||||
### `Layout::init_cache` no longer returns bool and takes a `NonZeroUsize` instead of `usize` ([#1145])
|
||||
|
||||
[#1145]: https://github.com/ratatui-org/ratatui/pull/1145
|
||||
|
|
|
@ -325,14 +325,14 @@ fn render_scatter(f: &mut Frame, area: Rect) {
|
|||
.title("Year")
|
||||
.bounds([1960., 2020.])
|
||||
.style(Style::default().fg(Color::Gray))
|
||||
.labels(vec!["1960".into(), "1990".into(), "2020".into()]),
|
||||
.labels(vec!["1960", "1990", "2020"]),
|
||||
)
|
||||
.y_axis(
|
||||
Axis::default()
|
||||
.title("Cost")
|
||||
.bounds([0., 75000.])
|
||||
.style(Style::default().fg(Color::Gray))
|
||||
.labels(vec!["0".into(), "37 500".into(), "75 000".into()]),
|
||||
.labels(vec!["0", "37 500", "75 000"]),
|
||||
)
|
||||
.hidden_legend_constraints((Constraint::Ratio(1, 2), Constraint::Ratio(1, 2)));
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ pub struct Axis<'a> {
|
|||
/// Bounds for the axis (all data points outside these limits will not be represented)
|
||||
bounds: [f64; 2],
|
||||
/// A list of labels to put to the left or below the axis
|
||||
labels: Option<Vec<Span<'a>>>,
|
||||
labels: Option<Vec<Line<'a>>>,
|
||||
/// The style used to draw the axis itself
|
||||
style: Style,
|
||||
/// The alignment of the labels of the Axis
|
||||
|
@ -84,6 +84,11 @@ impl<'a> Axis<'a> {
|
|||
///
|
||||
/// [issue 334]: https://github.com/ratatui-org/ratatui/issues/334
|
||||
///
|
||||
/// `labels` is a vector of any type that can be converted into a [`Line`] (e.g. `&str`,
|
||||
/// `String`, `&Line`, `Span`, ...). This allows you to style the labels using the methods
|
||||
/// provided by [`Line`]. Any alignment set on the labels will be ignored as the alignment is
|
||||
/// determined by the axis.
|
||||
///
|
||||
/// This is a fluent setter method which must be chained or used as it consumes self
|
||||
///
|
||||
/// # Examples
|
||||
|
@ -96,8 +101,8 @@ impl<'a> Axis<'a> {
|
|||
/// .labels(vec!["0".bold(), "25".into(), "50".bold()]);
|
||||
/// ```
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn labels(mut self, labels: Vec<Span<'a>>) -> Self {
|
||||
self.labels = Some(labels);
|
||||
pub fn labels<T: Into<Line<'a>>>(mut self, labels: Vec<T>) -> Self {
|
||||
self.labels = Some(labels.into_iter().map(Into::into).collect());
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -469,14 +474,14 @@ struct ChartLayout {
|
|||
/// .title("X Axis".red())
|
||||
/// .style(Style::default().white())
|
||||
/// .bounds([0.0, 10.0])
|
||||
/// .labels(vec!["0.0".into(), "5.0".into(), "10.0".into()]);
|
||||
/// .labels(vec!["0.0", "5.0", "10.0"]);
|
||||
///
|
||||
/// // Create the Y axis and define its properties
|
||||
/// let y_axis = Axis::default()
|
||||
/// .title("Y Axis".red())
|
||||
/// .style(Style::default().white())
|
||||
/// .bounds([0.0, 10.0])
|
||||
/// .labels(vec!["0.0".into(), "5.0".into(), "10.0".into()]);
|
||||
/// .labels(vec!["0.0", "5.0", "10.0"]);
|
||||
///
|
||||
/// // Create the chart and link all the parts together
|
||||
/// let chart = Chart::new(datasets)
|
||||
|
@ -578,7 +583,7 @@ impl<'a> Chart<'a> {
|
|||
/// Axis::default()
|
||||
/// .title("X Axis")
|
||||
/// .bounds([0.0, 20.0])
|
||||
/// .labels(vec!["0".into(), "20".into()]),
|
||||
/// .labels(vec!["0", "20"]),
|
||||
/// );
|
||||
/// ```
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
|
@ -601,7 +606,7 @@ impl<'a> Chart<'a> {
|
|||
/// Axis::default()
|
||||
/// .title("Y Axis")
|
||||
/// .bounds([0.0, 20.0])
|
||||
/// .labels(vec!["0".into(), "20".into()]),
|
||||
/// .labels(vec!["0", "20"]),
|
||||
/// );
|
||||
/// ```
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
|
@ -807,7 +812,7 @@ impl<'a> Chart<'a> {
|
|||
.y_axis
|
||||
.labels
|
||||
.as_ref()
|
||||
.map(|l| l.iter().map(Span::width).max().unwrap_or_default() as u16)
|
||||
.map(|l| l.iter().map(Line::width).max().unwrap_or_default() as u16)
|
||||
.unwrap_or_default();
|
||||
|
||||
if let Some(first_x_label) = self
|
||||
|
@ -903,17 +908,13 @@ impl<'a> Chart<'a> {
|
|||
Rect::new(min_x, y, max_x - min_x, 1)
|
||||
}
|
||||
|
||||
fn render_label(buf: &mut Buffer, label: &Span, label_area: Rect, alignment: Alignment) {
|
||||
let label_width = label.width() as u16;
|
||||
let bounded_label_width = label_area.width.min(label_width);
|
||||
|
||||
let x = match alignment {
|
||||
Alignment::Left => label_area.left(),
|
||||
Alignment::Center => label_area.left() + label_area.width / 2 - bounded_label_width / 2,
|
||||
Alignment::Right => label_area.right() - bounded_label_width,
|
||||
fn render_label(buf: &mut Buffer, label: &Line, label_area: Rect, alignment: Alignment) {
|
||||
let label = match alignment {
|
||||
Alignment::Left => label.clone().left_aligned(),
|
||||
Alignment::Center => label.clone().centered(),
|
||||
Alignment::Right => label.clone().right_aligned(),
|
||||
};
|
||||
|
||||
buf.set_span(x, label_area.top(), label, bounded_label_width);
|
||||
label.render(label_area, buf);
|
||||
}
|
||||
|
||||
fn render_y_labels(
|
||||
|
|
|
@ -203,7 +203,7 @@ fn widgets_chart_handles_long_labels<'line, Lines>(
|
|||
" ",
|
||||
" ",
|
||||
"──────────",
|
||||
"AAA B C",
|
||||
"AAA B C",
|
||||
],
|
||||
)]
|
||||
fn widgets_chart_handles_x_axis_labels_alignments<'line, Lines>(
|
||||
|
@ -229,9 +229,9 @@ fn widgets_chart_handles_x_axis_labels_alignments<'line, Lines>(
|
|||
"AAAAA B",
|
||||
])]
|
||||
#[case::center(Alignment::Center, [
|
||||
" D │ ",
|
||||
" D │ ",
|
||||
" │ ",
|
||||
" C │ ",
|
||||
" C │ ",
|
||||
" └───────────────",
|
||||
"AAAAA B",
|
||||
])]
|
||||
|
|
Loading…
Reference in a new issue