From e6257b531b35a4cc8a608dd1535ea5a26adeee2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20Le=C5=9Bnia=C5=84ski?= Date: Sat, 13 Aug 2022 19:00:41 +0200 Subject: [PATCH] Single plot takes slices of curves + colors --- examples/multiple_curves.rs | 45 +++++++++++++++++++++++++++++++++ examples/single_plot_mono.rs | 3 ++- examples/single_plot_rgb.rs | 3 ++- src/single_plot.rs | 49 ++++++++++++++++++++++-------------- 4 files changed, 79 insertions(+), 21 deletions(-) create mode 100644 examples/multiple_curves.rs diff --git a/examples/multiple_curves.rs b/examples/multiple_curves.rs new file mode 100644 index 0000000..cc2f6a9 --- /dev/null +++ b/examples/multiple_curves.rs @@ -0,0 +1,45 @@ +use embedded_graphics::{pixelcolor::Rgb565, prelude::*}; + +use embedded_graphics_simulator::{OutputSettingsBuilder, SimulatorDisplay, Window}; + +use embedded_plots::{ + axis::Scale, + curve::{Curve, PlotPoint}, + single_plot::SinglePlot, +}; + +fn main() -> Result<(), core::convert::Infallible> { + let mut display: SimulatorDisplay = SimulatorDisplay::new(Size::new(480, 272)); + + //min(x), max(x), min(y) and max(y) must be equal for each curve in order to display the plot correctly + let data = vec![ + PlotPoint { x: 0, y: 0 }, + PlotPoint { x: 1, y: 2 }, + PlotPoint { x: 2, y: 2 }, + PlotPoint { x: 3, y: 0 }, + ]; + + let data2 = vec![ + PlotPoint { x: 0, y: 0 }, + PlotPoint { x: 1, y: 2 }, + PlotPoint { x: 2, y: 1 }, + PlotPoint { x: 3, y: 1 }, + ]; + + let curve = Curve::from_data(data.as_slice()); + let curve2 = Curve::from_data(data2.as_slice()); + let curve_list = [(curve, RgbColor::YELLOW), (curve2, RgbColor::BLUE)]; + + let plot = SinglePlot::new(&curve_list, Scale::RangeFraction(3), Scale::RangeFraction(2)) + .into_drawable(Point { x: 50, y: 10 }, Point { x: 430, y: 250 }) + .set_color(RgbColor::YELLOW) + .set_text_color(RgbColor::WHITE); + + plot.draw(&mut display)?; + + let output_settings = OutputSettingsBuilder::new().build(); + + Window::new("Basic plot", &output_settings).show_static(&display); + + Ok(()) +} diff --git a/examples/single_plot_mono.rs b/examples/single_plot_mono.rs index fa85e8f..3238910 100644 --- a/examples/single_plot_mono.rs +++ b/examples/single_plot_mono.rs @@ -19,7 +19,8 @@ fn main() -> Result<(), core::convert::Infallible> { ]; let curve = Curve::from_data(data.as_slice()); - let plot = SinglePlot::new(&curve, Scale::RangeFraction(3), Scale::RangeFraction(2)) + let curve_list = [(curve, BinaryColor::On)]; + let plot = SinglePlot::new(&curve_list, Scale::RangeFraction(3), Scale::RangeFraction(2)) .into_drawable(Point { x: 18, y: 2 }, Point { x: 120, y: 30 }) .set_color(BinaryColor::On); diff --git a/examples/single_plot_rgb.rs b/examples/single_plot_rgb.rs index ad20912..19af114 100644 --- a/examples/single_plot_rgb.rs +++ b/examples/single_plot_rgb.rs @@ -18,7 +18,8 @@ fn main() -> Result<(), core::convert::Infallible> { ]; let curve = Curve::from_data(data.as_slice()); - let plot = SinglePlot::new(&curve, Scale::RangeFraction(3), Scale::RangeFraction(2)) + let curve_list = [(curve, RgbColor::YELLOW)]; + let plot = SinglePlot::new(&curve_list, Scale::RangeFraction(3), Scale::RangeFraction(2)) .into_drawable(Point { x: 50, y: 10 }, Point { x: 430, y: 250 }) .set_color(RgbColor::YELLOW) .set_text_color(RgbColor::WHITE); diff --git a/src/single_plot.rs b/src/single_plot.rs index 1e9cbc0..c639926 100644 --- a/src/single_plot.rs +++ b/src/single_plot.rs @@ -6,30 +6,33 @@ use embedded_graphics::{ }; /// Display agnostic single curve plot object #[derive(Clone, Copy)] -pub struct SinglePlot<'a> { +pub struct SinglePlot<'a, C> +where + C: PixelColor + Default, +{ /// curve to be drawn on the plot - curve: &'a Curve<'a>, + curves: &'a [(Curve<'a>, C)], /// range of X axis on which curve will be drawn x_scale: Scale, /// range of Y axis on which curve will be drawn y_scale: Scale, } -impl<'a> SinglePlot<'a> { +impl<'a, C> SinglePlot<'a, C> +where + C: PixelColor + Default, +{ /// create SinglePlot object with manual range - pub fn new(curve: &'a Curve<'a>, x_scale: Scale, y_scale: Scale) -> SinglePlot { + pub fn new(curves: &'a [(Curve<'a>, C)], x_scale: Scale, y_scale: Scale) -> SinglePlot { + assert!(curves.len() > 0, "At least one curve must be given to SinglePlot constructor"); SinglePlot { - curve, + curves, x_scale, y_scale, } } //TODO: add auto range plot constructor /// convert to drawable form for specific display - pub fn into_drawable( - self, - top_left: Point, - bottom_right: Point, - ) -> DrawableSinglePlot<'a, C> { + pub fn into_drawable(self, top_left: Point, bottom_right: Point) -> DrawableSinglePlot<'a, C> { DrawableSinglePlot { plot: self, color: None, @@ -47,7 +50,7 @@ pub struct DrawableSinglePlot<'a, C> where C: PixelColor + Default, { - plot: SinglePlot<'a>, + plot: SinglePlot<'a, C>, color: Option, text_color: Option, axis_color: Option, @@ -104,7 +107,11 @@ where let thickness = self.thickness.unwrap_or(2); let axis_thickness = self.axis_thickness.unwrap_or(thickness); let text_style = MonoTextStyleBuilder::new().text_color(text_color).build(); - Axis::new(self.plot.curve.x_range.clone()) + + 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) .set_title("X") .set_scale(self.plot.x_scale) .into_drawable_axis(Placement::X { @@ -117,7 +124,7 @@ where .set_tick_size(2) .set_thickness(axis_thickness) .draw(display)?; - Axis::new(self.plot.curve.y_range.clone()) + Axis::new(y_range) .set_title("Y") .set_scale(self.plot.y_scale) .into_drawable_axis(Placement::Y { @@ -130,12 +137,16 @@ where .set_tick_size(2) .set_thickness(axis_thickness) .draw(display)?; - self.plot - .curve - .into_drawable_curve(&self.top_left, &self.bottom_right) - .set_color(color) - .set_thickness(thickness) - .draw(display)?; + + 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)?; + } + Ok(()) } }