pub struct Chart<'a> { /* private fields */ }
Expand description
A widget to plot one or more Dataset
in a cartesian coordinate system
To use this widget, start by creating one or more Dataset
. With it, you can set the
data points, the name or the
chart type. See Dataset
for a complete documentation of what is
possible.
Then, you’ll usually want to configure the Axis
. Axis titles,
bounds and labels can be configured on both axis. See Axis
for a complete documentation of what is possible.
Finally, you can pass all of that to the Chart
via Chart::new
, Chart::x_axis
and
Chart::y_axis
.
Additionally, Chart
allows configuring the legend position and
hiding constraints.
§Examples
use ratatui::{
style::{Style, Stylize},
symbols,
widgets::{Axis, Block, Chart, Dataset, GraphType},
};
// Create the datasets to fill the chart with
let datasets = vec![
// Scatter chart
Dataset::default()
.name("data1")
.marker(symbols::Marker::Dot)
.graph_type(GraphType::Scatter)
.style(Style::default().cyan())
.data(&[(0.0, 5.0), (1.0, 6.0), (1.5, 6.434)]),
// Line chart
Dataset::default()
.name("data2")
.marker(symbols::Marker::Braille)
.graph_type(GraphType::Line)
.style(Style::default().magenta())
.data(&[(4.0, 5.0), (5.0, 8.0), (7.66, 13.5)]),
];
// Create the X axis and define its properties
let x_axis = Axis::default()
.title("X Axis".red())
.style(Style::default().white())
.bounds([0.0, 10.0])
.labels(["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(["0.0", "5.0", "10.0"]);
// Create the chart and link all the parts together
let chart = Chart::new(datasets)
.block(Block::new().title("Chart"))
.x_axis(x_axis)
.y_axis(y_axis);
Implementations§
Source§impl<'a> Chart<'a>
impl<'a> Chart<'a>
Sourcepub fn new(datasets: Vec<Dataset<'a>>) -> Self
pub fn new(datasets: Vec<Dataset<'a>>) -> Self
Creates a chart with the given datasets
A chart can render multiple datasets.
§Example
This creates a simple chart with one Dataset
use ratatui::widgets::{Chart, Dataset};
let data_points = vec![];
let chart = Chart::new(vec![Dataset::default().data(&data_points)]);
This creates a chart with multiple Dataset
s
use ratatui::widgets::{Chart, Dataset};
let data_points = vec![];
let data_points2 = vec![];
let chart = Chart::new(vec![
Dataset::default().data(&data_points),
Dataset::default().data(&data_points2),
]);
Examples found in repository?
132 fn render_animated_chart(&self, frame: &mut Frame, area: Rect) {
133 let x_labels = vec![
134 Span::styled(
135 format!("{}", self.window[0]),
136 Style::default().add_modifier(Modifier::BOLD),
137 ),
138 Span::raw(format!("{}", (self.window[0] + self.window[1]) / 2.0)),
139 Span::styled(
140 format!("{}", self.window[1]),
141 Style::default().add_modifier(Modifier::BOLD),
142 ),
143 ];
144 let datasets = vec![
145 Dataset::default()
146 .name("data2")
147 .marker(symbols::Marker::Dot)
148 .style(Style::default().fg(Color::Cyan))
149 .data(&self.data1),
150 Dataset::default()
151 .name("data3")
152 .marker(symbols::Marker::Braille)
153 .style(Style::default().fg(Color::Yellow))
154 .data(&self.data2),
155 ];
156
157 let chart = Chart::new(datasets)
158 .block(Block::bordered())
159 .x_axis(
160 Axis::default()
161 .title("X Axis")
162 .style(Style::default().fg(Color::Gray))
163 .labels(x_labels)
164 .bounds(self.window),
165 )
166 .y_axis(
167 Axis::default()
168 .title("Y Axis")
169 .style(Style::default().fg(Color::Gray))
170 .labels(["-20".bold(), "0".into(), "20".bold()])
171 .bounds([-20.0, 20.0]),
172 );
173
174 frame.render_widget(chart, area);
175 }
176}
177
178fn render_barchart(frame: &mut Frame, bar_chart: Rect) {
179 let dataset = Dataset::default()
180 .marker(symbols::Marker::HalfBlock)
181 .style(Style::new().fg(Color::Blue))
182 .graph_type(GraphType::Bar)
183 // a bell curve
184 .data(&[
185 (0., 0.4),
186 (10., 2.9),
187 (20., 13.5),
188 (30., 41.1),
189 (40., 80.1),
190 (50., 100.0),
191 (60., 80.1),
192 (70., 41.1),
193 (80., 13.5),
194 (90., 2.9),
195 (100., 0.4),
196 ]);
197
198 let chart = Chart::new(vec![dataset])
199 .block(Block::bordered().title_top(Line::from("Bar chart").cyan().bold().centered()))
200 .x_axis(
201 Axis::default()
202 .style(Style::default().gray())
203 .bounds([0.0, 100.0])
204 .labels(["0".bold(), "50".into(), "100.0".bold()]),
205 )
206 .y_axis(
207 Axis::default()
208 .style(Style::default().gray())
209 .bounds([0.0, 100.0])
210 .labels(["0".bold(), "50".into(), "100.0".bold()]),
211 )
212 .hidden_legend_constraints((Constraint::Ratio(1, 2), Constraint::Ratio(1, 2)));
213
214 frame.render_widget(chart, bar_chart);
215}
216
217fn render_line_chart(frame: &mut Frame, area: Rect) {
218 let datasets = vec![Dataset::default()
219 .name("Line from only 2 points".italic())
220 .marker(symbols::Marker::Braille)
221 .style(Style::default().fg(Color::Yellow))
222 .graph_type(GraphType::Line)
223 .data(&[(1., 1.), (4., 4.)])];
224
225 let chart = Chart::new(datasets)
226 .block(Block::bordered().title(Line::from("Line chart").cyan().bold().centered()))
227 .x_axis(
228 Axis::default()
229 .title("X Axis")
230 .style(Style::default().gray())
231 .bounds([0.0, 5.0])
232 .labels(["0".bold(), "2.5".into(), "5.0".bold()]),
233 )
234 .y_axis(
235 Axis::default()
236 .title("Y Axis")
237 .style(Style::default().gray())
238 .bounds([0.0, 5.0])
239 .labels(["0".bold(), "2.5".into(), "5.0".bold()]),
240 )
241 .legend_position(Some(LegendPosition::TopLeft))
242 .hidden_legend_constraints((Constraint::Ratio(1, 2), Constraint::Ratio(1, 2)));
243
244 frame.render_widget(chart, area);
245}
246
247fn render_scatter(frame: &mut Frame, area: Rect) {
248 let datasets = vec![
249 Dataset::default()
250 .name("Heavy")
251 .marker(Marker::Dot)
252 .graph_type(GraphType::Scatter)
253 .style(Style::new().yellow())
254 .data(&HEAVY_PAYLOAD_DATA),
255 Dataset::default()
256 .name("Medium".underlined())
257 .marker(Marker::Braille)
258 .graph_type(GraphType::Scatter)
259 .style(Style::new().magenta())
260 .data(&MEDIUM_PAYLOAD_DATA),
261 Dataset::default()
262 .name("Small")
263 .marker(Marker::Dot)
264 .graph_type(GraphType::Scatter)
265 .style(Style::new().cyan())
266 .data(&SMALL_PAYLOAD_DATA),
267 ];
268
269 let chart = Chart::new(datasets)
270 .block(Block::bordered().title(Line::from("Scatter chart").cyan().bold().centered()))
271 .x_axis(
272 Axis::default()
273 .title("Year")
274 .bounds([1960., 2020.])
275 .style(Style::default().fg(Color::Gray))
276 .labels(["1960", "1990", "2020"]),
277 )
278 .y_axis(
279 Axis::default()
280 .title("Cost")
281 .bounds([0., 75000.])
282 .style(Style::default().fg(Color::Gray))
283 .labels(["0", "37 500", "75 000"]),
284 )
285 .hidden_legend_constraints((Constraint::Ratio(1, 2), Constraint::Ratio(1, 2)));
286
287 frame.render_widget(chart, area);
288}
Sourcepub fn block(self, block: Block<'a>) -> Self
pub fn block(self, block: Block<'a>) -> Self
Wraps the chart with the given Block
This is a fluent setter method which must be chained or used as it consumes self
Examples found in repository?
132 fn render_animated_chart(&self, frame: &mut Frame, area: Rect) {
133 let x_labels = vec![
134 Span::styled(
135 format!("{}", self.window[0]),
136 Style::default().add_modifier(Modifier::BOLD),
137 ),
138 Span::raw(format!("{}", (self.window[0] + self.window[1]) / 2.0)),
139 Span::styled(
140 format!("{}", self.window[1]),
141 Style::default().add_modifier(Modifier::BOLD),
142 ),
143 ];
144 let datasets = vec![
145 Dataset::default()
146 .name("data2")
147 .marker(symbols::Marker::Dot)
148 .style(Style::default().fg(Color::Cyan))
149 .data(&self.data1),
150 Dataset::default()
151 .name("data3")
152 .marker(symbols::Marker::Braille)
153 .style(Style::default().fg(Color::Yellow))
154 .data(&self.data2),
155 ];
156
157 let chart = Chart::new(datasets)
158 .block(Block::bordered())
159 .x_axis(
160 Axis::default()
161 .title("X Axis")
162 .style(Style::default().fg(Color::Gray))
163 .labels(x_labels)
164 .bounds(self.window),
165 )
166 .y_axis(
167 Axis::default()
168 .title("Y Axis")
169 .style(Style::default().fg(Color::Gray))
170 .labels(["-20".bold(), "0".into(), "20".bold()])
171 .bounds([-20.0, 20.0]),
172 );
173
174 frame.render_widget(chart, area);
175 }
176}
177
178fn render_barchart(frame: &mut Frame, bar_chart: Rect) {
179 let dataset = Dataset::default()
180 .marker(symbols::Marker::HalfBlock)
181 .style(Style::new().fg(Color::Blue))
182 .graph_type(GraphType::Bar)
183 // a bell curve
184 .data(&[
185 (0., 0.4),
186 (10., 2.9),
187 (20., 13.5),
188 (30., 41.1),
189 (40., 80.1),
190 (50., 100.0),
191 (60., 80.1),
192 (70., 41.1),
193 (80., 13.5),
194 (90., 2.9),
195 (100., 0.4),
196 ]);
197
198 let chart = Chart::new(vec![dataset])
199 .block(Block::bordered().title_top(Line::from("Bar chart").cyan().bold().centered()))
200 .x_axis(
201 Axis::default()
202 .style(Style::default().gray())
203 .bounds([0.0, 100.0])
204 .labels(["0".bold(), "50".into(), "100.0".bold()]),
205 )
206 .y_axis(
207 Axis::default()
208 .style(Style::default().gray())
209 .bounds([0.0, 100.0])
210 .labels(["0".bold(), "50".into(), "100.0".bold()]),
211 )
212 .hidden_legend_constraints((Constraint::Ratio(1, 2), Constraint::Ratio(1, 2)));
213
214 frame.render_widget(chart, bar_chart);
215}
216
217fn render_line_chart(frame: &mut Frame, area: Rect) {
218 let datasets = vec![Dataset::default()
219 .name("Line from only 2 points".italic())
220 .marker(symbols::Marker::Braille)
221 .style(Style::default().fg(Color::Yellow))
222 .graph_type(GraphType::Line)
223 .data(&[(1., 1.), (4., 4.)])];
224
225 let chart = Chart::new(datasets)
226 .block(Block::bordered().title(Line::from("Line chart").cyan().bold().centered()))
227 .x_axis(
228 Axis::default()
229 .title("X Axis")
230 .style(Style::default().gray())
231 .bounds([0.0, 5.0])
232 .labels(["0".bold(), "2.5".into(), "5.0".bold()]),
233 )
234 .y_axis(
235 Axis::default()
236 .title("Y Axis")
237 .style(Style::default().gray())
238 .bounds([0.0, 5.0])
239 .labels(["0".bold(), "2.5".into(), "5.0".bold()]),
240 )
241 .legend_position(Some(LegendPosition::TopLeft))
242 .hidden_legend_constraints((Constraint::Ratio(1, 2), Constraint::Ratio(1, 2)));
243
244 frame.render_widget(chart, area);
245}
246
247fn render_scatter(frame: &mut Frame, area: Rect) {
248 let datasets = vec![
249 Dataset::default()
250 .name("Heavy")
251 .marker(Marker::Dot)
252 .graph_type(GraphType::Scatter)
253 .style(Style::new().yellow())
254 .data(&HEAVY_PAYLOAD_DATA),
255 Dataset::default()
256 .name("Medium".underlined())
257 .marker(Marker::Braille)
258 .graph_type(GraphType::Scatter)
259 .style(Style::new().magenta())
260 .data(&MEDIUM_PAYLOAD_DATA),
261 Dataset::default()
262 .name("Small")
263 .marker(Marker::Dot)
264 .graph_type(GraphType::Scatter)
265 .style(Style::new().cyan())
266 .data(&SMALL_PAYLOAD_DATA),
267 ];
268
269 let chart = Chart::new(datasets)
270 .block(Block::bordered().title(Line::from("Scatter chart").cyan().bold().centered()))
271 .x_axis(
272 Axis::default()
273 .title("Year")
274 .bounds([1960., 2020.])
275 .style(Style::default().fg(Color::Gray))
276 .labels(["1960", "1990", "2020"]),
277 )
278 .y_axis(
279 Axis::default()
280 .title("Cost")
281 .bounds([0., 75000.])
282 .style(Style::default().fg(Color::Gray))
283 .labels(["0", "37 500", "75 000"]),
284 )
285 .hidden_legend_constraints((Constraint::Ratio(1, 2), Constraint::Ratio(1, 2)));
286
287 frame.render_widget(chart, area);
288}
Sourcepub fn x_axis(self, axis: Axis<'a>) -> Self
pub fn x_axis(self, axis: Axis<'a>) -> Self
Sets the X Axis
The default is an empty Axis
, i.e. only a line.
This is a fluent setter method which must be chained or used as it consumes self
§Example
use ratatui::widgets::{Axis, Chart};
let chart = Chart::new(vec![]).x_axis(
Axis::default()
.title("X Axis")
.bounds([0.0, 20.0])
.labels(["0", "20"]),
);
Examples found in repository?
132 fn render_animated_chart(&self, frame: &mut Frame, area: Rect) {
133 let x_labels = vec![
134 Span::styled(
135 format!("{}", self.window[0]),
136 Style::default().add_modifier(Modifier::BOLD),
137 ),
138 Span::raw(format!("{}", (self.window[0] + self.window[1]) / 2.0)),
139 Span::styled(
140 format!("{}", self.window[1]),
141 Style::default().add_modifier(Modifier::BOLD),
142 ),
143 ];
144 let datasets = vec![
145 Dataset::default()
146 .name("data2")
147 .marker(symbols::Marker::Dot)
148 .style(Style::default().fg(Color::Cyan))
149 .data(&self.data1),
150 Dataset::default()
151 .name("data3")
152 .marker(symbols::Marker::Braille)
153 .style(Style::default().fg(Color::Yellow))
154 .data(&self.data2),
155 ];
156
157 let chart = Chart::new(datasets)
158 .block(Block::bordered())
159 .x_axis(
160 Axis::default()
161 .title("X Axis")
162 .style(Style::default().fg(Color::Gray))
163 .labels(x_labels)
164 .bounds(self.window),
165 )
166 .y_axis(
167 Axis::default()
168 .title("Y Axis")
169 .style(Style::default().fg(Color::Gray))
170 .labels(["-20".bold(), "0".into(), "20".bold()])
171 .bounds([-20.0, 20.0]),
172 );
173
174 frame.render_widget(chart, area);
175 }
176}
177
178fn render_barchart(frame: &mut Frame, bar_chart: Rect) {
179 let dataset = Dataset::default()
180 .marker(symbols::Marker::HalfBlock)
181 .style(Style::new().fg(Color::Blue))
182 .graph_type(GraphType::Bar)
183 // a bell curve
184 .data(&[
185 (0., 0.4),
186 (10., 2.9),
187 (20., 13.5),
188 (30., 41.1),
189 (40., 80.1),
190 (50., 100.0),
191 (60., 80.1),
192 (70., 41.1),
193 (80., 13.5),
194 (90., 2.9),
195 (100., 0.4),
196 ]);
197
198 let chart = Chart::new(vec![dataset])
199 .block(Block::bordered().title_top(Line::from("Bar chart").cyan().bold().centered()))
200 .x_axis(
201 Axis::default()
202 .style(Style::default().gray())
203 .bounds([0.0, 100.0])
204 .labels(["0".bold(), "50".into(), "100.0".bold()]),
205 )
206 .y_axis(
207 Axis::default()
208 .style(Style::default().gray())
209 .bounds([0.0, 100.0])
210 .labels(["0".bold(), "50".into(), "100.0".bold()]),
211 )
212 .hidden_legend_constraints((Constraint::Ratio(1, 2), Constraint::Ratio(1, 2)));
213
214 frame.render_widget(chart, bar_chart);
215}
216
217fn render_line_chart(frame: &mut Frame, area: Rect) {
218 let datasets = vec![Dataset::default()
219 .name("Line from only 2 points".italic())
220 .marker(symbols::Marker::Braille)
221 .style(Style::default().fg(Color::Yellow))
222 .graph_type(GraphType::Line)
223 .data(&[(1., 1.), (4., 4.)])];
224
225 let chart = Chart::new(datasets)
226 .block(Block::bordered().title(Line::from("Line chart").cyan().bold().centered()))
227 .x_axis(
228 Axis::default()
229 .title("X Axis")
230 .style(Style::default().gray())
231 .bounds([0.0, 5.0])
232 .labels(["0".bold(), "2.5".into(), "5.0".bold()]),
233 )
234 .y_axis(
235 Axis::default()
236 .title("Y Axis")
237 .style(Style::default().gray())
238 .bounds([0.0, 5.0])
239 .labels(["0".bold(), "2.5".into(), "5.0".bold()]),
240 )
241 .legend_position(Some(LegendPosition::TopLeft))
242 .hidden_legend_constraints((Constraint::Ratio(1, 2), Constraint::Ratio(1, 2)));
243
244 frame.render_widget(chart, area);
245}
246
247fn render_scatter(frame: &mut Frame, area: Rect) {
248 let datasets = vec![
249 Dataset::default()
250 .name("Heavy")
251 .marker(Marker::Dot)
252 .graph_type(GraphType::Scatter)
253 .style(Style::new().yellow())
254 .data(&HEAVY_PAYLOAD_DATA),
255 Dataset::default()
256 .name("Medium".underlined())
257 .marker(Marker::Braille)
258 .graph_type(GraphType::Scatter)
259 .style(Style::new().magenta())
260 .data(&MEDIUM_PAYLOAD_DATA),
261 Dataset::default()
262 .name("Small")
263 .marker(Marker::Dot)
264 .graph_type(GraphType::Scatter)
265 .style(Style::new().cyan())
266 .data(&SMALL_PAYLOAD_DATA),
267 ];
268
269 let chart = Chart::new(datasets)
270 .block(Block::bordered().title(Line::from("Scatter chart").cyan().bold().centered()))
271 .x_axis(
272 Axis::default()
273 .title("Year")
274 .bounds([1960., 2020.])
275 .style(Style::default().fg(Color::Gray))
276 .labels(["1960", "1990", "2020"]),
277 )
278 .y_axis(
279 Axis::default()
280 .title("Cost")
281 .bounds([0., 75000.])
282 .style(Style::default().fg(Color::Gray))
283 .labels(["0", "37 500", "75 000"]),
284 )
285 .hidden_legend_constraints((Constraint::Ratio(1, 2), Constraint::Ratio(1, 2)));
286
287 frame.render_widget(chart, area);
288}
Sourcepub fn y_axis(self, axis: Axis<'a>) -> Self
pub fn y_axis(self, axis: Axis<'a>) -> Self
Sets the Y Axis
The default is an empty Axis
, i.e. only a line.
This is a fluent setter method which must be chained or used as it consumes self
§Example
use ratatui::widgets::{Axis, Chart};
let chart = Chart::new(vec![]).y_axis(
Axis::default()
.title("Y Axis")
.bounds([0.0, 20.0])
.labels(["0", "20"]),
);
Examples found in repository?
132 fn render_animated_chart(&self, frame: &mut Frame, area: Rect) {
133 let x_labels = vec![
134 Span::styled(
135 format!("{}", self.window[0]),
136 Style::default().add_modifier(Modifier::BOLD),
137 ),
138 Span::raw(format!("{}", (self.window[0] + self.window[1]) / 2.0)),
139 Span::styled(
140 format!("{}", self.window[1]),
141 Style::default().add_modifier(Modifier::BOLD),
142 ),
143 ];
144 let datasets = vec![
145 Dataset::default()
146 .name("data2")
147 .marker(symbols::Marker::Dot)
148 .style(Style::default().fg(Color::Cyan))
149 .data(&self.data1),
150 Dataset::default()
151 .name("data3")
152 .marker(symbols::Marker::Braille)
153 .style(Style::default().fg(Color::Yellow))
154 .data(&self.data2),
155 ];
156
157 let chart = Chart::new(datasets)
158 .block(Block::bordered())
159 .x_axis(
160 Axis::default()
161 .title("X Axis")
162 .style(Style::default().fg(Color::Gray))
163 .labels(x_labels)
164 .bounds(self.window),
165 )
166 .y_axis(
167 Axis::default()
168 .title("Y Axis")
169 .style(Style::default().fg(Color::Gray))
170 .labels(["-20".bold(), "0".into(), "20".bold()])
171 .bounds([-20.0, 20.0]),
172 );
173
174 frame.render_widget(chart, area);
175 }
176}
177
178fn render_barchart(frame: &mut Frame, bar_chart: Rect) {
179 let dataset = Dataset::default()
180 .marker(symbols::Marker::HalfBlock)
181 .style(Style::new().fg(Color::Blue))
182 .graph_type(GraphType::Bar)
183 // a bell curve
184 .data(&[
185 (0., 0.4),
186 (10., 2.9),
187 (20., 13.5),
188 (30., 41.1),
189 (40., 80.1),
190 (50., 100.0),
191 (60., 80.1),
192 (70., 41.1),
193 (80., 13.5),
194 (90., 2.9),
195 (100., 0.4),
196 ]);
197
198 let chart = Chart::new(vec![dataset])
199 .block(Block::bordered().title_top(Line::from("Bar chart").cyan().bold().centered()))
200 .x_axis(
201 Axis::default()
202 .style(Style::default().gray())
203 .bounds([0.0, 100.0])
204 .labels(["0".bold(), "50".into(), "100.0".bold()]),
205 )
206 .y_axis(
207 Axis::default()
208 .style(Style::default().gray())
209 .bounds([0.0, 100.0])
210 .labels(["0".bold(), "50".into(), "100.0".bold()]),
211 )
212 .hidden_legend_constraints((Constraint::Ratio(1, 2), Constraint::Ratio(1, 2)));
213
214 frame.render_widget(chart, bar_chart);
215}
216
217fn render_line_chart(frame: &mut Frame, area: Rect) {
218 let datasets = vec![Dataset::default()
219 .name("Line from only 2 points".italic())
220 .marker(symbols::Marker::Braille)
221 .style(Style::default().fg(Color::Yellow))
222 .graph_type(GraphType::Line)
223 .data(&[(1., 1.), (4., 4.)])];
224
225 let chart = Chart::new(datasets)
226 .block(Block::bordered().title(Line::from("Line chart").cyan().bold().centered()))
227 .x_axis(
228 Axis::default()
229 .title("X Axis")
230 .style(Style::default().gray())
231 .bounds([0.0, 5.0])
232 .labels(["0".bold(), "2.5".into(), "5.0".bold()]),
233 )
234 .y_axis(
235 Axis::default()
236 .title("Y Axis")
237 .style(Style::default().gray())
238 .bounds([0.0, 5.0])
239 .labels(["0".bold(), "2.5".into(), "5.0".bold()]),
240 )
241 .legend_position(Some(LegendPosition::TopLeft))
242 .hidden_legend_constraints((Constraint::Ratio(1, 2), Constraint::Ratio(1, 2)));
243
244 frame.render_widget(chart, area);
245}
246
247fn render_scatter(frame: &mut Frame, area: Rect) {
248 let datasets = vec![
249 Dataset::default()
250 .name("Heavy")
251 .marker(Marker::Dot)
252 .graph_type(GraphType::Scatter)
253 .style(Style::new().yellow())
254 .data(&HEAVY_PAYLOAD_DATA),
255 Dataset::default()
256 .name("Medium".underlined())
257 .marker(Marker::Braille)
258 .graph_type(GraphType::Scatter)
259 .style(Style::new().magenta())
260 .data(&MEDIUM_PAYLOAD_DATA),
261 Dataset::default()
262 .name("Small")
263 .marker(Marker::Dot)
264 .graph_type(GraphType::Scatter)
265 .style(Style::new().cyan())
266 .data(&SMALL_PAYLOAD_DATA),
267 ];
268
269 let chart = Chart::new(datasets)
270 .block(Block::bordered().title(Line::from("Scatter chart").cyan().bold().centered()))
271 .x_axis(
272 Axis::default()
273 .title("Year")
274 .bounds([1960., 2020.])
275 .style(Style::default().fg(Color::Gray))
276 .labels(["1960", "1990", "2020"]),
277 )
278 .y_axis(
279 Axis::default()
280 .title("Cost")
281 .bounds([0., 75000.])
282 .style(Style::default().fg(Color::Gray))
283 .labels(["0", "37 500", "75 000"]),
284 )
285 .hidden_legend_constraints((Constraint::Ratio(1, 2), Constraint::Ratio(1, 2)));
286
287 frame.render_widget(chart, area);
288}
Sets the constraints used to determine whether the legend should be shown or not.
The tuple’s first constraint is used for the width and the second for the height. If the
legend takes more space than what is allowed by any constraint, the legend is hidden.
Constraint::Min
is an exception and will always show the legend.
If this is not set, the default behavior is to hide the legend if it is greater than 25% of the chart, either horizontally or vertically.
This is a fluent setter method which must be chained or used as it consumes self
§Examples
Hide the legend when either its width is greater than 33% of the total widget width or if its height is greater than 25% of the total widget height.
use ratatui::{layout::Constraint, widgets::Chart};
let constraints = (Constraint::Ratio(1, 3), Constraint::Ratio(1, 4));
let chart = Chart::new(vec![]).hidden_legend_constraints(constraints);
Always show the legend, note the second constraint doesn’t matter in this case since the first one is always true.
use ratatui::{layout::Constraint, widgets::Chart};
let constraints = (Constraint::Min(0), Constraint::Ratio(1, 4));
let chart = Chart::new(vec![]).hidden_legend_constraints(constraints);
Always hide the legend. Note this can be accomplished more explicitly by passing None
to
Chart::legend_position
.
use ratatui::{layout::Constraint, widgets::Chart};
let constraints = (Constraint::Length(0), Constraint::Ratio(1, 4));
let chart = Chart::new(vec![]).hidden_legend_constraints(constraints);
Examples found in repository?
178fn render_barchart(frame: &mut Frame, bar_chart: Rect) {
179 let dataset = Dataset::default()
180 .marker(symbols::Marker::HalfBlock)
181 .style(Style::new().fg(Color::Blue))
182 .graph_type(GraphType::Bar)
183 // a bell curve
184 .data(&[
185 (0., 0.4),
186 (10., 2.9),
187 (20., 13.5),
188 (30., 41.1),
189 (40., 80.1),
190 (50., 100.0),
191 (60., 80.1),
192 (70., 41.1),
193 (80., 13.5),
194 (90., 2.9),
195 (100., 0.4),
196 ]);
197
198 let chart = Chart::new(vec![dataset])
199 .block(Block::bordered().title_top(Line::from("Bar chart").cyan().bold().centered()))
200 .x_axis(
201 Axis::default()
202 .style(Style::default().gray())
203 .bounds([0.0, 100.0])
204 .labels(["0".bold(), "50".into(), "100.0".bold()]),
205 )
206 .y_axis(
207 Axis::default()
208 .style(Style::default().gray())
209 .bounds([0.0, 100.0])
210 .labels(["0".bold(), "50".into(), "100.0".bold()]),
211 )
212 .hidden_legend_constraints((Constraint::Ratio(1, 2), Constraint::Ratio(1, 2)));
213
214 frame.render_widget(chart, bar_chart);
215}
216
217fn render_line_chart(frame: &mut Frame, area: Rect) {
218 let datasets = vec![Dataset::default()
219 .name("Line from only 2 points".italic())
220 .marker(symbols::Marker::Braille)
221 .style(Style::default().fg(Color::Yellow))
222 .graph_type(GraphType::Line)
223 .data(&[(1., 1.), (4., 4.)])];
224
225 let chart = Chart::new(datasets)
226 .block(Block::bordered().title(Line::from("Line chart").cyan().bold().centered()))
227 .x_axis(
228 Axis::default()
229 .title("X Axis")
230 .style(Style::default().gray())
231 .bounds([0.0, 5.0])
232 .labels(["0".bold(), "2.5".into(), "5.0".bold()]),
233 )
234 .y_axis(
235 Axis::default()
236 .title("Y Axis")
237 .style(Style::default().gray())
238 .bounds([0.0, 5.0])
239 .labels(["0".bold(), "2.5".into(), "5.0".bold()]),
240 )
241 .legend_position(Some(LegendPosition::TopLeft))
242 .hidden_legend_constraints((Constraint::Ratio(1, 2), Constraint::Ratio(1, 2)));
243
244 frame.render_widget(chart, area);
245}
246
247fn render_scatter(frame: &mut Frame, area: Rect) {
248 let datasets = vec![
249 Dataset::default()
250 .name("Heavy")
251 .marker(Marker::Dot)
252 .graph_type(GraphType::Scatter)
253 .style(Style::new().yellow())
254 .data(&HEAVY_PAYLOAD_DATA),
255 Dataset::default()
256 .name("Medium".underlined())
257 .marker(Marker::Braille)
258 .graph_type(GraphType::Scatter)
259 .style(Style::new().magenta())
260 .data(&MEDIUM_PAYLOAD_DATA),
261 Dataset::default()
262 .name("Small")
263 .marker(Marker::Dot)
264 .graph_type(GraphType::Scatter)
265 .style(Style::new().cyan())
266 .data(&SMALL_PAYLOAD_DATA),
267 ];
268
269 let chart = Chart::new(datasets)
270 .block(Block::bordered().title(Line::from("Scatter chart").cyan().bold().centered()))
271 .x_axis(
272 Axis::default()
273 .title("Year")
274 .bounds([1960., 2020.])
275 .style(Style::default().fg(Color::Gray))
276 .labels(["1960", "1990", "2020"]),
277 )
278 .y_axis(
279 Axis::default()
280 .title("Cost")
281 .bounds([0., 75000.])
282 .style(Style::default().fg(Color::Gray))
283 .labels(["0", "37 500", "75 000"]),
284 )
285 .hidden_legend_constraints((Constraint::Ratio(1, 2), Constraint::Ratio(1, 2)));
286
287 frame.render_widget(chart, area);
288}
Sourcepub const fn legend_position(self, position: Option<LegendPosition>) -> Self
pub const fn legend_position(self, position: Option<LegendPosition>) -> Self
Sets the position of a legend or hide it
The default is LegendPosition::TopRight
.
If None
is given, hide the legend even if hidden_legend_constraints
determines it
should be shown. In contrast, if Some(...)
is given, hidden_legend_constraints
might
still decide whether to show the legend or not.
See LegendPosition
for all available positions.
This is a fluent setter method which must be chained or used as it consumes self
§Examples
Show the legend on the top left corner.
use ratatui::widgets::{Chart, LegendPosition};
let chart: Chart = Chart::new(vec![]).legend_position(Some(LegendPosition::TopLeft));
Hide the legend altogether
use ratatui::widgets::{Chart, LegendPosition};
let chart = Chart::new(vec![]).legend_position(None);
Examples found in repository?
217fn render_line_chart(frame: &mut Frame, area: Rect) {
218 let datasets = vec![Dataset::default()
219 .name("Line from only 2 points".italic())
220 .marker(symbols::Marker::Braille)
221 .style(Style::default().fg(Color::Yellow))
222 .graph_type(GraphType::Line)
223 .data(&[(1., 1.), (4., 4.)])];
224
225 let chart = Chart::new(datasets)
226 .block(Block::bordered().title(Line::from("Line chart").cyan().bold().centered()))
227 .x_axis(
228 Axis::default()
229 .title("X Axis")
230 .style(Style::default().gray())
231 .bounds([0.0, 5.0])
232 .labels(["0".bold(), "2.5".into(), "5.0".bold()]),
233 )
234 .y_axis(
235 Axis::default()
236 .title("Y Axis")
237 .style(Style::default().gray())
238 .bounds([0.0, 5.0])
239 .labels(["0".bold(), "2.5".into(), "5.0".bold()]),
240 )
241 .legend_position(Some(LegendPosition::TopLeft))
242 .hidden_legend_constraints((Constraint::Ratio(1, 2), Constraint::Ratio(1, 2)));
243
244 frame.render_widget(chart, area);
245}
Trait Implementations§
Source§impl WidgetRef for Chart<'_>
impl WidgetRef for Chart<'_>
Source§fn render_ref(&self, area: Rect, buf: &mut Buffer)
fn render_ref(&self, area: Rect, buf: &mut Buffer)
unstable-widget-ref
only.impl<'a> StructuralPartialEq for Chart<'a>
Auto Trait Implementations§
impl<'a> Freeze for Chart<'a>
impl<'a> RefUnwindSafe for Chart<'a>
impl<'a> Send for Chart<'a>
impl<'a> Sync for Chart<'a>
impl<'a> Unpin for Chart<'a>
impl<'a> UnwindSafe for Chart<'a>
Blanket Implementations§
Source§impl<S, D, Swp, Dwp, T> AdaptInto<D, Swp, Dwp, T> for Swhere
T: Real + Zero + Arithmetics + Clone,
Swp: WhitePoint<T>,
Dwp: WhitePoint<T>,
D: AdaptFrom<S, Swp, Dwp, T>,
impl<S, D, Swp, Dwp, T> AdaptInto<D, Swp, Dwp, T> for Swhere
T: Real + Zero + Arithmetics + Clone,
Swp: WhitePoint<T>,
Dwp: WhitePoint<T>,
D: AdaptFrom<S, Swp, Dwp, T>,
Source§fn adapt_into_using<M>(self, method: M) -> Dwhere
M: TransformMatrix<T>,
fn adapt_into_using<M>(self, method: M) -> Dwhere
M: TransformMatrix<T>,
Source§fn adapt_into(self) -> D
fn adapt_into(self) -> D
Source§impl<T, C> ArraysFrom<C> for Twhere
C: IntoArrays<T>,
impl<T, C> ArraysFrom<C> for Twhere
C: IntoArrays<T>,
Source§fn arrays_from(colors: C) -> T
fn arrays_from(colors: C) -> T
Source§impl<T, C> ArraysInto<C> for Twhere
C: FromArrays<T>,
impl<T, C> ArraysInto<C> for Twhere
C: FromArrays<T>,
Source§fn arrays_into(self) -> C
fn arrays_into(self) -> C
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<WpParam, T, U> Cam16IntoUnclamped<WpParam, T> for Uwhere
T: FromCam16Unclamped<WpParam, U>,
impl<WpParam, T, U> Cam16IntoUnclamped<WpParam, T> for Uwhere
T: FromCam16Unclamped<WpParam, U>,
Source§type Scalar = <T as FromCam16Unclamped<WpParam, U>>::Scalar
type Scalar = <T as FromCam16Unclamped<WpParam, U>>::Scalar
parameters
when converting.Source§fn cam16_into_unclamped(
self,
parameters: BakedParameters<WpParam, <U as Cam16IntoUnclamped<WpParam, T>>::Scalar>,
) -> T
fn cam16_into_unclamped( self, parameters: BakedParameters<WpParam, <U as Cam16IntoUnclamped<WpParam, T>>::Scalar>, ) -> T
self
into C
, using the provided parameters.Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T, C> ComponentsFrom<C> for Twhere
C: IntoComponents<T>,
impl<T, C> ComponentsFrom<C> for Twhere
C: IntoComponents<T>,
Source§fn components_from(colors: C) -> T
fn components_from(colors: C) -> T
Source§impl<T> FromAngle<T> for T
impl<T> FromAngle<T> for T
Source§fn from_angle(angle: T) -> T
fn from_angle(angle: T) -> T
angle
.Source§impl<T, U> FromStimulus<U> for Twhere
U: IntoStimulus<T>,
impl<T, U> FromStimulus<U> for Twhere
U: IntoStimulus<T>,
Source§fn from_stimulus(other: U) -> T
fn from_stimulus(other: U) -> T
other
into Self
, while performing the appropriate scaling,
rounding and clamping.Source§impl<T, U> IntoAngle<U> for Twhere
U: FromAngle<T>,
impl<T, U> IntoAngle<U> for Twhere
U: FromAngle<T>,
Source§fn into_angle(self) -> U
fn into_angle(self) -> U
T
.Source§impl<WpParam, T, U> IntoCam16Unclamped<WpParam, T> for Uwhere
T: Cam16FromUnclamped<WpParam, U>,
impl<WpParam, T, U> IntoCam16Unclamped<WpParam, T> for Uwhere
T: Cam16FromUnclamped<WpParam, U>,
Source§type Scalar = <T as Cam16FromUnclamped<WpParam, U>>::Scalar
type Scalar = <T as Cam16FromUnclamped<WpParam, U>>::Scalar
parameters
when converting.Source§fn into_cam16_unclamped(
self,
parameters: BakedParameters<WpParam, <U as IntoCam16Unclamped<WpParam, T>>::Scalar>,
) -> T
fn into_cam16_unclamped( self, parameters: BakedParameters<WpParam, <U as IntoCam16Unclamped<WpParam, T>>::Scalar>, ) -> T
self
into C
, using the provided parameters.Source§impl<T, U> IntoColor<U> for Twhere
U: FromColor<T>,
impl<T, U> IntoColor<U> for Twhere
U: FromColor<T>,
Source§fn into_color(self) -> U
fn into_color(self) -> U
Source§impl<T, U> IntoColorUnclamped<U> for Twhere
U: FromColorUnclamped<T>,
impl<T, U> IntoColorUnclamped<U> for Twhere
U: FromColorUnclamped<T>,
Source§fn into_color_unclamped(self) -> U
fn into_color_unclamped(self) -> U
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
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 moreSource§impl<T> IntoStimulus<T> for T
impl<T> IntoStimulus<T> for T
Source§fn into_stimulus(self) -> T
fn into_stimulus(self) -> T
self
into T
, while performing the appropriate scaling,
rounding and clamping.Source§impl<'a, T, U> Stylize<'a, T> for Uwhere
U: Styled<Item = T>,
impl<'a, T, U> Stylize<'a, T> for Uwhere
U: Styled<Item = T>,
fn bg<C>(self, color: C) -> T
fn fg<C>(self, color: C) -> T
fn add_modifier(self, modifier: Modifier) -> T
fn remove_modifier(self, modifier: Modifier) -> T
fn reset(self) -> T
Source§fn on_magenta(self) -> T
fn on_magenta(self) -> T
magenta
.Source§fn on_dark_gray(self) -> T
fn on_dark_gray(self) -> T
dark_gray
.Source§fn on_light_red(self) -> T
fn on_light_red(self) -> T
light_red
.Source§fn light_green(self) -> T
fn light_green(self) -> T
light_green
.Source§fn on_light_green(self) -> T
fn on_light_green(self) -> T
light_green
.Source§fn light_yellow(self) -> T
fn light_yellow(self) -> T
light_yellow
.Source§fn on_light_yellow(self) -> T
fn on_light_yellow(self) -> T
light_yellow
.Source§fn light_blue(self) -> T
fn light_blue(self) -> T
light_blue
.Source§fn on_light_blue(self) -> T
fn on_light_blue(self) -> T
light_blue
.Source§fn light_magenta(self) -> T
fn light_magenta(self) -> T
light_magenta
.Source§fn on_light_magenta(self) -> T
fn on_light_magenta(self) -> T
light_magenta
.Source§fn light_cyan(self) -> T
fn light_cyan(self) -> T
light_cyan
.Source§fn on_light_cyan(self) -> T
fn on_light_cyan(self) -> T
light_cyan
.Source§fn not_italic(self) -> T
fn not_italic(self) -> T
ITALIC
modifier.Source§fn underlined(self) -> T
fn underlined(self) -> T
UNDERLINED
modifier.Source§fn not_underlined(self) -> T
fn not_underlined(self) -> T
UNDERLINED
modifier.Source§fn slow_blink(self) -> T
fn slow_blink(self) -> T
SLOW_BLINK
modifier.Source§fn not_slow_blink(self) -> T
fn not_slow_blink(self) -> T
SLOW_BLINK
modifier.Source§fn rapid_blink(self) -> T
fn rapid_blink(self) -> T
RAPID_BLINK
modifier.Source§fn not_rapid_blink(self) -> T
fn not_rapid_blink(self) -> T
RAPID_BLINK
modifier.Source§fn not_reversed(self) -> T
fn not_reversed(self) -> T
REVERSED
modifier.HIDDEN
modifier.HIDDEN
modifier.Source§fn crossed_out(self) -> T
fn crossed_out(self) -> T
CROSSED_OUT
modifier.Source§fn not_crossed_out(self) -> T
fn not_crossed_out(self) -> T
CROSSED_OUT
modifier.Source§impl<T, C> TryComponentsInto<C> for Twhere
C: TryFromComponents<T>,
impl<T, C> TryComponentsInto<C> for Twhere
C: TryFromComponents<T>,
Source§type Error = <C as TryFromComponents<T>>::Error
type Error = <C as TryFromComponents<T>>::Error
try_into_colors
fails to cast.Source§fn try_components_into(self) -> Result<C, <T as TryComponentsInto<C>>::Error>
fn try_components_into(self) -> Result<C, <T as TryComponentsInto<C>>::Error>
Source§impl<T, U> TryIntoColor<U> for Twhere
U: TryFromColor<T>,
impl<T, U> TryIntoColor<U> for Twhere
U: TryFromColor<T>,
Source§fn try_into_color(self) -> Result<U, OutOfBounds<U>>
fn try_into_color(self) -> Result<U, OutOfBounds<U>>
OutOfBounds
error is returned which contains
the unclamped color. Read more