summaryrefslogtreecommitdiffstats
path: root/vendor/plotters/src/chart/axes3d.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/plotters/src/chart/axes3d.rs')
-rw-r--r--vendor/plotters/src/chart/axes3d.rs317
1 files changed, 317 insertions, 0 deletions
diff --git a/vendor/plotters/src/chart/axes3d.rs b/vendor/plotters/src/chart/axes3d.rs
new file mode 100644
index 000000000..33d7de39c
--- /dev/null
+++ b/vendor/plotters/src/chart/axes3d.rs
@@ -0,0 +1,317 @@
+use std::marker::PhantomData;
+
+use super::ChartContext;
+use crate::coord::cartesian::Cartesian3d;
+use crate::coord::ranged1d::{BoldPoints, LightPoints, Ranged, ValueFormatter};
+use crate::style::colors::{BLACK, TRANSPARENT};
+use crate::style::Color;
+use crate::style::{AsRelative, ShapeStyle, SizeDesc, TextStyle};
+
+use super::Coord3D;
+
+use crate::drawing::DrawingAreaErrorKind;
+
+use plotters_backend::DrawingBackend;
+
+/**
+Implements 3D plot axes configurations.
+
+The best way to use this struct is by way of the [`configure_axes()`] function.
+See [`ChartContext::configure_axes()`] for more information and examples.
+*/
+pub struct Axes3dStyle<'a, 'b, X: Ranged, Y: Ranged, Z: Ranged, DB: DrawingBackend> {
+ pub(super) parent_size: (u32, u32),
+ pub(super) target: Option<&'b mut ChartContext<'a, DB, Cartesian3d<X, Y, Z>>>,
+ pub(super) tick_size: i32,
+ pub(super) light_lines_limit: [usize; 3],
+ pub(super) n_labels: [usize; 3],
+ pub(super) bold_line_style: ShapeStyle,
+ pub(super) light_line_style: ShapeStyle,
+ pub(super) axis_panel_style: ShapeStyle,
+ pub(super) axis_style: ShapeStyle,
+ pub(super) label_style: TextStyle<'b>,
+ pub(super) format_x: &'b dyn Fn(&X::ValueType) -> String,
+ pub(super) format_y: &'b dyn Fn(&Y::ValueType) -> String,
+ pub(super) format_z: &'b dyn Fn(&Z::ValueType) -> String,
+ _phantom: PhantomData<&'a (X, Y, Z)>,
+}
+
+impl<'a, 'b, X, Y, Z, XT, YT, ZT, DB> Axes3dStyle<'a, 'b, X, Y, Z, DB>
+where
+ X: Ranged<ValueType = XT> + ValueFormatter<XT>,
+ Y: Ranged<ValueType = YT> + ValueFormatter<YT>,
+ Z: Ranged<ValueType = ZT> + ValueFormatter<ZT>,
+ DB: DrawingBackend,
+{
+ /**
+ Set the size of the tick marks.
+
+ - `value` Desired tick mark size, in pixels.
+
+ See [`ChartContext::configure_axes()`] for more information and examples.
+ */
+ pub fn tick_size<Size: SizeDesc>(&mut self, size: Size) -> &mut Self {
+ let actual_size = size.in_pixels(&self.parent_size);
+ self.tick_size = actual_size;
+ self
+ }
+
+ /**
+ Set the maximum number of divisions for the minor grid in the X axis.
+
+ - `value`: Maximum desired divisions between two consecutive X labels.
+
+ See [`ChartContext::configure_axes()`] for more information and examples.
+ */
+ pub fn x_max_light_lines(&mut self, value: usize) -> &mut Self {
+ self.light_lines_limit[0] = value;
+ self
+ }
+
+ /**
+ Set the maximum number of divisions for the minor grid in the Y axis.
+
+ - `value`: Maximum desired divisions between two consecutive Y labels.
+
+ See [`ChartContext::configure_axes()`] for more information and examples.
+ */
+ pub fn y_max_light_lines(&mut self, value: usize) -> &mut Self {
+ self.light_lines_limit[1] = value;
+ self
+ }
+
+ /**
+ Set the maximum number of divisions for the minor grid in the Z axis.
+
+ - `value`: Maximum desired divisions between two consecutive Z labels.
+
+ See [`ChartContext::configure_axes()`] for more information and examples.
+ */
+ pub fn z_max_light_lines(&mut self, value: usize) -> &mut Self {
+ self.light_lines_limit[2] = value;
+ self
+ }
+
+ /**
+ Set the maximum number of divisions for the minor grid.
+
+ - `value`: Maximum desired divisions between two consecutive labels in X, Y, and Z.
+
+ See [`ChartContext::configure_axes()`] for more information and examples.
+ */
+ pub fn max_light_lines(&mut self, value: usize) -> &mut Self {
+ self.light_lines_limit[0] = value;
+ self.light_lines_limit[1] = value;
+ self.light_lines_limit[2] = value;
+ self
+ }
+
+ /**
+ Set the number of labels on the X axes.
+
+ See [`ChartContext::configure_axes()`] for more information and examples.
+ */
+ pub fn x_labels(&mut self, n: usize) -> &mut Self {
+ self.n_labels[0] = n;
+ self
+ }
+
+ /**
+ Set the number of labels on the Y axes.
+
+ See [`ChartContext::configure_axes()`] for more information and examples.
+ */
+ pub fn y_labels(&mut self, n: usize) -> &mut Self {
+ self.n_labels[1] = n;
+ self
+ }
+
+ /**
+ Set the number of labels on the Z axes.
+
+ See [`ChartContext::configure_axes()`] for more information and examples.
+ */
+ pub fn z_labels(&mut self, n: usize) -> &mut Self {
+ self.n_labels[2] = n;
+ self
+ }
+
+ /**
+ Sets the style of the panels in the background.
+
+ See [`ChartContext::configure_axes()`] for more information and examples.
+ */
+ pub fn axis_panel_style<S: Into<ShapeStyle>>(&mut self, style: S) -> &mut Self {
+ self.axis_panel_style = style.into();
+ self
+ }
+
+ /**
+ Sets the style of the major grid lines.
+
+ See [`ChartContext::configure_axes()`] for more information and examples.
+ */
+ pub fn bold_grid_style<S: Into<ShapeStyle>>(&mut self, style: S) -> &mut Self {
+ self.bold_line_style = style.into();
+ self
+ }
+
+ /**
+ Sets the style of the minor grid lines.
+
+ See [`ChartContext::configure_axes()`] for more information and examples.
+ */
+ pub fn light_grid_style<S: Into<ShapeStyle>>(&mut self, style: S) -> &mut Self {
+ self.light_line_style = style.into();
+ self
+ }
+
+ /**
+ Sets the text style of the axis labels.
+
+ See [`ChartContext::configure_axes()`] for more information and examples.
+ */
+ pub fn label_style<S: Into<TextStyle<'b>>>(&mut self, style: S) -> &mut Self {
+ self.label_style = style.into();
+ self
+ }
+
+ /**
+ Specifies the string format of the X axis labels.
+
+ See [`ChartContext::configure_axes()`] for more information and examples.
+ */
+ pub fn x_formatter<F: Fn(&X::ValueType) -> String>(&mut self, f: &'b F) -> &mut Self {
+ self.format_x = f;
+ self
+ }
+
+ /**
+ Specifies the string format of the Y axis labels.
+
+ See [`ChartContext::configure_axes()`] for more information and examples.
+ */
+ pub fn y_formatter<F: Fn(&Y::ValueType) -> String>(&mut self, f: &'b F) -> &mut Self {
+ self.format_y = f;
+ self
+ }
+
+ /**
+ Specifies the string format of the Z axis labels.
+
+ See [`ChartContext::configure_axes()`] for more information and examples.
+ */
+ pub fn z_formatter<F: Fn(&Z::ValueType) -> String>(&mut self, f: &'b F) -> &mut Self {
+ self.format_z = f;
+ self
+ }
+
+ /**
+ Constructs a new configuration object and defines the defaults.
+
+ This is used internally by Plotters and should probably not be included in user code.
+ See [`ChartContext::configure_axes()`] for more information and examples.
+ */
+ pub(crate) fn new(chart: &'b mut ChartContext<'a, DB, Cartesian3d<X, Y, Z>>) -> Self {
+ let parent_size = chart.drawing_area.dim_in_pixel();
+ let base_tick_size = (5u32).percent().max(5).in_pixels(chart.plotting_area());
+ let tick_size = base_tick_size;
+ Self {
+ parent_size,
+ tick_size,
+ light_lines_limit: [10, 10, 10],
+ n_labels: [10, 10, 10],
+ bold_line_style: Into::<ShapeStyle>::into(&BLACK.mix(0.2)),
+ light_line_style: Into::<ShapeStyle>::into(&TRANSPARENT),
+ axis_panel_style: Into::<ShapeStyle>::into(&BLACK.mix(0.1)),
+ axis_style: Into::<ShapeStyle>::into(&BLACK.mix(0.8)),
+ label_style: ("sans-serif", (12).percent().max(12).in_pixels(&parent_size)).into(),
+ format_x: &X::format,
+ format_y: &Y::format,
+ format_z: &Z::format,
+ _phantom: PhantomData,
+ target: Some(chart),
+ }
+ }
+
+ pub fn draw(&mut self) -> Result<(), DrawingAreaErrorKind<DB::ErrorType>>
+ where
+ XT: Clone,
+ YT: Clone,
+ ZT: Clone,
+ {
+ let chart = self.target.take().unwrap();
+ let kps_bold = chart.get_key_points(
+ BoldPoints(self.n_labels[0]),
+ BoldPoints(self.n_labels[1]),
+ BoldPoints(self.n_labels[2]),
+ );
+ let kps_light = chart.get_key_points(
+ LightPoints::new(
+ self.n_labels[0],
+ self.n_labels[0] * self.light_lines_limit[0],
+ ),
+ LightPoints::new(
+ self.n_labels[1],
+ self.n_labels[1] * self.light_lines_limit[1],
+ ),
+ LightPoints::new(
+ self.n_labels[2],
+ self.n_labels[2] * self.light_lines_limit[2],
+ ),
+ );
+
+ let panels = chart.draw_axis_panels(
+ &kps_bold,
+ &kps_light,
+ self.axis_panel_style,
+ self.bold_line_style,
+ self.light_line_style,
+ )?;
+
+ for i in 0..3 {
+ let axis = chart.draw_axis(i, &panels, self.axis_style)?;
+ let labels: Vec<_> = match i {
+ 0 => kps_bold
+ .x_points
+ .iter()
+ .map(|x| {
+ let x_text = (self.format_x)(x);
+ let mut p = axis[0].clone();
+ p[0] = Coord3D::X(x.clone());
+ (p, x_text)
+ })
+ .collect(),
+ 1 => kps_bold
+ .y_points
+ .iter()
+ .map(|y| {
+ let y_text = (self.format_y)(y);
+ let mut p = axis[0].clone();
+ p[1] = Coord3D::Y(y.clone());
+ (p, y_text)
+ })
+ .collect(),
+ _ => kps_bold
+ .z_points
+ .iter()
+ .map(|z| {
+ let z_text = (self.format_z)(z);
+ let mut p = axis[0].clone();
+ p[2] = Coord3D::Z(z.clone());
+ (p, z_text)
+ })
+ .collect(),
+ };
+ chart.draw_axis_ticks(
+ axis,
+ &labels[..],
+ self.tick_size,
+ self.axis_style,
+ self.label_style.clone(),
+ )?;
+ }
+
+ Ok(())
+ }
+}