mirror of
https://gitlab.com/feliix42/embedded-plots.git
synced 2024-11-21 17:36:30 +00:00
Single plot takes slices of curves + colors
This commit is contained in:
parent
0ce5278b52
commit
e6257b531b
4 changed files with 79 additions and 21 deletions
45
examples/multiple_curves.rs
Normal file
45
examples/multiple_curves.rs
Normal file
|
@ -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<Rgb565> = 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(())
|
||||||
|
}
|
|
@ -19,7 +19,8 @@ fn main() -> Result<(), core::convert::Infallible> {
|
||||||
];
|
];
|
||||||
|
|
||||||
let curve = Curve::from_data(data.as_slice());
|
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 })
|
.into_drawable(Point { x: 18, y: 2 }, Point { x: 120, y: 30 })
|
||||||
.set_color(BinaryColor::On);
|
.set_color(BinaryColor::On);
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,8 @@ fn main() -> Result<(), core::convert::Infallible> {
|
||||||
];
|
];
|
||||||
|
|
||||||
let curve = Curve::from_data(data.as_slice());
|
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 })
|
.into_drawable(Point { x: 50, y: 10 }, Point { x: 430, y: 250 })
|
||||||
.set_color(RgbColor::YELLOW)
|
.set_color(RgbColor::YELLOW)
|
||||||
.set_text_color(RgbColor::WHITE);
|
.set_text_color(RgbColor::WHITE);
|
||||||
|
|
|
@ -6,30 +6,33 @@ use embedded_graphics::{
|
||||||
};
|
};
|
||||||
/// Display agnostic single curve plot object
|
/// Display agnostic single curve plot object
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct SinglePlot<'a> {
|
pub struct SinglePlot<'a, C>
|
||||||
|
where
|
||||||
|
C: PixelColor + Default,
|
||||||
|
{
|
||||||
/// curve to be drawn on the plot
|
/// 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
|
/// range of X axis on which curve will be drawn
|
||||||
x_scale: Scale,
|
x_scale: Scale,
|
||||||
/// range of Y axis on which curve will be drawn
|
/// range of Y axis on which curve will be drawn
|
||||||
y_scale: Scale,
|
y_scale: Scale,
|
||||||
}
|
}
|
||||||
impl<'a> SinglePlot<'a> {
|
impl<'a, C> SinglePlot<'a, C>
|
||||||
|
where
|
||||||
|
C: PixelColor + Default,
|
||||||
|
{
|
||||||
/// create SinglePlot object with manual range
|
/// 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<C> {
|
||||||
|
assert!(curves.len() > 0, "At least one curve must be given to SinglePlot constructor");
|
||||||
SinglePlot {
|
SinglePlot {
|
||||||
curve,
|
curves,
|
||||||
x_scale,
|
x_scale,
|
||||||
y_scale,
|
y_scale,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//TODO: add auto range plot constructor
|
//TODO: add auto range plot constructor
|
||||||
/// convert to drawable form for specific display
|
/// convert to drawable form for specific display
|
||||||
pub fn into_drawable<C: PixelColor + Default>(
|
pub fn into_drawable(self, top_left: Point, bottom_right: Point) -> DrawableSinglePlot<'a, C> {
|
||||||
self,
|
|
||||||
top_left: Point,
|
|
||||||
bottom_right: Point,
|
|
||||||
) -> DrawableSinglePlot<'a, C> {
|
|
||||||
DrawableSinglePlot {
|
DrawableSinglePlot {
|
||||||
plot: self,
|
plot: self,
|
||||||
color: None,
|
color: None,
|
||||||
|
@ -47,7 +50,7 @@ pub struct DrawableSinglePlot<'a, C>
|
||||||
where
|
where
|
||||||
C: PixelColor + Default,
|
C: PixelColor + Default,
|
||||||
{
|
{
|
||||||
plot: SinglePlot<'a>,
|
plot: SinglePlot<'a, C>,
|
||||||
color: Option<C>,
|
color: Option<C>,
|
||||||
text_color: Option<C>,
|
text_color: Option<C>,
|
||||||
axis_color: Option<C>,
|
axis_color: Option<C>,
|
||||||
|
@ -104,7 +107,11 @@ where
|
||||||
let thickness = self.thickness.unwrap_or(2);
|
let thickness = self.thickness.unwrap_or(2);
|
||||||
let axis_thickness = self.axis_thickness.unwrap_or(thickness);
|
let axis_thickness = self.axis_thickness.unwrap_or(thickness);
|
||||||
let text_style = MonoTextStyleBuilder::new().text_color(text_color).build();
|
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_title("X")
|
||||||
.set_scale(self.plot.x_scale)
|
.set_scale(self.plot.x_scale)
|
||||||
.into_drawable_axis(Placement::X {
|
.into_drawable_axis(Placement::X {
|
||||||
|
@ -117,7 +124,7 @@ where
|
||||||
.set_tick_size(2)
|
.set_tick_size(2)
|
||||||
.set_thickness(axis_thickness)
|
.set_thickness(axis_thickness)
|
||||||
.draw(display)?;
|
.draw(display)?;
|
||||||
Axis::new(self.plot.curve.y_range.clone())
|
Axis::new(y_range)
|
||||||
.set_title("Y")
|
.set_title("Y")
|
||||||
.set_scale(self.plot.y_scale)
|
.set_scale(self.plot.y_scale)
|
||||||
.into_drawable_axis(Placement::Y {
|
.into_drawable_axis(Placement::Y {
|
||||||
|
@ -130,12 +137,16 @@ where
|
||||||
.set_tick_size(2)
|
.set_tick_size(2)
|
||||||
.set_thickness(axis_thickness)
|
.set_thickness(axis_thickness)
|
||||||
.draw(display)?;
|
.draw(display)?;
|
||||||
self.plot
|
|
||||||
.curve
|
for curve in self.plot.curves {
|
||||||
.into_drawable_curve(&self.top_left, &self.bottom_right)
|
curve
|
||||||
.set_color(color)
|
.0
|
||||||
.set_thickness(thickness)
|
.into_drawable_curve(&self.top_left, &self.bottom_right)
|
||||||
.draw(display)?;
|
.set_color(curve.1)
|
||||||
|
.set_thickness(thickness)
|
||||||
|
.draw(display)?;
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue