scirs2_neural/visualization/
config.rs1use serde::Serialize;
7use std::path::PathBuf;
8#[derive(Debug, Clone, Serialize)]
10pub struct VisualizationConfig {
11 pub output_dir: PathBuf,
13 pub image_format: ImageFormat,
15 pub interactive: InteractiveConfig,
17 pub style: StyleConfig,
19 pub performance: PerformanceConfig,
21}
22#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize)]
24pub enum ImageFormat {
25 PNG,
27 SVG,
29 PDF,
31 HTML,
33 JSON,
35}
36
37#[derive(Debug, Clone, Serialize)]
39pub struct InteractiveConfig {
40 pub enable_interaction: bool,
42 pub server_port: u16,
44 pub refresh_interval_ms: u32,
46 pub real_time_updates: bool,
48 pub max_data_points: usize,
50}
51
52#[derive(Debug, Clone, Serialize)]
54pub struct StyleConfig {
55 pub color_palette: ColorPalette,
57 pub font: FontConfig,
59 pub layout: LayoutConfig,
61 pub theme: Theme,
63}
64
65#[derive(Debug, Clone, PartialEq, Serialize)]
67pub enum ColorPalette {
68 Default,
70 ColorblindFriendly,
72 HighContrast,
74 Grayscale,
76 Custom(Vec<String>),
78}
79
80#[derive(Debug, Clone, Serialize)]
82pub struct FontConfig {
83 pub family: String,
85 pub size: u32,
87 pub title_scale: f32,
89 pub label_scale: f32,
91}
92
93#[derive(Debug, Clone, Serialize)]
95pub struct LayoutConfig {
96 pub width: u32,
98 pub height: u32,
100 pub margins: Margins,
102 pub grid: GridConfig,
104}
105
106#[derive(Debug, Clone, Serialize)]
108pub struct Margins {
109 pub top: u32,
111 pub bottom: u32,
113 pub left: u32,
115 pub right: u32,
117}
118
119#[derive(Debug, Clone, Serialize)]
121pub struct GridConfig {
122 pub show_grid: bool,
124 pub grid_color: String,
126 pub grid_width: u32,
128 pub grid_opacity: f32,
130}
131
132#[derive(Debug, Clone, PartialEq, Serialize)]
134pub enum Theme {
135 Light,
137 Dark,
139 Auto,
141 Custom(CustomTheme),
143}
144
145#[derive(Debug, Clone, PartialEq, Serialize)]
147pub struct CustomTheme {
148 pub background: String,
150 pub text: String,
152 pub primary: String,
154 pub secondary: String,
156 pub success: String,
158 pub warning: String,
160 pub error: String,
162}
163
164#[derive(Debug, Clone, Serialize)]
166pub struct PerformanceConfig {
167 pub max_points_per_plot: usize,
169 pub enable_downsampling: bool,
171 pub downsampling_strategy: DownsamplingStrategy,
173 pub enable_caching: bool,
175 pub cache_size_mb: usize,
177}
178
179#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
181pub enum DownsamplingStrategy {
182 Uniform,
184 LTTB,
186 MinMax,
188 Statistical,
190}
191
192impl Default for VisualizationConfig {
194 fn default() -> Self {
195 Self {
196 output_dir: std::env::current_dir().unwrap_or_else(|_| PathBuf::from(".")),
197 image_format: ImageFormat::SVG,
198 interactive: InteractiveConfig::default(),
199 style: StyleConfig::default(),
200 performance: PerformanceConfig::default(),
201 }
202 }
203}
204
205impl Default for InteractiveConfig {
206 fn default() -> Self {
207 Self {
208 enable_interaction: true,
209 server_port: 8080,
210 refresh_interval_ms: 1000,
211 real_time_updates: true,
212 max_data_points: 10000,
213 }
214 }
215}
216
217impl Default for StyleConfig {
218 fn default() -> Self {
219 Self {
220 color_palette: ColorPalette::Default,
221 font: FontConfig::default(),
222 layout: LayoutConfig::default(),
223 theme: Theme::Light,
224 }
225 }
226}
227
228impl Default for FontConfig {
229 fn default() -> Self {
230 Self {
231 family: "Arial, sans-serif".to_string(),
232 size: 12,
233 title_scale: 1.5,
234 label_scale: 0.9,
235 }
236 }
237}
238
239impl Default for LayoutConfig {
240 fn default() -> Self {
241 Self {
242 width: 800,
243 height: 600,
244 margins: Margins::default(),
245 grid: GridConfig::default(),
246 }
247 }
248}
249
250impl Default for Margins {
251 fn default() -> Self {
252 Self {
253 top: 40,
254 bottom: 60,
255 left: 80,
256 right: 40,
257 }
258 }
259}
260
261impl Default for GridConfig {
262 fn default() -> Self {
263 Self {
264 show_grid: true,
265 grid_color: "#e0e0e0".to_string(),
266 grid_width: 1,
267 grid_opacity: 0.5,
268 }
269 }
270}
271
272impl Default for PerformanceConfig {
273 fn default() -> Self {
274 Self {
275 max_points_per_plot: 10000,
276 enable_downsampling: true,
277 downsampling_strategy: DownsamplingStrategy::Uniform,
278 enable_caching: true,
279 cache_size_mb: 100,
280 }
281 }
282}
283
284#[cfg(test)]
285mod tests {
286 use super::*;
287 #[test]
288 fn test_default_config() {
289 let config = VisualizationConfig::default();
290 assert_eq!(config.image_format, ImageFormat::SVG);
291 assert_eq!(config.interactive.server_port, 8080);
292 assert_eq!(config.style.theme, Theme::Light);
293 }
294
295 #[test]
296 fn test_custom_color_palette() {
297 let custom_colors = vec![
298 "#ff0000".to_string(),
299 "#00ff00".to_string(),
300 "#0000ff".to_string(),
301 ];
302 let palette = ColorPalette::Custom(custom_colors.clone());
303 match palette {
304 ColorPalette::Custom(colors) => assert_eq!(colors, custom_colors),
305 _ => panic!("Expected custom color palette"),
306 }
307 }
308
309 #[test]
310 fn test_interactive_config() {
311 let config = InteractiveConfig {
312 enable_interaction: false,
313 server_port: 3000,
314 ..Default::default()
315 };
316 assert!(!config.enable_interaction);
317 assert_eq!(config.server_port, 3000);
318 }
319
320 #[test]
321 fn test_performance_config() {
322 let config = PerformanceConfig::default();
323 assert!(config.enable_downsampling);
324 assert_eq!(config.downsampling_strategy, DownsamplingStrategy::Uniform);
325 assert!(config.enable_caching);
326 }
327
328 #[test]
329 fn test_theme_variants() {
330 let light = Theme::Light;
331 let dark = Theme::Dark;
332 let auto = Theme::Auto;
333 assert_eq!(light, Theme::Light);
334 assert_eq!(dark, Theme::Dark);
335 assert_eq!(auto, Theme::Auto);
336 }
337
338 #[test]
339 fn test_custom_theme() {
340 let custom = CustomTheme {
341 background: "#ffffff".to_string(),
342 text: "#000000".to_string(),
343 primary: "#007bff".to_string(),
344 secondary: "#6c757d".to_string(),
345 success: "#28a745".to_string(),
346 warning: "#ffc107".to_string(),
347 error: "#dc3545".to_string(),
348 };
349 let theme = Theme::Custom(custom.clone());
350 match theme {
351 Theme::Custom(t) => {
352 assert_eq!(t.background, "#ffffff");
353 assert_eq!(t.primary, "#007bff");
354 }
355 _ => panic!("Expected custom theme"),
356 }
357 }
358}