diff options
Diffstat (limited to 'src/canvas/widgets/mem_graph.rs')
-rw-r--r-- | src/canvas/widgets/mem_graph.rs | 106 |
1 files changed, 97 insertions, 9 deletions
diff --git a/src/canvas/widgets/mem_graph.rs b/src/canvas/widgets/mem_graph.rs index 9136b1ba..6b5bc5ab 100644 --- a/src/canvas/widgets/mem_graph.rs +++ b/src/canvas/widgets/mem_graph.rs @@ -1,4 +1,8 @@ -use crate::{app::App, canvas::Painter, constants::*}; +use crate::{ + app::App, + canvas::{drawing_utils::interpolate_points, Painter}, + constants::*, +}; use tui::{ backend::Backend, @@ -22,8 +26,10 @@ impl MemGraphWidget for Painter { &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: &[(f64, f64)] = &app_state.canvas_data.mem_data; - let swap_data: &[(f64, f64)] = &app_state.canvas_data.swap_data; + 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( @@ -33,7 +39,7 @@ impl MemGraphWidget for Painter { Span::styled("0s".to_string(), self.colours.graph_style), ]; let y_axis_label = vec![ - Span::styled("0%", self.colours.graph_style), + Span::styled(" 0%", self.colours.graph_style), Span::styled("100%", self.colours.graph_style), ]; @@ -41,24 +47,24 @@ impl MemGraphWidget for Painter { || (app_state.app_config_fields.autohide_time && mem_widget_state.autohide_timer.is_none()) { - Axis::default().bounds([-(mem_widget_state.current_display_time as f64), 0.0]) + 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 as u128 { Axis::default() - .bounds([-(mem_widget_state.current_display_time as f64), 0.0]) + .bounds([time_start, 0.0]) .style(self.colours.graph_style) .labels(display_time_labels) } else { mem_widget_state.autohide_timer = None; - Axis::default().bounds([-(mem_widget_state.current_display_time as f64), 0.0]) + Axis::default().bounds([time_start, 0.0]) } } else if draw_loc.height < TIME_LABEL_HEIGHT_LIMIT { - Axis::default().bounds([-(mem_widget_state.current_display_time as f64), 0.0]) + Axis::default().bounds([time_start, 0.0]) } else { Axis::default() - .bounds([-(mem_widget_state.current_display_time as f64), 0.0]) + .bounds([time_start, 0.0]) .style(self.colours.graph_style) .labels(display_time_labels) }; @@ -68,6 +74,75 @@ impl MemGraphWidget for Painter { .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); + + 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. + } + } 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. + } + } 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 { @@ -147,6 +222,19 @@ impl MemGraphWidget for Painter { .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; + } + } } if app_state.should_get_widget_bounds() { |