Skip to content

Commit 4d5b62c

Browse files
committed
closest by x
1 parent c7feb89 commit 4d5b62c

2 files changed

Lines changed: 38 additions & 5 deletions

File tree

egui_plot/src/items/mod.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ pub struct PlotItemBase {
6363
id: Id,
6464
highlight: bool,
6565
allow_hover: bool,
66+
closest_by_x: bool,
6667
}
6768

6869
impl PlotItemBase {
@@ -74,6 +75,7 @@ impl PlotItemBase {
7475
id,
7576
highlight: false,
7677
allow_hover: true,
78+
closest_by_x: false,
7779
}
7880
}
7981
}
@@ -166,6 +168,26 @@ pub trait PlotItem {
166168
}
167169
}
168170

171+
fn find_closest_x(&self, point: Pos2, transform: &PlotTransform) -> Option<ClosestElem> {
172+
match self.geometry() {
173+
PlotGeometry::None => None,
174+
175+
PlotGeometry::Points(points) => points
176+
.iter()
177+
.enumerate()
178+
.map(|(index, value)| {
179+
let pos = transform.position_from_point(value);
180+
let dist_x = (point.x - pos.x).abs();
181+
ClosestElem { index, dist_sq: dist_x }
182+
})
183+
.min_by_key(|e| e.dist_sq.ord()),
184+
185+
PlotGeometry::Rects => {
186+
panic!("If the PlotItem is made of rects, it should implement find_closest()")
187+
}
188+
}
189+
}
190+
169191
/// Handle hover events for the plot item.
170192
fn on_hover(
171193
&self,

egui_plot/src/plot.rs

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,8 @@ pub struct Plot<'a> {
131131
clamp_grid: bool,
132132

133133
sense: Sense,
134+
135+
closest_by_x: bool,
134136
}
135137

136138
impl<'a> Plot<'a> {
@@ -183,6 +185,8 @@ impl<'a> Plot<'a> {
183185
clamp_grid: false,
184186

185187
sense: egui::Sense::click_and_drag(),
188+
189+
closest_by_x: false,
186190
}
187191
}
188192

@@ -1535,17 +1539,24 @@ impl<'a> Plot<'a> {
15351539
.filter(|entry| entry.allow_hover())
15361540
.filter_map(|item| {
15371541
let item = &**item;
1538-
let closest = item.find_closest(pointer, transform);
1539-
1542+
let closest = if self.closest_by_x {
1543+
item.find_closest_x(pointer, transform)
1544+
} else {
1545+
item.find_closest(pointer, transform)
1546+
};
15401547
Some(item).zip(closest)
15411548
});
15421549

15431550
// Since many items can have same distance,
15441551
// and dist_sq can be zero for some items (e.g. rectangle)
15451552
// we pick topmost item within interact radius
1546-
let topmost = candidates
1547-
.filter(|(_, elem)| elem.dist_sq <= interact_radius_sq)
1548-
.next_back();
1553+
let topmost = if self.closest_by_x {
1554+
candidates.min_by(|x, y| x.1.dist_sq.total_cmp(&y.1.dist_sq))
1555+
} else {
1556+
candidates
1557+
.filter(|(_, elem)| elem.dist_sq <= interact_radius_sq)
1558+
.next_back()
1559+
};
15491560

15501561
let plot = crate::PlotConfig {
15511562
ui,

0 commit comments

Comments
 (0)