From cf012a69646d28ce7c5825a998aa969734ba4d37 Mon Sep 17 00:00:00 2001 From: York Xiang Date: Tue, 14 Oct 2025 09:31:26 +0800 Subject: [PATCH] Implement virtual element to allow elements to escape from auto bounds calculation --- egui_plot/src/items/mod.rs | 54 ++++++++++++++++++++++++++++++++++++++ egui_plot/src/lib.rs | 3 +++ 2 files changed, 57 insertions(+) diff --git a/egui_plot/src/items/mod.rs b/egui_plot/src/items/mod.rs index 89806f95..68b008ab 100644 --- a/egui_plot/src/items/mod.rs +++ b/egui_plot/src/items/mod.rs @@ -35,6 +35,7 @@ pub struct PlotItemBase { id: Id, highlight: bool, allow_hover: bool, + is_overlay: bool, } impl PlotItemBase { @@ -45,6 +46,7 @@ impl PlotItemBase { id, highlight: false, allow_hover: true, + is_overlay: false, } } } @@ -90,6 +92,14 @@ macro_rules! builder_methods_for_base { self.base_mut().id = id.into(); self } + + /// Places this element in the overlay layer, exempting it from automatic bounds calculation. + /// Default: `false`. + #[inline] + pub fn overlay(mut self, is_overlay: bool) -> Self { + self.base_mut().is_overlay = is_overlay; + self + } }; } @@ -198,6 +208,7 @@ pub trait PlotItem { label_formatter, ); } + fn is_overlay(&self) -> bool; } // ---------------------------------------------------------------------------- @@ -298,6 +309,10 @@ impl PlotItem for HLine { bounds.max[1] = self.y; bounds } + + fn is_overlay(&self) -> bool { + self.base().is_overlay + } } /// A vertical line in a plot, filling the full width @@ -396,6 +411,10 @@ impl PlotItem for VLine { bounds.max[0] = self.x; bounds } + + fn is_overlay(&self) -> bool { + self.base().is_overlay + } } /// A series of values forming a path. @@ -424,6 +443,9 @@ impl<'a> Line<'a> { } } + /// Places this element in the overlay layer, exempting it from automatic bounds calculation. + /// Default: `false`. + /// Add a stroke. #[inline] pub fn stroke(mut self, stroke: impl Into) -> Self { @@ -609,6 +631,10 @@ impl PlotItem for Line<'_> { fn bounds(&self) -> PlotBounds { self.series.bounds() } + + fn is_overlay(&self) -> bool { + self.base().is_overlay + } } /// A convex polygon. @@ -719,6 +745,10 @@ impl PlotItem for Polygon<'_> { fn base_mut(&mut self) -> &mut PlotItemBase { &mut self.base } + + fn is_overlay(&self) -> bool { + self.base().is_overlay + } } /// Text inside the plot. @@ -812,6 +842,10 @@ impl PlotItem for Text { fn base_mut(&mut self) -> &mut PlotItemBase { &mut self.base } + + fn is_overlay(&self) -> bool { + self.base().is_overlay + } } /// A set of points. @@ -1039,6 +1073,10 @@ impl PlotItem for Points<'_> { fn base_mut(&mut self) -> &mut PlotItemBase { &mut self.base } + + fn is_overlay(&self) -> bool { + self.base().is_overlay + } } /// A set of arrows. @@ -1150,6 +1188,10 @@ impl PlotItem for Arrows<'_> { fn base_mut(&mut self) -> &mut PlotItemBase { &mut self.base } + + fn is_overlay(&self) -> bool { + self.base().is_overlay + } } /// An image in the plot. @@ -1307,6 +1349,10 @@ impl PlotItem for PlotImage { fn base_mut(&mut self) -> &mut PlotItemBase { &mut self.base } + + fn is_overlay(&self) -> bool { + self.base().is_overlay + } } // ---------------------------------------------------------------------------- @@ -1468,6 +1514,10 @@ impl PlotItem for BarChart { fn base_mut(&mut self) -> &mut PlotItemBase { &mut self.base } + + fn is_overlay(&self) -> bool { + self.base().is_overlay + } } /// A diagram containing a series of [`BoxElem`] elements. @@ -1595,6 +1645,10 @@ impl PlotItem for BoxPlot { fn base_mut(&mut self) -> &mut PlotItemBase { &mut self.base } + + fn is_overlay(&self) -> bool { + self.base().is_overlay + } } // ---------------------------------------------------------------------------- diff --git a/egui_plot/src/lib.rs b/egui_plot/src/lib.rs index 506453f3..658e2fc8 100644 --- a/egui_plot/src/lib.rs +++ b/egui_plot/src/lib.rs @@ -1102,6 +1102,9 @@ impl<'a> Plot<'a> { // Set bounds automatically based on content. if auto_x || auto_y { for item in &items { + if item.is_overlay() { + continue; + } let item_bounds = item.bounds(); if auto_x { bounds.merge_x(&item_bounds);