Skip to main content

ppt_rs/generator/charts/
builder.rs

1//! Chart builder for fluent API
2
3use crate::core::ElementPlacement;
4use super::data::{Chart, ChartSeries};
5use super::types::ChartType;
6
7/// Chart builder for fluent API
8pub struct ChartBuilder {
9    title: String,
10    chart_type: ChartType,
11    categories: Vec<String>,
12    series: Vec<ChartSeries>,
13    placement: ElementPlacement,
14}
15
16impl ChartBuilder {
17    /// Create a new chart builder
18    pub fn new(title: &str, chart_type: ChartType) -> Self {
19        ChartBuilder {
20            title: title.to_string(),
21            chart_type,
22            categories: Vec::new(),
23            series: Vec::new(),
24            placement: ElementPlacement::chart_defaults(),
25        }
26    }
27
28    /// Set chart position
29    pub fn position(mut self, x: u32, y: u32) -> Self {
30        self.placement.set_position(x, y);
31        self
32    }
33
34    /// Set chart size
35    pub fn size(mut self, width: u32, height: u32) -> Self {
36        self.placement.set_size(width, height);
37        self
38    }
39
40    /// Add categories
41    pub fn categories(mut self, categories: Vec<&str>) -> Self {
42        self.categories = categories.into_iter().map(|c| c.to_string()).collect();
43        self
44    }
45
46    /// Add a data series
47    pub fn add_series(mut self, series: ChartSeries) -> Self {
48        self.series.push(series);
49        self
50    }
51
52    /// Build the chart
53    pub fn build(self) -> Chart {
54        Chart {
55            title: self.title,
56            chart_type: self.chart_type,
57            categories: self.categories,
58            series: self.series,
59            x: self.placement.x,
60            y: self.placement.y,
61            width: self.placement.width,
62            height: self.placement.height,
63        }
64    }
65}
66
67#[cfg(test)]
68mod tests {
69    use super::*;
70
71    #[test]
72    fn test_chart_builder() {
73        let chart = ChartBuilder::new("Revenue", ChartType::Bar)
74            .categories(vec!["Q1", "Q2", "Q3"])
75            .add_series(ChartSeries::new("2023", vec![100.0, 150.0, 200.0]))
76            .add_series(ChartSeries::new("2024", vec![120.0, 180.0, 220.0]))
77            .position(100000, 200000)
78            .size(4000000, 3000000)
79            .build();
80
81        assert_eq!(chart.title, "Revenue");
82        assert_eq!(chart.chart_type, ChartType::Bar);
83        assert_eq!(chart.category_count(), 3);
84        assert_eq!(chart.series_count(), 2);
85        assert_eq!(chart.x, 100000);
86        assert_eq!(chart.y, 200000);
87    }
88}