summaryrefslogtreecommitdiffstats
path: root/vendor/plotters/src/element/points.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/plotters/src/element/points.rs')
-rw-r--r--vendor/plotters/src/element/points.rs154
1 files changed, 154 insertions, 0 deletions
diff --git a/vendor/plotters/src/element/points.rs b/vendor/plotters/src/element/points.rs
new file mode 100644
index 000000000..423625b08
--- /dev/null
+++ b/vendor/plotters/src/element/points.rs
@@ -0,0 +1,154 @@
+use super::*;
+use super::{Drawable, PointCollection};
+use crate::style::{Color, ShapeStyle, SizeDesc};
+use plotters_backend::{BackendCoord, DrawingBackend, DrawingErrorKind};
+
+/**
+A common trait for elements that can be interpreted as points: A cross, a circle, a triangle marker...
+
+This is used internally by Plotters and should probably not be included in user code.
+See [`EmptyElement`] for more information and examples.
+*/
+pub trait PointElement<Coord, Size: SizeDesc> {
+ /**
+ Point creator.
+
+ This is used internally by Plotters and should probably not be included in user code.
+ See [`EmptyElement`] for more information and examples.
+ */
+ fn make_point(pos: Coord, size: Size, style: ShapeStyle) -> Self;
+}
+
+/**
+A cross marker for visualizing data series.
+
+See [`EmptyElement`] for more information and examples.
+*/
+pub struct Cross<Coord, Size: SizeDesc> {
+ center: Coord,
+ size: Size,
+ style: ShapeStyle,
+}
+
+impl<Coord, Size: SizeDesc> Cross<Coord, Size> {
+ /**
+ Creates a cross marker.
+
+ See [`EmptyElement`] for more information and examples.
+ */
+ pub fn new<T: Into<ShapeStyle>>(coord: Coord, size: Size, style: T) -> Self {
+ Self {
+ center: coord,
+ size,
+ style: style.into(),
+ }
+ }
+}
+
+impl<'a, Coord: 'a, Size: SizeDesc> PointCollection<'a, Coord> for &'a Cross<Coord, Size> {
+ type Point = &'a Coord;
+ type IntoIter = std::iter::Once<&'a Coord>;
+ fn point_iter(self) -> std::iter::Once<&'a Coord> {
+ std::iter::once(&self.center)
+ }
+}
+
+impl<Coord, DB: DrawingBackend, Size: SizeDesc> Drawable<DB> for Cross<Coord, Size> {
+ fn draw<I: Iterator<Item = BackendCoord>>(
+ &self,
+ mut points: I,
+ backend: &mut DB,
+ ps: (u32, u32),
+ ) -> Result<(), DrawingErrorKind<DB::ErrorType>> {
+ if let Some((x, y)) = points.next() {
+ let size = self.size.in_pixels(&ps);
+ let (x0, y0) = (x - size, y - size);
+ let (x1, y1) = (x + size, y + size);
+ backend.draw_line((x0, y0), (x1, y1), &self.style)?;
+ backend.draw_line((x0, y1), (x1, y0), &self.style)?;
+ }
+ Ok(())
+ }
+}
+
+/**
+A triangle marker for visualizing data series.
+
+See [`EmptyElement`] for more information and examples.
+*/
+pub struct TriangleMarker<Coord, Size: SizeDesc> {
+ center: Coord,
+ size: Size,
+ style: ShapeStyle,
+}
+
+impl<Coord, Size: SizeDesc> TriangleMarker<Coord, Size> {
+ /**
+ Creates a triangle marker.
+
+ See [`EmptyElement`] for more information and examples.
+ */
+ pub fn new<T: Into<ShapeStyle>>(coord: Coord, size: Size, style: T) -> Self {
+ Self {
+ center: coord,
+ size,
+ style: style.into(),
+ }
+ }
+}
+
+impl<'a, Coord: 'a, Size: SizeDesc> PointCollection<'a, Coord> for &'a TriangleMarker<Coord, Size> {
+ type Point = &'a Coord;
+ type IntoIter = std::iter::Once<&'a Coord>;
+ fn point_iter(self) -> std::iter::Once<&'a Coord> {
+ std::iter::once(&self.center)
+ }
+}
+
+impl<Coord, DB: DrawingBackend, Size: SizeDesc> Drawable<DB> for TriangleMarker<Coord, Size> {
+ fn draw<I: Iterator<Item = BackendCoord>>(
+ &self,
+ mut points: I,
+ backend: &mut DB,
+ ps: (u32, u32),
+ ) -> Result<(), DrawingErrorKind<DB::ErrorType>> {
+ if let Some((x, y)) = points.next() {
+ let size = self.size.in_pixels(&ps);
+ let points = [-90, -210, -330]
+ .iter()
+ .map(|deg| f64::from(*deg) * std::f64::consts::PI / 180.0)
+ .map(|rad| {
+ (
+ (rad.cos() * f64::from(size) + f64::from(x)).ceil() as i32,
+ (rad.sin() * f64::from(size) + f64::from(y)).ceil() as i32,
+ )
+ });
+ backend.fill_polygon(points, &self.style.color.to_backend_color())?;
+ }
+ Ok(())
+ }
+}
+
+impl<Coord, Size: SizeDesc> PointElement<Coord, Size> for Cross<Coord, Size> {
+ fn make_point(pos: Coord, size: Size, style: ShapeStyle) -> Self {
+ Self::new(pos, size, style)
+ }
+}
+
+impl<Coord, Size: SizeDesc> PointElement<Coord, Size> for TriangleMarker<Coord, Size> {
+ fn make_point(pos: Coord, size: Size, style: ShapeStyle) -> Self {
+ Self::new(pos, size, style)
+ }
+}
+
+impl<Coord, Size: SizeDesc> PointElement<Coord, Size> for Circle<Coord, Size> {
+ fn make_point(pos: Coord, size: Size, style: ShapeStyle) -> Self {
+ Self::new(pos, size, style)
+ }
+}
+
+impl<Coord, Size: SizeDesc> PointElement<Coord, Size> for Pixel<Coord> {
+ fn make_point(pos: Coord, _: Size, style: ShapeStyle) -> Self {
+ Self::new(pos, style)
+ }
+}