Skip to main content

esoc_chart/
theme.rs

1// SPDX-License-Identifier: MIT OR Apache-2.0
2//! Chart themes controlling colors, fonts, and visual style.
3
4use esoc_gfx::color::Color;
5use esoc_gfx::palette::Palette;
6
7/// A theme controlling the visual appearance of charts.
8#[derive(Clone, Debug)]
9pub struct Theme {
10    /// Background color.
11    pub background: Color,
12    /// Foreground color (text, axes, ticks).
13    pub foreground: Color,
14    /// Color palette for data series.
15    pub palette: Palette,
16    /// Grid line color.
17    pub grid_color: Color,
18    /// Grid line width.
19    pub grid_width: f64,
20    /// Whether to show grid lines.
21    pub show_grid: bool,
22    /// Title font size.
23    pub title_font_size: f64,
24    /// Axis label font size.
25    pub label_font_size: f64,
26    /// Tick label font size.
27    pub tick_font_size: f64,
28    /// Legend font size.
29    pub legend_font_size: f64,
30    /// Font family.
31    pub font_family: String,
32    /// Axis line width.
33    pub axis_width: f64,
34    /// Default data line width.
35    pub line_width: f64,
36    /// Default scatter point radius.
37    pub point_radius: f64,
38}
39
40impl Theme {
41    /// Default light theme.
42    pub fn light() -> Self {
43        Self {
44            background: Color::WHITE,
45            foreground: Color::BLACK,
46            palette: Palette::tab10(),
47            grid_color: Color::new(0.9, 0.9, 0.9, 1.0),
48            grid_width: 0.5,
49            show_grid: true,
50            title_font_size: 16.0,
51            label_font_size: 13.0,
52            tick_font_size: 11.0,
53            legend_font_size: 11.0,
54            font_family: "sans-serif".to_string(),
55            axis_width: 1.0,
56            line_width: 2.0,
57            point_radius: 4.0,
58        }
59    }
60
61    /// Dark theme.
62    pub fn dark() -> Self {
63        Self {
64            background: Color::from_rgb8(0x1e, 0x1e, 0x2e),
65            foreground: Color::from_rgb8(0xcd, 0xd6, 0xf4),
66            palette: Palette::tab10(),
67            grid_color: Color::new(0.3, 0.3, 0.35, 1.0),
68            grid_width: 0.5,
69            show_grid: true,
70            title_font_size: 16.0,
71            label_font_size: 13.0,
72            tick_font_size: 11.0,
73            legend_font_size: 11.0,
74            font_family: "sans-serif".to_string(),
75            axis_width: 1.0,
76            line_width: 2.0,
77            point_radius: 4.0,
78        }
79    }
80
81    /// Minimal theme — no grid, thin axes.
82    pub fn minimal() -> Self {
83        Self {
84            background: Color::WHITE,
85            foreground: Color::from_rgb8(0x33, 0x33, 0x33),
86            palette: Palette::tab10(),
87            grid_color: Color::TRANSPARENT,
88            grid_width: 0.0,
89            show_grid: false,
90            title_font_size: 14.0,
91            label_font_size: 12.0,
92            tick_font_size: 10.0,
93            legend_font_size: 10.0,
94            font_family: "sans-serif".to_string(),
95            axis_width: 0.5,
96            line_width: 1.5,
97            point_radius: 3.0,
98        }
99    }
100}
101
102impl Default for Theme {
103    fn default() -> Self {
104        Self::light()
105    }
106}