Skip to content

Commit a9d5c0a

Browse files
committed
Add shift option
1 parent d9fb1ec commit a9d5c0a

File tree

2 files changed

+20
-15
lines changed

2 files changed

+20
-15
lines changed

plotters/src/element/basic_shapes.rs

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,7 @@ fn test_dashed_path_element() {
277277
/// It's similar to [`PathElement`] but use a marker function to draw markers with spacing.
278278
pub struct DottedPathElement<I: Iterator + Clone, Size: SizeDesc, Marker> {
279279
points: I,
280+
shift: Size,
280281
spacing: Size,
281282
func: Box<dyn Fn(BackendCoord) -> Marker>,
282283
}
@@ -287,13 +288,14 @@ impl<I: Iterator + Clone, Size: SizeDesc, Marker> DottedPathElement<I, Size, Mar
287288
/// - `spacing`: The spacing between markers
288289
/// - `func`: The marker function
289290
/// - returns the created element
290-
pub fn new<I0, F>(points: I0, spacing: Size, func: F) -> Self
291+
pub fn new<I0, F>(points: I0, shift: Size, spacing: Size, func: F) -> Self
291292
where
292293
I0: IntoIterator<IntoIter = I>,
293294
F: Fn(BackendCoord) -> Marker + 'static,
294295
{
295296
Self {
296297
points: points.into_iter(),
298+
shift,
297299
spacing,
298300
func: Box::new(func),
299301
}
@@ -324,25 +326,19 @@ where
324326
ps: (u32, u32),
325327
) -> Result<(), DrawingErrorKind<DB::ErrorType>> {
326328
let mut start = match points.next() {
327-
Some(start_i) => {
328-
(self.func)(start_i)
329-
.into_dyn()
330-
.draw(std::iter::once(start_i), backend, ps)?;
331-
to_f(start_i)
332-
}
329+
Some(c) => to_f(c),
333330
None => return Ok(()),
334331
};
332+
let mut shift = self.shift.in_pixels(&ps).max(0) as f32;
335333
let spacing = self.spacing.in_pixels(&ps).max(0) as f32;
336-
if spacing == 0. {
337-
return Ok(());
338-
}
339334
let mut dist = 0.;
340335
for curr in points {
341336
let end = to_f(curr);
342337
// Loop for spacing
343338
while start != end {
344339
let (dx, dy) = (end.0 - start.0, end.1 - start.1);
345340
let d = dx.hypot(dy);
341+
let spacing = if shift == 0. { spacing } else { shift };
346342
let left = spacing - dist;
347343
// Set next point to `start`
348344
if left < d {
@@ -360,6 +356,7 @@ where
360356
.into_dyn()
361357
.draw(std::iter::once(start_i), backend, ps)?;
362358
dist = 0.;
359+
shift = 0.;
363360
}
364361
}
365362
}
@@ -374,11 +371,12 @@ fn test_dotted_path_element() {
374371
let da = crate::create_mocked_drawing_area(300, 300, |m| {
375372
m.drop_check(|b| {
376373
assert_eq!(b.num_draw_path_call, 0);
377-
assert_eq!(b.draw_count, 8);
374+
assert_eq!(b.draw_count, 7);
378375
});
379376
});
380377
da.draw(&DottedPathElement::new(
381378
vec![(100, 100), (105, 105), (150, 150)],
379+
5,
382380
10,
383381
|c| Circle::new(c, 5, Into::<ShapeStyle>::into(RED).filled()),
384382
))

plotters/src/series/line_series.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ impl<I: Iterator + Clone, Size: SizeDesc> IntoIterator for DashedLineSeries<I, S
131131
/// A dotted line series, map an iterable object to the dotted line element.
132132
pub struct DottedLineSeries<I: Iterator + Clone, Size: SizeDesc, Marker> {
133133
points: I,
134+
shift: Size,
134135
spacing: Size,
135136
func: Box<dyn Fn(BackendCoord) -> Marker>,
136137
}
@@ -141,13 +142,14 @@ impl<I: Iterator + Clone, Size: SizeDesc, Marker> DottedLineSeries<I, Size, Mark
141142
/// - `spacing`: The spacing between markers
142143
/// - `func`: The marker function
143144
/// - returns the created element
144-
pub fn new<I0, F>(points: I0, spacing: Size, func: F) -> Self
145+
pub fn new<I0, F>(points: I0, shift: Size, spacing: Size, func: F) -> Self
145146
where
146147
I0: IntoIterator<IntoIter = I>,
147148
F: Fn(BackendCoord) -> Marker + 'static,
148149
{
149150
Self {
150151
points: points.into_iter(),
152+
shift,
151153
spacing,
152154
func: Box::new(func),
153155
}
@@ -161,7 +163,12 @@ impl<I: Iterator + Clone, Size: SizeDesc, Marker: 'static> IntoIterator
161163
type IntoIter = std::iter::Once<Self::Item>;
162164

163165
fn into_iter(self) -> Self::IntoIter {
164-
std::iter::once(DottedPathElement::new(self.points, self.spacing, self.func))
166+
std::iter::once(DottedPathElement::new(
167+
self.points,
168+
self.shift,
169+
self.spacing,
170+
self.func,
171+
))
165172
}
166173
}
167174

@@ -184,7 +191,7 @@ mod test {
184191

185192
m.drop_check(|b| {
186193
assert_eq!(b.num_draw_path_call, 8);
187-
assert_eq!(b.draw_count, 28);
194+
assert_eq!(b.draw_count, 27);
188195
});
189196
});
190197

@@ -208,7 +215,7 @@ mod test {
208215
.expect("Drawing Error");
209216
let mk_f = |c| Circle::new(c, 3, Into::<ShapeStyle>::into(RED).filled());
210217
chart
211-
.draw_series(DottedLineSeries::new((0..=50).map(|x| (x, 0)), 5, mk_f))
218+
.draw_series(DottedLineSeries::new((0..=50).map(|x| (x, 0)), 5, 5, mk_f))
212219
.expect("Drawing Error");
213220
}
214221
}

0 commit comments

Comments
 (0)