summaryrefslogtreecommitdiffstats
path: root/src/canvas/drawing_utils.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/canvas/drawing_utils.rs')
-rw-r--r--src/canvas/drawing_utils.rs222
1 files changed, 208 insertions, 14 deletions
diff --git a/src/canvas/drawing_utils.rs b/src/canvas/drawing_utils.rs
index 7cdb3eb5..3b4fc3f6 100644
--- a/src/canvas/drawing_utils.rs
+++ b/src/canvas/drawing_utils.rs
@@ -1,5 +1,10 @@
+use tui::layout::Rect;
+
use crate::app;
-use std::cmp::{max, min};
+use std::{
+ cmp::{max, min},
+ time::Instant,
+};
/// Return a (hard)-width vector for column widths.
///
@@ -186,8 +191,7 @@ pub fn get_start_position(
}
}
-/// Calculate how many bars are to be
-/// drawn within basic mode's components.
+/// Calculate how many bars are to be drawn within basic mode's components.
pub fn calculate_basic_use_bars(use_percentage: f64, num_bars_available: usize) -> usize {
std::cmp::min(
(num_bars_available as f64 * use_percentage / 100.0).round() as usize,
@@ -195,22 +199,215 @@ pub fn calculate_basic_use_bars(use_percentage: f64, num_bars_available: usize)
)
}
-/// Interpolates between two points. Mainly used to help fill in tui-rs blanks in certain situations.
-/// It is expected point_one is "further left" compared to point_two.
-/// A point is two floats, in (x, y) form. x is time, y is value.
-pub fn interpolate_points(point_one: &(f64, f64), point_two: &(f64, f64), time: f64) -> f64 {
- let delta_x = point_two.0 - point_one.0;
- let delta_y = point_two.1 - point_one.1;
- let slope = delta_y / delta_x;
+/// Determine whether a graph x-label should be hidden.
+pub fn should_hide_x_label(
+ always_hide_time: bool, autohide_time: bool, timer: &mut Option<Instant>, draw_loc: Rect,
+) -> bool {
+ use crate::constants::*;
- (point_one.1 + (time - point_one.0) * slope).max(0.0)
+ if always_hide_time || (autohide_time && timer.is_none()) {
+ true
+ } else if let Some(time) = timer {
+ if Instant::now().duration_since(*time).as_millis() < AUTOHIDE_TIMEOUT_MILLISECONDS.into() {
+ false
+ } else {
+ *timer = None;
+ true
+ }
+ } else {
+ draw_loc.height < TIME_LABEL_HEIGHT_LIMIT
+ }
}
#[cfg(test)]
mod test {
+
use super::*;
#[test]
+ fn test_get_start_position() {
+ use crate::app::ScrollDirection;
+
+ // Scrolling down from start
+ {
+ let mut bar = 0;
+ assert_eq!(
+ get_start_position(10, &ScrollDirection::Down, &mut bar, 0, false),
+ 0
+ );
+ assert_eq!(bar, 0);
+ }
+
+ // Simple scrolling down
+ {
+ let mut bar = 0;
+ assert_eq!(
+ get_start_position(10, &ScrollDirection::Down, &mut bar, 1, false),
+ 0
+ );
+ assert_eq!(bar, 0);
+ }
+
+ // Scrolling down from the middle high up
+ {
+ let mut bar = 0;
+ assert_eq!(
+ get_start_position(10, &ScrollDirection::Down, &mut bar, 5, false),
+ 0
+ );
+ assert_eq!(bar, 0);
+ }
+
+ // Scrolling down into boundary
+ {
+ let mut bar = 0;
+ assert_eq!(
+ get_start_position(10, &ScrollDirection::Down, &mut bar, 11, false),
+ 1
+ );
+ assert_eq!(bar, 1);
+ }
+
+ // Scrolling down from the with non-zero bar
+ {
+ let mut bar = 5;
+ assert_eq!(
+ get_start_position(10, &ScrollDirection::Down, &mut bar, 15, false),
+ 5
+ );
+ assert_eq!(bar, 5);
+ }
+
+ // Force redraw scrolling down (e.g. resize)
+ {
+ let mut bar = 5;
+ assert_eq!(
+ get_start_position(15, &ScrollDirection::Down, &mut bar, 15, true),
+ 0
+ );
+ assert_eq!(bar, 0);
+ }
+
+ // Test jumping down
+ {
+ let mut bar = 1;
+ assert_eq!(
+ get_start_position(10, &ScrollDirection::Down, &mut bar, 20, true),
+ 10
+ );
+ assert_eq!(bar, 10);
+ }
+
+ // Scrolling up from bottom
+ {
+ let mut bar = 10;
+ assert_eq!(
+ get_start_position(10, &ScrollDirection::Up, &mut bar, 20, false),
+ 10
+ );
+ assert_eq!(bar, 10);
+ }
+
+ // Simple scrolling up
+ {
+ let mut bar = 10;
+ assert_eq!(
+ get_start_position(10, &ScrollDirection::Up, &mut bar, 19, false),
+ 10
+ );
+ assert_eq!(bar, 10);
+ }
+
+ // Scrolling up from the middle
+ {
+ let mut bar = 10;
+ assert_eq!(
+ get_start_position(10, &ScrollDirection::Up, &mut bar, 10, false),
+ 10
+ );
+ assert_eq!(bar, 10);
+ }
+
+ // Scrolling up into boundary
+ {
+ let mut bar = 10;
+ assert_eq!(
+ get_start_position(10, &ScrollDirection::Up, &mut bar, 9, false),
+ 9
+ );
+ assert_eq!(bar, 9);
+ }
+
+ // Force redraw scrolling up (e.g. resize)
+ {
+ let mut bar = 5;
+ assert_eq!(
+ get_start_position(10, &ScrollDirection::Up, &mut bar, 15, true),
+ 5
+ );
+ assert_eq!(bar, 5);
+ }
+
+ // Test jumping up
+ {
+ let mut bar = 10;
+ assert_eq!(
+ get_start_position(10, &ScrollDirection::Up, &mut bar, 0, false),
+ 0
+ );
+ assert_eq!(bar, 0);
+ }
+ }
+
+ #[test]
+ fn test_calculate_basic_use_bars() {
+ // Testing various breakpoints and edge cases.
+ assert_eq!(calculate_basic_use_bars(0.0, 15), 0);
+ assert_eq!(calculate_basic_use_bars(1.0, 15), 0);
+ assert_eq!(calculate_basic_use_bars(5.0, 15), 1);
+ assert_eq!(calculate_basic_use_bars(10.0, 15), 2);
+ assert_eq!(calculate_basic_use_bars(40.0, 15), 6);
+ assert_eq!(calculate_basic_use_bars(45.0, 15), 7);
+ assert_eq!(calculate_basic_use_bars(50.0, 15), 8);
+ assert_eq!(calculate_basic_use_bars(100.0, 15), 15);
+ assert_eq!(calculate_basic_use_bars(150.0, 15), 15);
+ }
+
+ #[test]
+ fn test_should_hide_x_label() {
+ use crate::constants::*;
+ use std::time::{Duration, Instant};
+ use tui::layout::Rect;
+
+ let rect = Rect::new(0, 0, 10, 10);
+ let small_rect = Rect::new(0, 0, 10, 6);
+
+ let mut under_timer = Some(Instant::now());
+ let mut over_timer =
+ Instant::now().checked_sub(Duration::from_millis(AUTOHIDE_TIMEOUT_MILLISECONDS + 100));
+
+ assert!(should_hide_x_label(true, false, &mut None, rect));
+ assert!(should_hide_x_label(false, true, &mut None, rect));
+ assert!(should_hide_x_label(false, false, &mut None, small_rect));
+
+ assert!(!should_hide_x_label(
+ false,
+ true,
+ &mut under_timer,
+ small_rect
+ ));
+ assert!(under_timer.is_some());
+
+ assert!(should_hide_x_label(
+ false,
+ true,
+ &mut over_timer,
+ small_rect
+ ));
+ assert!(over_timer.is_none());
+ }
+
+ #[test]
fn test_zero_width() {
assert_eq!(
get_column_widths(
@@ -222,7 +419,6 @@ mod test {
true
),
vec![],
- "vector should be empty"
);
}
@@ -238,7 +434,6 @@ mod test {
true
),
vec![],
- "vector should be empty"
);
}
@@ -254,7 +449,6 @@ mod test {
true
),
vec![2, 2, 7],
- "vector should not be empty"
);
}
}