1use anyhow::Result;
7use serde::{Deserialize, Serialize};
8
9pub mod echarts;
10pub mod templates;
11
12#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
14#[serde(rename_all = "lowercase")]
15pub enum ChartType {
16 Line,
18 Scatter,
20 Bar,
22 Area,
24 Heatmap,
26 Scatter3D,
28 Surface3D,
30 Bar3D,
32}
33
34#[derive(Debug, Clone, Serialize, Deserialize)]
36pub struct ChartConfig {
37 pub chart_type: ChartType,
39 pub title: String,
41 pub x_label: Option<String>,
43 pub y_label: Option<String>,
45 pub z_label: Option<String>,
47 pub width: u32,
49 pub height: u32,
51 pub use_webgl: bool,
53 pub theme: String,
55}
56
57impl Default for ChartConfig {
58 fn default() -> Self {
59 Self {
60 chart_type: ChartType::Line,
61 title: "XDL Chart".to_string(),
62 x_label: None,
63 y_label: None,
64 z_label: None,
65 width: 800,
66 height: 600,
67 use_webgl: false,
68 theme: "default".to_string(),
69 }
70 }
71}
72
73#[derive(Debug, Clone, Serialize, Deserialize)]
75pub struct Series2D {
76 pub name: String,
78 pub x_data: Vec<f64>,
80 pub y_data: Vec<f64>,
82}
83
84#[derive(Debug, Clone, Serialize, Deserialize)]
86pub struct Series3D {
87 pub name: String,
89 pub data: Vec<[f64; 3]>,
91}
92
93pub fn generate_2d_chart(config: &ChartConfig, series: &[Series2D]) -> Result<String> {
95 let echarts_option = echarts::build_2d_option(config, series)?;
96 let html = templates::create_echarts_html(config, &echarts_option)?;
97 Ok(html)
98}
99
100pub fn generate_3d_chart(config: &ChartConfig, series: &[Series3D]) -> Result<String> {
102 let echarts_option = echarts::build_3d_option(config, series)?;
103 let html = templates::create_echarts_html(config, &echarts_option)?;
104 Ok(html)
105}
106
107pub fn generate_surface_plot(
109 config: &ChartConfig,
110 z_data: &[Vec<f64>],
111 x_range: (f64, f64),
112 y_range: (f64, f64),
113) -> Result<String> {
114 let echarts_option = echarts::build_surface_option(config, z_data, x_range, y_range)?;
115 let html = templates::create_echarts_html(config, &echarts_option)?;
116 Ok(html)
117}
118
119pub fn generate_heatmap(config: &ChartConfig, data: &[[f64; 3]]) -> Result<String> {
121 let echarts_option = echarts::build_heatmap_option(config, data)?;
122 let html = templates::create_echarts_html(config, &echarts_option)?;
123 Ok(html)
124}
125
126#[cfg(test)]
127mod tests {
128 use super::*;
129
130 #[test]
131 fn test_chart_config_default() {
132 let config = ChartConfig::default();
133 assert_eq!(config.chart_type, ChartType::Line);
134 assert_eq!(config.width, 800);
135 assert_eq!(config.height, 600);
136 }
137
138 #[test]
139 fn test_series_2d_creation() {
140 let series = Series2D {
141 name: "Test".to_string(),
142 x_data: vec![1.0, 2.0, 3.0],
143 y_data: vec![4.0, 5.0, 6.0],
144 };
145 assert_eq!(series.x_data.len(), 3);
146 assert_eq!(series.y_data.len(), 3);
147 }
148}