Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Plot auto_bounds when LinkedAxisGroup one axis #1599

Merged
merged 3 commits into from
May 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 66 additions & 20 deletions egui/src/widgets/plot/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,34 @@ impl Default for CoordinatesFormatter {

const MIN_LINE_SPACING_IN_POINTS: f64 = 6.0; // TODO: large enough for a wide label

#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
#[derive(Clone)]
struct AutoBounds {
x: bool,
y: bool,
}

impl AutoBounds {
fn from_bool(val: bool) -> Self {
AutoBounds { x: val, y: val }
}

fn any(&self) -> bool {
self.x || self.y
}
}

impl From<bool> for AutoBounds {
fn from(val: bool) -> Self {
AutoBounds::from_bool(val)
}
}

/// Information about the plot that has to persist between frames.
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
#[derive(Clone)]
struct PlotMemory {
auto_bounds: bool,
auto_bounds: AutoBounds,
hovered_entry: Option<String>,
hidden_items: AHashSet<String>,
min_auto_bounds: PlotBounds,
Expand Down Expand Up @@ -556,7 +579,7 @@ impl Plot {
let plot_id = ui.make_persistent_id(id_source);
ui.ctx().check_for_id_clash(plot_id, rect, "Plot");
let mut memory = PlotMemory::load(ui.ctx(), plot_id).unwrap_or_else(|| PlotMemory {
auto_bounds: !min_auto_bounds.is_valid(),
auto_bounds: (!min_auto_bounds.is_valid()).into(),
hovered_entry: None,
hidden_items: Default::default(),
min_auto_bounds,
Expand All @@ -572,7 +595,7 @@ impl Plot {
// If the min bounds changed, recalculate everything.
if min_auto_bounds != memory.min_auto_bounds {
memory = PlotMemory {
auto_bounds: !min_auto_bounds.is_valid(),
auto_bounds: (!min_auto_bounds.is_valid()).into(),
hovered_entry: None,
min_auto_bounds,
..memory
Expand Down Expand Up @@ -642,28 +665,51 @@ impl Plot {
if let Some(axes) = linked_axes.as_ref() {
if let Some(linked_bounds) = axes.get() {
if axes.link_x {
bounds.min[0] = linked_bounds.min[0];
bounds.max[0] = linked_bounds.max[0];
bounds.set_x(&linked_bounds);
// Turn off auto bounds to keep it from overriding what we just set.
auto_bounds.x = false;
}
if axes.link_y {
bounds.min[1] = linked_bounds.min[1];
bounds.max[1] = linked_bounds.max[1];
bounds.set_y(&linked_bounds);
// Turn off auto bounds to keep it from overriding what we just set.
auto_bounds.y = false
}
// Turn off auto bounds to keep it from overriding what we just set.
auto_bounds = false;
}
}
};

// Allow double clicking to reset to automatic bounds.
auto_bounds |= response.double_clicked_by(PointerButton::Primary);
if response.double_clicked_by(PointerButton::Primary) {
auto_bounds = true.into()
}

// Set bounds automatically based on content.
if auto_bounds || !bounds.is_valid() {
bounds = min_auto_bounds;
if auto_bounds.any() || !bounds.is_valid() {
if auto_bounds.x {
bounds.set_x(&min_auto_bounds);
}

if auto_bounds.y {
bounds.set_y(&min_auto_bounds);
}

for item in &items {
bounds.merge(&item.get_bounds());
// bounds.merge(&item.get_bounds());

if auto_bounds.x {
bounds.merge_x(&item.get_bounds());
}
if auto_bounds.y {
bounds.merge_y(&item.get_bounds());
}
}

if auto_bounds.x {
bounds.add_relative_margin_x(margin_fraction);
}

if auto_bounds.y {
bounds.add_relative_margin_y(margin_fraction);
}
bounds.add_relative_margin(margin_fraction);
}

let mut transform = ScreenTransform::new(rect, bounds, center_x_axis, center_y_axis);
Expand All @@ -680,7 +726,7 @@ impl Plot {
if allow_drag && response.dragged_by(PointerButton::Primary) {
response = response.on_hover_cursor(CursorIcon::Grabbing);
transform.translate_bounds(-response.drag_delta());
auto_bounds = false;
auto_bounds = false.into()
}

// Zooming
Expand Down Expand Up @@ -721,9 +767,9 @@ impl Plot {
};
if new_bounds.is_valid() {
*transform.bounds_mut() = new_bounds;
auto_bounds = false;
auto_bounds = false.into()
} else {
auto_bounds = true;
auto_bounds = true.into()
}
// reset the boxed zoom state
last_click_pos_for_zoom = None;
Expand All @@ -740,14 +786,14 @@ impl Plot {
};
if zoom_factor != Vec2::splat(1.0) {
transform.zoom(zoom_factor, hover_pos);
auto_bounds = false;
auto_bounds = false.into()
}
}
if allow_scroll {
let scroll_delta = ui.input().scroll_delta;
if scroll_delta != Vec2::ZERO {
transform.translate_bounds(-scroll_delta);
auto_bounds = false;
auto_bounds = false.into()
}
}
}
Expand Down
27 changes: 25 additions & 2 deletions egui/src/widgets/plot/transform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,26 @@ impl PlotBounds {
self.max[1] += pad;
}

pub(crate) fn merge_x(&mut self, other: &PlotBounds) {
self.min[0] = self.min[0].min(other.min[0]);
self.max[0] = self.max[0].max(other.max[0]);
}

pub(crate) fn merge_y(&mut self, other: &PlotBounds) {
self.min[1] = self.min[1].min(other.min[1]);
self.max[1] = self.max[1].max(other.max[1]);
}

pub(crate) fn set_x(&mut self, other: &PlotBounds) {
self.min[0] = other.min[0];
self.max[0] = other.max[0];
}

pub(crate) fn set_y(&mut self, other: &PlotBounds) {
self.min[1] = other.min[1];
self.max[1] = other.max[1];
}

pub(crate) fn merge(&mut self, other: &PlotBounds) {
self.min[0] = self.min[0].min(other.min[0]);
self.min[1] = self.min[1].min(other.min[1]);
Expand All @@ -109,10 +129,13 @@ impl PlotBounds {
self.translate_y(delta.y as f64);
}

pub(crate) fn add_relative_margin(&mut self, margin_fraction: Vec2) {
pub(crate) fn add_relative_margin_x(&mut self, margin_fraction: Vec2) {
let width = self.width().max(0.0);
let height = self.height().max(0.0);
self.expand_x(margin_fraction.x as f64 * width);
}

pub(crate) fn add_relative_margin_y(&mut self, margin_fraction: Vec2) {
let height = self.height().max(0.0);
self.expand_y(margin_fraction.y as f64 * height);
}

Expand Down