feat: basic cpu graph
This commit is contained in:
parent
8f0abd2b78
commit
99c60658fa
4 changed files with 237 additions and 13 deletions
49
src/app/cpu_graph.rs
Normal file
49
src/app/cpu_graph.rs
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
use std::collections::VecDeque;
|
||||
|
||||
use iced::{Color, Point, Renderer, Theme, mouse, widget::canvas};
|
||||
|
||||
use crate::app;
|
||||
|
||||
const CYAN: Color = Color::from_rgb8(0, 255, 255);
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct CpuGraph {
|
||||
pub cache: canvas::Cache,
|
||||
timeline: VecDeque<f32>,
|
||||
}
|
||||
|
||||
impl CpuGraph {
|
||||
pub fn update(&mut self, usage: f32) {
|
||||
self.timeline.push_back(usage);
|
||||
if self.timeline.len() > 1000 {
|
||||
self.timeline.pop_front();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl canvas::Program<app::Message, Theme, Renderer> for CpuGraph {
|
||||
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_with_bounds(renderer, bounds, |frame| {
|
||||
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 { x, y })
|
||||
}
|
||||
}),
|
||||
canvas::Stroke::default().with_color(CYAN),
|
||||
);
|
||||
});
|
||||
|
||||
vec![geometry]
|
||||
}
|
||||
}
|
||||
|
|
@ -1,23 +1,68 @@
|
|||
use iced::{Color, Element, Renderer, Task, Theme, application, theme, widget};
|
||||
use std::time::Instant;
|
||||
|
||||
enum Message {}
|
||||
use iced::{
|
||||
Color, Element, Length, Renderer, Subscription, Task, Theme, application, theme, widget, window,
|
||||
};
|
||||
|
||||
struct State {}
|
||||
use crate::app::cpu_graph::CpuGraph;
|
||||
|
||||
mod cpu_graph;
|
||||
|
||||
enum Message {
|
||||
Frame(Instant),
|
||||
}
|
||||
|
||||
struct State {
|
||||
sys: sysinfo::System,
|
||||
refreshes: sysinfo::RefreshKind,
|
||||
|
||||
last_refresh: Instant,
|
||||
|
||||
cpu_graph: CpuGraph,
|
||||
}
|
||||
|
||||
impl State {
|
||||
fn new() -> Self {
|
||||
Self {}
|
||||
Self {
|
||||
sys: sysinfo::System::new(),
|
||||
refreshes: sysinfo::RefreshKind::nothing()
|
||||
.with_cpu(sysinfo::CpuRefreshKind::nothing().with_cpu_usage()),
|
||||
|
||||
cpu_graph: Default::default(),
|
||||
last_refresh: Instant::now(),
|
||||
}
|
||||
}
|
||||
fn update(&mut self, message: Message) -> Task<Message> {
|
||||
match message {
|
||||
Message::Frame(instant) => {
|
||||
if instant.duration_since(self.last_refresh) >= sysinfo::MINIMUM_CPU_UPDATE_INTERVAL
|
||||
{
|
||||
self.sys.refresh_specifics(self.refreshes);
|
||||
self.cpu_graph.update(self.sys.global_cpu_usage());
|
||||
self.cpu_graph.cache.clear();
|
||||
|
||||
self.last_refresh = instant;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Task::none()
|
||||
}
|
||||
fn view(&self) -> Element<'_, Message, Theme, Renderer> {
|
||||
widget::text("hiiiiiii").into()
|
||||
widget::Canvas::new(&self.cpu_graph)
|
||||
.width(Length::Fill)
|
||||
.height(Length::Fill)
|
||||
.into()
|
||||
}
|
||||
|
||||
fn subscription(&self) -> Subscription<Message> {
|
||||
window::frames().map(Message::Frame)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run() -> Result<(), impl std::error::Error> {
|
||||
application(State::new, State::update, State::view)
|
||||
.subscription(State::subscription)
|
||||
.theme(theme::Theme::custom(
|
||||
"high-contrast-dark",
|
||||
theme::Palette {
|
||||
|
|
|
|||
Loading…
Reference in a new issue