2021-07-23 15:01:38 +00:00
|
|
|
use crate::axis::{Axis, Placement, Scale};
|
2020-12-20 11:11:06 +00:00
|
|
|
use crate::curve::Curve;
|
2021-07-23 15:01:38 +00:00
|
|
|
use embedded_graphics::mono_font::MonoTextStyleBuilder;
|
|
|
|
use embedded_graphics::{
|
|
|
|
draw_target::DrawTarget, pixelcolor::PixelColor, prelude::Point, Drawable,
|
|
|
|
};
|
2021-03-03 21:20:44 +00:00
|
|
|
/// Display agnostic single curve plot object
|
2021-07-23 15:01:38 +00:00
|
|
|
#[derive(Clone, Copy)]
|
2022-08-13 17:00:41 +00:00
|
|
|
pub struct SinglePlot<'a, C>
|
|
|
|
where
|
|
|
|
C: PixelColor + Default,
|
|
|
|
{
|
2021-03-03 21:20:44 +00:00
|
|
|
/// curve to be drawn on the plot
|
2022-08-13 17:00:41 +00:00
|
|
|
curves: &'a [(Curve<'a>, C)],
|
2021-03-03 21:20:44 +00:00
|
|
|
/// range of X axis on which curve will be drawn
|
2021-01-04 21:20:07 +00:00
|
|
|
x_scale: Scale,
|
2021-03-03 21:20:44 +00:00
|
|
|
/// range of Y axis on which curve will be drawn
|
2021-01-04 21:20:07 +00:00
|
|
|
y_scale: Scale,
|
2020-12-20 11:11:06 +00:00
|
|
|
}
|
2022-08-13 17:00:41 +00:00
|
|
|
impl<'a, C> SinglePlot<'a, C>
|
|
|
|
where
|
|
|
|
C: PixelColor + Default,
|
|
|
|
{
|
2021-03-03 21:20:44 +00:00
|
|
|
/// create SinglePlot object with manual range
|
2022-08-13 17:00:41 +00:00
|
|
|
pub fn new(curves: &'a [(Curve<'a>, C)], x_scale: Scale, y_scale: Scale) -> SinglePlot<C> {
|
|
|
|
assert!(curves.len() > 0, "At least one curve must be given to SinglePlot constructor");
|
2021-07-23 15:01:38 +00:00
|
|
|
SinglePlot {
|
2022-08-13 17:00:41 +00:00
|
|
|
curves,
|
2021-07-23 15:01:38 +00:00
|
|
|
x_scale,
|
|
|
|
y_scale,
|
|
|
|
}
|
2021-02-16 19:51:09 +00:00
|
|
|
}
|
2021-03-03 21:20:44 +00:00
|
|
|
//TODO: add auto range plot constructor
|
|
|
|
/// convert to drawable form for specific display
|
2022-08-13 17:00:41 +00:00
|
|
|
pub fn into_drawable(self, top_left: Point, bottom_right: Point) -> DrawableSinglePlot<'a, C> {
|
2021-07-23 15:01:38 +00:00
|
|
|
DrawableSinglePlot {
|
|
|
|
plot: self,
|
|
|
|
color: None,
|
|
|
|
text_color: None,
|
|
|
|
axis_color: None,
|
|
|
|
thickness: None,
|
|
|
|
axis_thickness: None,
|
|
|
|
top_left,
|
|
|
|
bottom_right,
|
|
|
|
}
|
2021-02-16 19:51:09 +00:00
|
|
|
}
|
|
|
|
}
|
2021-03-03 21:20:44 +00:00
|
|
|
/// Drawable single plot object, constructed for specific display
|
2021-02-16 19:51:09 +00:00
|
|
|
pub struct DrawableSinglePlot<'a, C>
|
2021-07-23 15:01:38 +00:00
|
|
|
where
|
|
|
|
C: PixelColor + Default,
|
2020-12-20 11:11:06 +00:00
|
|
|
{
|
2022-08-13 17:00:41 +00:00
|
|
|
plot: SinglePlot<'a, C>,
|
2021-02-25 22:53:10 +00:00
|
|
|
color: Option<C>,
|
|
|
|
text_color: Option<C>,
|
|
|
|
axis_color: Option<C>,
|
|
|
|
thickness: Option<usize>,
|
|
|
|
axis_thickness: Option<usize>,
|
2021-02-16 19:51:09 +00:00
|
|
|
top_left: Point,
|
|
|
|
bottom_right: Point,
|
2020-12-20 11:11:06 +00:00
|
|
|
}
|
2021-03-03 21:20:44 +00:00
|
|
|
/// builder methods to modify plot decoration
|
2021-02-25 22:53:10 +00:00
|
|
|
impl<'a, C> DrawableSinglePlot<'a, C>
|
2021-07-23 15:01:38 +00:00
|
|
|
where
|
|
|
|
C: PixelColor + Default,
|
2021-02-25 22:53:10 +00:00
|
|
|
{
|
|
|
|
pub fn set_color(mut self, color: C) -> DrawableSinglePlot<'a, C> {
|
|
|
|
self.color = Some(color);
|
|
|
|
self
|
|
|
|
}
|
2021-03-03 21:20:44 +00:00
|
|
|
/// if not set, main color will be used
|
2021-02-25 22:53:10 +00:00
|
|
|
pub fn set_text_color(mut self, color: C) -> DrawableSinglePlot<'a, C> {
|
|
|
|
self.text_color = Some(color);
|
|
|
|
self
|
|
|
|
}
|
2021-03-03 21:20:44 +00:00
|
|
|
/// if not set, main color will be used
|
2021-02-25 22:53:10 +00:00
|
|
|
pub fn set_axis_color(mut self, color: C) -> DrawableSinglePlot<'a, C> {
|
|
|
|
self.axis_color = Some(color);
|
|
|
|
self
|
|
|
|
}
|
2021-03-03 21:20:44 +00:00
|
|
|
/// set curve thickness
|
2021-02-25 22:53:10 +00:00
|
|
|
pub fn set_thickness(mut self, thickness: usize) -> DrawableSinglePlot<'a, C> {
|
|
|
|
self.thickness = Some(thickness);
|
|
|
|
self
|
|
|
|
}
|
2021-03-03 21:20:44 +00:00
|
|
|
///set axis thickness
|
2021-02-25 22:53:10 +00:00
|
|
|
pub fn set_axis_thickness(mut self, thickness: usize) -> DrawableSinglePlot<'a, C> {
|
|
|
|
self.axis_thickness = Some(thickness);
|
|
|
|
self
|
|
|
|
}
|
2021-03-03 21:20:44 +00:00
|
|
|
//TODO: add axis ticks thickness
|
2021-02-25 22:53:10 +00:00
|
|
|
}
|
2021-07-23 15:01:38 +00:00
|
|
|
impl<'a, C> Drawable for DrawableSinglePlot<'a, C>
|
|
|
|
where
|
|
|
|
C: PixelColor + Default,
|
2020-12-20 11:11:06 +00:00
|
|
|
{
|
2021-07-23 15:01:38 +00:00
|
|
|
type Color = C;
|
|
|
|
type Output = ();
|
2021-03-03 21:20:44 +00:00
|
|
|
/// most important function - draw the plot on the display
|
2021-07-23 15:01:38 +00:00
|
|
|
fn draw<D>(&self, display: &mut D) -> Result<Self::Output, D::Error>
|
|
|
|
where
|
|
|
|
D: DrawTarget<Color = C>,
|
|
|
|
{
|
2021-03-02 20:18:53 +00:00
|
|
|
let color = self.color.unwrap_or_default();
|
|
|
|
let text_color = self.text_color.unwrap_or(color);
|
|
|
|
let axis_color = self.axis_color.unwrap_or(color);
|
|
|
|
let thickness = self.thickness.unwrap_or(2);
|
|
|
|
let axis_thickness = self.axis_thickness.unwrap_or(thickness);
|
2021-07-23 15:01:38 +00:00
|
|
|
let text_style = MonoTextStyleBuilder::new().text_color(text_color).build();
|
2022-08-13 17:00:41 +00:00
|
|
|
|
|
|
|
let x_range = self.plot.curves[0].0.x_range.clone();
|
|
|
|
let y_range = self.plot.curves[0].0.y_range.clone();
|
|
|
|
|
|
|
|
Axis::new(x_range)
|
2021-03-02 20:18:53 +00:00
|
|
|
.set_title("X")
|
|
|
|
.set_scale(self.plot.x_scale)
|
2021-07-23 15:01:38 +00:00
|
|
|
.into_drawable_axis(Placement::X {
|
|
|
|
x1: self.top_left.x,
|
|
|
|
x2: self.bottom_right.x,
|
|
|
|
y: self.bottom_right.y,
|
|
|
|
})
|
2021-03-02 20:18:53 +00:00
|
|
|
.set_color(axis_color)
|
|
|
|
.set_text_style(text_style)
|
|
|
|
.set_tick_size(2)
|
|
|
|
.set_thickness(axis_thickness)
|
2021-01-02 09:28:38 +00:00
|
|
|
.draw(display)?;
|
2022-08-13 17:00:41 +00:00
|
|
|
Axis::new(y_range)
|
2021-03-02 20:18:53 +00:00
|
|
|
.set_title("Y")
|
|
|
|
.set_scale(self.plot.y_scale)
|
2021-07-23 15:01:38 +00:00
|
|
|
.into_drawable_axis(Placement::Y {
|
|
|
|
y1: self.top_left.y,
|
|
|
|
y2: self.bottom_right.y,
|
|
|
|
x: self.top_left.x,
|
|
|
|
})
|
2021-03-02 20:18:53 +00:00
|
|
|
.set_color(axis_color)
|
|
|
|
.set_text_style(text_style)
|
|
|
|
.set_tick_size(2)
|
|
|
|
.set_thickness(axis_thickness)
|
2021-01-02 09:28:38 +00:00
|
|
|
.draw(display)?;
|
2022-08-13 17:00:41 +00:00
|
|
|
|
|
|
|
for curve in self.plot.curves {
|
|
|
|
curve
|
|
|
|
.0
|
|
|
|
.into_drawable_curve(&self.top_left, &self.bottom_right)
|
|
|
|
.set_color(curve.1)
|
|
|
|
.set_thickness(thickness)
|
|
|
|
.draw(display)?;
|
|
|
|
}
|
|
|
|
|
2020-12-20 11:11:06 +00:00
|
|
|
Ok(())
|
|
|
|
}
|
2021-07-23 15:01:38 +00:00
|
|
|
}
|