use anyhow::Result;
use serde::{Deserialize, Serialize};
pub mod echarts;
pub mod templates;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum ChartType {
Line,
Scatter,
Bar,
Area,
Heatmap,
Scatter3D,
Surface3D,
Bar3D,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ChartConfig {
pub chart_type: ChartType,
pub title: String,
pub x_label: Option<String>,
pub y_label: Option<String>,
pub z_label: Option<String>,
pub width: u32,
pub height: u32,
pub use_webgl: bool,
pub theme: String,
}
impl Default for ChartConfig {
fn default() -> Self {
Self {
chart_type: ChartType::Line,
title: "XDL Chart".to_string(),
x_label: None,
y_label: None,
z_label: None,
width: 800,
height: 600,
use_webgl: false,
theme: "default".to_string(),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Series2D {
pub name: String,
pub x_data: Vec<f64>,
pub y_data: Vec<f64>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Series3D {
pub name: String,
pub data: Vec<[f64; 3]>,
}
pub fn generate_2d_chart(config: &ChartConfig, series: &[Series2D]) -> Result<String> {
let echarts_option = echarts::build_2d_option(config, series)?;
let html = templates::create_echarts_html(config, &echarts_option)?;
Ok(html)
}
pub fn generate_3d_chart(config: &ChartConfig, series: &[Series3D]) -> Result<String> {
let echarts_option = echarts::build_3d_option(config, series)?;
let html = templates::create_echarts_html(config, &echarts_option)?;
Ok(html)
}
pub fn generate_surface_plot(
config: &ChartConfig,
z_data: &[Vec<f64>],
x_range: (f64, f64),
y_range: (f64, f64),
) -> Result<String> {
let echarts_option = echarts::build_surface_option(config, z_data, x_range, y_range)?;
let html = templates::create_echarts_html(config, &echarts_option)?;
Ok(html)
}
pub fn generate_heatmap(config: &ChartConfig, data: &[[f64; 3]]) -> Result<String> {
let echarts_option = echarts::build_heatmap_option(config, data)?;
let html = templates::create_echarts_html(config, &echarts_option)?;
Ok(html)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_chart_config_default() {
let config = ChartConfig::default();
assert_eq!(config.chart_type, ChartType::Line);
assert_eq!(config.width, 800);
assert_eq!(config.height, 600);
}
#[test]
fn test_series_2d_creation() {
let series = Series2D {
name: "Test".to_string(),
x_data: vec![1.0, 2.0, 3.0],
y_data: vec![4.0, 5.0, 6.0],
};
assert_eq!(series.x_data.len(), 3);
assert_eq!(series.y_data.len(), 3);
}
}