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.
This commit is contained in:
Clement Tsang 2020-12-22 01:12:13 -05:00 committed by GitHub
parent 837c382ee9
commit 9d1f3c9ac2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 176 additions and 124 deletions

View file

@ -30,8 +30,8 @@ pub struct TimedData {
pub rx_data: Value,
pub tx_data: Value,
pub cpu_data: Vec<Value>,
pub mem_data: Value,
pub swap_data: Value,
pub mem_data: Option<Value>,
pub swap_data: Option<Value>,
}
/// 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;

View file

@ -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<Option<MemHarvest>> {
let memory = heim::memory::memory().await?;
let mem_total_in_kb = memory.total().get::<heim::units::information::kibibyte>();
Ok(Some(MemHarvest {
mem_total_in_mb: memory.total().get::<heim::units::information::megabyte>(),
mem_used_in_mb: memory.total().get::<heim::units::information::megabyte>()
mem_total_in_kib: mem_total_in_kb,
mem_used_in_kib: mem_total_in_kb
- memory
.available()
.get::<heim::units::information::megabyte>(),
.get::<heim::units::information::kibibyte>(),
}))
}
@ -44,7 +46,7 @@ pub async fn get_swap_data() -> crate::utils::error::Result<Option<MemHarvest>>
let memory = heim::memory::swap().await?;
Ok(Some(MemHarvest {
mem_total_in_mb: memory.total().get::<heim::units::information::megabyte>(),
mem_used_in_mb: memory.used().get::<heim::units::information::megabyte>(),
mem_total_in_kib: memory.total().get::<heim::units::information::kibibyte>(),
mem_used_in_kib: memory.used().get::<heim::units::information::kibibyte>(),
}))
}

View file

@ -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 {

View file

@ -50,10 +50,10 @@ pub struct DisplayableData {
pub single_process_data: HashMap<Pid, ConvertedProcessData>, // Contains single process data, key is PID
pub finalized_process_data_map: HashMap<u64, Vec<ConvertedProcessData>>, // What's actually displayed, key is the widget ID.
pub stringified_process_data_map: HashMap<u64, Vec<(Vec<(String, Option<String>)>, 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<Point>,
pub swap_data: Vec<Point>,
pub cpu_data: Vec<ConvertedCpuData>,

View file

@ -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
)
};

View file

@ -69,40 +69,38 @@ impl MemGraphWidget for Painter {
.labels(y_axis_label);
let mut mem_canvas_vec: Vec<Dataset<'_>> = 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 {

View file

@ -272,10 +272,13 @@ pub fn convert_mem_data_points(
};
for (time, data) in &current_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 &current_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
},
)
}