scrin 0.1.80

A terminal UI toolkit with panes, widgets, overlays, animations, and Aisling-powered effects/loaders.
Documentation
use crate::core::buffer::Buffer;
use crate::core::color::Color;
use crate::core::rect::Rect;
use crate::widgets::Widget;

#[derive(Debug, Clone)]
pub struct Sparkline {
    pub data: Vec<u64>,
    pub max: Option<u64>,
    pub color: Color,
    pub bar_set: &'static str,
}

impl Sparkline {
    pub fn new() -> Self {
        Self {
            data: Vec::new(),
            max: None,
            color: Color::rgb(88, 166, 255),
            bar_set: " ▁▂▃▄▅▆▇█",
        }
    }

    pub fn with_data(mut self, data: Vec<u64>) -> Self {
        self.data = data;
        self
    }

    pub fn with_max(mut self, max: u64) -> Self {
        self.max = Some(max);
        self
    }

    pub fn with_color(mut self, color: Color) -> Self {
        self.color = color;
        self
    }

    fn get_bar(&self, value: u64, max: u64) -> char {
        if max == 0 {
            return ' ';
        }
        let ratio = value as f32 / max as f32;
        let idx = (ratio * (self.bar_set.len() - 1) as f32) as usize;
        self.bar_set.chars().nth(idx).unwrap_or(' ')
    }
}

impl Widget for Sparkline {
    fn render(&self, buffer: &mut Buffer, area: Rect) {
        if self.data.is_empty() || area.width == 0 {
            return;
        }
        let max = self
            .max
            .unwrap_or_else(|| self.data.iter().copied().max().unwrap_or(1));
        let w = area.width as usize;
        for i in 0..w {
            let data_idx = (i * self.data.len()) / w;
            let value = self.data.get(data_idx).copied().unwrap_or(0);
            let ch = self.get_bar(value, max);
            buffer.set(
                area.x as usize + i,
                area.y as usize,
                crate::core::buffer::Cell {
                    ch,
                    fg: self.color,
                    bg: None,
                    bold: false,
                    italic: false,
                    underlined: false,
                },
            );
        }
    }
}

impl Default for Sparkline {
    fn default() -> Self {
        Self::new()
    }
}