plotters/
evcxr.rs

1use crate::coord::Shift;
2use crate::drawing::{DrawingArea, IntoDrawingArea};
3use plotters_backend::DrawingBackend;
4use plotters_svg::SVGBackend;
5use std::fs::File;
6use std::io::Write;
7
8#[cfg(feature = "evcxr_bitmap")]
9#[cfg_attr(doc_cfg, doc(cfg(feature = "evcxr_bitmap")))]
10use plotters_bitmap::BitMapBackend;
11
12/// The wrapper for the generated SVG
13pub struct SVGWrapper(String, String);
14
15impl SVGWrapper {
16    /// Displays the contents of the `SVGWrapper` struct.
17    pub fn evcxr_display(&self) {
18        println!("{:?}", self);
19    }
20    /// Sets the style of the `SVGWrapper` struct.
21    pub fn style<S: Into<String>>(mut self, style: S) -> Self {
22        self.1 = style.into();
23        self
24    }
25}
26
27impl std::fmt::Debug for SVGWrapper {
28    fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
29        let svg = self.0.as_str();
30        write!(
31            formatter,
32            "EVCXR_BEGIN_CONTENT text/html\n<div style=\"{}\">{}</div>\nEVCXR_END_CONTENT",
33            self.1, svg
34        )
35    }
36}
37
38/// Start drawing an evcxr figure
39pub fn evcxr_figure<
40    Draw: FnOnce(DrawingArea<SVGBackend, Shift>) -> Result<(), Box<dyn std::error::Error>>,
41>(
42    size: (u32, u32),
43    draw: Draw,
44) -> SVGWrapper {
45    let mut buffer = "".to_string();
46    let root = SVGBackend::with_string(&mut buffer, size).into_drawing_area();
47    draw(root).expect("Drawing failure");
48    SVGWrapper(buffer, "".to_string())
49}
50
51/// An evcxr figure that can save to the local file system and render in a notebook.
52pub fn evcxr_figure_with_saving<
53    Draw: FnOnce(DrawingArea<SVGBackend, Shift>) -> Result<(), Box<dyn std::error::Error>>,
54>(
55    filename: &str,
56    size: (u32, u32),
57    draw: Draw,
58) -> SVGWrapper {
59    let mut buffer = "".to_string();
60    let root = SVGBackend::with_string(&mut buffer, size).into_drawing_area();
61    draw(root).expect("Drawing failure");
62
63    let mut file = File::create(filename).expect("Unable to create file");
64    file.write_all(buffer.as_bytes())
65        .expect("Unable to write data");
66
67    SVGWrapper(buffer, "".to_string())
68}
69/// Start drawing an evcxr figure
70#[cfg(feature = "evcxr_bitmap")]
71#[cfg_attr(doc_cfg, doc(cfg(feature = "evcxr_bitmap")))]
72pub fn evcxr_bitmap_figure<
73    Draw: FnOnce(DrawingArea<BitMapBackend, Shift>) -> Result<(), Box<dyn std::error::Error>>,
74>(
75    size: (u32, u32),
76    draw: Draw,
77) -> SVGWrapper {
78    const PIXEL_SIZE: usize = 3;
79
80    let mut buf = vec![0; (size.0 as usize) * (size.1 as usize) * PIXEL_SIZE];
81
82    let root = BitMapBackend::with_buffer(&mut buf, size).into_drawing_area();
83    draw(root).expect("Drawing failure");
84    let mut buffer = "".to_string();
85    {
86        let mut svg_root = SVGBackend::with_string(&mut buffer, size);
87        svg_root
88            .blit_bitmap((0, 0), size, &buf)
89            .expect("Failure converting to SVG");
90    }
91    SVGWrapper(buffer, "".to_string())
92}