Skip to content

Commit 73278a4

Browse files
committed
Add function plotting
1 parent c80b8b5 commit 73278a4

File tree

2 files changed

+71
-4
lines changed

2 files changed

+71
-4
lines changed

src/function.rs

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,45 @@
1+
use std::f64;
2+
13
use svg;
24

35
use axis;
46
use representation::Representation;
57

8+
use svg_render;
9+
610
pub struct Function {
7-
func: Fn(f64) -> f64,
11+
pub data: Vec<(f64, f64)>,
812
}
913

1014
impl Function {
15+
pub fn new<F>(f: F, lower: f64, upper: f64) -> Self
16+
where F: Fn(f64) -> f64 {
17+
let sampling = (upper - lower) / 200.;
18+
let samples = (0..).map(|x| lower + (x as f64 * sampling)).take_while(|&x| x <= upper);
19+
let values = samples.map(|s| (s, f(s))).collect();
20+
Function {
21+
data: values,
22+
}
23+
}
24+
1125
fn x_range(&self) -> (f64, f64) {
12-
(0., 1.)
26+
let mut min = f64::INFINITY;
27+
let mut max = f64::NEG_INFINITY;
28+
for &(x, _) in &self.data {
29+
min = min.min(x);
30+
max = max.max(x);
31+
}
32+
(min, max)
1333
}
1434

1535
fn y_range(&self) -> (f64, f64) {
16-
(0., 1.)
36+
let mut min = f64::INFINITY;
37+
let mut max = f64::NEG_INFINITY;
38+
for &(_, y) in &self.data {
39+
min = min.min(y);
40+
max = max.max(y);
41+
}
42+
(min, max)
1743
}
1844
}
1945

@@ -32,7 +58,7 @@ impl Representation for Function {
3258
face_width: f64,
3359
face_height: f64)
3460
-> svg::node::element::Group {
35-
svg::node::element::Group::new()
61+
svg_render::draw_face_line(self, x_axis, y_axis, face_width, face_height)
3662
}
3763

3864
fn to_text(&self,
@@ -44,3 +70,13 @@ impl Representation for Function {
4470
"".into()
4571
}
4672
}
73+
74+
#[cfg(test)]
75+
mod tests {
76+
use super::*;
77+
78+
#[test]
79+
fn test_function() {
80+
let f = Function::new(|x| x*x, 0., 10.);
81+
}
82+
}

src/svg_render.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use svg::node;
33

44
use histogram;
55
use scatter;
6+
use function;
67
use axis;
78
use utils::PairWise;
89

@@ -180,6 +181,36 @@ pub fn draw_face_bars(h: &histogram::Histogram,
180181
group
181182
}
182183

184+
pub fn draw_face_line(s: &function::Function,
185+
x_axis: &axis::Axis,
186+
y_axis: &axis::Axis,
187+
face_width: f64,
188+
face_height: f64)
189+
-> node::element::Group {
190+
let mut group = node::element::Group::new();
191+
192+
let mut d: Vec<node::element::path::Command> = vec![];
193+
let &(first_x, first_y) = s.data.first().unwrap();
194+
let first_x_pos = value_to_face_offset(first_x, x_axis, face_width);
195+
let first_y_pos = -value_to_face_offset(first_y, y_axis, face_height);
196+
d.push(node::element::path::Command::Move(node::element::path::Position::Absolute, (first_x_pos, first_y_pos).into()));
197+
for &(x, y) in &s.data {
198+
let x_pos = value_to_face_offset(x, x_axis, face_width);
199+
let y_pos = -value_to_face_offset(y, y_axis, face_height);
200+
d.push(node::element::path::Command::Line(node::element::path::Position::Absolute, (x_pos, y_pos).into()));
201+
}
202+
203+
let mut path = node::element::path::Data::from(d);
204+
205+
group.append(node::element::Path::new()
206+
.set("fill", "none")
207+
.set("stroke", "black")
208+
.set("stroke-width", 2)
209+
.set("d", path));
210+
211+
group
212+
}
213+
183214
#[cfg(test)]
184215
mod tests {
185216
use super::*;

0 commit comments

Comments
 (0)