plotly/export.rs
1#[cfg(feature = "plotly_static")]
2pub mod sync {
3 use std::path::Path;
4
5 use crate::{plot::Plot, ImageFormat};
6
7 /// Extension methods for exporting plots using a synchronous exporter.
8 pub trait ExporterSyncExt {
9 /// Convert the `Plot` to a static image of the given image format and
10 /// save at the given location using a provided StaticExporter.
11 ///
12 /// This method allows you to reuse a StaticExporter instance across
13 /// multiple plots, which is more efficient than creating a new one for
14 /// each operation.
15 ///
16 /// This method requires the usage of the `plotly_static` crate using
17 /// one of the available feature flags. For advanced usage (parallelism, exporter reuse, custom config), see the [plotly_static documentation](https://docs.rs/plotly_static/).
18 ///
19 /// # Arguments
20 ///
21 /// * `exporter` - A mutable reference to a StaticExporter instance
22 /// * `filename` - The destination path for the output file
23 /// * `format` - The desired output image format
24 /// * `width` - The width of the output image in pixels
25 /// * `height` - The height of the output image in pixels
26 /// * `scale` - The scale factor for the image (1.0 = normal size)
27 ///
28 /// # Examples
29 ///
30 /// ```no_run
31 /// use plotly::{Plot, Scatter};
32 /// use plotly::export::sync::ExporterSyncExt as _;
33 /// use plotly::plotly_static::{StaticExporterBuilder, ImageFormat};
34 ///
35 /// let mut plot = Plot::new();
36 /// plot.add_trace(Scatter::new(vec![1, 2, 3], vec![4, 5, 6]));
37 ///
38 /// let mut exporter = StaticExporterBuilder::default()
39 /// .build()
40 /// .expect("Failed to create StaticExporter");
41 ///
42 /// // Export multiple plots using the same exporter
43 /// exporter.write_image(&plot, "plot1", ImageFormat::PNG, 800, 600, 1.0)
44 /// .expect("Failed to export plot");
45 ///
46 /// exporter.close();
47 /// ```
48 fn write_image<P: AsRef<Path>>(
49 &mut self,
50 plot: &Plot,
51 filename: P,
52 format: ImageFormat,
53 width: usize,
54 height: usize,
55 scale: f64,
56 ) -> Result<(), Box<dyn std::error::Error>>;
57
58 /// Convert the `Plot` to a static image and return the image as a
59 /// `base64` string. Supported formats are [ImageFormat::JPEG],
60 /// [ImageFormat::PNG] and [ImageFormat::WEBP].
61 ///
62 /// This method allows you to reuse the same StaticExporter instance
63 /// across multiple plots, which is more efficient than creating
64 /// a new one for each operation.
65 ///
66 /// For advanced usage (parallelism, exporter reuse, custom config), see the [plotly_static documentation](https://docs.rs/plotly_static/).
67 ///
68 /// # Arguments
69 ///
70 /// * `format` - The desired output image format
71 /// * `width` - The width of the output image in pixels
72 /// * `height` - The height of the output image in pixels
73 /// * `scale` - The scale factor for the image (1.0 = normal size)
74 ///
75 /// # Examples
76 ///
77 /// ```no_run
78 /// use plotly::{Plot, Scatter};
79 /// use plotly::export::sync::ExporterSyncExt as _;
80 /// use plotly::plotly_static::{StaticExporterBuilder, ImageFormat};
81 ///
82 /// let mut plot = Plot::new();
83 /// plot.add_trace(Scatter::new(vec![1, 2, 3], vec![4, 5, 6]));
84 ///
85 /// let mut exporter = StaticExporterBuilder::default()
86 /// .build()
87 /// .expect("Failed to create StaticExporter");
88 ///
89 /// let base64_data = exporter.to_base64(&plot, ImageFormat::PNG, 800, 600, 1.0)
90 /// .expect("Failed to export plot");
91 ///
92 /// exporter.close();
93 /// ```
94 fn to_base64(
95 &mut self,
96 plot: &Plot,
97 format: ImageFormat,
98 width: usize,
99 height: usize,
100 scale: f64,
101 ) -> Result<String, Box<dyn std::error::Error>>;
102
103 /// Convert the `Plot` to SVG and return it as a String.
104 ///
105 /// This method allows you to reuse the same StaticExporter instance
106 /// across multiple plots, which is more efficient than creating
107 /// a new one for each operation.
108 ///
109 /// For advanced usage (parallelism, exporter reuse, custom config), see the [plotly_static documentation](https://docs.rs/plotly_static/).
110 ///
111 /// # Arguments
112 ///
113 /// * `width` - The width of the output image in pixels
114 /// * `height` - The height of the output image in pixels
115 /// * `scale` - The scale factor for the image (1.0 = normal size)
116 ///
117 /// # Examples
118 ///
119 /// ```no_run
120 /// use plotly::{Plot, Scatter};
121 /// use plotly::export::sync::ExporterSyncExt as _;
122 /// use plotly::plotly_static::{StaticExporterBuilder, ImageFormat};
123 ///
124 /// let mut plot = Plot::new();
125 /// plot.add_trace(Scatter::new(vec![1, 2, 3], vec![4, 5, 6]));
126 ///
127 /// let mut exporter = StaticExporterBuilder::default()
128 /// .build()
129 /// .expect("Failed to create StaticExporter");
130 ///
131 /// let svg_data = exporter.to_svg(&plot, 800, 600, 1.0)
132 /// .expect("Failed to export plot");
133 ///
134 /// exporter.close();
135 /// ```
136 fn to_svg(
137 &mut self,
138 plot: &Plot,
139 width: usize,
140 height: usize,
141 scale: f64,
142 ) -> Result<String, Box<dyn std::error::Error>>;
143 }
144
145 impl ExporterSyncExt for plotly_static::StaticExporter {
146 fn write_image<P: AsRef<Path>>(
147 &mut self,
148 plot: &Plot,
149 filename: P,
150 format: ImageFormat,
151 width: usize,
152 height: usize,
153 scale: f64,
154 ) -> Result<(), Box<dyn std::error::Error>> {
155 self.write_fig(
156 filename.as_ref(),
157 &serde_json::to_value(plot)?,
158 format,
159 width,
160 height,
161 scale,
162 )
163 }
164
165 fn to_base64(
166 &mut self,
167 plot: &Plot,
168 format: ImageFormat,
169 width: usize,
170 height: usize,
171 scale: f64,
172 ) -> Result<String, Box<dyn std::error::Error>> {
173 match format {
174 ImageFormat::JPEG | ImageFormat::PNG | ImageFormat::WEBP => self.write_to_string(
175 &serde_json::to_value(plot)?,
176 format,
177 width,
178 height,
179 scale,
180 ),
181 _ => Err(format!(
182 "Cannot generate base64 string for ImageFormat:{format}. Allowed formats are JPEG, PNG, WEBP"
183 )
184 .into()),
185 }
186 }
187
188 fn to_svg(
189 &mut self,
190 plot: &Plot,
191 width: usize,
192 height: usize,
193 scale: f64,
194 ) -> Result<String, Box<dyn std::error::Error>> {
195 self.write_to_string(
196 &serde_json::to_value(plot)?,
197 ImageFormat::SVG,
198 width,
199 height,
200 scale,
201 )
202 }
203 }
204}
205
206#[cfg(feature = "plotly_static")]
207pub mod r#async {
208 use std::path::Path;
209
210 use async_trait::async_trait;
211
212 use crate::{plot::Plot, ImageFormat};
213
214 /// Extension methods for exporting plots using an asynchronous exporter.
215 #[async_trait(?Send)]
216 pub trait ExporterAsyncExt {
217 /// Convert the `Plot` to a static image of the given format and save at
218 /// the given location using the asynchronous exporter.
219 ///
220 /// The exporter must have been built with the `build_async` method of
221 /// the StaticExporterBuilder.
222 ///
223 /// Functionally signature equivalent to the sync version in
224 /// [`crate::export::sync::ExporterSyncExt::write_image`], but meant for
225 /// async contexts.
226 ///
227 /// For more details see the [plotly_static documentation](https://docs.rs/plotly_static/).
228 async fn write_image<P: AsRef<Path>>(
229 &mut self,
230 plot: &Plot,
231 filename: P,
232 format: ImageFormat,
233 width: usize,
234 height: usize,
235 scale: f64,
236 ) -> Result<(), Box<dyn std::error::Error>>;
237
238 /// Convert the `Plot` to a static image and return the image as a
239 /// `base64` string using the asynchronous exporter.
240 ///
241 /// The exporter must have been built with the `build_async` method of
242 /// the StaticExporterBuilder.
243 ///
244 /// Functionally signature equivalent to the sync version in
245 /// [`crate::export::sync::ExporterSyncExt::to_base64`], but meant for
246 /// async contexts.
247 ///
248 /// For more details see the [plotly_static documentation](https://docs.rs/plotly_static/).
249 async fn to_base64(
250 &mut self,
251 plot: &Plot,
252 format: ImageFormat,
253 width: usize,
254 height: usize,
255 scale: f64,
256 ) -> Result<String, Box<dyn std::error::Error>>;
257
258 /// Convert the `Plot` to SVG and return it as a String using the
259 /// asynchronous exporter.
260 ///
261 /// Functionally signature equivalent to the sync version in
262 /// [`crate::export::sync::ExporterSyncExt::to_svg`], but meant for
263 /// async contexts.
264 ///
265 /// For more details see the [plotly_static documentation](https://docs.rs/plotly_static/).
266 async fn to_svg(
267 &mut self,
268 plot: &Plot,
269 width: usize,
270 height: usize,
271 scale: f64,
272 ) -> Result<String, Box<dyn std::error::Error>>;
273 }
274
275 #[async_trait(?Send)]
276 impl ExporterAsyncExt for plotly_static::AsyncStaticExporter {
277 async fn write_image<P: AsRef<Path>>(
278 &mut self,
279 plot: &Plot,
280 filename: P,
281 format: ImageFormat,
282 width: usize,
283 height: usize,
284 scale: f64,
285 ) -> Result<(), Box<dyn std::error::Error>> {
286 self.write_fig(
287 filename.as_ref(),
288 &serde_json::to_value(plot)?,
289 format,
290 width,
291 height,
292 scale,
293 )
294 .await
295 }
296
297 async fn to_base64(
298 &mut self,
299 plot: &Plot,
300 format: ImageFormat,
301 width: usize,
302 height: usize,
303 scale: f64,
304 ) -> Result<String, Box<dyn std::error::Error>> {
305 match format {
306 ImageFormat::JPEG | ImageFormat::PNG | ImageFormat::WEBP => self
307 .write_to_string(
308 &serde_json::to_value(plot)?,
309 format,
310 width,
311 height,
312 scale,
313 )
314 .await,
315 _ => Err(format!(
316 "Cannot generate base64 string for ImageFormat:{format}. Allowed formats are JPEG, PNG, WEBP"
317 )
318 .into()),
319 }
320 }
321
322 async fn to_svg(
323 &mut self,
324 plot: &Plot,
325 width: usize,
326 height: usize,
327 scale: f64,
328 ) -> Result<String, Box<dyn std::error::Error>> {
329 self.write_to_string(
330 &serde_json::to_value(plot)?,
331 ImageFormat::SVG,
332 width,
333 height,
334 scale,
335 )
336 .await
337 }
338 }
339}