1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
/*!
The `page` module provides structures for laying out and rendering multiple views.
*/

use std::path::Path;
use std::ffi::OsStr;

use svg;
use svg::Node;
use svg::Document;

use view::View;

/**
A single page page laying out the views in a grid
*/
pub struct Page<'a> {
    views: Vec<&'a View<'a>>,
    num_views: u32,
}

impl<'a> Page<'a> {
    /**
    Creates a plot containing a single view
    */
    pub fn single(view: &'a View) -> Self {
        Page {
            views: vec![view],
            num_views: 1,
        }
    }

    /**
    Render the plot to an svg document
    */
    pub fn to_svg(&self) -> svg::Document {
        let mut document = Document::new().set("viewBox", (0, 0, 600, 400));
        // TODO put multiple views in correct places
        for &view in &self.views {
            let view_group = view.to_svg(500., 340.)
                .set("transform", format!("translate({}, {})", 50, 360));
            document.append(view_group);
        }
        document
    }

    /**
    Render the plot to an `String`
    */
    pub fn to_text(&self) -> String {
        // TODO compose multiple views into a plot
        let view = self.views[0];
        view.to_text(90, 30)
    }

    /**
    Save the plot to a file.

    The type of file will be based on the file extension.
    */

    pub fn save<P>(&self, path: P)
    where
        P: AsRef<Path>,
    {
        match path.as_ref().extension().and_then(OsStr::to_str) {
            Some("svg") => {
                svg::save(path, &self.to_svg()).unwrap();
            }
            _ => {
                // some default
            }
        }
    }
}