Skip to content

Commit 3300be8

Browse files
committed
Move scatter styling to a 'Point' trait
1 parent c3d2256 commit 3300be8

File tree

6 files changed

+70
-48
lines changed

6 files changed

+70
-48
lines changed

examples/scatter_svg.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
extern crate plotlib;
22

3+
use plotlib::style::Point;
4+
35
fn main() {
46
let data = [
57
(-3.0, 2.3),
@@ -11,7 +13,7 @@ fn main() {
1113
];
1214
let s1 = plotlib::scatter::Scatter::from_vec(&data).style(
1315
plotlib::scatter::Style::new()
14-
.marker(plotlib::scatter::Marker::Square)
16+
.marker(plotlib::style::Marker::Square)
1517
.colour("#DD3355"),
1618
);
1719
let s2 = plotlib::scatter::Scatter::from_vec(&[(-1.4, 2.5), (7.2, -0.3)])

examples/scatter_text.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
extern crate plotlib;
22

3+
use plotlib::style::Point;
4+
35
fn main() {
46
let data = [
57
(-3.0, 2.3),
@@ -11,7 +13,7 @@ fn main() {
1113
];
1214
let s1 = plotlib::scatter::Scatter::from_vec(&data);
1315
let s2 = plotlib::scatter::Scatter::from_vec(&[(-1.4, 2.5), (7.2, -0.3)])
14-
.style(plotlib::scatter::Style::new().marker(plotlib::scatter::Marker::Square));
16+
.style(plotlib::scatter::Style::new().marker(plotlib::style::Marker::Square));
1517
let v = plotlib::view::View::new()
1618
.add(&s1)
1719
.add(&s2)

src/scatter.rs

Lines changed: 16 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,7 @@ use axis;
66
use svg_render;
77
use text_render;
88
use representation::Representation;
9-
10-
/**
11-
The marker that should be used for the points of the scatter plot
12-
*/
13-
#[derive(Debug, Clone)]
14-
pub enum Marker {
15-
Circle,
16-
Square,
17-
Cross,
18-
}
9+
use style;
1910

2011
/// `Style` follows the 'optional builder' pattern
2112
/// Each field is a `Option` which start as `None`
@@ -24,7 +15,7 @@ pub enum Marker {
2415
/// Settings will be cloned in and out of it.
2516
#[derive(Debug, Default)]
2617
pub struct Style {
27-
marker: Option<Marker>,
18+
marker: Option<style::Marker>,
2819
colour: Option<String>,
2920
}
3021

@@ -36,45 +27,41 @@ impl Style {
3627
}
3728
}
3829

39-
pub fn overlay(&mut self, other: Self) {
30+
pub fn overlay(&mut self, other: &Self) {
4031
match other.marker {
41-
Some(v) => self.marker = Some(v),
32+
Some(ref v) => self.marker = Some(v.clone()),
4233
None => {}
4334
}
4435
match other.colour {
45-
Some(v) => self.colour = Some(v),
36+
Some(ref v) => self.colour = Some(v.clone()),
4637
None => {}
4738
}
4839
}
40+
}
4941

50-
pub fn marker<T>(mut self, value: T) -> Self
42+
impl style::Point for Style {
43+
fn marker<T>(&mut self, value: T) -> &mut Self
5144
where
52-
T: Into<Marker>,
45+
T: Into<style::Marker>,
5346
{
5447
self.marker = Some(value.into());
5548
self
5649
}
5750

58-
pub fn get_marker(&self) -> Marker {
59-
match self.marker.clone() {
60-
Some(v) => v,
61-
None => Marker::Circle,
62-
}
51+
fn get_marker(&self) -> &Option<style::Marker> {
52+
&self.marker
6353
}
6454

65-
pub fn colour<T>(mut self, value: T) -> Self
55+
fn colour<T>(&mut self, value: T) -> &mut Self
6656
where
6757
T: Into<String>,
6858
{
6959
self.colour = Some(value.into());
7060
self
7161
}
7262

73-
pub fn get_colour(&self) -> String {
74-
match self.colour.clone() {
75-
Some(v) => v,
76-
None => "".into(),
77-
}
63+
fn get_colour(&self) -> &Option<String> {
64+
&self.colour
7865
}
7966
}
8067

@@ -99,8 +86,8 @@ impl Scatter {
9986
}
10087
}
10188

102-
pub fn style(mut self, style: Style) -> Self {
103-
self.style.overlay(style);
89+
pub fn style(mut self, style: &Style) -> Self {
90+
self.style.overlay(&style);
10491
self
10592
}
10693

src/style.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,27 @@ pub trait Line {
1111

1212
fn get_colour(&self) -> &Option<String>;
1313
}
14+
15+
/**
16+
The marker that should be used for the points of the scatter plot
17+
*/
18+
#[derive(Debug, Clone)]
19+
pub enum Marker {
20+
Circle,
21+
Square,
22+
Cross,
23+
}
24+
25+
pub trait Point {
26+
fn marker<T>(&mut self, value: T) -> &mut Self
27+
where
28+
T: Into<Marker>;
29+
30+
fn get_marker(&self) -> &Option<Marker>;
31+
32+
fn colour<T>(&mut self, value: T) -> &mut Self
33+
where
34+
T: Into<String>;
35+
36+
fn get_colour(&self) -> &Option<String>;
37+
}

src/svg_render.rs

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -110,41 +110,44 @@ pub fn draw_y_axis(a: &axis::Axis, face_height: f64) -> node::element::Group {
110110
.add(label)
111111
}
112112

113-
pub fn draw_face_points(
113+
pub fn draw_face_points<S>(
114114
s: &scatter::Scatter,
115115
x_axis: &axis::Axis,
116116
y_axis: &axis::Axis,
117117
face_width: f64,
118118
face_height: f64,
119-
style: &scatter::Style,
120-
) -> node::element::Group {
119+
style: &S,
120+
) -> node::element::Group
121+
where
122+
S: style::Point,
123+
{
121124
let mut group = node::element::Group::new();
122125

123126
for &(x, y) in &s.data {
124127
let x_pos = value_to_face_offset(x, x_axis, face_width);
125128
let y_pos = -value_to_face_offset(y, y_axis, face_height);
126129
let radius = 5.;
127-
match style.get_marker() {
128-
scatter::Marker::Circle => {
130+
match style.get_marker().clone().unwrap_or(style::Marker::Circle) {
131+
style::Marker::Circle => {
129132
group.append(
130133
node::element::Circle::new()
131134
.set("cx", x_pos)
132135
.set("cy", y_pos)
133136
.set("r", radius)
134-
.set("fill", style.get_colour()),
137+
.set("fill", style.get_colour().clone().unwrap_or("".into())),
135138
);
136139
}
137-
scatter::Marker::Square => {
140+
style::Marker::Square => {
138141
group.append(
139142
node::element::Rectangle::new()
140143
.set("x", x_pos - radius)
141144
.set("y", y_pos - radius)
142145
.set("width", 2. * radius)
143146
.set("height", 2. * radius)
144-
.set("fill", style.get_colour()),
147+
.set("fill", style.get_colour().clone().unwrap_or("".into())),
145148
);
146149
}
147-
scatter::Marker::Cross => {
150+
style::Marker::Cross => {
148151
let path = node::element::path::Data::new()
149152
.move_to((x_pos - radius, y_pos - radius))
150153
.line_by((radius * 2., radius * 2.))
@@ -154,7 +157,7 @@ pub fn draw_face_points(
154157
group.append(
155158
node::element::Path::new()
156159
.set("fill", "none")
157-
.set("stroke", style.get_colour())
160+
.set("stroke", style.get_colour().clone().unwrap_or("".into()))
158161
.set("stroke-width", 2)
159162
.set("d", path),
160163
);

src/text_render.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use histogram;
77
use scatter;
88
use axis;
99
use utils::PairWise;
10+
use style;
1011

1112
// Given a value like a tick label or a bin count,
1213
// calculate how far from the x-axis it should be plotted
@@ -350,14 +351,17 @@ pub fn render_face_bars(
350351
/// the x ands y-axes
351352
/// and the face height and width,
352353
/// create the strings to be drawn as the face
353-
pub fn render_face_points(
354+
pub fn render_face_points<S>(
354355
s: &scatter::Scatter,
355356
x_axis: &axis::Axis,
356357
y_axis: &axis::Axis,
357358
face_width: u32,
358359
face_height: u32,
359-
style: &scatter::Style,
360-
) -> String {
360+
style: &S,
361+
) -> String
362+
where
363+
S: style::Point,
364+
{
361365
let points: Vec<_> = s.data
362366
.iter()
363367
.map(|&(x, y)| {
@@ -368,10 +372,10 @@ pub fn render_face_points(
368372
})
369373
.collect();
370374

371-
let marker = match style.get_marker() {
372-
scatter::Marker::Circle => '●',
373-
scatter::Marker::Square => '■',
374-
scatter::Marker::Cross => '×',
375+
let marker = match style.get_marker().clone().unwrap_or(style::Marker::Circle) {
376+
style::Marker::Circle => '●',
377+
style::Marker::Square => '■',
378+
style::Marker::Cross => '×',
375379
};
376380

377381
let mut face_strings: Vec<String> = vec![];

0 commit comments

Comments
 (0)