feat(widgets/chart): add option to set the position of legend

pull/628/head
Lyuha 2 years ago
parent a6b25a4877
commit 614e5d785d

@ -10,7 +10,7 @@ use std::{
};
use tui::{
backend::{Backend, CrosstermBackend},
layout::{Constraint, Direction, Layout},
layout::{Constraint, Corner, Direction, Layout},
style::{Color, Modifier, Style},
symbols,
text::Span,
@ -296,6 +296,7 @@ fn ui<B: Backend>(f: &mut Frame<B>, app: &App) {
Span::raw("2.5"),
Span::styled("5", Style::default().add_modifier(Modifier::BOLD)),
]),
);
)
.legend_position(Corner::BottomRight);
f.render_widget(chart, chunks[2]);
}

@ -5,7 +5,7 @@ use unicode_width::UnicodeWidthStr;
use crate::layout::Alignment;
use crate::{
buffer::Buffer,
layout::{Constraint, Rect},
layout::{Constraint, Corner, Rect},
style::{Color, Style},
symbols,
text::{Span, Spans},
@ -226,6 +226,8 @@ pub struct Chart<'a> {
style: Style,
/// Constraints used to determine whether the legend should be shown or not
hidden_legend_constraints: (Constraint, Constraint),
/// The position of a legend
legend_position: Corner,
}
impl<'a> Chart<'a> {
@ -237,6 +239,7 @@ impl<'a> Chart<'a> {
style: Default::default(),
datasets,
hidden_legend_constraints: (Constraint::Ratio(1, 4), Constraint::Ratio(1, 4)),
legend_position: Corner::TopRight,
}
}
@ -281,6 +284,21 @@ impl<'a> Chart<'a> {
self
}
/// Set the position of a legend.
///
/// # Examples
///
/// ```
/// # use tui::widgets::Chart;
/// # use tui::layout::Corner;
/// let _chart: Chart = Chart::new(vec![])
/// .legend_position(Corner::TopLeft);
/// ```
pub fn legend_position(mut self, position: Corner) -> Chart<'a> {
self.legend_position = position;
self
}
/// Compute the internal layout of the chart given the area. If the area is too small some
/// elements may be automatically hidden
fn layout(&self, area: Rect) -> ChartLayout {
@ -342,12 +360,25 @@ impl<'a> Chart<'a> {
&& legend_width < max_legend_width
&& legend_height < max_legend_height
{
layout.legend_area = Some(Rect::new(
layout.graph_area.right() - legend_width,
layout.graph_area.top(),
legend_width,
legend_height,
));
let (x, y) = match self.legend_position {
Corner::TopRight => (
layout.graph_area.right() - legend_width,
layout.graph_area.top(),
),
Corner::TopLeft => (
layout.graph_area.left(),
layout.graph_area.top() - legend_height
+ if self.y_axis.title.is_some() { 1 } else { 0 },
),
Corner::BottomRight => (
layout.graph_area.right() - legend_width,
layout.graph_area.bottom()
- legend_height
- if self.x_axis.title.is_some() { 1 } else { 0 },
),
Corner::BottomLeft => (layout.graph_area.left(), layout.graph_area.bottom()),
};
layout.legend_area = Some(Rect::new(x, y, legend_width, legend_height));
}
}
layout

Loading…
Cancel
Save