mirror of
https://github.com/ilya-zlobintsev/LACT.git
synced 2025-02-25 18:55:26 -06:00
perf: optimize plot drawing
This commit is contained in:
parent
50fea14480
commit
06e061b88e
@ -27,7 +27,7 @@ pub type TimePeriod = (i64, i64);
|
|||||||
// Define a function to perform cubic spline interpolation
|
// Define a function to perform cubic spline interpolation
|
||||||
pub fn cubic_spline_interpolation<'a, I>(iter: I) -> Vec<(TimePeriod, CubicSplineSegment)>
|
pub fn cubic_spline_interpolation<'a, I>(iter: I) -> Vec<(TimePeriod, CubicSplineSegment)>
|
||||||
where
|
where
|
||||||
I: IntoIterator<Item = (&'a i64, &'a f64)> + 'a,
|
I: IntoIterator<Item = &'a (i64, f64)> + 'a,
|
||||||
{
|
{
|
||||||
let data: Vec<_> = iter.into_iter().collect();
|
let data: Vec<_> = iter.into_iter().collect();
|
||||||
|
|
||||||
@ -36,7 +36,7 @@ where
|
|||||||
// Compute differences between consecutive x values
|
// Compute differences between consecutive x values
|
||||||
let mut dx = Vec::with_capacity(n - 1);
|
let mut dx = Vec::with_capacity(n - 1);
|
||||||
for i in 1..n {
|
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);
|
dx.push(x_diff);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -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 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 c = d[i] / 2.0;
|
||||||
let d = (d[i + 1] - d[i]) / (6.0 * dx[i]);
|
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
|
// Group 2 closest points together
|
||||||
.tuple_windows::<(_, _)>()
|
.tuple_windows::<(_, _)>()
|
||||||
// Get first time, second time and their corresponding interpolation segment
|
// Get first time, second time and their corresponding interpolation segment
|
||||||
.map(|(((first_time, _), segment), ((second_time, _), _))| {
|
.map(|(((first_time, _), segment), ((second_time, _), _))| {
|
||||||
((**first_time, **second_time), segment)
|
((*first_time, *second_time), segment)
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
@ -66,8 +66,8 @@ impl WidgetImpl for Plot {
|
|||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
#[cfg_attr(feature = "bench", derive(Clone))]
|
#[cfg_attr(feature = "bench", derive(Clone))]
|
||||||
pub struct PlotData {
|
pub struct PlotData {
|
||||||
line_series: BTreeMap<String, BTreeMap<i64, f64>>,
|
line_series: BTreeMap<String, Vec<(i64, f64)>>,
|
||||||
throttling: BTreeMap<i64, (String, bool)>,
|
throttling: Vec<(i64, (String, bool))>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PlotData {
|
impl PlotData {
|
||||||
@ -79,17 +79,17 @@ impl PlotData {
|
|||||||
self.line_series
|
self.line_series
|
||||||
.entry(name.to_owned())
|
.entry(name.to_owned())
|
||||||
.or_default()
|
.or_default()
|
||||||
.insert(time.timestamp_millis(), point);
|
.push((time.timestamp_millis(), point));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn push_throttling(&mut self, name: &str, point: bool) {
|
pub fn push_throttling(&mut self, name: &str, point: bool) {
|
||||||
self.throttling.insert(
|
self.throttling.push((
|
||||||
chrono::Local::now().naive_local().timestamp_millis(),
|
chrono::Local::now().naive_local().timestamp_millis(),
|
||||||
(name.to_owned(), point),
|
(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()
|
self.line_series.iter()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,11 +103,11 @@ impl PlotData {
|
|||||||
// Limit data to N seconds
|
// Limit data to N seconds
|
||||||
for data in self.line_series.values_mut() {
|
for data in self.line_series.values_mut() {
|
||||||
let maximum_point = data
|
let maximum_point = data
|
||||||
.last_key_value()
|
.last()
|
||||||
.map(|(date_time, _)| *date_time)
|
.map(|(date_time, _)| *date_time)
|
||||||
.unwrap_or_default();
|
.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());
|
self.line_series.retain(|_, data| !data.is_empty());
|
||||||
@ -115,12 +115,12 @@ impl PlotData {
|
|||||||
// Limit data to N seconds
|
// Limit data to N seconds
|
||||||
let maximum_point = self
|
let maximum_point = self
|
||||||
.throttling
|
.throttling
|
||||||
.last_key_value()
|
.last()
|
||||||
.map(|(date_time, _)| *date_time)
|
.map(|(date_time, _)| *date_time)
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
|
||||||
self.throttling
|
self.throttling
|
||||||
.retain(|time_point, _| ((maximum_point - *time_point) / 1000) < last_seconds);
|
.retain(|(time_point, _)| ((maximum_point - *time_point) / 1000) < last_seconds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,21 +136,19 @@ impl Plot {
|
|||||||
|
|
||||||
let start_date = data
|
let start_date = data
|
||||||
.line_series_iter()
|
.line_series_iter()
|
||||||
.filter_map(|(_, data)| Some(data.first_key_value()?.0))
|
.filter_map(|(_, data)| Some(data.first()?.0))
|
||||||
.min()
|
.min()
|
||||||
.cloned()
|
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
let end_date = data
|
let end_date = data
|
||||||
.line_series_iter()
|
.line_series_iter()
|
||||||
.map(|(_, value)| value)
|
.map(|(_, value)| value)
|
||||||
.filter_map(|data| Some(data.last_key_value()?.0))
|
.filter_map(|data| Some(data.first()?.0))
|
||||||
.max()
|
.max()
|
||||||
.cloned()
|
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
|
||||||
let mut maximum_value = data
|
let mut maximum_value = data
|
||||||
.line_series_iter()
|
.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))
|
.max_by(|x, y| x.partial_cmp(y).unwrap_or(std::cmp::Ordering::Equal))
|
||||||
.cloned()
|
.cloned()
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
Loading…
Reference in New Issue
Block a user