1use crate::axes::Axes;
5use crate::error::Result;
6use crate::render::render_figure;
7use crate::theme::Theme;
8
9pub struct Figure {
11 pub width: f64,
13 pub height: f64,
15 pub title: Option<String>,
17 pub theme: Theme,
19 pub(crate) axes: Vec<Axes>,
21}
22
23impl Figure {
24 pub fn new() -> Self {
26 Self {
27 width: 800.0,
28 height: 600.0,
29 title: None,
30 theme: Theme::default(),
31 axes: Vec::new(),
32 }
33 }
34
35 pub fn size(mut self, width: f64, height: f64) -> Self {
37 self.width = width;
38 self.height = height;
39 self
40 }
41
42 pub fn title(mut self, title: impl Into<String>) -> Self {
44 self.title = Some(title.into());
45 self
46 }
47
48 pub fn theme(mut self, theme: Theme) -> Self {
50 self.theme = theme;
51 self
52 }
53
54 pub fn add_axes(&mut self) -> &mut Axes {
56 self.axes.push(Axes::new());
57 self.axes.last_mut().unwrap()
58 }
59
60 pub fn to_svg(&self) -> Result<String> {
62 let canvas = render_figure(self)?;
63 let svg = esoc_gfx::backend::svg::render_svg(&canvas)?;
64 Ok(svg)
65 }
66
67 pub fn save_svg(&self, path: &str) -> Result<()> {
69 let svg = self.to_svg()?;
70 std::fs::write(path, svg)?;
71 Ok(())
72 }
73
74 #[cfg(feature = "png")]
76 pub fn to_png(&self) -> Result<Vec<u8>> {
77 use esoc_gfx::backend::RenderBackend;
78 let canvas = render_figure(self)?;
79 let bytes = esoc_gfx::backend::png::PngBackend
80 .render(&canvas)
81 .map_err(crate::error::ChartError::Gfx)?;
82 Ok(bytes)
83 }
84
85 #[cfg(feature = "png")]
87 pub fn save_png(&self, path: &str) -> Result<()> {
88 let bytes = self.to_png()?;
89 std::fs::write(path, bytes)?;
90 Ok(())
91 }
92}
93
94impl Default for Figure {
95 fn default() -> Self {
96 Self::new()
97 }
98}