ratatui/examples/chart.rs

378 lines
11 KiB
Rust
Raw Normal View History

//! # [Ratatui] Chart example
//!
//! The latest version of this example is available in the [examples] folder in the repository.
//!
//! Please note that the examples are designed to be run against the `main` branch of the Github
//! repository. This means that you may not be able to compile with the latest release version on
//! crates.io, or the one that you have installed locally.
//!
//! See the [examples readme] for more information on finding examples that match the version of the
//! library you are using.
//!
//! [Ratatui]: https://github.com/ratatui/ratatui
//! [examples]: https://github.com/ratatui/ratatui/blob/main/examples
//! [examples readme]: https://github.com/ratatui/ratatui/blob/main/examples/README.md
feat(terminal): Add ratatui::init() and restore() methods (#1289) These are simple opinionated methods for creating a terminal that is useful to use in most apps. The new init method creates a crossterm backend writing to stdout, enables raw mode, enters the alternate screen, and sets a panic handler that restores the terminal on panic. A minimal hello world now looks a bit like: ```rust use ratatui::{ crossterm::event::{self, Event}, text::Text, Frame, }; fn main() { let mut terminal = ratatui::init(); loop { terminal .draw(|frame: &mut Frame| frame.render_widget(Text::raw("Hello World!"), frame.area())) .expect("Failed to draw"); if matches!(event::read().expect("failed to read event"), Event::Key(_)) { break; } } ratatui::restore(); } ``` A type alias `DefaultTerminal` is added to represent this terminal type and to simplify any cases where applications need to pass this terminal around. It is equivalent to: `Terminal<CrosstermBackend<Stdout>>` We also added `ratatui::try_init()` and `try_restore()`, for situations where you might want to handle initialization errors yourself instead of letting the panic handler fire and cleanup. Simple Apps should prefer the `init` and `restore` functions over these functions. Corresponding functions to allow passing a `TerminalOptions` with a `Viewport` (e.g. inline, fixed) are also available (`init_with_options`, and `try_init_with_options`). The existing code to create a backend and terminal will remain and is not deprecated by this approach. This just provides a simple one line initialization using the common options. --------- Co-authored-by: Orhun Parmaksız <orhunparmaksiz@gmail.com>
2024-08-22 12:16:35 +00:00
use std::time::{Duration, Instant};
feat(terminal): Add ratatui::init() and restore() methods (#1289) These are simple opinionated methods for creating a terminal that is useful to use in most apps. The new init method creates a crossterm backend writing to stdout, enables raw mode, enters the alternate screen, and sets a panic handler that restores the terminal on panic. A minimal hello world now looks a bit like: ```rust use ratatui::{ crossterm::event::{self, Event}, text::Text, Frame, }; fn main() { let mut terminal = ratatui::init(); loop { terminal .draw(|frame: &mut Frame| frame.render_widget(Text::raw("Hello World!"), frame.area())) .expect("Failed to draw"); if matches!(event::read().expect("failed to read event"), Event::Key(_)) { break; } } ratatui::restore(); } ``` A type alias `DefaultTerminal` is added to represent this terminal type and to simplify any cases where applications need to pass this terminal around. It is equivalent to: `Terminal<CrosstermBackend<Stdout>>` We also added `ratatui::try_init()` and `try_restore()`, for situations where you might want to handle initialization errors yourself instead of letting the panic handler fire and cleanup. Simple Apps should prefer the `init` and `restore` functions over these functions. Corresponding functions to allow passing a `TerminalOptions` with a `Viewport` (e.g. inline, fixed) are also available (`init_with_options`, and `try_init_with_options`). The existing code to create a backend and terminal will remain and is not deprecated by this approach. This just provides a simple one line initialization using the common options. --------- Co-authored-by: Orhun Parmaksız <orhunparmaksiz@gmail.com>
2024-08-22 12:16:35 +00:00
use color_eyre::Result;
use ratatui::{
feat(terminal): Add ratatui::init() and restore() methods (#1289) These are simple opinionated methods for creating a terminal that is useful to use in most apps. The new init method creates a crossterm backend writing to stdout, enables raw mode, enters the alternate screen, and sets a panic handler that restores the terminal on panic. A minimal hello world now looks a bit like: ```rust use ratatui::{ crossterm::event::{self, Event}, text::Text, Frame, }; fn main() { let mut terminal = ratatui::init(); loop { terminal .draw(|frame: &mut Frame| frame.render_widget(Text::raw("Hello World!"), frame.area())) .expect("Failed to draw"); if matches!(event::read().expect("failed to read event"), Event::Key(_)) { break; } } ratatui::restore(); } ``` A type alias `DefaultTerminal` is added to represent this terminal type and to simplify any cases where applications need to pass this terminal around. It is equivalent to: `Terminal<CrosstermBackend<Stdout>>` We also added `ratatui::try_init()` and `try_restore()`, for situations where you might want to handle initialization errors yourself instead of letting the panic handler fire and cleanup. Simple Apps should prefer the `init` and `restore` functions over these functions. Corresponding functions to allow passing a `TerminalOptions` with a `Viewport` (e.g. inline, fixed) are also available (`init_with_options`, and `try_init_with_options`). The existing code to create a backend and terminal will remain and is not deprecated by this approach. This just provides a simple one line initialization using the common options. --------- Co-authored-by: Orhun Parmaksız <orhunparmaksiz@gmail.com>
2024-08-22 12:16:35 +00:00
crossterm::event::{self, Event, KeyCode},
layout::{Alignment, Constraint, Layout, Rect},
style::{Color, Modifier, Style, Stylize},
symbols::{self, Marker},
text::Span,
widgets::{block::Title, Axis, Block, Chart, Dataset, GraphType, LegendPosition},
feat(terminal): Add ratatui::init() and restore() methods (#1289) These are simple opinionated methods for creating a terminal that is useful to use in most apps. The new init method creates a crossterm backend writing to stdout, enables raw mode, enters the alternate screen, and sets a panic handler that restores the terminal on panic. A minimal hello world now looks a bit like: ```rust use ratatui::{ crossterm::event::{self, Event}, text::Text, Frame, }; fn main() { let mut terminal = ratatui::init(); loop { terminal .draw(|frame: &mut Frame| frame.render_widget(Text::raw("Hello World!"), frame.area())) .expect("Failed to draw"); if matches!(event::read().expect("failed to read event"), Event::Key(_)) { break; } } ratatui::restore(); } ``` A type alias `DefaultTerminal` is added to represent this terminal type and to simplify any cases where applications need to pass this terminal around. It is equivalent to: `Terminal<CrosstermBackend<Stdout>>` We also added `ratatui::try_init()` and `try_restore()`, for situations where you might want to handle initialization errors yourself instead of letting the panic handler fire and cleanup. Simple Apps should prefer the `init` and `restore` functions over these functions. Corresponding functions to allow passing a `TerminalOptions` with a `Viewport` (e.g. inline, fixed) are also available (`init_with_options`, and `try_init_with_options`). The existing code to create a backend and terminal will remain and is not deprecated by this approach. This just provides a simple one line initialization using the common options. --------- Co-authored-by: Orhun Parmaksız <orhunparmaksiz@gmail.com>
2024-08-22 12:16:35 +00:00
DefaultTerminal, Frame,
};
feat(terminal): Add ratatui::init() and restore() methods (#1289) These are simple opinionated methods for creating a terminal that is useful to use in most apps. The new init method creates a crossterm backend writing to stdout, enables raw mode, enters the alternate screen, and sets a panic handler that restores the terminal on panic. A minimal hello world now looks a bit like: ```rust use ratatui::{ crossterm::event::{self, Event}, text::Text, Frame, }; fn main() { let mut terminal = ratatui::init(); loop { terminal .draw(|frame: &mut Frame| frame.render_widget(Text::raw("Hello World!"), frame.area())) .expect("Failed to draw"); if matches!(event::read().expect("failed to read event"), Event::Key(_)) { break; } } ratatui::restore(); } ``` A type alias `DefaultTerminal` is added to represent this terminal type and to simplify any cases where applications need to pass this terminal around. It is equivalent to: `Terminal<CrosstermBackend<Stdout>>` We also added `ratatui::try_init()` and `try_restore()`, for situations where you might want to handle initialization errors yourself instead of letting the panic handler fire and cleanup. Simple Apps should prefer the `init` and `restore` functions over these functions. Corresponding functions to allow passing a `TerminalOptions` with a `Viewport` (e.g. inline, fixed) are also available (`init_with_options`, and `try_init_with_options`). The existing code to create a backend and terminal will remain and is not deprecated by this approach. This just provides a simple one line initialization using the common options. --------- Co-authored-by: Orhun Parmaksız <orhunparmaksiz@gmail.com>
2024-08-22 12:16:35 +00:00
fn main() -> Result<()> {
color_eyre::install()?;
let terminal = ratatui::init();
let app_result = App::new().run(terminal);
ratatui::restore();
app_result
}
struct App {
signal1: SinSignal,
data1: Vec<(f64, f64)>,
signal2: SinSignal,
data2: Vec<(f64, f64)>,
window: [f64; 2],
}
2021-11-11 14:56:37 +00:00
#[derive(Clone)]
struct SinSignal {
2021-11-11 14:56:37 +00:00
x: f64,
interval: f64,
period: f64,
scale: f64,
}
impl SinSignal {
const fn new(interval: f64, period: f64, scale: f64) -> Self {
Self {
2021-11-11 14:56:37 +00:00
x: 0.0,
interval,
period,
scale,
}
}
}
impl Iterator for SinSignal {
type Item = (f64, f64);
fn next(&mut self) -> Option<Self::Item> {
let point = (self.x, (self.x * 1.0 / self.period).sin() * self.scale);
self.x += self.interval;
Some(point)
}
}
2016-11-07 23:35:46 +00:00
impl App {
fn new() -> Self {
2016-11-07 23:35:46 +00:00
let mut signal1 = SinSignal::new(0.2, 3.0, 18.0);
let mut signal2 = SinSignal::new(0.1, 2.0, 10.0);
let data1 = signal1.by_ref().take(200).collect::<Vec<(f64, f64)>>();
let data2 = signal2.by_ref().take(200).collect::<Vec<(f64, f64)>>();
Self {
2018-08-12 22:27:56 +00:00
signal1,
data1,
signal2,
data2,
2016-11-07 23:35:46 +00:00
window: [0.0, 20.0],
}
}
feat(terminal): Add ratatui::init() and restore() methods (#1289) These are simple opinionated methods for creating a terminal that is useful to use in most apps. The new init method creates a crossterm backend writing to stdout, enables raw mode, enters the alternate screen, and sets a panic handler that restores the terminal on panic. A minimal hello world now looks a bit like: ```rust use ratatui::{ crossterm::event::{self, Event}, text::Text, Frame, }; fn main() { let mut terminal = ratatui::init(); loop { terminal .draw(|frame: &mut Frame| frame.render_widget(Text::raw("Hello World!"), frame.area())) .expect("Failed to draw"); if matches!(event::read().expect("failed to read event"), Event::Key(_)) { break; } } ratatui::restore(); } ``` A type alias `DefaultTerminal` is added to represent this terminal type and to simplify any cases where applications need to pass this terminal around. It is equivalent to: `Terminal<CrosstermBackend<Stdout>>` We also added `ratatui::try_init()` and `try_restore()`, for situations where you might want to handle initialization errors yourself instead of letting the panic handler fire and cleanup. Simple Apps should prefer the `init` and `restore` functions over these functions. Corresponding functions to allow passing a `TerminalOptions` with a `Viewport` (e.g. inline, fixed) are also available (`init_with_options`, and `try_init_with_options`). The existing code to create a backend and terminal will remain and is not deprecated by this approach. This just provides a simple one line initialization using the common options. --------- Co-authored-by: Orhun Parmaksız <orhunparmaksiz@gmail.com>
2024-08-22 12:16:35 +00:00
fn run(mut self, mut terminal: DefaultTerminal) -> Result<()> {
let tick_rate = Duration::from_millis(250);
let mut last_tick = Instant::now();
loop {
terminal.draw(|frame| self.draw(frame))?;
let timeout = tick_rate.saturating_sub(last_tick.elapsed());
if event::poll(timeout)? {
if let Event::Key(key) = event::read()? {
if key.code == KeyCode::Char('q') {
return Ok(());
}
}
}
if last_tick.elapsed() >= tick_rate {
self.on_tick();
last_tick = Instant::now();
}
}
}
fn on_tick(&mut self) {
self.data1.drain(0..5);
2016-11-07 23:35:46 +00:00
self.data1.extend(self.signal1.by_ref().take(5));
self.data2.drain(0..10);
2016-11-07 23:35:46 +00:00
self.data2.extend(self.signal2.by_ref().take(10));
2016-11-07 23:35:46 +00:00
self.window[0] += 1.0;
self.window[1] += 1.0;
}
feat(terminal): Add ratatui::init() and restore() methods (#1289) These are simple opinionated methods for creating a terminal that is useful to use in most apps. The new init method creates a crossterm backend writing to stdout, enables raw mode, enters the alternate screen, and sets a panic handler that restores the terminal on panic. A minimal hello world now looks a bit like: ```rust use ratatui::{ crossterm::event::{self, Event}, text::Text, Frame, }; fn main() { let mut terminal = ratatui::init(); loop { terminal .draw(|frame: &mut Frame| frame.render_widget(Text::raw("Hello World!"), frame.area())) .expect("Failed to draw"); if matches!(event::read().expect("failed to read event"), Event::Key(_)) { break; } } ratatui::restore(); } ``` A type alias `DefaultTerminal` is added to represent this terminal type and to simplify any cases where applications need to pass this terminal around. It is equivalent to: `Terminal<CrosstermBackend<Stdout>>` We also added `ratatui::try_init()` and `try_restore()`, for situations where you might want to handle initialization errors yourself instead of letting the panic handler fire and cleanup. Simple Apps should prefer the `init` and `restore` functions over these functions. Corresponding functions to allow passing a `TerminalOptions` with a `Viewport` (e.g. inline, fixed) are also available (`init_with_options`, and `try_init_with_options`). The existing code to create a backend and terminal will remain and is not deprecated by this approach. This just provides a simple one line initialization using the common options. --------- Co-authored-by: Orhun Parmaksız <orhunparmaksiz@gmail.com>
2024-08-22 12:16:35 +00:00
fn draw(&self, frame: &mut Frame) {
let [top, bottom] = Layout::vertical([Constraint::Fill(1); 2]).areas(frame.area());
let [animated_chart, bar_chart] =
Layout::horizontal([Constraint::Fill(1), Constraint::Length(29)]).areas(top);
let [line_chart, scatter] = Layout::horizontal([Constraint::Fill(1); 2]).areas(bottom);
feat(terminal): Add ratatui::init() and restore() methods (#1289) These are simple opinionated methods for creating a terminal that is useful to use in most apps. The new init method creates a crossterm backend writing to stdout, enables raw mode, enters the alternate screen, and sets a panic handler that restores the terminal on panic. A minimal hello world now looks a bit like: ```rust use ratatui::{ crossterm::event::{self, Event}, text::Text, Frame, }; fn main() { let mut terminal = ratatui::init(); loop { terminal .draw(|frame: &mut Frame| frame.render_widget(Text::raw("Hello World!"), frame.area())) .expect("Failed to draw"); if matches!(event::read().expect("failed to read event"), Event::Key(_)) { break; } } ratatui::restore(); } ``` A type alias `DefaultTerminal` is added to represent this terminal type and to simplify any cases where applications need to pass this terminal around. It is equivalent to: `Terminal<CrosstermBackend<Stdout>>` We also added `ratatui::try_init()` and `try_restore()`, for situations where you might want to handle initialization errors yourself instead of letting the panic handler fire and cleanup. Simple Apps should prefer the `init` and `restore` functions over these functions. Corresponding functions to allow passing a `TerminalOptions` with a `Viewport` (e.g. inline, fixed) are also available (`init_with_options`, and `try_init_with_options`). The existing code to create a backend and terminal will remain and is not deprecated by this approach. This just provides a simple one line initialization using the common options. --------- Co-authored-by: Orhun Parmaksız <orhunparmaksiz@gmail.com>
2024-08-22 12:16:35 +00:00
self.render_animated_chart(frame, animated_chart);
render_barchart(frame, bar_chart);
render_line_chart(frame, line_chart);
render_scatter(frame, scatter);
}
2016-11-07 23:35:46 +00:00
feat(terminal): Add ratatui::init() and restore() methods (#1289) These are simple opinionated methods for creating a terminal that is useful to use in most apps. The new init method creates a crossterm backend writing to stdout, enables raw mode, enters the alternate screen, and sets a panic handler that restores the terminal on panic. A minimal hello world now looks a bit like: ```rust use ratatui::{ crossterm::event::{self, Event}, text::Text, Frame, }; fn main() { let mut terminal = ratatui::init(); loop { terminal .draw(|frame: &mut Frame| frame.render_widget(Text::raw("Hello World!"), frame.area())) .expect("Failed to draw"); if matches!(event::read().expect("failed to read event"), Event::Key(_)) { break; } } ratatui::restore(); } ``` A type alias `DefaultTerminal` is added to represent this terminal type and to simplify any cases where applications need to pass this terminal around. It is equivalent to: `Terminal<CrosstermBackend<Stdout>>` We also added `ratatui::try_init()` and `try_restore()`, for situations where you might want to handle initialization errors yourself instead of letting the panic handler fire and cleanup. Simple Apps should prefer the `init` and `restore` functions over these functions. Corresponding functions to allow passing a `TerminalOptions` with a `Viewport` (e.g. inline, fixed) are also available (`init_with_options`, and `try_init_with_options`). The existing code to create a backend and terminal will remain and is not deprecated by this approach. This just provides a simple one line initialization using the common options. --------- Co-authored-by: Orhun Parmaksız <orhunparmaksiz@gmail.com>
2024-08-22 12:16:35 +00:00
fn render_animated_chart(&self, frame: &mut Frame, area: Rect) {
let x_labels = vec![
Span::styled(
format!("{}", self.window[0]),
Style::default().add_modifier(Modifier::BOLD),
),
Span::raw(format!("{}", (self.window[0] + self.window[1]) / 2.0)),
Span::styled(
format!("{}", self.window[1]),
Style::default().add_modifier(Modifier::BOLD),
),
];
let datasets = vec![
Dataset::default()
.name("data2")
.marker(symbols::Marker::Dot)
.style(Style::default().fg(Color::Cyan))
.data(&self.data1),
Dataset::default()
.name("data3")
.marker(symbols::Marker::Braille)
.style(Style::default().fg(Color::Yellow))
.data(&self.data2),
];
let chart = Chart::new(datasets)
.block(Block::bordered())
.x_axis(
Axis::default()
.title("X Axis")
.style(Style::default().fg(Color::Gray))
.labels(x_labels)
.bounds(self.window),
)
.y_axis(
Axis::default()
.title("Y Axis")
.style(Style::default().fg(Color::Gray))
.labels(["-20".bold(), "0".into(), "20".bold()])
.bounds([-20.0, 20.0]),
);
frame.render_widget(chart, area);
2016-11-07 23:35:46 +00:00
}
}
2016-11-07 23:35:46 +00:00
fn render_barchart(frame: &mut Frame, bar_chart: Rect) {
let dataset = Dataset::default()
.marker(symbols::Marker::HalfBlock)
.style(Style::new().fg(Color::Blue))
.graph_type(GraphType::Bar)
// a bell curve
.data(&[
(0., 0.4),
(10., 2.9),
(20., 13.5),
(30., 41.1),
(40., 80.1),
(50., 100.0),
(60., 80.1),
(70., 41.1),
(80., 13.5),
(90., 2.9),
(100., 0.4),
]);
let chart = Chart::new(vec![dataset])
.block(
Block::bordered().title(
Title::default()
.content("Bar chart".cyan().bold())
.alignment(Alignment::Center),
),
)
.x_axis(
Axis::default()
.style(Style::default().gray())
.bounds([0.0, 100.0])
.labels(["0".bold(), "50".into(), "100.0".bold()]),
)
.y_axis(
Axis::default()
.style(Style::default().gray())
.bounds([0.0, 100.0])
.labels(["0".bold(), "50".into(), "100.0".bold()]),
)
.hidden_legend_constraints((Constraint::Ratio(1, 2), Constraint::Ratio(1, 2)));
frame.render_widget(chart, bar_chart);
}
feat(terminal): Add ratatui::init() and restore() methods (#1289) These are simple opinionated methods for creating a terminal that is useful to use in most apps. The new init method creates a crossterm backend writing to stdout, enables raw mode, enters the alternate screen, and sets a panic handler that restores the terminal on panic. A minimal hello world now looks a bit like: ```rust use ratatui::{ crossterm::event::{self, Event}, text::Text, Frame, }; fn main() { let mut terminal = ratatui::init(); loop { terminal .draw(|frame: &mut Frame| frame.render_widget(Text::raw("Hello World!"), frame.area())) .expect("Failed to draw"); if matches!(event::read().expect("failed to read event"), Event::Key(_)) { break; } } ratatui::restore(); } ``` A type alias `DefaultTerminal` is added to represent this terminal type and to simplify any cases where applications need to pass this terminal around. It is equivalent to: `Terminal<CrosstermBackend<Stdout>>` We also added `ratatui::try_init()` and `try_restore()`, for situations where you might want to handle initialization errors yourself instead of letting the panic handler fire and cleanup. Simple Apps should prefer the `init` and `restore` functions over these functions. Corresponding functions to allow passing a `TerminalOptions` with a `Viewport` (e.g. inline, fixed) are also available (`init_with_options`, and `try_init_with_options`). The existing code to create a backend and terminal will remain and is not deprecated by this approach. This just provides a simple one line initialization using the common options. --------- Co-authored-by: Orhun Parmaksız <orhunparmaksiz@gmail.com>
2024-08-22 12:16:35 +00:00
fn render_line_chart(frame: &mut Frame, area: Rect) {
let datasets = vec![Dataset::default()
.name("Line from only 2 points".italic())
.marker(symbols::Marker::Braille)
.style(Style::default().fg(Color::Yellow))
.graph_type(GraphType::Line)
.data(&[(1., 1.), (4., 4.)])];
let chart = Chart::new(datasets)
.block(
Block::bordered().title(
Title::default()
.content("Line chart".cyan().bold())
.alignment(Alignment::Center),
),
)
.x_axis(
Axis::default()
.title("X Axis")
.style(Style::default().gray())
.bounds([0.0, 5.0])
.labels(["0".bold(), "2.5".into(), "5.0".bold()]),
)
.y_axis(
Axis::default()
.title("Y Axis")
.style(Style::default().gray())
.bounds([0.0, 5.0])
.labels(["0".bold(), "2.5".into(), "5.0".bold()]),
)
.legend_position(Some(LegendPosition::TopLeft))
.hidden_legend_constraints((Constraint::Ratio(1, 2), Constraint::Ratio(1, 2)));
feat(terminal): Add ratatui::init() and restore() methods (#1289) These are simple opinionated methods for creating a terminal that is useful to use in most apps. The new init method creates a crossterm backend writing to stdout, enables raw mode, enters the alternate screen, and sets a panic handler that restores the terminal on panic. A minimal hello world now looks a bit like: ```rust use ratatui::{ crossterm::event::{self, Event}, text::Text, Frame, }; fn main() { let mut terminal = ratatui::init(); loop { terminal .draw(|frame: &mut Frame| frame.render_widget(Text::raw("Hello World!"), frame.area())) .expect("Failed to draw"); if matches!(event::read().expect("failed to read event"), Event::Key(_)) { break; } } ratatui::restore(); } ``` A type alias `DefaultTerminal` is added to represent this terminal type and to simplify any cases where applications need to pass this terminal around. It is equivalent to: `Terminal<CrosstermBackend<Stdout>>` We also added `ratatui::try_init()` and `try_restore()`, for situations where you might want to handle initialization errors yourself instead of letting the panic handler fire and cleanup. Simple Apps should prefer the `init` and `restore` functions over these functions. Corresponding functions to allow passing a `TerminalOptions` with a `Viewport` (e.g. inline, fixed) are also available (`init_with_options`, and `try_init_with_options`). The existing code to create a backend and terminal will remain and is not deprecated by this approach. This just provides a simple one line initialization using the common options. --------- Co-authored-by: Orhun Parmaksız <orhunparmaksiz@gmail.com>
2024-08-22 12:16:35 +00:00
frame.render_widget(chart, area);
}
feat(terminal): Add ratatui::init() and restore() methods (#1289) These are simple opinionated methods for creating a terminal that is useful to use in most apps. The new init method creates a crossterm backend writing to stdout, enables raw mode, enters the alternate screen, and sets a panic handler that restores the terminal on panic. A minimal hello world now looks a bit like: ```rust use ratatui::{ crossterm::event::{self, Event}, text::Text, Frame, }; fn main() { let mut terminal = ratatui::init(); loop { terminal .draw(|frame: &mut Frame| frame.render_widget(Text::raw("Hello World!"), frame.area())) .expect("Failed to draw"); if matches!(event::read().expect("failed to read event"), Event::Key(_)) { break; } } ratatui::restore(); } ``` A type alias `DefaultTerminal` is added to represent this terminal type and to simplify any cases where applications need to pass this terminal around. It is equivalent to: `Terminal<CrosstermBackend<Stdout>>` We also added `ratatui::try_init()` and `try_restore()`, for situations where you might want to handle initialization errors yourself instead of letting the panic handler fire and cleanup. Simple Apps should prefer the `init` and `restore` functions over these functions. Corresponding functions to allow passing a `TerminalOptions` with a `Viewport` (e.g. inline, fixed) are also available (`init_with_options`, and `try_init_with_options`). The existing code to create a backend and terminal will remain and is not deprecated by this approach. This just provides a simple one line initialization using the common options. --------- Co-authored-by: Orhun Parmaksız <orhunparmaksiz@gmail.com>
2024-08-22 12:16:35 +00:00
fn render_scatter(frame: &mut Frame, area: Rect) {
let datasets = vec![
Dataset::default()
.name("Heavy")
.marker(Marker::Dot)
.graph_type(GraphType::Scatter)
.style(Style::new().yellow())
.data(&HEAVY_PAYLOAD_DATA),
Dataset::default()
.name("Medium".underlined())
.marker(Marker::Braille)
.graph_type(GraphType::Scatter)
.style(Style::new().magenta())
.data(&MEDIUM_PAYLOAD_DATA),
Dataset::default()
.name("Small")
.marker(Marker::Dot)
.graph_type(GraphType::Scatter)
.style(Style::new().cyan())
.data(&SMALL_PAYLOAD_DATA),
];
let chart = Chart::new(datasets)
.block(
Block::bordered().title(
Title::default()
.content("Scatter chart".cyan().bold())
.alignment(Alignment::Center),
),
)
.x_axis(
Axis::default()
.title("Year")
.bounds([1960., 2020.])
.style(Style::default().fg(Color::Gray))
.labels(["1960", "1990", "2020"]),
)
.y_axis(
Axis::default()
.title("Cost")
.bounds([0., 75000.])
.style(Style::default().fg(Color::Gray))
.labels(["0", "37 500", "75 000"]),
)
.hidden_legend_constraints((Constraint::Ratio(1, 2), Constraint::Ratio(1, 2)));
feat(terminal): Add ratatui::init() and restore() methods (#1289) These are simple opinionated methods for creating a terminal that is useful to use in most apps. The new init method creates a crossterm backend writing to stdout, enables raw mode, enters the alternate screen, and sets a panic handler that restores the terminal on panic. A minimal hello world now looks a bit like: ```rust use ratatui::{ crossterm::event::{self, Event}, text::Text, Frame, }; fn main() { let mut terminal = ratatui::init(); loop { terminal .draw(|frame: &mut Frame| frame.render_widget(Text::raw("Hello World!"), frame.area())) .expect("Failed to draw"); if matches!(event::read().expect("failed to read event"), Event::Key(_)) { break; } } ratatui::restore(); } ``` A type alias `DefaultTerminal` is added to represent this terminal type and to simplify any cases where applications need to pass this terminal around. It is equivalent to: `Terminal<CrosstermBackend<Stdout>>` We also added `ratatui::try_init()` and `try_restore()`, for situations where you might want to handle initialization errors yourself instead of letting the panic handler fire and cleanup. Simple Apps should prefer the `init` and `restore` functions over these functions. Corresponding functions to allow passing a `TerminalOptions` with a `Viewport` (e.g. inline, fixed) are also available (`init_with_options`, and `try_init_with_options`). The existing code to create a backend and terminal will remain and is not deprecated by this approach. This just provides a simple one line initialization using the common options. --------- Co-authored-by: Orhun Parmaksız <orhunparmaksiz@gmail.com>
2024-08-22 12:16:35 +00:00
frame.render_widget(chart, area);
2016-11-07 23:35:46 +00:00
}
// Data from https://ourworldindata.org/space-exploration-satellites
const HEAVY_PAYLOAD_DATA: [(f64, f64); 9] = [
(1965., 8200.),
(1967., 5400.),
(1981., 65400.),
(1989., 30800.),
(1997., 10200.),
(2004., 11600.),
(2014., 4500.),
(2016., 7900.),
(2018., 1500.),
];
const MEDIUM_PAYLOAD_DATA: [(f64, f64); 29] = [
(1963., 29500.),
(1964., 30600.),
(1965., 177_900.),
(1965., 21000.),
(1966., 17900.),
(1966., 8400.),
(1975., 17500.),
(1982., 8300.),
(1985., 5100.),
(1988., 18300.),
(1990., 38800.),
(1990., 9900.),
(1991., 18700.),
(1992., 9100.),
(1994., 10500.),
(1994., 8500.),
(1994., 8700.),
(1997., 6200.),
(1999., 18000.),
(1999., 7600.),
(1999., 8900.),
(1999., 9600.),
(2000., 16000.),
(2001., 10000.),
(2002., 10400.),
(2002., 8100.),
(2010., 2600.),
(2013., 13600.),
(2017., 8000.),
];
const SMALL_PAYLOAD_DATA: [(f64, f64); 23] = [
(1961., 118_500.),
(1962., 14900.),
(1975., 21400.),
(1980., 32800.),
(1988., 31100.),
(1990., 41100.),
(1993., 23600.),
(1994., 20600.),
(1994., 34600.),
(1996., 50600.),
(1997., 19200.),
(1997., 45800.),
(1998., 19100.),
(2000., 73100.),
(2003., 11200.),
(2008., 12600.),
(2010., 30500.),
(2012., 20000.),
(2013., 10600.),
(2013., 34500.),
(2015., 10600.),
(2018., 23100.),
(2019., 17300.),
];