mirror of
https://gitlab.com/feliix42/embedded-plots.git
synced 2024-11-22 09:56:31 +00:00
Merge branch 'feature/axis' into 'develop'
Feature/axis See merge request mchodzikiewicz/embedded-plots!4
This commit is contained in:
commit
7e46ee253c
13 changed files with 342 additions and 98 deletions
|
@ -9,8 +9,8 @@ edition = "2018"
|
|||
[dependencies]
|
||||
embedded-graphics = "0.6.0"
|
||||
itertools = "0.9.0"
|
||||
heapless = "0.5.6"
|
||||
|
||||
[dev-dependencies]
|
||||
embedded-graphics-simulator = "0.2.1"
|
||||
test-case = "1.0.0"
|
||||
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
use embedded_graphics::{
|
||||
pixelcolor::Rgb565,
|
||||
prelude::*,
|
||||
};
|
||||
|
||||
use embedded_graphics_simulator::{
|
||||
SimulatorDisplay,
|
||||
Window,
|
||||
OutputSettingsBuilder
|
||||
};
|
||||
|
||||
use embedded_plots::curve::{PlotPoint, Curve};
|
||||
|
||||
fn main() -> Result<(), core::convert::Infallible> {
|
||||
let mut display: SimulatorDisplay<Rgb565> = SimulatorDisplay::new(Size::new(480, 272));
|
||||
|
||||
let data = vec![
|
||||
PlotPoint{x: 0,y: 0},
|
||||
PlotPoint{x: 1,y: 1},
|
||||
PlotPoint{x: 2,y: 1},
|
||||
PlotPoint{x: 3,y: 0},
|
||||
];
|
||||
Curve::new(data.as_slice())
|
||||
.into_drawable_curve(&(0..3),&(0..1),&Point{x: 20, y: 20}, &Point{x:450,y:250},RgbColor::WHITE)
|
||||
.draw(&mut display)?;
|
||||
|
||||
let output_settings = OutputSettingsBuilder::new()
|
||||
.build();
|
||||
Window::new("Hello World", &output_settings).show_static(&display);
|
||||
|
||||
Ok(())
|
||||
}
|
126
examples/free_axis.rs
Normal file
126
examples/free_axis.rs
Normal file
|
@ -0,0 +1,126 @@
|
|||
use embedded_graphics::{
|
||||
pixelcolor::Rgb565,
|
||||
prelude::*,
|
||||
style::TextStyleBuilder,
|
||||
fonts::{Font6x8, Font6x6},
|
||||
};
|
||||
|
||||
use embedded_graphics_simulator::{
|
||||
SimulatorDisplay,
|
||||
Window,
|
||||
OutputSettingsBuilder,
|
||||
};
|
||||
|
||||
use embedded_plots::{
|
||||
axis::{Axis, Placement, Scale},
|
||||
};
|
||||
|
||||
fn main() -> Result<(), core::convert::Infallible> {
|
||||
let mut display: SimulatorDisplay<Rgb565> = SimulatorDisplay::new(Size::new(480, 272));
|
||||
|
||||
let text_style_white = TextStyleBuilder::new(Font6x8)
|
||||
.text_color(RgbColor::WHITE)
|
||||
.build();
|
||||
|
||||
let text_style_yellow_compact = TextStyleBuilder::new(Font6x6)
|
||||
.text_color(RgbColor::YELLOW)
|
||||
.build();
|
||||
|
||||
Axis::new("X Fixed 0-100(10)", 0..100, Scale::Fixed(10))
|
||||
.into_drawable_axis(
|
||||
Placement::X{x1: 40, x2: 230, y: 10},
|
||||
RgbColor::WHITE,
|
||||
text_style_white,
|
||||
2
|
||||
)
|
||||
.draw(&mut display)?;
|
||||
|
||||
Axis::new("X Fixed 0-200(100)", 0..200, Scale::Fixed(100))
|
||||
.into_drawable_axis(
|
||||
Placement::X{x1: 240, x2: 470, y: 10},
|
||||
RgbColor::YELLOW,
|
||||
text_style_yellow_compact,
|
||||
1
|
||||
)
|
||||
.draw(&mut display)?;
|
||||
|
||||
Axis::new("X Frac 0-100(7)", 0..100, Scale::RangeFraction(7))
|
||||
.into_drawable_axis(
|
||||
Placement::X{x1: 50, x2: 220, y: 30},
|
||||
RgbColor::BLUE,
|
||||
text_style_white,
|
||||
3
|
||||
)
|
||||
.draw(&mut display)?;
|
||||
|
||||
Axis::new("X Frac 0-200(4)", 0..200, Scale::RangeFraction(4))
|
||||
.into_drawable_axis(
|
||||
Placement::X{x1: 250, x2: 460, y: 40},
|
||||
RgbColor::RED,
|
||||
text_style_yellow_compact,
|
||||
7
|
||||
)
|
||||
.draw(&mut display)?;
|
||||
|
||||
Axis::new("Y Fixed 0-100(10)", 0..100, Scale::Fixed(10))
|
||||
.into_drawable_axis(
|
||||
Placement::Y{y1: 70, y2: 230, x: 160},
|
||||
RgbColor::WHITE,
|
||||
text_style_white,
|
||||
2
|
||||
)
|
||||
.draw(&mut display)?;
|
||||
|
||||
Axis::new("Y Fixed 0-200(100)", 0..200, Scale::Fixed(100))
|
||||
.into_drawable_axis(
|
||||
Placement::Y{y1: 70, y2: 210, x: 260},
|
||||
RgbColor::YELLOW,
|
||||
text_style_yellow_compact,
|
||||
1
|
||||
)
|
||||
.draw(&mut display)?;
|
||||
|
||||
Axis::new("Y Frac 0-100(7)", 0..100, Scale::RangeFraction(7))
|
||||
.into_drawable_axis(
|
||||
Placement::Y{y1: 60, y2: 180, x: 370},
|
||||
RgbColor::BLUE,
|
||||
text_style_white,
|
||||
3
|
||||
)
|
||||
.draw(&mut display)?;
|
||||
|
||||
Axis::new("Y Frac 0-200(4)", 0..200, Scale::RangeFraction(4))
|
||||
.into_drawable_axis(
|
||||
Placement::Y{y1: 90, y2: 220, x: 470},
|
||||
RgbColor::RED,
|
||||
text_style_yellow_compact,
|
||||
7
|
||||
)
|
||||
.draw(&mut display)?;
|
||||
|
||||
Axis::new("X", 123..2137, Scale::Fixed(150))
|
||||
.into_drawable_axis(
|
||||
Placement::X{x1: 30, x2: 470, y: 250},
|
||||
RgbColor::YELLOW,
|
||||
text_style_white,
|
||||
2
|
||||
)
|
||||
.draw(&mut display)?;
|
||||
|
||||
Axis::new("Y", 0..2137, Scale::RangeFraction(15))
|
||||
.into_drawable_axis(
|
||||
Placement::Y{y1: 10, y2: 250, x: 30},
|
||||
RgbColor::WHITE,
|
||||
text_style_white,
|
||||
2
|
||||
)
|
||||
.draw(&mut display)?;
|
||||
|
||||
|
||||
let output_settings = OutputSettingsBuilder::new()
|
||||
.pixel_spacing(1)
|
||||
.build();
|
||||
Window::new("Free axis", &output_settings).show_static(&display);
|
||||
|
||||
Ok(())
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
use embedded_graphics::{
|
||||
prelude::*,
|
||||
pixelcolor::BinaryColor,
|
||||
};
|
||||
|
||||
use embedded_graphics_simulator::{SimulatorDisplay, Window, OutputSettingsBuilder, BinaryColorTheme};
|
||||
|
@ -7,21 +8,29 @@ use embedded_graphics_simulator::{SimulatorDisplay, Window, OutputSettingsBuilde
|
|||
use embedded_plots::{
|
||||
single_plot::{SinglePlot},
|
||||
curve::{PlotPoint, Curve},
|
||||
axis::Scale,
|
||||
};
|
||||
use embedded_graphics::pixelcolor::BinaryColor;
|
||||
|
||||
fn main() -> Result<(), core::convert::Infallible> {
|
||||
let mut display: SimulatorDisplay<BinaryColor> = SimulatorDisplay::new(Size::new(128, 48));
|
||||
|
||||
let data = vec![
|
||||
PlotPoint { x: 0, y: 0 },
|
||||
PlotPoint { x: 1, y: 1 },
|
||||
PlotPoint { x: 2, y: 1 },
|
||||
PlotPoint { x: 1, y: 2 },
|
||||
PlotPoint { x: 2, y: 2 },
|
||||
PlotPoint { x: 3, y: 0 },
|
||||
];
|
||||
let curve = Curve::from_data(data.as_slice());
|
||||
|
||||
let plot = SinglePlot::new(&curve, BinaryColor::On, Point { x: 9, y: 3 }, Point { x: 120, y: 45 });
|
||||
let plot = SinglePlot::new(
|
||||
&curve,
|
||||
Scale::RangeFraction(3),
|
||||
Scale::RangeFraction(2),
|
||||
).into_drawable(
|
||||
BinaryColor::On,
|
||||
Point { x: 18, y: 2 },
|
||||
Point { x: 120, y: 30 },
|
||||
);
|
||||
|
||||
plot.draw(&mut display)?;
|
||||
let output_settings = OutputSettingsBuilder::new()
|
||||
|
|
|
@ -7,12 +7,12 @@ use embedded_graphics_simulator::{
|
|||
SimulatorDisplay,
|
||||
Window,
|
||||
OutputSettingsBuilder,
|
||||
|
||||
};
|
||||
|
||||
use embedded_plots::{
|
||||
single_plot::{SinglePlot},
|
||||
curve::{PlotPoint, Curve},
|
||||
axis::Scale,
|
||||
};
|
||||
|
||||
fn main() -> Result<(), core::convert::Infallible> {
|
||||
|
@ -20,13 +20,22 @@ fn main() -> Result<(), core::convert::Infallible> {
|
|||
|
||||
let data = vec![
|
||||
PlotPoint { x: 0, y: 0 },
|
||||
PlotPoint { x: 1, y: 1 },
|
||||
PlotPoint { x: 2, y: 1 },
|
||||
PlotPoint { x: 1, y: 2 },
|
||||
PlotPoint { x: 2, y: 2 },
|
||||
PlotPoint { x: 3, y: 0 },
|
||||
];
|
||||
let curve = Curve::from_data(data.as_slice());
|
||||
|
||||
let plot = SinglePlot::new(&curve, RgbColor::YELLOW, Point { x: 10, y: 10 }, Point { x: 470, y: 260 });
|
||||
let plot = SinglePlot::new(
|
||||
&curve,
|
||||
Scale::RangeFraction(3),
|
||||
Scale::RangeFraction(2),
|
||||
)
|
||||
.into_drawable(
|
||||
RgbColor::YELLOW,
|
||||
Point { x: 50, y: 10 },
|
||||
Point { x: 430, y: 250 }
|
||||
);
|
||||
|
||||
plot.draw(&mut display)?;
|
||||
let output_settings = OutputSettingsBuilder::new()
|
||||
|
|
45
src/axis.rs
Normal file
45
src/axis.rs
Normal file
|
@ -0,0 +1,45 @@
|
|||
use core::ops::Range;
|
||||
use embedded_graphics::prelude::*;
|
||||
use embedded_graphics::style::{TextStyle};
|
||||
|
||||
use crate::drawable_axis::DrawableAxis;
|
||||
|
||||
pub enum Placement {
|
||||
X {
|
||||
x1: i32,
|
||||
x2: i32,
|
||||
y: i32,
|
||||
},
|
||||
Y {
|
||||
y1: i32,
|
||||
y2: i32,
|
||||
x: i32,
|
||||
},
|
||||
}
|
||||
|
||||
pub enum Scale {
|
||||
Fixed(usize),
|
||||
RangeFraction(usize),
|
||||
}
|
||||
|
||||
pub struct Axis<'a> {
|
||||
title: &'a str,
|
||||
range: Range<i32>,
|
||||
scale: Scale,
|
||||
}
|
||||
|
||||
impl<'a> Axis<'a>
|
||||
{
|
||||
pub fn new(title: &'a str, range: Range<i32>, scale: Scale) -> Axis<'a> {
|
||||
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>
|
||||
where
|
||||
C: PixelColor,
|
||||
F: Font,
|
||||
TextStyle<C, F>: Clone,
|
||||
{
|
||||
DrawableAxis::new(self.title,placement,self.range,self.scale,plot_color,text_style,tick_height)
|
||||
}
|
||||
}
|
|
@ -13,8 +13,8 @@ pub struct PlotPoint {
|
|||
|
||||
pub struct Curve<'a> {
|
||||
points: &'a [PlotPoint],
|
||||
x_range: Range<i32>,
|
||||
y_range: Range<i32>,
|
||||
pub x_range: Range<i32>,
|
||||
pub y_range: Range<i32>,
|
||||
}
|
||||
|
||||
impl<'a> Curve<'a> {
|
||||
|
|
105
src/drawable_axis.rs
Normal file
105
src/drawable_axis.rs
Normal file
|
@ -0,0 +1,105 @@
|
|||
use embedded_graphics::prelude::*;
|
||||
use crate::axis::{Placement, Scale};
|
||||
use core::ops::Range;
|
||||
use embedded_graphics::style::{TextStyle, PrimitiveStyle};
|
||||
use embedded_graphics::fonts::Text;
|
||||
use crate::range_conv::Scalable;
|
||||
use embedded_graphics::primitives::Line;
|
||||
use heapless::{consts::*, String};
|
||||
use core::fmt::Write;
|
||||
|
||||
|
||||
pub struct DrawableAxis<'a, C, F>
|
||||
where
|
||||
C: PixelColor,
|
||||
F: Font,
|
||||
TextStyle<C, F>: Clone,
|
||||
{
|
||||
title: &'a str,
|
||||
placement: Placement,
|
||||
range: Range<i32>,
|
||||
scale: Scale,
|
||||
color: C,
|
||||
text_style: TextStyle<C, F>,
|
||||
tick_size: usize,
|
||||
}
|
||||
|
||||
impl<'a, C, F> DrawableAxis<'a, C, F>
|
||||
where
|
||||
C: PixelColor,
|
||||
F: Font,
|
||||
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> {
|
||||
DrawableAxis { title, placement, range, scale, color, text_style, tick_size: tick_height }
|
||||
}
|
||||
|
||||
pub fn size(&self) -> Point {
|
||||
Point { x: 50, y: 50 }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl<'a, C, F> Drawable<C> for DrawableAxis<'a, C, F>
|
||||
where
|
||||
C: PixelColor,
|
||||
F: Font + Copy,
|
||||
TextStyle<C, F>: Clone,
|
||||
{
|
||||
fn draw<D: DrawTarget<C>>(self, display: &mut D) -> Result<(), D::Error> {
|
||||
let scale_marks = match self.scale {
|
||||
Scale::Fixed(interval) => {
|
||||
self.range.clone().into_iter().step_by(interval)
|
||||
}
|
||||
Scale::RangeFraction(fraction) => {
|
||||
let len = self.range.len();
|
||||
self.range.clone().into_iter().step_by(len / fraction)
|
||||
}
|
||||
};
|
||||
match self.placement {
|
||||
Placement::X { x1, x2, y } => {
|
||||
Line { start: Point { x: x1, y }, end: Point { x: x2, y } }
|
||||
.into_styled(PrimitiveStyle::with_stroke(self.color, 1))
|
||||
.draw(display)?;
|
||||
let title = Text::new(self.title, Point { x: x1, y: y + 10 })
|
||||
.into_styled(self.text_style);
|
||||
let title = title.translate(Point { x: (x2 - x1) / 2 - title.size().width as i32 / 2, y: 0 });
|
||||
title.draw(display)?;
|
||||
|
||||
for mark in scale_marks {
|
||||
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 } }
|
||||
.into_styled(PrimitiveStyle::with_stroke(self.color, 1))
|
||||
.draw(display)?;
|
||||
let mut buf: String::<U8> = String::new();
|
||||
write!(buf, "{}", mark).unwrap();
|
||||
Text::new(&buf, Point { x: x + 2, y: y + 2 }).into_styled(self.text_style).draw(display)?;
|
||||
}
|
||||
}
|
||||
Placement::Y { y1, y2, x } => {
|
||||
Line { start: Point { x, y: y1 }, end: Point { x, y: y2 } }
|
||||
.into_styled(PrimitiveStyle::with_stroke(self.color, 1))
|
||||
.draw(display)?;
|
||||
|
||||
let mut max_tick_text_width = 0;
|
||||
for mark in scale_marks {
|
||||
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 } }
|
||||
.into_styled(PrimitiveStyle::with_stroke(self.color, 1))
|
||||
.draw(display)?;
|
||||
let mut buf: String::<U8> = String::new();
|
||||
write!(buf, "{}", mark).unwrap();
|
||||
let tick_val = Text::new(&buf, Point { x, y }).into_styled(self.text_style);
|
||||
let tick_val = tick_val.translate(Point { x: -(tick_val.size().width as i32) - 2, y: 2 });
|
||||
if tick_val.size().width > max_tick_text_width { max_tick_text_width = tick_val.size().width }
|
||||
tick_val.draw(display)?;
|
||||
}
|
||||
let title = Text::new(self.title, Point { x, y: y1 })
|
||||
.into_styled(self.text_style);
|
||||
let title = title.translate(Point { x: -(title.size().width as i32) - max_tick_text_width as i32 - self.tick_size as i32 - 2, y: (y2 - y1) / 2 });
|
||||
title.draw(display)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
|
@ -6,8 +6,6 @@ use embedded_graphics::primitives::{Line, Primitive};
|
|||
use embedded_graphics::style::PrimitiveStyle;
|
||||
|
||||
pub struct DrawableCurve<C, I>
|
||||
where
|
||||
I: Iterator<Item=Point>,
|
||||
{
|
||||
scaled_data: I,
|
||||
color: C,
|
||||
|
@ -18,7 +16,7 @@ impl<C, I> DrawableCurve<C, I>
|
|||
C: PixelColor,
|
||||
I: Iterator<Item=Point>,
|
||||
{
|
||||
pub fn new(data: I, color: C) -> DrawableCurve<C, I> {
|
||||
pub(in crate) fn new(data: I, color: C) -> DrawableCurve<C, I> {
|
||||
DrawableCurve {
|
||||
scaled_data: data,
|
||||
color,
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
#![no_std]
|
||||
|
||||
pub mod curve;
|
||||
pub mod axis;
|
||||
pub mod polyplot;
|
||||
pub mod single_plot;
|
||||
|
||||
mod drawable_curve;
|
||||
mod range_conv;
|
||||
mod drawable_axis;
|
||||
|
|
37
src/plot.rs
37
src/plot.rs
|
@ -1,37 +0,0 @@
|
|||
use crate::curve::Curve;
|
||||
use embedded_graphics::drawable::Drawable;
|
||||
use embedded_graphics::DrawTarget;
|
||||
use embedded_graphics::prelude::Point;
|
||||
use embedded_graphics::pixelcolor::PixelColor;
|
||||
|
||||
struct Plot<'a, C>
|
||||
where
|
||||
C: PixelColor
|
||||
{
|
||||
curves: &'a [Curve<'a>],
|
||||
color: C,
|
||||
}
|
||||
|
||||
impl<'a, C> Plot<'a, C> {
|
||||
fn new(curves: &'a [Curve<'a>], color : C) -> Plot<C> {
|
||||
Plot{curves, color}
|
||||
}
|
||||
}
|
||||
|
||||
impl<C> Drawable<C> for Plot<'_, C>
|
||||
where
|
||||
C: PixelColor
|
||||
{
|
||||
fn draw<D: DrawTarget<C>>(self, display: &mut D) -> Result<(), <D as DrawTarget<_>>::Error> {
|
||||
for curve in self.curves {
|
||||
curve.into_drawable_curve(
|
||||
&(0..50),
|
||||
&(-10..10),
|
||||
&Point{x: 10,y: 10},
|
||||
&Point{x: 470, y: 270},
|
||||
self.color
|
||||
).draw(display)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
|
@ -5,8 +5,6 @@ use embedded_graphics::prelude::Point;
|
|||
use embedded_graphics::pixelcolor::PixelColor;
|
||||
|
||||
pub struct PolyPlot<'a, C>
|
||||
where
|
||||
C: PixelColor
|
||||
{
|
||||
curves: &'a [(Curve<'a>, C)],
|
||||
top_left: Point,
|
||||
|
|
|
@ -3,33 +3,54 @@ use embedded_graphics::drawable::Drawable;
|
|||
use embedded_graphics::DrawTarget;
|
||||
use embedded_graphics::prelude::Point;
|
||||
use embedded_graphics::pixelcolor::PixelColor;
|
||||
use crate::axis::{Scale, Placement, Axis};
|
||||
use embedded_graphics::style::TextStyleBuilder;
|
||||
use embedded_graphics::fonts::Font6x8;
|
||||
|
||||
pub struct SinglePlot<'a, C>
|
||||
pub struct SinglePlot<'a> {
|
||||
curve: &'a Curve<'a>,
|
||||
x_scale: Scale,
|
||||
y_scale: Scale,
|
||||
}
|
||||
|
||||
impl<'a> SinglePlot<'a> {
|
||||
pub fn new(curve: &'a Curve<'a>, x_scale: Scale, y_scale: Scale) -> SinglePlot {
|
||||
SinglePlot { curve, x_scale, y_scale }
|
||||
}
|
||||
|
||||
pub fn into_drawable<C: PixelColor>(self, color: C, top_left: Point, bottom_right: Point) -> DrawableSinglePlot<'a, C> {
|
||||
DrawableSinglePlot { plot: self, color, top_left, bottom_right }
|
||||
}
|
||||
}
|
||||
|
||||
pub struct DrawableSinglePlot<'a, C>
|
||||
where
|
||||
C: PixelColor
|
||||
{
|
||||
curve: &'a Curve<'a>,
|
||||
plot: SinglePlot<'a>,
|
||||
color: C,
|
||||
top_left: Point,
|
||||
bottom_right: Point,
|
||||
}
|
||||
|
||||
impl<'a, C> SinglePlot<'a, C>
|
||||
where
|
||||
C: PixelColor
|
||||
{
|
||||
pub fn new(curve: &'a Curve<'a>, color: C, top_left: Point, bottom_right: Point) -> SinglePlot<'a, C> {
|
||||
SinglePlot { curve, color, top_left, bottom_right}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, C> Drawable<C> for SinglePlot<'a, C>
|
||||
impl<'a, C> Drawable<C> for DrawableSinglePlot<'a, C>
|
||||
where
|
||||
C: PixelColor
|
||||
{
|
||||
fn draw<D: DrawTarget<C>>(self, display: &mut D) -> Result<(), D::Error> {
|
||||
let text_style = TextStyleBuilder::new(Font6x8)
|
||||
.text_color(self.color)
|
||||
.build();
|
||||
|
||||
self.curve.into_drawable_curve(
|
||||
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)
|
||||
.draw(display)?;
|
||||
|
||||
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)
|
||||
.draw(display)?;
|
||||
|
||||
self.plot.curve.into_drawable_curve(
|
||||
&self.top_left,
|
||||
&self.bottom_right,
|
||||
self.color,
|
||||
|
|
Loading…
Reference in a new issue