From 097dde71cd83816566f7ebf13dc0570dc1ca3145 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Mon, 14 Aug 2023 15:54:22 +0200 Subject: [PATCH] Axis are present by default, with empty names --- crates/egui/src/widgets/plot/axis.rs | 13 +-- crates/egui/src/widgets/plot/mod.rs | 105 ++++++++---------- crates/egui_demo_lib/src/demo/plot_demo.rs | 39 ++++--- .../egui_demo_lib/src/demo/widget_gallery.rs | 2 +- 4 files changed, 77 insertions(+), 82 deletions(-) diff --git a/crates/egui/src/widgets/plot/axis.rs b/crates/egui/src/widgets/plot/axis.rs index 1331c0a3c..46b0e9432 100644 --- a/crates/egui/src/widgets/plot/axis.rs +++ b/crates/egui/src/widgets/plot/axis.rs @@ -56,17 +56,12 @@ const LINE_HEIGHT: f32 = 12.0; impl Default for AxisHints { /// Initializes a default axis configuration for the specified axis. /// - /// `label` is 'x' or 'y' - /// `formatter` is default float to string formatter - /// maximum `digits` on tick label is 5 + /// `label` is empty. + /// `formatter` is default float to string formatter. + /// maximum `digits` on tick label is 5. fn default() -> Self { - let label = match AXIS { - X_AXIS => "x".into(), - Y_AXIS => "y".into(), - _ => unreachable!(), - }; Self { - label, + label: Default::default(), formatter: Self::default_formatter, digits: 5, placement: Placement::Default, diff --git a/crates/egui/src/widgets/plot/mod.rs b/crates/egui/src/widgets/plot/mod.rs index 3b1c486b2..577381402 100644 --- a/crates/egui/src/widgets/plot/mod.rs +++ b/crates/egui/src/widgets/plot/mod.rs @@ -81,6 +81,7 @@ pub struct AxisBools { } impl AxisBools { + #[inline] pub fn new(x: bool, y: bool) -> Self { Self { x, y } } @@ -92,11 +93,19 @@ impl AxisBools { } impl From for AxisBools { + #[inline] fn from(val: bool) -> Self { AxisBools { x: val, y: val } } } +impl From<[bool; 2]> for AxisBools { + #[inline] + fn from([x, y]: [bool; 2]) -> Self { + AxisBools { x, y } + } +} + /// Information about the plot that has to persist between frames. #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] #[derive(Clone)] @@ -252,8 +261,8 @@ impl Plot { show_y: true, label_formatter: None, coordinates_formatter: None, - x_axes: Vec::new(), - y_axes: Vec::new(), + x_axes: vec![Default::default()], + y_axes: vec![Default::default()], legend_config: None, show_background: true, show_axes: true.into(), @@ -314,13 +323,13 @@ impl Plot { self } - /// Always keep the x-axis centered. Default: `false`. + /// Always keep the X-axis centered. Default: `false`. pub fn center_x_axis(mut self, on: bool) -> Self { self.center_axis.x = on; self } - /// Always keep the y-axis centered. Default: `false`. + /// Always keep the Y-axis centered. Default: `false`. pub fn center_y_axis(mut self, on: bool) -> Self { self.center_axis.y = on; self @@ -511,21 +520,19 @@ impl Plot { self } - /// Show axis labels. + /// Show axis labels and grid tick values on the side of the plot. /// /// Default: `[true; 2]`. - pub fn show_axes(mut self, show: [bool; 2]) -> Self { - self.show_axes.x = show[0]; - self.show_axes.y = show[1]; + pub fn show_axes(mut self, show: impl Into) -> Self { + self.show_axes = show.into(); self } - /// Show the grid. - /// Can be useful to disable if the plot is overlaid over an existing grid or content. + /// Show a grid overlay on the plot. + /// /// Default: `[true; 2]`. - pub fn show_grid(mut self, show: [bool; 2]) -> Self { - self.show_grid.x = show[0]; - self.show_grid.y = show[1]; + pub fn show_grid(mut self, show: impl Into) -> Self { + self.show_grid = show.into(); self } @@ -568,93 +575,79 @@ impl Plot { self } - /// Set the x axis label of the main x-axis + /// Set the x axis label of the main X-axis. /// - /// If no x-axis has been specified so far a new one will be created. + /// Default: no label. pub fn x_axis_label(mut self, label: impl Into) -> Self { - if self.x_axes.is_empty() { - self.x_axes.push(XAxisHints::default().label(label)); - } else { - self.x_axes[0].label = label.into(); + if let Some(main) = self.x_axes.first_mut() { + main.label = label.into(); } self } - /// Set the y axis label of the main y-axis + /// Set the y axis label of the main Y-axis. /// - /// If no y-axis has been specified so far a new one will be created. + /// Default: no label. pub fn y_axis_label(mut self, label: impl Into) -> Self { - if self.y_axes.is_empty() { - self.y_axes.push(YAxisHints::default().label(label)); - } else { - self.y_axes[0].label = label.into(); + if let Some(main) = self.y_axes.first_mut() { + main.label = label.into(); } self } - /// Set the position of the main x-axis - /// - /// > Note: This requires an x-axis to exist, either by [`Self::custom_x_axes`] or [`Self::x_axis_label`] + /// Set the position of the main X-axis. pub fn x_axis_position(mut self, placement: axis::Placement) -> Self { - if !self.x_axes.is_empty() { - self.x_axes[0].placement = placement; + if let Some(main) = self.x_axes.first_mut() { + main.placement = placement; } self } - /// Set the position of the main y-axis - /// - /// > Note: This requires a y-axis to exist, either by [`Self::custom_y_axes`] or [`Self::y_axis_label`] + /// Set the position of the main Y-axis. pub fn y_axis_position(mut self, placement: axis::Placement) -> Self { - if !self.y_axes.is_empty() { - self.y_axes[0].placement = placement; + if let Some(main) = self.y_axes.first_mut() { + main.placement = placement; } self } - /// Specify custom formatter for ticks on the main x-axis - /// - /// > Note: This requires an x-axis to exist, either by [`Self::custom_x_axes`] or [`Self::x_axis_label`] + /// Specify custom formatter for ticks on the main X-axis. /// /// The first parameter of `fmt` is the raw tick value as `f64`. /// The second parameter is the maximum requested number of characters per tick label. /// The second parameter of `fmt` is the currently shown range on this axis. pub fn x_axis_formatter(mut self, fmt: fn(f64, usize, &RangeInclusive) -> String) -> Self { - if !self.x_axes.is_empty() { - self.x_axes[0].formatter = fmt; + if let Some(main) = self.x_axes.first_mut() { + main.formatter = fmt; } self } - /// Specify custom formatter for ticks on the main y-axis - /// - /// > Note: This requires a y-axis to exist, either by [`Self::custom_y_axes`] or [`Self::y_axis_label`] + /// Specify custom formatter for ticks on the main Y-axis. /// /// The first parameter of `formatter` is the raw tick value as `f64`. /// The second parameter is the maximum requested number of characters per tick label. /// The second parameter of `formatter` is the currently shown range on this axis. pub fn y_axis_formatter(mut self, fmt: fn(f64, usize, &RangeInclusive) -> String) -> Self { - if !self.y_axes.is_empty() { - self.y_axes[0].formatter = fmt; + if let Some(main) = self.y_axes.first_mut() { + main.formatter = fmt; } self } - /// Set the main y-axis-width by number of digits + /// Set the main Y-axis-width by number of digits /// /// The default is 5 digits. /// - /// > Note: This requires a y-axis to exist, either by [`Self::custom_y_axes`] or [`Self::y_axis_label`] - /// /// > Todo: This is experimental. Changing the font size might break this. pub fn y_axis_width(mut self, digits: usize) -> Self { - if !self.y_axes.is_empty() { - self.y_axes[0].digits = digits; + if let Some(main) = self.y_axes.first_mut() { + main.digits = digits; } self } - /// Set custom configuration for bottom x-axis + /// Set custom configuration for X-axis /// /// More than one axis may be specified. The first specified axis is considered the main axis. pub fn custom_x_axes(mut self, hints: Vec) -> Self { @@ -662,7 +655,7 @@ impl Plot { self } - /// Set custom configuration for left y-axis + /// Set custom configuration for left Y-axis /// /// More than one axis may be specified. The first specified axis is considered the main axis. pub fn custom_y_axes(mut self, hints: Vec) -> Self { @@ -751,9 +744,9 @@ impl Plot { // // left right // +---+---------x----------+ + - // | | x-Axis 3 | + // | | X-axis 3 | // | +--------------------+ top - // | | x-Axis 2 | + // | | X-axis 2 | // +-+-+--------------------+-+-+ // |y|y| |y|y| // |-|-| |-|-| @@ -763,9 +756,9 @@ impl Plot { // |s|s| |s|s| // |1|0| |2|3| // +-+-+--------------------+-+-+ - // | x-Axis 0 | | + // | X-axis 0 | | // +--------------------+ | bottom - // | x-Axis 1 | | + // | X-axis 1 | | // + +--------------------+---+ // diff --git a/crates/egui_demo_lib/src/demo/plot_demo.rs b/crates/egui_demo_lib/src/demo/plot_demo.rs index 63b35cf3e..43a204d03 100644 --- a/crates/egui_demo_lib/src/demo/plot_demo.rs +++ b/crates/egui_demo_lib/src/demo/plot_demo.rs @@ -121,7 +121,7 @@ impl super::View for PlotDemo { // ---------------------------------------------------------------------------- -#[derive(PartialEq)] +#[derive(Copy, Clone, PartialEq)] struct LineDemo { animate: bool, time: f64, @@ -130,6 +130,8 @@ struct LineDemo { square: bool, proportional: bool, coordinates: bool, + show_axes: bool, + show_grid: bool, line_style: LineStyle, } @@ -143,6 +145,8 @@ impl Default for LineDemo { square: false, proportional: true, coordinates: true, + show_axes: true, + show_grid: true, line_style: LineStyle::Solid, } } @@ -157,9 +161,10 @@ impl LineDemo { circle_center, square, proportional, - line_style, coordinates, - .. + show_axes, + show_grid, + line_style, } = self; ui.horizontal(|ui| { @@ -187,6 +192,13 @@ impl LineDemo { }); }); + ui.vertical(|ui| { + ui.checkbox(show_axes, "Show axes"); + ui.checkbox(show_grid, "Show grid"); + ui.checkbox(coordinates, "Show coordinates on hover") + .on_hover_text("Can take a custom formatting function."); + }); + ui.vertical(|ui| { ui.style_mut().wrap = Some(false); ui.checkbox(animate, "Animate"); @@ -194,8 +206,6 @@ impl LineDemo { .on_hover_text("Always keep the viewport square."); ui.checkbox(proportional, "Proportional data axes") .on_hover_text("Tick are the same size on both axes."); - ui.checkbox(coordinates, "Show coordinates") - .on_hover_text("Can take a custom formatting function."); ComboBox::from_label("Line style") .selected_text(line_style.to_string()) @@ -260,15 +270,16 @@ impl LineDemo { impl LineDemo { fn ui(&mut self, ui: &mut Ui) -> Response { self.options_ui(ui); + if self.animate { ui.ctx().request_repaint(); self.time += ui.input(|i| i.unstable_dt).at_most(1.0 / 30.0) as f64; }; let mut plot = Plot::new("lines_demo") .legend(Legend::default()) - .x_axis_label("") - .y_axis_label("") - .y_axis_width(4); + .y_axis_width(4) + .show_axes(self.show_axes) + .show_grid(self.show_grid); if self.square { plot = plot.view_aspect(1.0); } @@ -426,8 +437,6 @@ impl LegendDemo { ui.end_row(); }); let legend_plot = Plot::new("legend_demo") - .x_axis_label("") - .y_axis_label("") .y_axis_width(2) .legend(config.clone()) .data_aspect(1.0); @@ -653,25 +662,25 @@ impl LinkedAxesDemo { let link_group_id = ui.id().with("linked_demo"); ui.horizontal(|ui| { - Plot::new("linked_axis_1") + Plot::new("left-top") .data_aspect(1.0) .width(250.0) .height(250.0) .link_axis(link_group_id, self.link_x, self.link_y) .link_cursor(link_group_id, self.link_cursor_x, self.link_cursor_y) .show(ui, LinkedAxesDemo::configure_plot); - Plot::new("linked_axis_2") + Plot::new("right-top") .data_aspect(2.0) .width(150.0) .height(250.0) + .y_axis_width(3) .y_axis_label("y") .y_axis_position(Placement::Opposite) - .y_axis_width(3) .link_axis(link_group_id, self.link_x, self.link_y) .link_cursor(link_group_id, self.link_cursor_x, self.link_cursor_y) .show(ui, LinkedAxesDemo::configure_plot); }); - Plot::new("linked_axis_3") + Plot::new("left-bottom") .data_aspect(0.5) .width(250.0) .height(150.0) @@ -904,8 +913,6 @@ impl ChartsDemo { Plot::new("Normal Distribution Demo") .legend(Legend::default()) .clamp_grid(true) - .x_axis_label("") - .y_axis_label("") .y_axis_width(3) .allow_zoom(self.allow_zoom) .allow_drag(self.allow_drag) diff --git a/crates/egui_demo_lib/src/demo/widget_gallery.rs b/crates/egui_demo_lib/src/demo/widget_gallery.rs index 8b9c5197d..27dc4026b 100644 --- a/crates/egui_demo_lib/src/demo/widget_gallery.rs +++ b/crates/egui_demo_lib/src/demo/widget_gallery.rs @@ -271,7 +271,7 @@ fn example_plot(ui: &mut egui::Ui) -> egui::Response { let line = Line::new(line_points); egui::plot::Plot::new("example_plot") .height(32.0) - .show_axes([false, false]) + .show_axes(false) .data_aspect(1.0) .show(ui, |plot_ui| plot_ui.line(line)) .response