Skip to content

Commit 334b4b2

Browse files
committed
Settle the 'optional builder' pattern a little using clones
1 parent 4b3a160 commit 334b4b2

File tree

7 files changed

+79
-36
lines changed

7 files changed

+79
-36
lines changed

examples/scatter_svg.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,14 @@ extern crate plotlib;
22

33
fn main() {
44
let data = [(-3.0, 2.3), (-1.6, 5.3), (0.3, 0.7), (4.3, -1.4), (6.4, 4.3), (8.5, 3.7)];
5-
let s = plotlib::scatter::Scatter::from_vec(&data);
5+
let s1 = plotlib::scatter::Scatter::from_vec(&data).style(plotlib::scatter::Style::new()
6+
.marker(plotlib::scatter::Marker::Square)
7+
.colour("#DD3355".into()));
8+
let s2 = plotlib::scatter::Scatter::from_vec(&[(-1.4, 2.5), (7.2, -0.3)])
9+
.style(plotlib::scatter::Style::new().colour("#35C788".into()));
610
let v = plotlib::view::View::new()
7-
.add(&s)
11+
.add(&s1)
12+
.add(&s2)
813
.x_range(-5., 10.)
914
.y_range(-2., 6.);
1015
plotlib::plot::Plot::single(&v).save("scatter.svg");

examples/scatter_text.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@ extern crate plotlib;
22

33
fn main() {
44
let data = [(-3.0, 2.3), (-1.6, 5.3), (0.3, 0.7), (4.3, -1.4), (6.4, 4.3), (8.5, 3.7)];
5-
let s = plotlib::scatter::Scatter::from_vec(&data);
5+
let s1 = plotlib::scatter::Scatter::from_vec(&data);
6+
let s2 = plotlib::scatter::Scatter::from_vec(&[(-1.4, 2.5), (7.2, -0.3)])
7+
.style(plotlib::scatter::Style::new().marker(plotlib::scatter::Marker::Square));
68
let v = plotlib::view::View::new()
7-
.add(&s)
9+
.add(&s1)
10+
.add(&s2)
811
.x_range(-5., 10.)
912
.y_range(-2., 6.);
1013
println!("{}", plotlib::plot::Plot::single(&v).to_text());

src/histogram.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ impl Representation for Histogram {
9999
match dim {
100100
0 => self.x_range(),
101101
1 => self.y_range(),
102-
_ => panic!("Axis out of range")
102+
_ => panic!("Axis out of range"),
103103
}
104104
}
105105

src/plot.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ impl<'a> Plot<'a> {
2323
pub fn to_svg(&self) -> svg::Document {
2424
let mut document = Document::new().set("viewBox", (0, 0, 600, 400));
2525
for &view in self.views.iter() {
26-
let view_group = view.to_svg(500., 350.).set("transform", format!("translate({}, {})", 50, 370));
26+
let view_group = view.to_svg(500., 350.)
27+
.set("transform", format!("translate({}, {})", 50, 370));
2728
document.append(view_group);
2829
}
2930
document

src/scatter.rs

Lines changed: 51 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,15 @@ pub enum Marker {
1313
Square,
1414
}
1515

16-
#[derive(Debug,Clone)]
16+
/// `Style` follows the 'optional builder' pattern
17+
/// Each field is a `Option` which start as `None`
18+
/// Each can be set with setter methods and instances
19+
/// of `Style` can be overlaid to set many at once.
20+
/// Settings will be cloned in and out of it.
21+
#[derive(Debug)]
1722
pub struct Style {
18-
pub marker: Option<Marker>,
19-
pub colour: Option<String>,
23+
marker: Option<Marker>,
24+
colour: Option<String>,
2025
}
2126

2227
impl Style {
@@ -27,16 +32,38 @@ impl Style {
2732
}
2833
}
2934

30-
pub fn fill_defaults(&self) -> Self {
31-
Style {
32-
marker: match self.marker {
33-
Some(ref m) => Some(m.clone()),
34-
None => Some(Marker::Circle),
35-
},
36-
colour: match self.colour {
37-
Some(ref c) => Some(c.clone()),
38-
None => Some("".into()),
39-
}
35+
pub fn overlay(&mut self, other: Self) {
36+
match other.marker {
37+
Some(v) => self.marker = Some(v),
38+
None => {}
39+
}
40+
match other.colour {
41+
Some(v) => self.colour = Some(v),
42+
None => {}
43+
}
44+
}
45+
46+
pub fn marker(mut self, value: Marker) -> Self {
47+
self.marker = Some(value);
48+
self
49+
}
50+
51+
pub fn get_marker(&self) -> Marker {
52+
match self.marker.clone() {
53+
Some(v) => v,
54+
None => Marker::Circle,
55+
}
56+
}
57+
58+
pub fn colour(mut self, value: String) -> Self {
59+
self.colour = Some(value);
60+
self
61+
}
62+
63+
pub fn get_colour(&self) -> String {
64+
match self.colour.clone() {
65+
Some(v) => v,
66+
None => "".into(),
4067
}
4168
}
4269
}
@@ -63,12 +90,12 @@ impl Scatter {
6390
}
6491

6592
pub fn style(mut self, style: Style) -> Self {
66-
self.style = style;
93+
self.style.overlay(style);
6794
self
6895
}
6996

70-
pub fn get_style(&self) -> Style {
71-
self.style.clone()
97+
pub fn get_style(&self) -> &Style {
98+
&self.style
7299
}
73100

74101
fn x_range(&self) -> (f64, f64) {
@@ -97,7 +124,7 @@ impl Representation for Scatter {
97124
match dim {
98125
0 => self.x_range(),
99126
1 => self.y_range(),
100-
_ => panic!("Axis out of range")
127+
_ => panic!("Axis out of range"),
101128
}
102129
}
103130

@@ -107,7 +134,7 @@ impl Representation for Scatter {
107134
face_width: f64,
108135
face_height: f64)
109136
-> svg::node::element::Group {
110-
svg_render::draw_face_points(self, &x_axis, &y_axis, face_width, face_height, &self.style.fill_defaults())
137+
svg_render::draw_face_points(self, &x_axis, &y_axis, face_width, face_height, &self.style)
111138
}
112139

113140
fn to_text(&self,
@@ -116,6 +143,11 @@ impl Representation for Scatter {
116143
face_width: u32,
117144
face_height: u32)
118145
-> String {
119-
text_render::render_face_points(self, &x_axis, &y_axis, face_width, face_height, &self.style.fill_defaults())
146+
text_render::render_face_points(self,
147+
&x_axis,
148+
&y_axis,
149+
face_width,
150+
face_height,
151+
&self.style)
120152
}
121153
}

src/svg_render.rs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -109,20 +109,22 @@ pub fn draw_face_points(s: &scatter::Scatter,
109109
let x_pos = value_to_face_offset(x, &x_axis, face_width);
110110
let y_pos = -value_to_face_offset(y, &y_axis, face_height);
111111
let radius = 5.;
112-
match style.marker.as_ref().unwrap() {
113-
&scatter::Marker::Circle => {
112+
match style.get_marker() {
113+
scatter::Marker::Circle => {
114114
group.append(node::element::Circle::new()
115115
.set("cx", x_pos)
116116
.set("cy", y_pos)
117-
.set("r", radius));
118-
},
119-
&scatter::Marker::Square => {
117+
.set("r", radius)
118+
.set("fill", style.get_colour()));
119+
}
120+
scatter::Marker::Square => {
120121
group.append(node::element::Rectangle::new()
121122
.set("x", x_pos - radius)
122123
.set("y", y_pos - radius)
123124
.set("width", 2. * radius)
124-
.set("height", 2. * radius));
125-
},
125+
.set("height", 2. * radius)
126+
.set("fill", style.get_colour()));
127+
}
126128
};
127129
}
128130

src/text_render.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -331,9 +331,9 @@ pub fn render_face_points(s: &scatter::Scatter,
331331
})
332332
.collect();
333333

334-
let marker = match style.marker.as_ref().unwrap() {
335-
&scatter::Marker::Circle => '●',
336-
&scatter::Marker::Square => '■',
334+
let marker = match style.get_marker() {
335+
scatter::Marker::Circle => '●',
336+
scatter::Marker::Square => '■',
337337
};
338338

339339
let mut face_strings: Vec<String> = vec![];
@@ -557,7 +557,7 @@ mod tests {
557557
let s = scatter::Scatter::from_vec(&data);
558558
let x_axis = axis::Axis::new(-3.575, 9.075);
559559
let y_axis = axis::Axis::new(-1.735, 5.635);
560-
let style = scatter::Style::new().fill_defaults();
560+
let style = scatter::Style::new();
561561
let strings = render_face_points(&s, &x_axis, &y_axis, 20, 10, &style);
562562
assert_eq!(strings.lines().count(), 10);
563563
assert!(strings.lines().all(|s| s.chars().count() == 20));

0 commit comments

Comments
 (0)