Skip to main content

oino_ui/widgets/
sparkline.rs

1//! ratatui `Sparkline` (§4.5.1).
2
3use serde::{Deserialize, Serialize};
4
5use crate::node::{Common, IntoNode, Node};
6
7/// Sparkline drawing direction.
8#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash, Serialize, Deserialize)]
9pub enum SparkDirection {
10    /// Oldest value on the left.
11    #[default]
12    LeftToRight,
13    /// Oldest value on the right.
14    RightToLeft,
15}
16
17/// Bar glyph set.
18#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash, Serialize, Deserialize)]
19pub enum BarSet {
20    /// Nine levels (ratatui default `▁▂▃▄▅▆▇█`).
21    #[default]
22    Nine,
23    /// Three levels (`░▒▓`).
24    Three,
25}
26
27/// ratatui `Sparkline` (§4.5.1). `None` data points render the absent-value symbol.
28#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
29#[serde(rename_all = "camelCase")]
30pub struct Sparkline {
31    /// Common node props (`key`, `style`, `block`, `fallback`).
32    #[serde(flatten)]
33    pub common: Common,
34    /// Values (≤ 1 000, §4.8).
35    pub data: Vec<Option<u64>>,
36    /// Maximum value (auto from data when absent).
37    #[serde(default, skip_serializing_if = "Option::is_none")]
38    pub max: Option<u64>,
39    /// Drawing direction.
40    #[serde(default, skip_serializing_if = "Option::is_none")]
41    pub direction: Option<SparkDirection>,
42    /// Bar glyph set.
43    #[serde(default, skip_serializing_if = "Option::is_none")]
44    pub bar_set: Option<BarSet>,
45    /// Symbol for `None` points (ratatui default `" "`).
46    #[serde(default, skip_serializing_if = "Option::is_none")]
47    pub absent_value_symbol: Option<String>,
48}
49
50impl Sparkline {
51    /// A sparkline from data points.
52    #[must_use]
53    pub fn new(data: impl IntoIterator<Item = Option<u64>>) -> Self {
54        Self {
55            data: data.into_iter().collect(),
56            ..Self::default()
57        }
58    }
59
60    /// Sets the maximum value.
61    #[must_use]
62    pub fn max(mut self, max: u64) -> Self {
63        self.max = Some(max);
64        self
65    }
66
67    /// Sets the drawing direction.
68    #[must_use]
69    pub fn direction(mut self, direction: SparkDirection) -> Self {
70        self.direction = Some(direction);
71        self
72    }
73
74    /// Sets the bar glyph set.
75    #[must_use]
76    pub fn bar_set(mut self, bar_set: BarSet) -> Self {
77        self.bar_set = Some(bar_set);
78        self
79    }
80
81    /// Sets the absent-value symbol.
82    #[must_use]
83    pub fn absent_value_symbol(mut self, symbol: impl Into<String>) -> Self {
84        self.absent_value_symbol = Some(symbol.into());
85        self
86    }
87}
88
89impl IntoNode for Sparkline {}
90impl From<Sparkline> for Node {
91    fn from(s: Sparkline) -> Self {
92        Node::Sparkline(s)
93    }
94}