Refactor single_plot to builder pattern

This commit is contained in:
Michał Chodzikiewicz 2021-02-25 23:53:10 +01:00
parent 641feb9eb4
commit a555d74a25
9 changed files with 108 additions and 38 deletions

View file

@ -31,7 +31,8 @@ fn main() -> Result<(), core::convert::Infallible> {
Placement::X{x1: 40, x2: 230, y: 10}, Placement::X{x1: 40, x2: 230, y: 10},
RgbColor::WHITE, RgbColor::WHITE,
text_style_white, text_style_white,
2 2,
2,
) )
.draw(&mut display)?; .draw(&mut display)?;
@ -40,7 +41,8 @@ fn main() -> Result<(), core::convert::Infallible> {
Placement::X{x1: 240, x2: 470, y: 10}, Placement::X{x1: 240, x2: 470, y: 10},
RgbColor::YELLOW, RgbColor::YELLOW,
text_style_yellow_compact, text_style_yellow_compact,
1 1,
2,
) )
.draw(&mut display)?; .draw(&mut display)?;
@ -49,7 +51,8 @@ fn main() -> Result<(), core::convert::Infallible> {
Placement::X{x1: 50, x2: 220, y: 30}, Placement::X{x1: 50, x2: 220, y: 30},
RgbColor::BLUE, RgbColor::BLUE,
text_style_white, text_style_white,
3 3,
1,
) )
.draw(&mut display)?; .draw(&mut display)?;
@ -58,7 +61,8 @@ fn main() -> Result<(), core::convert::Infallible> {
Placement::X{x1: 250, x2: 460, y: 40}, Placement::X{x1: 250, x2: 460, y: 40},
RgbColor::RED, RgbColor::RED,
text_style_yellow_compact, text_style_yellow_compact,
7 7,
1,
) )
.draw(&mut display)?; .draw(&mut display)?;
@ -67,7 +71,8 @@ fn main() -> Result<(), core::convert::Infallible> {
Placement::Y{y1: 70, y2: 230, x: 160}, Placement::Y{y1: 70, y2: 230, x: 160},
RgbColor::WHITE, RgbColor::WHITE,
text_style_white, text_style_white,
2 2,
1,
) )
.draw(&mut display)?; .draw(&mut display)?;
@ -76,7 +81,8 @@ fn main() -> Result<(), core::convert::Infallible> {
Placement::Y{y1: 70, y2: 210, x: 260}, Placement::Y{y1: 70, y2: 210, x: 260},
RgbColor::YELLOW, RgbColor::YELLOW,
text_style_yellow_compact, text_style_yellow_compact,
1 1,
1,
) )
.draw(&mut display)?; .draw(&mut display)?;
@ -85,7 +91,8 @@ fn main() -> Result<(), core::convert::Infallible> {
Placement::Y{y1: 60, y2: 180, x: 370}, Placement::Y{y1: 60, y2: 180, x: 370},
RgbColor::BLUE, RgbColor::BLUE,
text_style_white, text_style_white,
3 3,
1,
) )
.draw(&mut display)?; .draw(&mut display)?;
@ -94,7 +101,8 @@ fn main() -> Result<(), core::convert::Infallible> {
Placement::Y{y1: 90, y2: 220, x: 470}, Placement::Y{y1: 90, y2: 220, x: 470},
RgbColor::RED, RgbColor::RED,
text_style_yellow_compact, text_style_yellow_compact,
7 7,
1,
) )
.draw(&mut display)?; .draw(&mut display)?;
@ -103,7 +111,8 @@ fn main() -> Result<(), core::convert::Infallible> {
Placement::X{x1: 30, x2: 470, y: 250}, Placement::X{x1: 30, x2: 470, y: 250},
RgbColor::YELLOW, RgbColor::YELLOW,
text_style_white, text_style_white,
2 2,
1,
) )
.draw(&mut display)?; .draw(&mut display)?;
@ -112,7 +121,8 @@ fn main() -> Result<(), core::convert::Infallible> {
Placement::Y{y1: 10, y2: 250, x: 30}, Placement::Y{y1: 10, y2: 250, x: 30},
RgbColor::WHITE, RgbColor::WHITE,
text_style_white, text_style_white,
2 2,
1,
) )
.draw(&mut display)?; .draw(&mut display)?;

View file

@ -27,10 +27,9 @@ fn main() -> Result<(), core::convert::Infallible> {
Scale::RangeFraction(3), Scale::RangeFraction(3),
Scale::RangeFraction(2), Scale::RangeFraction(2),
).into_drawable( ).into_drawable(
BinaryColor::On,
Point { x: 18, y: 2 }, Point { x: 18, y: 2 },
Point { x: 120, y: 30 }, Point { x: 120, y: 30 },
); ).set_color(BinaryColor::On);
plot.draw(&mut display)?; plot.draw(&mut display)?;
let output_settings = OutputSettingsBuilder::new() let output_settings = OutputSettingsBuilder::new()

View file

@ -29,13 +29,10 @@ fn main() -> Result<(), core::convert::Infallible> {
let plot = SinglePlot::new( let plot = SinglePlot::new(
&curve, &curve,
Scale::RangeFraction(3), Scale::RangeFraction(3),
Scale::RangeFraction(2), Scale::RangeFraction(2)).into_drawable(
)
.into_drawable(
RgbColor::YELLOW,
Point { x: 50, y: 10 }, Point { x: 50, y: 10 },
Point { x: 430, y: 250 } Point { x: 430, y: 250 },
); ).set_color(RgbColor::YELLOW).set_text_color(RgbColor::WHITE);
plot.draw(&mut display)?; plot.draw(&mut display)?;
let output_settings = OutputSettingsBuilder::new() let output_settings = OutputSettingsBuilder::new()

View file

@ -34,12 +34,12 @@ impl<'a> Axis<'a>
Axis{title, range, scale} Axis{title, range, scale}
} }
pub fn into_drawable_axis<C, F>(self, placement: Placement, plot_color: C, text_style: TextStyle<C, F>, tick_height: usize) -> DrawableAxis<'a, C, F> pub fn into_drawable_axis<C, F>(self, placement: Placement, plot_color: C, text_style: TextStyle<C, F>, tick_height: usize, thickness: usize) -> DrawableAxis<'a, C, F>
where where
C: PixelColor, C: PixelColor,
F: Font, F: Font,
TextStyle<C, F>: Clone, TextStyle<C, F>: Clone,
{ {
DrawableAxis::new(self.title,placement,self.range,self.scale,plot_color,text_style,tick_height) DrawableAxis::new(self.title,placement,self.range,self.scale,plot_color,text_style,tick_height,thickness)
} }
} }

View file

@ -44,6 +44,7 @@ impl<'a> Curve<'a> {
top_left: &'a Point, top_left: &'a Point,
bottom_right: &'a Point, bottom_right: &'a Point,
color: C, color: C,
thickness: usize,
) -> DrawableCurve<C, impl Iterator<Item=Point> + '_> ) -> DrawableCurve<C, impl Iterator<Item=Point> + '_>
where C: PixelColor where C: PixelColor
{ {
@ -63,7 +64,7 @@ impl<'a> Curve<'a> {
&Range { start: bottom_right.y, end: top_left.y }, &Range { start: bottom_right.y, end: top_left.y },
), ),
}); });
DrawableCurve::new(it, color) DrawableCurve::new(it, color,thickness)
} }
} }

View file

@ -22,6 +22,7 @@ pub struct DrawableAxis<'a, C, F>
color: C, color: C,
text_style: TextStyle<C, F>, text_style: TextStyle<C, F>,
tick_size: usize, tick_size: usize,
thickness: usize,
} }
impl<'a, C, F> DrawableAxis<'a, C, F> impl<'a, C, F> DrawableAxis<'a, C, F>
@ -30,8 +31,8 @@ impl<'a, C, F> DrawableAxis<'a, C, F>
F: Font, F: Font,
TextStyle<C, F>: Clone, TextStyle<C, F>: Clone,
{ {
pub(in crate) fn new(title: &'a str, placement: Placement, range: Range<i32>, scale: Scale, color: C, text_style: TextStyle<C, F>, tick_height: usize) -> DrawableAxis<'a, C, F> { pub(in crate) fn new(title: &'a str, placement: Placement, range: Range<i32>, scale: Scale, color: C, text_style: TextStyle<C, F>, tick_height: usize, thickness: usize) -> DrawableAxis<'a, C, F> {
DrawableAxis { title, placement, range, scale, color, text_style, tick_size: tick_height } DrawableAxis { title, placement, range, scale, color, text_style, tick_size: tick_height, thickness }
} }
pub fn size(&self) -> Point { pub fn size(&self) -> Point {
@ -59,7 +60,7 @@ impl<'a, C, F> Drawable<C> for DrawableAxis<'a, C, F>
match self.placement { match self.placement {
Placement::X { x1, x2, y } => { Placement::X { x1, x2, y } => {
Line { start: Point { x: x1, y }, end: Point { x: x2, y } } Line { start: Point { x: x1, y }, end: Point { x: x2, y } }
.into_styled(PrimitiveStyle::with_stroke(self.color, 1)) .into_styled(PrimitiveStyle::with_stroke(self.color, self.thickness as u32))
.draw(display)?; .draw(display)?;
let title = Text::new(self.title, Point { x: x1, y: y + 10 }) let title = Text::new(self.title, Point { x: x1, y: y + 10 })
.into_styled(self.text_style); .into_styled(self.text_style);
@ -69,7 +70,7 @@ impl<'a, C, F> Drawable<C> for DrawableAxis<'a, C, F>
for mark in scale_marks { for mark in scale_marks {
let x = mark.scale_between_ranges(&self.range, &(x1..x2)); let x = mark.scale_between_ranges(&self.range, &(x1..x2));
Line { start: Point { x, y: y - self.tick_size as i32 }, end: Point { x, y: y + self.tick_size as i32 } } Line { start: Point { x, y: y - self.tick_size as i32 }, end: Point { x, y: y + self.tick_size as i32 } }
.into_styled(PrimitiveStyle::with_stroke(self.color, 1)) .into_styled(PrimitiveStyle::with_stroke(self.color, self.thickness as u32))
.draw(display)?; .draw(display)?;
let mut buf: String::<U8> = String::new(); let mut buf: String::<U8> = String::new();
write!(buf, "{}", mark).unwrap(); write!(buf, "{}", mark).unwrap();
@ -78,14 +79,14 @@ impl<'a, C, F> Drawable<C> for DrawableAxis<'a, C, F>
} }
Placement::Y { y1, y2, x } => { Placement::Y { y1, y2, x } => {
Line { start: Point { x, y: y1 }, end: Point { x, y: y2 } } Line { start: Point { x, y: y1 }, end: Point { x, y: y2 } }
.into_styled(PrimitiveStyle::with_stroke(self.color, 1)) .into_styled(PrimitiveStyle::with_stroke(self.color, self.thickness as u32))
.draw(display)?; .draw(display)?;
let mut max_tick_text_width = 0; let mut max_tick_text_width = 0;
for mark in scale_marks { for mark in scale_marks {
let y = mark.scale_between_ranges(&self.range, &(y2..y1)); let y = mark.scale_between_ranges(&self.range, &(y2..y1));
Line { start: Point { x: x - self.tick_size as i32, y }, end: Point { x: x + self.tick_size as i32, y } } Line { start: Point { x: x - self.tick_size as i32, y }, end: Point { x: x + self.tick_size as i32, y } }
.into_styled(PrimitiveStyle::with_stroke(self.color, 1)) .into_styled(PrimitiveStyle::with_stroke(self.color, self.thickness as u32))
.draw(display)?; .draw(display)?;
let mut buf: String::<U8> = String::new(); let mut buf: String::<U8> = String::new();
write!(buf, "{}", mark).unwrap(); write!(buf, "{}", mark).unwrap();

View file

@ -9,6 +9,7 @@ pub struct DrawableCurve<C, I>
{ {
scaled_data: I, scaled_data: I,
color: C, color: C,
thickness: usize,
} }
impl<C, I> DrawableCurve<C, I> impl<C, I> DrawableCurve<C, I>
@ -16,10 +17,11 @@ impl<C, I> DrawableCurve<C, I>
C: PixelColor, C: PixelColor,
I: Iterator<Item=Point>, I: Iterator<Item=Point>,
{ {
pub(in crate) fn new(data: I, color: C) -> DrawableCurve<C, I> { pub(in crate) fn new(data: I, color: C, thickness: usize) -> DrawableCurve<C, I> {
DrawableCurve { DrawableCurve {
scaled_data: data, scaled_data: data,
color, color,
thickness,
} }
} }
} }
@ -29,7 +31,7 @@ impl<C, I> Drawable<C> for DrawableCurve<C, I>
I: Iterator<Item=Point>, I: Iterator<Item=Point>,
{ {
fn draw<D: DrawTarget<C>>(self, display: &mut D) -> Result<(), D::Error> { fn draw<D: DrawTarget<C>>(self, display: &mut D) -> Result<(), D::Error> {
let style = PrimitiveStyle::with_stroke(self.color, 2); let style = PrimitiveStyle::with_stroke(self.color, self.thickness as u32);
let mut iter = self.scaled_data.into_iter(); let mut iter = self.scaled_data.into_iter();
let mut prev = iter.next().unwrap(); let mut prev = iter.next().unwrap();
for point in iter { for point in iter {

View file

@ -30,6 +30,7 @@ impl<'a, C> Drawable<C> for PolyPlot<'a, C>
&self.top_left, &self.top_left,
&self.bottom_right, &self.bottom_right,
*color, *color,
2
).draw(display)?; ).draw(display)?;
} }
Ok(()) Ok(())

View file

@ -18,42 +18,101 @@ impl<'a> SinglePlot<'a> {
SinglePlot { curve, x_scale, y_scale } SinglePlot { curve, x_scale, y_scale }
} }
pub fn into_drawable<C: PixelColor>(self, color: C, top_left: Point, bottom_right: Point) -> DrawableSinglePlot<'a, C> { pub fn into_drawable<C: PixelColor + Default>(self, top_left: Point, bottom_right: Point) -> DrawableSinglePlot<'a, C> {
DrawableSinglePlot { plot: self, color, top_left, bottom_right } DrawableSinglePlot { plot: self, color: None, text_color: None, axis_color: None, thickness: None, axis_thickness: None, top_left, bottom_right }
} }
} }
pub struct DrawableSinglePlot<'a, C> pub struct DrawableSinglePlot<'a, C>
where where
C: PixelColor C: PixelColor + Default,
{ {
plot: SinglePlot<'a>, plot: SinglePlot<'a>,
color: C, color: Option<C>,
text_color: Option<C>,
axis_color: Option<C>,
thickness: Option<usize>,
axis_thickness: Option<usize>,
top_left: Point, top_left: Point,
bottom_right: Point, bottom_right: Point,
} }
impl<'a, C> DrawableSinglePlot<'a, C>
where
C: PixelColor + Default,
{
pub fn set_color(mut self, color: C) -> DrawableSinglePlot<'a, C> {
self.color = Some(color);
self
}
pub fn set_text_color(mut self, color: C) -> DrawableSinglePlot<'a, C> {
self.text_color = Some(color);
self
}
pub fn set_axis_color(mut self, color: C) -> DrawableSinglePlot<'a, C> {
self.axis_color = Some(color);
self
}
pub fn set_thickness(mut self, thickness: usize) -> DrawableSinglePlot<'a, C> {
self.thickness = Some(thickness);
self
}
pub fn set_axis_thickness(mut self, thickness: usize) -> DrawableSinglePlot<'a, C> {
self.axis_thickness = Some(thickness);
self
}
}
impl<'a, C> Drawable<C> for DrawableSinglePlot<'a, C> impl<'a, C> Drawable<C> for DrawableSinglePlot<'a, C>
where where
C: PixelColor C: PixelColor + Default,
{ {
fn draw<D: DrawTarget<C>>(self, display: &mut D) -> Result<(), D::Error> { fn draw<D: DrawTarget<C>>(self, display: &mut D) -> Result<(), D::Error> {
let color = match self.color {
None => C::default(),
Some(c) => c,
};
let text_color = match self.text_color {
None => color,
Some(c) => c,
};
let axis_color = match self.axis_color {
None => color,
Some(c) => c,
};
let thickness = match self.thickness {
None => 2,
Some(t) => t,
};
let axis_thickness = match self.axis_thickness {
None => thickness,
Some(t) => t,
};
let text_style = TextStyleBuilder::new(Font6x8) let text_style = TextStyleBuilder::new(Font6x8)
.text_color(self.color) .text_color(text_color)
.build(); .build();
Axis::new("X", self.plot.curve.x_range.clone(), self.plot.x_scale) Axis::new("X", self.plot.curve.x_range.clone(), self.plot.x_scale)
.into_drawable_axis(Placement::X { x1: self.top_left.x, x2: self.bottom_right.x, y: self.bottom_right.y }, self.color, text_style, 2) .into_drawable_axis(Placement::X { x1: self.top_left.x, x2: self.bottom_right.x, y: self.bottom_right.y }, axis_color, text_style, 2, axis_thickness)
.draw(display)?; .draw(display)?;
Axis::new("Y", self.plot.curve.y_range.clone(), self.plot.y_scale) Axis::new("Y", self.plot.curve.y_range.clone(), self.plot.y_scale)
.into_drawable_axis(Placement::Y { y1: self.top_left.y, y2: self.bottom_right.y, x: self.top_left.x }, self.color, text_style, 2) .into_drawable_axis(Placement::Y { y1: self.top_left.y, y2: self.bottom_right.y, x: self.top_left.x }, axis_color, text_style, 2,axis_thickness)
.draw(display)?; .draw(display)?;
self.plot.curve.into_drawable_curve( self.plot.curve.into_drawable_curve(
&self.top_left, &self.top_left,
&self.bottom_right, &self.bottom_right,
self.color, color,
thickness,
).draw(display)?; ).draw(display)?;
Ok(()) Ok(())
} }