diff --git a/src/data/data.rs b/src/data/data.rs index f397c95..1614544 100644 --- a/src/data/data.rs +++ b/src/data/data.rs @@ -2,24 +2,24 @@ use std::time::{SystemTime, UNIX_EPOCH}; use rkyv::{Archive, Deserialize, Serialize}; -#[derive(Serialize, Deserialize, Archive)] +#[derive(Serialize, Deserialize, Archive, Debug)] pub struct Data { pub data_chunks: Vec, pub data_static: BatteryStatic, } -#[derive(Serialize, Deserialize, Archive)] +#[derive(Serialize, Deserialize, Archive, Debug)] pub struct DataChunk { pub timestamp: u64, pub battery: BatteryMutable, } -#[derive(Serialize, Deserialize, Archive)] +#[derive(Serialize, Deserialize, Archive, Debug)] pub struct BatteryMutable { pub charge: i64, } -#[derive(Serialize, Deserialize, Archive)] +#[derive(Serialize, Deserialize, Archive, Debug)] pub struct BatteryStatic { pub total_capacity: i64, } diff --git a/src/tui/dashboard.rs b/src/tui/dashboard.rs index 030caab..350c34e 100644 --- a/src/tui/dashboard.rs +++ b/src/tui/dashboard.rs @@ -1,6 +1,16 @@ -use crate::component::Component; +use crate::{ + component::Component, + data_graph::{Graphable, SplitData}, +}; use crossterm::event::Event; -use ratatui::{layout::Rect, text::Text, Frame}; +use data::{ArchivedData, Data}; +use ratatui::{ + layout::{Constraint, Layout, Rect}, + text::Text, + widgets::{Axis, Chart, Dataset}, + Frame, +}; +use rkyv::{deserialize, rancor}; #[derive(Debug)] pub enum MenuMsg { @@ -12,6 +22,8 @@ pub enum MenuMsg { #[derive(Default, Debug)] pub struct Menu { counter: i32, + split_data: Option, + data: Vec<(f64, f64)>, } impl Component for Menu { type Msg = MenuMsg; @@ -19,22 +31,48 @@ impl Component for Menu { match msg { MenuMsg::MoveUp => self.counter += 1, MenuMsg::MoveDown => self.counter -= 1, + MenuMsg::Select => self.get_data(), _ => {} } } fn view(&self, f: &mut Frame) { + let [text, graph] = + Layout::vertical([Constraint::Length(5), Constraint::Fill(1)]).areas(f.area()); let text_raw = format!("meow - {}", self.counter); - let text = Text::raw(text_raw); - f.render_widget(text, f.area()); + let text_widget = Text::raw(text_raw); + f.render_widget(text_widget, text); + + let a = &self.data; + let data_set = Dataset::default().data(a).name("Battery"); + let x_axis = Axis::default().title("timeframe"); + let y_axis = Axis::default() + .title("Charge") + .labels(["0%", "50%", "100%"]); + let graph_widget = Chart::new(vec![data_set]); + f.render_widget(graph_widget, graph); } fn handle_event(&mut self, event: Event) { match event { Event::Key(x) => match x.code { crossterm::event::KeyCode::Up => self.update(MenuMsg::MoveUp), crossterm::event::KeyCode::Down => self.update(MenuMsg::MoveDown), + crossterm::event::KeyCode::Enter => self.update(MenuMsg::Select), _ => {} }, _ => {} } } } +impl Menu { + fn get_data(&mut self) { + let data = std::fs::read("./battery.data").unwrap(); + let access_data: &ArchivedData = + rkyv::access::(&data).unwrap(); + let data: data::Data = deserialize::(access_data).unwrap(); + + let split_data = SplitData { + chunks: data.data_chunks, + }; + self.data = split_data.timeframe(0, 999999999); + } +} diff --git a/src/tui/data_graph.rs b/src/tui/data_graph.rs index 1717e54..efda464 100644 --- a/src/tui/data_graph.rs +++ b/src/tui/data_graph.rs @@ -1,8 +1,6 @@ -use ratatui::widgets::Dataset; - use data::DataChunk; -trait Graphable { +pub trait Graphable { fn timeframe(&self, start: u64, end: u64) -> Vec<(f64, f64)>; } @@ -24,6 +22,7 @@ impl Graphable for SplitData { } } -struct SplitData { - chunks: Vec, +#[derive(Debug)] +pub struct SplitData { + pub chunks: Vec, } diff --git a/src/tui/main.rs b/src/tui/main.rs index 8285384..a9ff396 100644 --- a/src/tui/main.rs +++ b/src/tui/main.rs @@ -19,6 +19,7 @@ use crate::{ mod component; mod dashboard; +mod data_graph; // -- GLOBAL APP MESSAGE -- enum AppMsg { @@ -48,17 +49,25 @@ impl App { } } - // The "View" part of TEA fn view(&self, f: &mut Frame) { - // Centering logic we discussed earlier! - self.menu.view(f); + match self.screen { + Screen::Menu => self.menu.view(f), + } } fn handle_event(&mut self, event: Event) { + match event { + Event::Key(x) => match x.code { + crossterm::event::KeyCode::Esc => self.update(AppMsg::GlobalQuit), + _ => {} + }, + _ => {} + } match self.screen { Screen::Menu => self.menu.handle_event(event), } } + fn propagate_events(&mut self) { if crossterm::event::poll(Duration::from_millis(100)).unwrap() { if let Ok(event) = crossterm::event::read() { @@ -70,8 +79,10 @@ impl App { fn main() { let mut app: App = App::default(); - ratatui::run(|terminal| loop { - terminal.draw(|f| app.view(f)); - app.propagate_events(); + ratatui::run(|terminal| { + while !app.should_quit { + terminal.draw(|f| app.view(f)).unwrap(); + app.propagate_events(); + } }); }