summaryrefslogtreecommitdiffstats
path: root/src/canvas/widgets/mem_graph.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/canvas/widgets/mem_graph.rs')
-rw-r--r--src/canvas/widgets/mem_graph.rs258
1 files changed, 48 insertions, 210 deletions
diff --git a/src/canvas/widgets/mem_graph.rs b/src/canvas/widgets/mem_graph.rs
index efb1f341..e5d0fbcc 100644
--- a/src/canvas/widgets/mem_graph.rs
+++ b/src/canvas/widgets/mem_graph.rs
@@ -1,234 +1,72 @@
+use std::borrow::Cow;
+
use crate::{
app::App,
- canvas::{drawing_utils::interpolate_points, Painter},
- constants::*,
+ canvas::{
+ components::{GraphData, TimeGraph},
+ drawing_utils::should_hide_x_label,
+ Painter,
+ },
};
use tui::{
backend::Backend,
layout::{Constraint, Rect},
- symbols::Marker,
terminal::Frame,
- text::Span,
- text::Spans,
- widgets::{Axis, Block, Borders, Chart, Dataset},
};
-use unicode_segmentation::UnicodeSegmentation;
impl Painter {
pub fn draw_memory_graph<B: Backend>(
&self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect, widget_id: u64,
) {
- if let Some(mem_widget_state) = app_state.mem_state.widget_states.get_mut(&widget_id) {
- let mem_data: &mut [(f64, f64)] = &mut app_state.canvas_data.mem_data;
- let swap_data: &mut [(f64, f64)] = &mut app_state.canvas_data.swap_data;
-
- let time_start = -(mem_widget_state.current_display_time as f64);
-
- let display_time_labels = vec![
- Span::styled(
- format!("{}s", mem_widget_state.current_display_time / 1000),
- self.colours.graph_style,
- ),
- Span::styled("0s".to_string(), self.colours.graph_style),
- ];
- let y_axis_label = vec![
- Span::styled(" 0%", self.colours.graph_style),
- Span::styled("100%", self.colours.graph_style),
- ];
-
- let x_axis = if app_state.app_config_fields.hide_time
- || (app_state.app_config_fields.autohide_time
- && mem_widget_state.autohide_timer.is_none())
- {
- Axis::default().bounds([time_start, 0.0])
- } else if let Some(time) = mem_widget_state.autohide_timer {
- if std::time::Instant::now().duration_since(time).as_millis()
- < AUTOHIDE_TIMEOUT_MILLISECONDS.into()
- {
- Axis::default()
- .bounds([time_start, 0.0])
- .style(self.colours.graph_style)
- .labels(display_time_labels)
- } else {
- mem_widget_state.autohide_timer = None;
- Axis::default().bounds([time_start, 0.0])
- }
- } else if draw_loc.height < TIME_LABEL_HEIGHT_LIMIT {
- Axis::default().bounds([time_start, 0.0])
- } else {
- Axis::default()
- .bounds([time_start, 0.0])
- .style(self.colours.graph_style)
- .labels(display_time_labels)
- };
-
- let y_axis = Axis::default()
- .style(self.colours.graph_style)
- .bounds([0.0, 100.5])
- .labels(y_axis_label);
-
- // Interpolate values to avoid ugly gaps
- let interpolated_mem_point = if let Some(end_pos) = mem_data
- .iter()
- .position(|(time, _data)| *time >= time_start)
- {
- if end_pos > 1 {
- let start_pos = end_pos - 1;
- let outside_point = mem_data.get(start_pos);
- let inside_point = mem_data.get(end_pos);
+ const Y_BOUNDS: [f64; 2] = [0.0, 100.5];
+ const Y_LABELS: [Cow<'static, str>; 2] = [Cow::Borrowed(" 0%"), Cow::Borrowed("100%")];
- if let (Some(outside_point), Some(inside_point)) = (outside_point, inside_point)
- {
- let old = *outside_point;
-
- let new_point = (
- time_start,
- interpolate_points(outside_point, inside_point, time_start),
- );
-
- if let Some(to_replace) = mem_data.get_mut(start_pos) {
- *to_replace = new_point;
- Some((start_pos, old))
- } else {
- None // Failed to get mutable reference.
- }
- } else {
- None // Point somehow doesn't exist in our data
- }
- } else {
- None // Point is already "leftmost", no need to interpolate.
+ if let Some(mem_widget_state) = app_state.mem_state.widget_states.get_mut(&widget_id) {
+ let border_style = self.get_border_style(widget_id, app_state.current_widget.widget_id);
+ let x_bounds = [0, mem_widget_state.current_display_time];
+ let hide_x_labels = should_hide_x_label(
+ app_state.app_config_fields.hide_time,
+ app_state.app_config_fields.autohide_time,
+ &mut mem_widget_state.autohide_timer,
+ draw_loc,
+ );
+ let points = {
+ let mut points = Vec::with_capacity(2);
+ if let Some((label_percent, label_frac)) = &app_state.canvas_data.mem_labels {
+ let mem_label = format!("RAM:{}{}", label_percent, label_frac);
+ points.push(GraphData {
+ points: &app_state.canvas_data.mem_data,
+ style: self.colours.ram_style,
+ name: Some(mem_label.into()),
+ });
}
- } else {
- None // There is no point.
- };
-
- let interpolated_swap_point = if let Some(end_pos) = swap_data
- .iter()
- .position(|(time, _data)| *time >= time_start)
- {
- if end_pos > 1 {
- let start_pos = end_pos - 1;
- let outside_point = swap_data.get(start_pos);
- let inside_point = swap_data.get(end_pos);
-
- if let (Some(outside_point), Some(inside_point)) = (outside_point, inside_point)
- {
- let old = *outside_point;
-
- let new_point = (
- time_start,
- interpolate_points(outside_point, inside_point, time_start),
- );
-
- if let Some(to_replace) = swap_data.get_mut(start_pos) {
- *to_replace = new_point;
- Some((start_pos, old))
- } else {
- None // Failed to get mutable reference.
- }
- } else {
- None // Point somehow doesn't exist in our data
- }
- } else {
- None // Point is already "leftmost", no need to interpolate.
+ if let Some((label_percent, label_frac)) = &app_state.canvas_data.swap_labels {
+ let swap_label = format!("SWP:{}{}", label_percent, label_frac);
+ points.push(GraphData {
+ points: &app_state.canvas_data.swap_data,
+ style: self.colours.swap_style,
+ name: Some(swap_label.into()),
+ });
}
- } else {
- None // There is no point.
- };
- let mut mem_canvas_vec: Vec<Dataset<'_>> = vec![];
-
- if let Some((label_percent, label_frac)) = &app_state.canvas_data.mem_labels {
- let mem_label = format!("RAM:{}{}", label_percent, label_frac);
- mem_canvas_vec.push(
- Dataset::default()
- .name(mem_label)
- .marker(if app_state.app_config_fields.use_dot {
- Marker::Dot
- } else {
- Marker::Braille
- })
- .style(self.colours.ram_style)
- .data(mem_data)
- .graph_type(tui::widgets::GraphType::Line),
- );
- }
-
- if let Some((label_percent, label_frac)) = &app_state.canvas_data.swap_labels {
- let swap_label = format!("SWP:{}{}", label_percent, label_frac);
- mem_canvas_vec.push(
- Dataset::default()
- .name(swap_label)
- .marker(if app_state.app_config_fields.use_dot {
- Marker::Dot
- } else {
- Marker::Braille
- })
- .style(self.colours.swap_style)
- .data(swap_data)
- .graph_type(tui::widgets::GraphType::Line),
- );
- }
-
- let is_on_widget = widget_id == app_state.current_widget.widget_id;
- let border_style = if is_on_widget {
- self.colours.highlighted_border_style
- } else {
- self.colours.border_style
+ points
};
- let title = if app_state.is_expanded {
- const TITLE_BASE: &str = " Memory ── Esc to go back ";
- Spans::from(vec![
- Span::styled(" Memory ", self.colours.widget_title_style),
- Span::styled(
- format!(
- "─{}─ Esc to go back ",
- "─".repeat(usize::from(draw_loc.width).saturating_sub(
- UnicodeSegmentation::graphemes(TITLE_BASE, true).count() + 2
- ))
- ),
- border_style,
- ),
- ])
- } else {
- Spans::from(Span::styled(
- " Memory ".to_string(),
- self.colours.widget_title_style,
- ))
- };
-
- f.render_widget(
- Chart::new(mem_canvas_vec)
- .block(
- Block::default()
- .title(title)
- .borders(Borders::ALL)
- .border_style(if app_state.current_widget.widget_id == widget_id {
- self.colours.highlighted_border_style
- } else {
- self.colours.border_style
- }),
- )
- .x_axis(x_axis)
- .y_axis(y_axis)
- .hidden_legend_constraints((Constraint::Ratio(3, 4), Constraint::Ratio(3, 4))),
- draw_loc,
- );
-
- // Now if you're done, reset any interpolated points!
- if let Some((index, old_value)) = interpolated_mem_point {
- if let Some(to_replace) = mem_data.get_mut(index) {
- *to_replace = old_value;
- }
- }
-
- if let Some((index, old_value)) = interpolated_swap_point {
- if let Some(to_replace) = swap_data.get_mut(index) {
- *to_replace = old_value;
- }
+ TimeGraph {
+ use_dot: app_state.app_config_fields.use_dot,
+ x_bounds,
+ hide_x_labels,
+ y_bounds: Y_BOUNDS,
+ y_labels: &Y_LABELS,
+ graph_style: self.colours.graph_style,
+ border_style,
+ title: " Memory ".into(),
+ is_expanded: app_state.is_expanded,
+ title_style: self.colours.widget_title_style,
+ legend_constraints: Some((Constraint::Ratio(3, 4), Constraint::Ratio(3, 4))),
}
+ .draw_time_graph(f, draw_loc, &points);
}
if app_state.should_get_widget_bounds() {