From 4a35ffbde175df259780de32bfc2dcdaa00f84d0 Mon Sep 17 00:00:00 2001 From: Ilya Zlobintsev Date: Sun, 12 Jan 2025 11:23:35 +0200 Subject: [PATCH] fix: avoid crashing history graph on empty plot with throttling data --- lact-gui/src/app/graphs_window/plot/imp.rs | 6 +- .../app/graphs_window/plot/render_thread.rs | 58 ++++++++++--------- 2 files changed, 35 insertions(+), 29 deletions(-) diff --git a/lact-gui/src/app/graphs_window/plot/imp.rs b/lact-gui/src/app/graphs_window/plot/imp.rs index 18b6ebc..fe5d7ce 100644 --- a/lact-gui/src/app/graphs_window/plot/imp.rs +++ b/lact-gui/src/app/graphs_window/plot/imp.rs @@ -105,7 +105,7 @@ impl PlotData { self.push_secondary_line_series_with_time(name, point, chrono::Local::now().naive_local()); } - pub fn push_line_series_with_time(&mut self, name: &str, point: f64, time: NaiveDateTime) { + fn push_line_series_with_time(&mut self, name: &str, point: f64, time: NaiveDateTime) { self.line_series .entry(name.to_owned()) .or_default() @@ -183,4 +183,8 @@ impl PlotData { self.throttling .retain(|(time_point, _)| ((maximum_point - *time_point) / 1000) < last_seconds); } + + pub fn is_empty(&self) -> bool { + self.line_series.is_empty() && self.secondary_line_series.is_empty() + } } diff --git a/lact-gui/src/app/graphs_window/plot/render_thread.rs b/lact-gui/src/app/graphs_window/plot/render_thread.rs index b776015..fc2dce6 100644 --- a/lact-gui/src/app/graphs_window/plot/render_thread.rs +++ b/lact-gui/src/app/graphs_window/plot/render_thread.rs @@ -293,34 +293,36 @@ impl RenderRequest { .context("Failed to draw mesh")?; // Draw the throttling histogram as a series of bars. - chart - .draw_series( - data.throttling_iter() - .chunk_by(|(_, _, point)| *point) - .into_iter() - .filter_map(|(point, group_iter)| point.then_some(group_iter)) - .filter_map(|mut group_iter| { - let first = group_iter.next()?; - Some((first, group_iter.last().unwrap_or(first))) - }) - .map(|((start, name, _), (end, _, _))| ((start, end), name)) - .map(|((start_time, end_time), _)| (start_time, end_time)) - .sorted_by_key(|&(start_time, _)| start_time) - .coalesce(|(start1, end1), (start2, end2)| { - if end1 >= start2 { - Ok((start1, std::cmp::max(end1, end2))) - } else { - Err(((start1, end1), (start2, end2))) - } - }) - .map(|(start_time, end_time)| { - Rectangle::new( - [(start_time, 0f64), (end_time, maximum_value)], - DEEPORANGE_100.filled(), - ) - }), - ) - .context("Failed to draw throttling histogram")?; + if !data.is_empty() { + chart + .draw_series( + data.throttling_iter() + .chunk_by(|(_, _, point)| *point) + .into_iter() + .filter_map(|(point, group_iter)| point.then_some(group_iter)) + .filter_map(|mut group_iter| { + let first = group_iter.next()?; + Some((first, group_iter.last().unwrap_or(first))) + }) + .map(|((start, name, _), (end, _, _))| ((start, end), name)) + .map(|((start_time, end_time), _)| (start_time, end_time)) + .sorted_by_key(|&(start_time, _)| start_time) + .coalesce(|(start1, end1), (start2, end2)| { + if end1 >= start2 { + Ok((start1, std::cmp::max(end1, end2))) + } else { + Err(((start1, end1), (start2, end2))) + } + }) + .map(|(start_time, end_time)| { + Rectangle::new( + [(start_time, 0f64), (end_time, maximum_value)], + DEEPORANGE_100.filled(), + ) + }), + ) + .context("Failed to draw throttling histogram")?; + } // Draw the main line series using cubic spline interpolation. for (idx, (caption, data)) in (0..).zip(data.line_series_iter()) {