Skip to content

Commit

Permalink
perf: optimize plot drawing
Browse files Browse the repository at this point in the history
  • Loading branch information
ilya-zlobintsev committed Apr 22, 2024
1 parent 50fea14 commit 06e061b
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 19 deletions.
8 changes: 4 additions & 4 deletions lact-gui/src/app/graphs_window/plot/cubic_spline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ pub type TimePeriod = (i64, i64);
// Define a function to perform cubic spline interpolation
pub fn cubic_spline_interpolation<'a, I>(iter: I) -> Vec<(TimePeriod, CubicSplineSegment)>
where
I: IntoIterator<Item = (&'a i64, &'a f64)> + 'a,
I: IntoIterator<Item = &'a (i64, f64)> + 'a,
{
let data: Vec<_> = iter.into_iter().collect();

Expand All @@ -36,7 +36,7 @@ where
// Compute differences between consecutive x values
let mut dx = Vec::with_capacity(n - 1);
for i in 1..n {
let x_diff = (*data[i].0 - *data[i - 1].0) as f64;
let x_diff = (data[i].0 - data[i - 1].0) as f64;
dx.push(x_diff);
}

Expand Down Expand Up @@ -74,14 +74,14 @@ where
let b = (dy[i + 1] - dy[i]) / dx[i] - dx[i] * (2.0 * d[i] + d[i + 1]) / 6.0;
let c = d[i] / 2.0;
let d = (d[i + 1] - d[i]) / (6.0 * dx[i]);
CubicSplineSegment::new(a, b, c, d, *data[i].0)
CubicSplineSegment::new(a, b, c, d, data[i].0)
}),
)
// Group 2 closest points together
.tuple_windows::<(_, _)>()
// Get first time, second time and their corresponding interpolation segment
.map(|(((first_time, _), segment), ((second_time, _), _))| {
((**first_time, **second_time), segment)
((*first_time, *second_time), segment)
})
.collect()
}
28 changes: 13 additions & 15 deletions lact-gui/src/app/graphs_window/plot/imp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ impl WidgetImpl for Plot {
#[derive(Default)]
#[cfg_attr(feature = "bench", derive(Clone))]
pub struct PlotData {
line_series: BTreeMap<String, BTreeMap<i64, f64>>,
throttling: BTreeMap<i64, (String, bool)>,
line_series: BTreeMap<String, Vec<(i64, f64)>>,
throttling: Vec<(i64, (String, bool))>,
}

impl PlotData {
Expand All @@ -79,17 +79,17 @@ impl PlotData {
self.line_series
.entry(name.to_owned())
.or_default()
.insert(time.timestamp_millis(), point);
.push((time.timestamp_millis(), point));
}

pub fn push_throttling(&mut self, name: &str, point: bool) {
self.throttling.insert(
self.throttling.push((
chrono::Local::now().naive_local().timestamp_millis(),
(name.to_owned(), point),
);
));
}

pub fn line_series_iter(&self) -> impl Iterator<Item = (&String, &BTreeMap<i64, f64>)> {
pub fn line_series_iter(&self) -> impl Iterator<Item = (&String, &Vec<(i64, f64)>)> {
self.line_series.iter()
}

Expand All @@ -103,24 +103,24 @@ impl PlotData {
// Limit data to N seconds
for data in self.line_series.values_mut() {
let maximum_point = data
.last_key_value()
.last()
.map(|(date_time, _)| *date_time)
.unwrap_or_default();

data.retain(|time_point, _| ((maximum_point - *time_point) / 1000) < last_seconds);
data.retain(|(time_point, _)| ((maximum_point - *time_point) / 1000) < last_seconds);
}

self.line_series.retain(|_, data| !data.is_empty());

// Limit data to N seconds
let maximum_point = self
.throttling
.last_key_value()
.last()
.map(|(date_time, _)| *date_time)
.unwrap_or_default();

self.throttling
.retain(|time_point, _| ((maximum_point - *time_point) / 1000) < last_seconds);
.retain(|(time_point, _)| ((maximum_point - *time_point) / 1000) < last_seconds);
}
}

Expand All @@ -136,21 +136,19 @@ impl Plot {

let start_date = data
.line_series_iter()
.filter_map(|(_, data)| Some(data.first_key_value()?.0))
.filter_map(|(_, data)| Some(data.first()?.0))
.min()
.cloned()
.unwrap_or_default();
let end_date = data
.line_series_iter()
.map(|(_, value)| value)
.filter_map(|data| Some(data.last_key_value()?.0))
.filter_map(|data| Some(data.first()?.0))
.max()
.cloned()
.unwrap_or_default();

let mut maximum_value = data
.line_series_iter()
.flat_map(|(_, data)| data.values())
.flat_map(|(_, data)| data.iter().map(|(_, value)| value))
.max_by(|x, y| x.partial_cmp(y).unwrap_or(std::cmp::Ordering::Equal))
.cloned()
.unwrap_or_default();
Expand Down

0 comments on commit 06e061b

Please sign in to comment.