Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
ee4dc4f7b9 |
|||
|
96a972f9f0 |
2 changed files with 14 additions and 16 deletions
64
src/app/graph.rs
Normal file
64
src/app/graph.rs
Normal file
|
|
@ -0,0 +1,64 @@
|
||||||
|
use std::collections::VecDeque;
|
||||||
|
|
||||||
|
use iced::{Color, Point, Renderer, Theme, mouse, widget::canvas};
|
||||||
|
|
||||||
|
const CYAN: Color = Color::from_rgb8(0, 255, 255);
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct Graph {
|
||||||
|
timeline: VecDeque<f32>,
|
||||||
|
|
||||||
|
pub cache: canvas::Cache,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Graph {
|
||||||
|
pub fn new(value: f32) -> Self {
|
||||||
|
Self {
|
||||||
|
timeline: {
|
||||||
|
let mut vec = VecDeque::new();
|
||||||
|
vec.push_front(value);
|
||||||
|
vec
|
||||||
|
},
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update(&mut self, value: f32) {
|
||||||
|
self.timeline.push_back(value);
|
||||||
|
if self.timeline.len() > 1000 {
|
||||||
|
self.timeline.pop_front();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl canvas::Program<(), Theme, Renderer> for Graph {
|
||||||
|
type State = ();
|
||||||
|
fn draw(
|
||||||
|
&self,
|
||||||
|
_state: &Self::State,
|
||||||
|
renderer: &Renderer,
|
||||||
|
_theme: &Theme,
|
||||||
|
bounds: iced::Rectangle,
|
||||||
|
_cursor: mouse::Cursor,
|
||||||
|
) -> Vec<canvas::Geometry<Renderer>> {
|
||||||
|
let geometry = self.cache.draw(renderer, bounds.size(), |frame| {
|
||||||
|
frame.stroke_rectangle(
|
||||||
|
Point::new(0., 0.),
|
||||||
|
bounds.size(),
|
||||||
|
canvas::Stroke::default().with_color(Color::from_rgb8(255, 0, 0)),
|
||||||
|
);
|
||||||
|
frame.stroke(
|
||||||
|
&canvas::Path::new(|builder| {
|
||||||
|
for (index, value) in self.timeline.iter().enumerate() {
|
||||||
|
let x = index as f32 / self.timeline.len() as f32 * bounds.width;
|
||||||
|
let y = bounds.height - value / 100. * bounds.height;
|
||||||
|
builder.line_to(Point::new(x, y))
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
canvas::Stroke::default().with_color(CYAN),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
vec![geometry]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -4,9 +4,9 @@ use iced::{
|
||||||
};
|
};
|
||||||
use smol::Timer;
|
use smol::Timer;
|
||||||
|
|
||||||
use crate::{app::cpu_graph::CpuGraph, sysinfo_snapshot::SysinfoSnapshot};
|
use crate::{app::graph::Graph, sysinfo_snapshot::SysinfoSnapshot};
|
||||||
|
|
||||||
mod cpu_graph;
|
mod graph;
|
||||||
|
|
||||||
enum Message {
|
enum Message {
|
||||||
Info(SysinfoSnapshot),
|
Info(SysinfoSnapshot),
|
||||||
|
|
@ -14,8 +14,8 @@ enum Message {
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct State {
|
struct State {
|
||||||
total_cpu_graph: CpuGraph,
|
total_cpu_graph: Graph,
|
||||||
cpu_graphs: Vec<CpuGraph>,
|
cpu_graphs: Vec<Graph>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl State {
|
impl State {
|
||||||
|
|
@ -51,12 +51,12 @@ impl State {
|
||||||
self.cpu_graphs = snapshot
|
self.cpu_graphs = snapshot
|
||||||
.cpus
|
.cpus
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|usage| CpuGraph::new(usage))
|
.map(|value| Graph::new(value))
|
||||||
.collect();
|
.collect();
|
||||||
} else {
|
} else {
|
||||||
for (graph, usage) in self.cpu_graphs.iter_mut().zip(snapshot.cpus.into_iter())
|
for (graph, value) in self.cpu_graphs.iter_mut().zip(snapshot.cpus.into_iter())
|
||||||
{
|
{
|
||||||
graph.update(usage);
|
graph.update(value);
|
||||||
graph.cache.clear();
|
graph.cache.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue