use ratatui::{
Frame,
layout::{Constraint, Direction, Layout, Rect},
style::{Color, Style},
symbols,
text::Span,
widgets::{Axis, Block, Borders, Chart, Dataset, GraphType},
};
use crate::app::App;
use crate::metrics::HISTORY_LEN;
use crate::ui::helpers::usage_color_f64;
use crate::ui::widgets::SplitGauge;
pub fn draw(frame: &mut Frame, app: &App, area: Rect) {
let chunks = Layout::default()
.direction(Direction::Vertical)
.constraints([Constraint::Percentage(50), Constraint::Percentage(50)])
.split(area);
let data: Vec<(f64, f64)> = app
.mem
.history
.iter()
.enumerate()
.map(|(i, &v)| (i as f64, v as f64))
.collect();
let datasets = vec![Dataset::default()
.name(app.t.mem_dataset_label.as_str())
.marker(symbols::Marker::Braille)
.graph_type(GraphType::Line)
.style(Style::default().fg(Color::Green))
.data(&data)];
let chart = Chart::new(datasets)
.block(
Block::default()
.title(Span::styled(
format!(" {} ", app.t.mem_history_title),
Style::default().fg(Color::Green),
))
.borders(Borders::ALL),
)
.x_axis(
Axis::default()
.bounds([0.0, HISTORY_LEN as f64])
.labels(vec![
Span::raw(app.t.ago_60s.as_str()),
Span::raw(app.t.ago_30s.as_str()),
Span::raw(app.t.now.as_str()),
]),
)
.y_axis(
Axis::default()
.bounds([0.0, 100.0])
.labels(vec![Span::raw("0%"), Span::raw("50%"), Span::raw("100%")]),
);
frame.render_widget(chart, chunks[0]);
let used_gb = app.mem.used as f64 / 1_073_741_824.0;
let total_gb = app.mem.total as f64 / 1_073_741_824.0;
let swap_used_gb = app.mem.swap_used as f64 / 1_073_741_824.0;
let swap_total_gb = app.mem.swap_total as f64 / 1_073_741_824.0;
let mem_pct = if app.mem.total > 0 {
app.mem.used as f64 / app.mem.total as f64
} else {
0.0
};
let swap_pct = if app.mem.swap_total > 0 {
app.mem.swap_used as f64 / app.mem.swap_total as f64
} else {
0.0
};
let gauge_chunks = Layout::default()
.direction(Direction::Vertical)
.constraints([Constraint::Length(3), Constraint::Length(3), Constraint::Min(0)])
.split(chunks[1]);
let mem_gauge = SplitGauge::new(
mem_pct,
usage_color_f64(mem_pct * 100.0),
format!("{:.0}%", mem_pct * 100.0),
)
.block(
Block::default()
.title(format!(" {} {used_gb:.1} / {total_gb:.1} GiB ", app.t.ram))
.borders(Borders::ALL),
);
let swap_gauge = SplitGauge::new(
swap_pct,
Color::Magenta,
format!("{:.0}%", swap_pct * 100.0),
)
.block(
Block::default()
.title(format!(" {} {swap_used_gb:.1} / {swap_total_gb:.1} GiB ", app.t.swap))
.borders(Borders::ALL),
);
frame.render_widget(mem_gauge, gauge_chunks[0]);
frame.render_widget(swap_gauge, gauge_chunks[1]);
}
pub fn draw_gauge(frame: &mut Frame, app: &App, area: Rect) {
let pct = if app.mem.total > 0 {
app.mem.used as f64 / app.mem.total as f64
} else {
0.0
};
let used_gb = app.mem.used as f64 / 1_073_741_824.0;
let total_gb = app.mem.total as f64 / 1_073_741_824.0;
let gauge = SplitGauge::new(
pct,
usage_color_f64(pct * 100.0),
format!("{:.0}%", pct * 100.0),
)
.block(
Block::default()
.title(format!(
" {} {:.1}/{:.1} GiB ({:.1}%) ",
app.t.ram,
used_gb,
total_gb,
pct * 100.0
))
.borders(Borders::ALL),
);
frame.render_widget(gauge, area);
}