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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
use std::ffi::OsStr;
use std::path::Path;
use svg;
use svg::Document;
use svg::Node;
use crate::errors::Result;
use crate::view::View;
use failure::ResultExt;
pub struct Page<'a> {
views: Vec<&'a View>,
num_views: u32,
dimensions: (u32, u32),
}
impl<'a> Page<'a> {
pub fn empty() -> Self {
Page {
views: Vec::new(),
num_views: 0,
dimensions: (600, 400),
}
}
pub fn single(view: &'a View) -> Self {
Page::empty().add_plot(view)
}
pub fn dimensions(mut self, x: u32, y: u32) -> Self {
self.dimensions = (x, y);
self
}
pub fn add_plot(mut self, view: &'a View) -> Self {
self.views.push(view);
self.num_views += 1;
self
}
pub fn to_svg(&self) -> Result<svg::Document> {
let (width, height) = self.dimensions;
let mut document = Document::new().set("viewBox", (0, 0, width, height));
let x_margin = 80;
let y_margin = 60;
let x_offset = 0.6 * f64::from(x_margin);
let y_offset = 0.6 * f64::from(y_margin);
for &view in &self.views {
let view_group = view
.to_svg(f64::from(width - x_margin), f64::from(height - y_margin))?
.set(
"transform",
format!("translate({}, {})", x_offset, f64::from(height) - y_offset),
);
document.append(view_group);
}
Ok(document)
}
pub fn to_text(&self) -> Result<String> {
let (width, height) = self.dimensions;
let view = self.views[0];
view.to_text(width, height)
}
pub fn save<P>(&self, path: P) -> Result<()>
where
P: AsRef<Path>,
{
match path.as_ref().extension().and_then(OsStr::to_str) {
Some("svg") => svg::save(path, &self.to_svg()?)
.context("saving svg")
.map_err(From::from),
_ => Ok(()),
}
}
}