From d0c1816fe51d661795c345cf365d27cf23040114 Mon Sep 17 00:00:00 2001 From: thatscringebro Date: Tue, 31 Mar 2026 14:47:23 -0400 Subject: [PATCH] cumulative total --- src/app.rs | 9 ++++++++- src/data_layer.rs | 29 +++++++++++++++++++++++++++ src/ui.rs | 50 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 87 insertions(+), 1 deletion(-) diff --git a/src/app.rs b/src/app.rs index 7589212..b56d3c7 100644 --- a/src/app.rs +++ b/src/app.rs @@ -51,7 +51,7 @@ impl App { tabs: [ "Transactions".to_string(), "Amnt by Type".to_string(), - "Chart 2".to_string(), + "Total".to_string(), "Chart 3".to_string(), ] .to_vec(), @@ -305,6 +305,13 @@ impl App { } } + pub fn get_cumulative_total(&self) -> Vec<(f64, f64)> { + return data_layer::get_cumulative_account_sum( + &self.connection, + self.acc_list.get_selected_id(), + ); + } + pub fn get_trtype_data(&self) -> Vec<(f64, f64)> { return data_layer::get_tr_type_price_over_time( &self.connection, diff --git a/src/data_layer.rs b/src/data_layer.rs index 69c4314..f62b984 100644 --- a/src/data_layer.rs +++ b/src/data_layer.rs @@ -361,3 +361,32 @@ WHERE type_id = :tr_type return data; } + +pub fn get_cumulative_account_sum(con: &Connection, ac_id: i64) -> Vec<(f64, f64)> { + let mut query = " +SELECT + SUM(amount) OVER ( + ORDER BY date + ) y +FROM + Transactions" + .to_owned(); + if ac_id != 0 { + query.push_str(" WHERE account_id = :ac_id"); + } + + let mut statement = con.prepare(query).unwrap(); + if ac_id != 0 { + statement.bind((":ac_id", ac_id)).unwrap(); + } + let mut data = Vec::<(f64, f64)>::new(); + let mut x = 0.0; + + while let Ok(State::Row) = statement.next() { + let y = statement.read::("y").unwrap(); + data.push((x, y)); + x += 1.0; + } + + return data; +} diff --git a/src/ui.rs b/src/ui.rs index 0012f9d..15941fa 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -179,6 +179,56 @@ pub fn ui(frame: &mut Frame, app: &mut App) { let area = helper_rect(frame.area()); frame.render_widget(Clear, area); frame.render_widget(helper_paragraph, area); + } else if app.selected_tab == 2 { + let slice: &[(f64, f64)] = &app.get_cumulative_total(); + let dataset = Dataset::default() + .marker(Marker::Braille) + .graph_type(GraphType::Line) + .style(Color::Blue) + .data(slice); + + let min_x = slice + .into_iter() + .map(|&(x, _)| x) + .min_by(|a, b| a.partial_cmp(b).unwrap()) + .unwrap() + .round(); + let max_x = slice + .into_iter() + .map(|&(x, _)| x) + .max_by(|a, b| a.partial_cmp(b).unwrap()) + .unwrap() + .round() + + 1.0; + let x_axis = Axis::default() + .title("Time") + .bounds([min_x, max_x]) + .labels([min_x.to_string(), max_x.to_string()]); + + let min_y = slice + .into_iter() + .map(|&(_, y)| y) + .min_by(|a, b| a.partial_cmp(b).unwrap()) + .unwrap() + .round() + - 1.0; + let max_y = slice + .into_iter() + .map(|&(_, y)| y) + .max_by(|a, b| a.partial_cmp(b).unwrap()) + .unwrap() + .round() + + 1.0; + let y_axis = Axis::default() + .title("Total") + .bounds([min_y, max_y]) + .labels([min_y.to_string(), max_y.to_string()]); + + let chart = Chart::new(vec![dataset]) + .block(trx_block.clone()) + .x_axis(x_axis) + .y_axis(y_axis); + frame.render_widget(chart, right_layout[1]); } else { let p = Paragraph::new("Tab not implemented") .block(trx_block)