charming_fork_zephyr/renderer/
html_renderer.rs

1use handlebars::Handlebars;
2
3use crate::{component::SaveAsImageType, theme::Theme, Chart, EchartsError};
4
5pub struct HtmlRenderer {
6    title: String,
7    theme: Theme,
8    width: u64,
9    height: u64,
10}
11
12impl HtmlRenderer {
13    pub fn new<S: Into<String>>(title: S, width: u64, height: u64) -> Self {
14        Self {
15            title: title.into(),
16            theme: Theme::Default,
17            width,
18            height,
19        }
20    }
21
22    pub fn theme(mut self, theme: Theme) -> Self {
23        self.theme = theme;
24        self
25    }
26
27    pub fn render(&self, chart: &Chart) -> Result<String, EchartsError> {
28        let template = include_str!("../asset/charts.html.hbs");
29        let (theme, theme_source) = self.theme.to_str();
30        let canvas_type = match chart.save_as_image_type() {
31            Some(&SaveAsImageType::Svg) => "svg".to_string(),
32            _ => "canvas".to_string(),
33        };
34        let data = Handlebars::new()
35            .render_template(
36                template,
37                &serde_json::json!({
38                    "title": self.title,
39                    "theme": theme,
40                    "theme_source": theme_source,
41                    "width": self.width,
42                    "height": self.height,
43                    "chart_id": "chart",
44                    "canvas_type": canvas_type,
45                    "chart_option": chart.to_string(),
46                }),
47            )
48            .map_err(|error| EchartsError::HtmlRenderingError(error.to_string()))?;
49        Ok(data)
50    }
51
52    pub fn save<P: AsRef<std::path::Path>>(
53        &mut self,
54        chart: &Chart,
55        path: P,
56    ) -> Result<(), EchartsError> {
57        let svg = self.render(chart)?;
58        std::fs::write(path, svg)
59            .map_err(|error| EchartsError::ImageRenderingError(error.to_string()))
60    }
61}