use std::collections::VecDeque;
use ratatui::prelude::*;
pub fn sparkline_data(data: &VecDeque<f64>) -> Vec<u64> {
let max_val = data.iter().cloned().fold(f64::MIN, f64::max);
let scale = if max_val > 0.0 { 100.0 / max_val } else { 1.0 };
data.iter().map(|v| (v * scale) as u64).collect()
}
pub fn mini_progress_bar(progress: f32, width: usize) -> String {
let filled = (progress * width as f32).round() as usize;
let empty = width.saturating_sub(filled);
let filled_char = '\u{2588}'; let empty_char = '\u{2591}';
format!(
"{}{}",
filled_char.to_string().repeat(filled),
empty_char.to_string().repeat(empty)
)
}
pub fn format_si(n: u64) -> String {
const K: u64 = 1_000;
const M: u64 = 1_000_000;
const G: u64 = 1_000_000_000;
if n >= G {
format!("{:.1}G", n as f64 / G as f64)
} else if n >= M {
format!("{:.1}M", n as f64 / M as f64)
} else if n >= K {
format!("{:.1}K", n as f64 / K as f64)
} else {
format!("{}", n)
}
}
pub fn segmented_progress_bar(
succeeded: u64,
skipped: u64,
total: u64,
width: usize,
) -> Vec<Span<'static>> {
if total == 0 {
return vec![Span::raw("░".repeat(width))];
}
let succeeded_width = ((succeeded as f64 / total as f64) * width as f64).round() as usize;
let skipped_width = ((skipped as f64 / total as f64) * width as f64).round() as usize;
let empty_width = width.saturating_sub(succeeded_width + skipped_width);
vec![
Span::styled(
"█".repeat(succeeded_width),
Style::default().fg(Color::Green),
),
Span::styled(
"█".repeat(skipped_width),
Style::default().fg(Color::Yellow),
),
Span::raw("░".repeat(empty_width)),
]
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_mini_progress_bar() {
assert_eq!(mini_progress_bar(0.0, 10).chars().count(), 10);
assert_eq!(mini_progress_bar(1.0, 10).chars().count(), 10);
assert_eq!(mini_progress_bar(0.5, 10).chars().count(), 10);
}
#[test]
fn test_format_si() {
assert_eq!(format_si(0), "0");
assert_eq!(format_si(999), "999");
assert_eq!(format_si(1000), "1.0K");
assert_eq!(format_si(1500), "1.5K");
assert_eq!(format_si(1_000_000), "1.0M");
assert_eq!(format_si(1_500_000), "1.5M");
assert_eq!(format_si(1_000_000_000), "1.0G");
}
}