mirror of
https://github.com/ilya-zlobintsev/LACT.git
synced 2025-02-25 18:55:26 -06:00
feat: add fan speed plot (#338)
This commit is contained in:
parent
fd85122d4a
commit
3f99eab263
@ -27,6 +27,7 @@ impl GraphsWindow {
|
||||
let mut temperature_plot = imp.temperature_plot.data_mut();
|
||||
let mut clockspeed_plot = imp.clockspeed_plot.data_mut();
|
||||
let mut power_plot = imp.power_plot.data_mut();
|
||||
let mut fan_plot = imp.fan_plot.data_mut();
|
||||
|
||||
let throttling_plots = [&mut temperature_plot, &mut clockspeed_plot, &mut power_plot];
|
||||
match &stats.throttle_info {
|
||||
@ -81,13 +82,31 @@ impl GraphsWindow {
|
||||
clockspeed_plot.push_line_series("VRAM", point as f64);
|
||||
}
|
||||
|
||||
if let Some(max_speed) = stats.fan.speed_max {
|
||||
fan_plot.push_line_series("Maximum", max_speed as f64);
|
||||
}
|
||||
if let Some(min_speed) = stats.fan.speed_min {
|
||||
fan_plot.push_line_series("Minimum", min_speed as f64);
|
||||
}
|
||||
|
||||
if let Some(current_speed) = stats.fan.speed_current {
|
||||
fan_plot.push_line_series("Current", current_speed as f64);
|
||||
}
|
||||
|
||||
if let Some(pwm) = stats.fan.pwm_current {
|
||||
fan_plot
|
||||
.push_secondary_line_series("Percentage", (pwm as f64 / u8::MAX as f64) * 100.0);
|
||||
}
|
||||
|
||||
temperature_plot.trim_data(GRAPH_WIDTH_SECONDS);
|
||||
clockspeed_plot.trim_data(GRAPH_WIDTH_SECONDS);
|
||||
power_plot.trim_data(GRAPH_WIDTH_SECONDS);
|
||||
fan_plot.trim_data(GRAPH_WIDTH_SECONDS);
|
||||
|
||||
imp.temperature_plot.queue_draw();
|
||||
imp.clockspeed_plot.queue_draw();
|
||||
imp.power_plot.queue_draw();
|
||||
imp.fan_plot.queue_draw();
|
||||
}
|
||||
|
||||
pub fn clear(&self) {
|
||||
@ -95,9 +114,12 @@ impl GraphsWindow {
|
||||
*imp.temperature_plot.data_mut() = PlotData::default();
|
||||
*imp.clockspeed_plot.data_mut() = PlotData::default();
|
||||
*imp.power_plot.data_mut() = PlotData::default();
|
||||
*imp.fan_plot.data_mut() = PlotData::default();
|
||||
|
||||
imp.temperature_plot.queue_draw();
|
||||
imp.clockspeed_plot.queue_draw();
|
||||
imp.power_plot.queue_draw();
|
||||
imp.fan_plot.queue_draw();
|
||||
}
|
||||
}
|
||||
|
||||
@ -128,6 +150,8 @@ mod imp {
|
||||
pub(super) clockspeed_plot: TemplateChild<Plot>,
|
||||
#[template_child]
|
||||
pub(super) power_plot: TemplateChild<Plot>,
|
||||
#[template_child]
|
||||
pub(super) fan_plot: TemplateChild<Plot>,
|
||||
}
|
||||
|
||||
#[glib::object_subclass]
|
||||
|
@ -21,7 +21,11 @@ pub struct Plot {
|
||||
#[property(get, set)]
|
||||
value_suffix: RefCell<String>,
|
||||
#[property(get, set)]
|
||||
secondary_value_suffix: RefCell<String>,
|
||||
#[property(get, set)]
|
||||
y_label_area_size: Cell<u32>,
|
||||
#[property(get, set)]
|
||||
secondary_y_label_area_size: Cell<u32>,
|
||||
pub(super) data: RefCell<PlotData>,
|
||||
}
|
||||
|
||||
@ -67,6 +71,7 @@ impl WidgetImpl for Plot {
|
||||
#[cfg_attr(feature = "bench", derive(Clone))]
|
||||
pub struct PlotData {
|
||||
line_series: BTreeMap<String, Vec<(i64, f64)>>,
|
||||
secondary_line_series: BTreeMap<String, Vec<(i64, f64)>>,
|
||||
throttling: Vec<(i64, (String, bool))>,
|
||||
}
|
||||
|
||||
@ -75,6 +80,10 @@ impl PlotData {
|
||||
self.push_line_series_with_time(name, point, chrono::Local::now().naive_local());
|
||||
}
|
||||
|
||||
pub fn push_secondary_line_series(&mut self, name: &str, point: f64) {
|
||||
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) {
|
||||
self.line_series
|
||||
.entry(name.to_owned())
|
||||
@ -82,6 +91,18 @@ impl PlotData {
|
||||
.push((time.timestamp_millis(), point));
|
||||
}
|
||||
|
||||
pub fn push_secondary_line_series_with_time(
|
||||
&mut self,
|
||||
name: &str,
|
||||
point: f64,
|
||||
time: NaiveDateTime,
|
||||
) {
|
||||
self.secondary_line_series
|
||||
.entry(name.to_owned())
|
||||
.or_default()
|
||||
.push((time.timestamp_millis(), point));
|
||||
}
|
||||
|
||||
pub fn push_throttling(&mut self, name: &str, point: bool) {
|
||||
self.throttling.push((
|
||||
chrono::Local::now().naive_local().timestamp_millis(),
|
||||
@ -93,6 +114,10 @@ impl PlotData {
|
||||
self.line_series.iter()
|
||||
}
|
||||
|
||||
pub fn secondary_line_series_iter(&self) -> impl Iterator<Item = (&String, &Vec<(i64, f64)>)> {
|
||||
self.secondary_line_series.iter()
|
||||
}
|
||||
|
||||
pub fn throttling_iter(&self) -> impl Iterator<Item = (i64, &str, bool)> {
|
||||
self.throttling
|
||||
.iter()
|
||||
@ -112,6 +137,18 @@ impl PlotData {
|
||||
|
||||
self.line_series.retain(|_, data| !data.is_empty());
|
||||
|
||||
for data in self.secondary_line_series.values_mut() {
|
||||
let maximum_point = data
|
||||
.last()
|
||||
.map(|(date_time, _)| *date_time)
|
||||
.unwrap_or_default();
|
||||
|
||||
data.retain(|(time_point, _)| ((maximum_point - *time_point) / 1000) < last_seconds);
|
||||
}
|
||||
|
||||
self.secondary_line_series
|
||||
.retain(|_, data| !data.is_empty());
|
||||
|
||||
// Limit data to N seconds
|
||||
let maximum_point = self
|
||||
.throttling
|
||||
@ -162,12 +199,17 @@ impl Plot {
|
||||
let mut chart = ChartBuilder::on(&root)
|
||||
.x_label_area_size(40)
|
||||
.y_label_area_size(self.y_label_area_size.get())
|
||||
.right_y_label_area_size(self.secondary_y_label_area_size.get())
|
||||
.margin(20)
|
||||
.caption(self.title.borrow().as_str(), ("sans-serif", 30))
|
||||
.build_cartesian_2d(
|
||||
start_date..max(end_date, start_date + 60 * 1000),
|
||||
0f64..maximum_value,
|
||||
)?;
|
||||
)?
|
||||
.set_secondary_coord(
|
||||
start_date..max(end_date, start_date + 60 * 1000),
|
||||
0.0..100.0,
|
||||
);
|
||||
|
||||
chart
|
||||
.configure_mesh()
|
||||
@ -182,6 +224,14 @@ impl Plot {
|
||||
.draw()
|
||||
.context("Failed to draw mesh")?;
|
||||
|
||||
chart
|
||||
.configure_secondary_axes()
|
||||
.y_label_formatter(&|x| format!("{x}{}", self.secondary_value_suffix.borrow()))
|
||||
.y_labels(10)
|
||||
.label_style(("sans-serif", 30))
|
||||
.draw()
|
||||
.context("Failed to draw mesh")?;
|
||||
|
||||
// Draw the throttling histogram
|
||||
chart
|
||||
.draw_series(
|
||||
@ -229,6 +279,29 @@ impl Plot {
|
||||
});
|
||||
}
|
||||
|
||||
for (idx, (caption, data)) in (0..).zip(data.secondary_line_series_iter()) {
|
||||
chart
|
||||
.draw_secondary_series(LineSeries::new(
|
||||
cubic_spline_interpolation(data.iter())
|
||||
.into_iter()
|
||||
.flat_map(|((first_time, second_time), segment)| {
|
||||
// Interpolate in intervals of one millisecond
|
||||
(first_time..second_time).map(move |current_date| {
|
||||
(current_date, segment.evaluate(current_date))
|
||||
})
|
||||
}),
|
||||
Palette99::pick(idx + 10).stroke_width(1), // Offset the pallete pick compared to the main graph
|
||||
))
|
||||
.context("Failed to draw series")?
|
||||
.label(caption)
|
||||
.legend(move |(x, y)| {
|
||||
Rectangle::new(
|
||||
[(x - 10, y - 10), (x + 10, y + 10)],
|
||||
Palette99::pick(idx + 10),
|
||||
)
|
||||
});
|
||||
}
|
||||
|
||||
chart
|
||||
.configure_series_labels()
|
||||
.margin(30)
|
||||
|
@ -1,7 +1,7 @@
|
||||
using Gtk 4.0;
|
||||
|
||||
template $GraphsWindow: Window {
|
||||
default-height: 600;
|
||||
default-height: 800;
|
||||
default-width: 600;
|
||||
title: "Historical data";
|
||||
hide-on-close: true;
|
||||
@ -27,6 +27,20 @@ template $GraphsWindow: Window {
|
||||
}
|
||||
}
|
||||
|
||||
$Plot fan_plot {
|
||||
title: "Fan speed";
|
||||
hexpand: true;
|
||||
value-suffix: "PWM";
|
||||
secondary-value-suffix: "%";
|
||||
y-label-area-size: 140;
|
||||
secondary-y-label-area-size: 80;
|
||||
|
||||
layout {
|
||||
column: 0;
|
||||
row: 1;
|
||||
}
|
||||
}
|
||||
|
||||
$Plot clockspeed_plot {
|
||||
title: "Clockspeed";
|
||||
hexpand: true;
|
||||
@ -35,7 +49,7 @@ template $GraphsWindow: Window {
|
||||
|
||||
layout {
|
||||
column: 0;
|
||||
row: 1;
|
||||
row: 2;
|
||||
}
|
||||
}
|
||||
|
||||
@ -47,7 +61,7 @@ template $GraphsWindow: Window {
|
||||
|
||||
layout {
|
||||
column: 0;
|
||||
row: 2;
|
||||
row: 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user