From 9d1f3c9ac2e8f816e275ed46c43d0f1d56a335e7 Mon Sep 17 00:00:00 2001 From: Clement Tsang <34804052+ClementTsang@users.noreply.github.com> Date: Tue, 22 Dec 2020 01:12:13 -0500 Subject: [PATCH] feature: Hide SWAP graph and legend in normal mode if SWAP is 0 (#372) Firstly, note this currently won't affect basic mode. There is code changes due to it, but instead, we'll just display `0.0B/0.0B` instead. I'm personally not really sure if we want to get rid of it in basic mode, since it'll leave an ugly gap in that mode. Anyways, this change is mainly for the normal mode. All this does is hide the legend entry and chart if the total SWAP drops to 0 KB. It also has a small change to do a unit check on the memory used, as well as slightly adjusting the calculation we use. --- src/app/data_farmer.rs | 24 +++--- src/app/data_harvester/mem.rs | 20 ++--- src/bin/main.rs | 10 +-- src/canvas.rs | 8 +- src/canvas/widgets/mem_basic.rs | 48 ++++++------ src/canvas/widgets/mem_graph.rs | 64 ++++++++-------- src/data_conversion.rs | 126 ++++++++++++++++++++++---------- 7 files changed, 176 insertions(+), 124 deletions(-) diff --git a/src/app/data_farmer.rs b/src/app/data_farmer.rs index b2dc0cc5..b1ba6a51 100644 --- a/src/app/data_farmer.rs +++ b/src/app/data_farmer.rs @@ -30,8 +30,8 @@ pub struct TimedData { pub rx_data: Value, pub tx_data: Value, pub cpu_data: Vec, - pub mem_data: Value, - pub swap_data: Value, + pub mem_data: Option, + pub swap_data: Option, } /// AppCollection represents the pooled data stored within the main app @@ -175,20 +175,20 @@ impl DataCollection { ) { // trace!("Eating mem and swap."); // Memory - let mem_percent = match memory.mem_total_in_mb { - 0 => 0f64, - total => (memory.mem_used_in_mb as f64) / (total as f64) * 100.0, + let mem_percent = if memory.mem_total_in_kib > 0 { + Some((memory.mem_used_in_kib as f64) / (memory.mem_total_in_kib as f64) * 100.0) + } else { + None }; new_entry.mem_data = mem_percent; // Swap - if swap.mem_total_in_mb > 0 { - let swap_percent = match swap.mem_total_in_mb { - 0 => 0f64, - total => (swap.mem_used_in_mb as f64) / (total as f64) * 100.0, - }; - new_entry.swap_data = swap_percent; - } + let swap_percent = if swap.mem_total_in_kib > 0 { + Some((swap.mem_used_in_kib as f64) / (swap.mem_total_in_kib as f64) * 100.0) + } else { + None + }; + new_entry.swap_data = swap_percent; // In addition copy over latest data for easy reference self.memory_harvest = memory; diff --git a/src/app/data_harvester/mem.rs b/src/app/data_harvester/mem.rs index 7dd0f4ca..014cbcdc 100644 --- a/src/app/data_harvester/mem.rs +++ b/src/app/data_harvester/mem.rs @@ -1,14 +1,14 @@ #[derive(Debug, Clone)] pub struct MemHarvest { - pub mem_total_in_mb: u64, - pub mem_used_in_mb: u64, + pub mem_total_in_kib: u64, + pub mem_used_in_kib: u64, } impl Default for MemHarvest { fn default() -> Self { MemHarvest { - mem_total_in_mb: 0, - mem_used_in_mb: 0, + mem_total_in_kib: 0, + mem_used_in_kib: 0, } } } @@ -31,12 +31,14 @@ pub async fn get_mem_data( pub async fn get_ram_data() -> crate::utils::error::Result> { let memory = heim::memory::memory().await?; + let mem_total_in_kb = memory.total().get::(); + Ok(Some(MemHarvest { - mem_total_in_mb: memory.total().get::(), - mem_used_in_mb: memory.total().get::() + mem_total_in_kib: mem_total_in_kb, + mem_used_in_kib: mem_total_in_kb - memory .available() - .get::(), + .get::(), })) } @@ -44,7 +46,7 @@ pub async fn get_swap_data() -> crate::utils::error::Result> let memory = heim::memory::swap().await?; Ok(Some(MemHarvest { - mem_total_in_mb: memory.total().get::(), - mem_used_in_mb: memory.used().get::(), + mem_total_in_kib: memory.total().get::(), + mem_used_in_kib: memory.used().get::(), })) } diff --git a/src/bin/main.rs b/src/bin/main.rs index 869c39db..47572bcf 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -207,11 +207,11 @@ fn main() -> Result<()> { convert_mem_data_points(&app.data_collection, false); app.canvas_data.swap_data = convert_swap_data_points(&app.data_collection, false); - let memory_and_swap_labels = convert_mem_labels(&app.data_collection); - app.canvas_data.mem_label_percent = memory_and_swap_labels.0; - app.canvas_data.mem_label_frac = memory_and_swap_labels.1; - app.canvas_data.swap_label_percent = memory_and_swap_labels.2; - app.canvas_data.swap_label_frac = memory_and_swap_labels.3; + let (memory_labels, swap_labels) = + convert_mem_labels(&app.data_collection); + + app.canvas_data.mem_labels = memory_labels; + app.canvas_data.swap_labels = swap_labels; } if app.used_widgets.use_cpu { diff --git a/src/canvas.rs b/src/canvas.rs index 7fdba228..e0aff886 100644 --- a/src/canvas.rs +++ b/src/canvas.rs @@ -50,10 +50,10 @@ pub struct DisplayableData { pub single_process_data: HashMap, // Contains single process data, key is PID pub finalized_process_data_map: HashMap>, // What's actually displayed, key is the widget ID. pub stringified_process_data_map: HashMap)>, bool)>>, // Represents the row and whether it is disabled, key is the widget ID - pub mem_label_percent: String, - pub swap_label_percent: String, - pub mem_label_frac: String, - pub swap_label_frac: String, + + pub mem_labels: Option<(String, String)>, + pub swap_labels: Option<(String, String)>, + pub mem_data: Vec, pub swap_data: Vec, pub cpu_data: Vec, diff --git a/src/canvas/widgets/mem_basic.rs b/src/canvas/widgets/mem_basic.rs index 7c9de191..3bb40ad7 100644 --- a/src/canvas/widgets/mem_basic.rs +++ b/src/canvas/widgets/mem_basic.rs @@ -51,20 +51,28 @@ impl MemBasicWidget for Painter { 0.0 }; + const EMPTY_MEMORY_FRAC_STRING: &str = "0.0B/0.0B"; + + let trimmed_memory_frac = + if let Some((_label_percent, label_frac)) = &app_state.canvas_data.mem_labels { + label_frac.trim() + } else { + EMPTY_MEMORY_FRAC_STRING + }; + + let trimmed_swap_frac = + if let Some((_label_percent, label_frac)) = &app_state.canvas_data.swap_labels { + label_frac.trim() + } else { + EMPTY_MEMORY_FRAC_STRING + }; + // +7 due to 3 + 2 + 2 columns for the name & space + bar bounds + margin spacing // Then + length of fraction - let ram_bar_length = usize::from( - draw_loc - .width - .saturating_sub(7) - .saturating_sub(app_state.canvas_data.mem_label_frac.trim().len() as u16), - ); - let swap_bar_length = usize::from( - draw_loc - .width - .saturating_sub(7) - .saturating_sub(app_state.canvas_data.swap_label_frac.trim().len() as u16), - ); + let ram_bar_length = + usize::from(draw_loc.width.saturating_sub(7)).saturating_sub(trimmed_memory_frac.len()); + let swap_bar_length = + usize::from(draw_loc.width.saturating_sub(7)).saturating_sub(trimmed_swap_frac.len()); let num_bars_ram = calculate_basic_use_bars(ram_use_percentage, ram_bar_length); let num_bars_swap = calculate_basic_use_bars(swap_use_percentage, swap_bar_length); @@ -73,11 +81,7 @@ impl MemBasicWidget for Painter { format!( "RAM[{}{}{:3.0}%]\n", "|".repeat(num_bars_ram), - " ".repeat( - ram_bar_length - num_bars_ram - + app_state.canvas_data.mem_label_frac.trim().len() - - 4 - ), + " ".repeat(ram_bar_length - num_bars_ram + trimmed_memory_frac.len() - 4), ram_use_percentage.round() ) } else { @@ -85,18 +89,14 @@ impl MemBasicWidget for Painter { "RAM[{}{}{}]\n", "|".repeat(num_bars_ram), " ".repeat(ram_bar_length - num_bars_ram), - &app_state.canvas_data.mem_label_frac.trim() + trimmed_memory_frac ) }; let swap_label = if app_state.basic_mode_use_percent { format!( "SWP[{}{}{:3.0}%]", "|".repeat(num_bars_swap), - " ".repeat( - swap_bar_length - num_bars_swap - + app_state.canvas_data.swap_label_frac.trim().len() - - 4 - ), + " ".repeat(swap_bar_length - num_bars_swap + trimmed_swap_frac.len() - 4), swap_use_percentage.round() ) } else { @@ -104,7 +104,7 @@ impl MemBasicWidget for Painter { "SWP[{}{}{}]", "|".repeat(num_bars_swap), " ".repeat(swap_bar_length - num_bars_swap), - &app_state.canvas_data.swap_label_frac.trim() + trimmed_swap_frac ) }; diff --git a/src/canvas/widgets/mem_graph.rs b/src/canvas/widgets/mem_graph.rs index c3f62197..9136b1ba 100644 --- a/src/canvas/widgets/mem_graph.rs +++ b/src/canvas/widgets/mem_graph.rs @@ -69,40 +69,38 @@ impl MemGraphWidget for Painter { .labels(y_axis_label); let mut mem_canvas_vec: Vec> = vec![]; - let mem_label = format!( - "RAM:{}{}", - app_state.canvas_data.mem_label_percent, app_state.canvas_data.mem_label_frac - ); - mem_canvas_vec.push( - Dataset::default() - .name(&mem_label) - .marker(if app_state.app_config_fields.use_dot { - Marker::Dot - } else { - Marker::Braille - }) - .style(self.colours.ram_style) - .data(&mem_data) - .graph_type(tui::widgets::GraphType::Line), - ); - // FIXME: [SWAP] Hide this if denominator is 0... - let swap_label = format!( - "SWP:{}{}", - app_state.canvas_data.swap_label_percent, app_state.canvas_data.swap_label_frac - ); - mem_canvas_vec.push( - Dataset::default() - .name(&swap_label) - .marker(if app_state.app_config_fields.use_dot { - Marker::Dot - } else { - Marker::Braille - }) - .style(self.colours.swap_style) - .data(&swap_data) - .graph_type(tui::widgets::GraphType::Line), - ); + if let Some((label_percent, label_frac)) = &app_state.canvas_data.mem_labels { + let mem_label = format!("RAM:{}{}", label_percent, label_frac); + mem_canvas_vec.push( + Dataset::default() + .name(mem_label) + .marker(if app_state.app_config_fields.use_dot { + Marker::Dot + } else { + Marker::Braille + }) + .style(self.colours.ram_style) + .data(&mem_data) + .graph_type(tui::widgets::GraphType::Line), + ); + } + + if let Some((label_percent, label_frac)) = &app_state.canvas_data.swap_labels { + let swap_label = format!("SWP:{}{}", label_percent, label_frac); + mem_canvas_vec.push( + Dataset::default() + .name(swap_label) + .marker(if app_state.app_config_fields.use_dot { + Marker::Dot + } else { + Marker::Braille + }) + .style(self.colours.swap_style) + .data(&swap_data) + .graph_type(tui::widgets::GraphType::Line), + ); + } let is_on_widget = widget_id == app_state.current_widget.widget_id; let border_style = if is_on_widget { diff --git a/src/data_conversion.rs b/src/data_conversion.rs index a25a0f82..fb12ba80 100644 --- a/src/data_conversion.rs +++ b/src/data_conversion.rs @@ -272,10 +272,13 @@ pub fn convert_mem_data_points( }; for (time, data) in ¤t_data.timed_data_vec { - let time_from_start: f64 = (current_time.duration_since(*time).as_millis() as f64).floor(); - result.push((-time_from_start, data.mem_data)); - if *time == current_time { - break; + if let Some(mem_data) = data.mem_data { + let time_from_start: f64 = + (current_time.duration_since(*time).as_millis() as f64).floor(); + result.push((-time_from_start, mem_data)); + if *time == current_time { + break; + } } } @@ -297,10 +300,13 @@ pub fn convert_swap_data_points( }; for (time, data) in ¤t_data.timed_data_vec { - let time_from_start: f64 = (current_time.duration_since(*time).as_millis() as f64).floor(); - result.push((-time_from_start, data.swap_data)); - if *time == current_time { - break; + if let Some(swap_data) = data.swap_data { + let time_from_start: f64 = + (current_time.duration_since(*time).as_millis() as f64).floor(); + result.push((-time_from_start, swap_data)); + if *time == current_time { + break; + } } } @@ -309,36 +315,82 @@ pub fn convert_swap_data_points( pub fn convert_mem_labels( current_data: &data_farmer::DataCollection, -) -> (String, String, String, String) { +) -> (Option<(String, String)>, Option<(String, String)>) { + fn return_unit_and_numerator_for_kb(mem_total_kb: u64) -> (&'static str, f64) { + if mem_total_kb < 1024 { + // Stay with KB + ("KB", 1.0) + } else if mem_total_kb < 1_048_576 { + // Use MB + ("MB", 1024.0) + } else if mem_total_kb < 1_073_741_824 { + // Use GB + ("GB", 1_048_576.0) + } else { + // Use TB + ("TB", 1_073_741_824.0) + } + } + ( - format!( - "{:3.0}%", - match current_data.memory_harvest.mem_total_in_mb { - 0 => 0.0, - _ => - current_data.memory_harvest.mem_used_in_mb as f64 * 100.0 - / current_data.memory_harvest.mem_total_in_mb as f64, - } - ), - format!( - " {:.1}GB/{:.1}GB", - current_data.memory_harvest.mem_used_in_mb as f64 / 1024.0, - (current_data.memory_harvest.mem_total_in_mb as f64 / 1024.0) - ), - format!( - "{:3.0}%", - match current_data.swap_harvest.mem_total_in_mb { - 0 => 0.0, - _ => - current_data.swap_harvest.mem_used_in_mb as f64 * 100.0 - / current_data.swap_harvest.mem_total_in_mb as f64, - } - ), - format!( - " {:.1}GB/{:.1}GB", - current_data.swap_harvest.mem_used_in_mb as f64 / 1024.0, - (current_data.swap_harvest.mem_total_in_mb as f64 / 1024.0) - ), + if current_data.memory_harvest.mem_total_in_kib > 0 { + Some(( + format!( + "{:3.0}%", + match current_data.memory_harvest.mem_total_in_kib { + 0 => 0.0, + _ => + current_data.memory_harvest.mem_used_in_kib as f64 + / current_data.memory_harvest.mem_total_in_kib as f64 + * 100.0, + } + ), + { + let (unit, numerator) = return_unit_and_numerator_for_kb( + current_data.memory_harvest.mem_total_in_kib, + ); + + format!( + " {:.1}{}/{:.1}{}", + current_data.memory_harvest.mem_used_in_kib as f64 / numerator, + unit, + (current_data.memory_harvest.mem_total_in_kib as f64 / numerator), + unit + ) + }, + )) + } else { + None + }, + if current_data.swap_harvest.mem_total_in_kib > 0 { + Some(( + format!( + "{:3.0}%", + match current_data.swap_harvest.mem_total_in_kib { + 0 => 0.0, + _ => + current_data.swap_harvest.mem_used_in_kib as f64 + / current_data.swap_harvest.mem_total_in_kib as f64 + * 100.0, + } + ), + { + let (unit, numerator) = return_unit_and_numerator_for_kb( + current_data.swap_harvest.mem_total_in_kib, + ); + + format!( + " {:.1}{}/{:.1}{}", + current_data.swap_harvest.mem_used_in_kib as f64 / numerator, + unit, + (current_data.swap_harvest.mem_total_in_kib as f64 / numerator), + unit + ) + }, + )) + } else { + None + }, ) }