Skip to content
Open
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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ target_wasm
**/tests/snapshots/**/*.new.png
**/tests/snapshots/**/*.old.png

**/*.diff.png
**/*.new.png
**/*.old.png
# trunk output folder
dist

Expand Down
11 changes: 11 additions & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -956,6 +956,7 @@ dependencies = [
"plot_span",
"save_plot",
"stacked_bar",
"userdata_points",
"wasm-bindgen-futures",
"web-sys",
]
Expand Down Expand Up @@ -3616,6 +3617,16 @@ version = "2.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da"

[[package]]
name = "userdata_points"
version = "0.1.0"
dependencies = [
"eframe",
"egui_plot",
"env_logger",
"examples_utils",
]

[[package]]
name = "utf8_iter"
version = "1.0.4"
Expand Down
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ performance = { version = "0.1.0", path = "examples/performance" }
plot_span = { version = "0.1.0", path = "examples/plot_span" }
save_plot = { version = "0.1.0", path = "examples/save_plot" }
stacked_bar = { version = "0.1.0", path = "examples/stacked_bar" }
userdata_points = { version = "0.1.0", path = "examples/userdata_points" }

ahash = { version = "0.8.12", default-features = false, features = [
"no-rng", # we don't need DOS-protection, so we let users opt-in to it instead
Expand Down Expand Up @@ -283,4 +284,4 @@ map_unwrap_or = "allow" # this is better on 'allow'


[workspace.metadata.cargo-shear]
ignored = ["log", "assertables"]
ignored = ["assertables"]
1 change: 1 addition & 0 deletions demo/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ performance.workspace = true
plot_span.workspace = true
save_plot.workspace = true
stacked_bar.workspace = true
userdata_points.workspace = true

# native:
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
Expand Down
1 change: 1 addition & 0 deletions demo/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ impl DemoGallery {
Box::new(plot_span::PlotSpanDemo::default()),
Box::new(save_plot::SavePlotExample::default()),
Box::new(stacked_bar::StackedBarExample::default()),
Box::new(userdata_points::UserdataPointsExample::default()),
];
let thumbnail_textures = Self::load_thumbnails(ctx, &examples);

Expand Down
2 changes: 1 addition & 1 deletion egui_plot/src/items/arrows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ impl PlotItem for Arrows<'_> {
}

fn geometry(&self) -> PlotGeometry<'_> {
PlotGeometry::Points(self.origins.points())
PlotGeometry::Points(self.origins.points(), self.id())
}

fn bounds(&self) -> PlotBounds {
Expand Down
21 changes: 15 additions & 6 deletions egui_plot/src/items/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ pub trait PlotItem {
match self.geometry() {
PlotGeometry::None => None,

PlotGeometry::Points(points) => points
PlotGeometry::Points(points, _) => points
.iter()
.enumerate()
.map(|(index, value)| {
Expand All @@ -176,8 +176,8 @@ pub trait PlotItem {
plot: &PlotConfig<'_>,
label_formatter: &Option<LabelFormatter<'_>>,
) {
let points = match self.geometry() {
PlotGeometry::Points(points) => points,
let (points, id) = match self.geometry() {
PlotGeometry::Points(points, id) => (points, id),
PlotGeometry::None => {
panic!("If the PlotItem has no geometry, on_hover() must not be called")
}
Expand All @@ -198,7 +198,15 @@ pub trait PlotItem {
let pointer = plot.transform.position_from_point(&value);
shapes.push(Shape::circle_filled(pointer, 3.0, line_color));

rulers_and_tooltip_at_value(plot_area_response, value, self.name(), plot, cursors, label_formatter);
rulers_and_tooltip_at_value(
plot_area_response,
value,
Some((id, elem.index)),
self.name(),
plot,
cursors,
label_formatter,
);
}
}

Expand Down Expand Up @@ -272,6 +280,7 @@ fn add_rulers_and_text(
pub(super) fn rulers_and_tooltip_at_value(
plot_area_response: &egui::Response,
value: PlotPoint,
item: Option<(Id, usize)>,
name: &str,
plot: &PlotConfig<'_>,
cursors: &mut Vec<Cursor>,
Expand All @@ -292,7 +301,7 @@ pub(super) fn rulers_and_tooltip_at_value(
return;
};

let text = custom_label(name, &value);
let text = custom_label(name, &value, item);
if text.is_empty() {
return;
}
Expand Down Expand Up @@ -322,7 +331,7 @@ pub enum PlotGeometry<'a> {
None,

/// Point values (X-Y graphs)
Points(&'a [PlotPoint]),
Points(&'a [PlotPoint], Id),

/// Rectangles (examples: boxes or bars)
// Has currently no data, as it would require copying rects or iterating a list of pointers.
Expand Down
2 changes: 1 addition & 1 deletion egui_plot/src/items/points.rs
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ impl PlotItem for Points<'_> {
}

fn geometry(&self) -> PlotGeometry<'_> {
PlotGeometry::Points(self.series.points())
PlotGeometry::Points(self.series.points(), self.id())
}

fn bounds(&self) -> PlotBounds {
Expand Down
2 changes: 1 addition & 1 deletion egui_plot/src/items/polygon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ impl PlotItem for Polygon<'_> {
}

fn geometry(&self) -> PlotGeometry<'_> {
PlotGeometry::Points(self.series.points())
PlotGeometry::Points(self.series.points(), self.id())
}

fn bounds(&self) -> PlotBounds {
Expand Down
2 changes: 1 addition & 1 deletion egui_plot/src/items/series.rs
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ impl PlotItem for Line<'_> {
}

fn geometry(&self) -> PlotGeometry<'_> {
PlotGeometry::Points(self.series.points())
PlotGeometry::Points(self.series.points(), self.id())
}

fn bounds(&self) -> PlotBounds {
Expand Down
10 changes: 8 additions & 2 deletions egui_plot/src/label.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use egui::Id;
use emath::NumExt as _;

use crate::bounds::PlotPoint;
Expand All @@ -16,14 +17,19 @@ pub fn format_number(number: f64, num_decimals: usize) -> String {
}
}

type LabelFormatterFn<'a> = dyn Fn(&str, &PlotPoint) -> String + 'a;
type LabelFormatterFn<'a> = dyn Fn(&str, &PlotPoint, Option<(Id, usize)>) -> String + 'a;

/// Optional label formatter function for customizing hover labels.
///
/// The formatter receives the item name, the hovered point, and an optional
/// `(Id, index)` for the hovered plot item. The `Id` matches the item `id()`,
/// and `index` is the point index within that item. The argument is `None`
/// when the cursor isn't hovering a concrete plot item.
pub type LabelFormatter<'a> = Box<LabelFormatterFn<'a>>;

/// Default label formatter that shows the x and y coordinates with 3 decimal
/// places.
pub fn default_label_formatter(name: &str, value: &PlotPoint) -> String {
pub fn default_label_formatter(name: &str, value: &PlotPoint, _id_index: Option<(Id, usize)>) -> String {
let prefix = if name.is_empty() {
String::new()
} else {
Expand Down
20 changes: 16 additions & 4 deletions egui_plot/src/plot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,11 @@ impl<'a> Plot<'a> {
self
}

/// Provide a function to customize the on-hover label for the x and y axis
/// Provide a function to customize the on-hover label for the x and y axis.
///
/// The third argument is `Some((Id, index))` when hovering a plot item,
/// where `Id` is the item's id and `index` is the point index within that
/// item. It is `None` when the cursor isn't hovering a concrete plot item.
///
/// ```
/// # egui::__run_test_ui(|ui| {
Expand All @@ -404,9 +408,13 @@ impl<'a> Plot<'a> {
/// let line = Line::new("sin", sin);
/// Plot::new("my_plot")
/// .view_aspect(2.0)
/// .label_formatter(|name, value| {
/// .label_formatter(|name, value, id_index| {
/// if !name.is_empty() {
/// format!("{}: {:.*}%", name, 1, value.y)
/// if let Some((_id, index)) = id_index {
/// format!("{}_{}: {:.*}%", name, index, 1, value.y)
/// } else {
/// format!("{}: {:.*}%", name, 1, value.y)
/// }
/// } else {
/// "".to_owned()
/// }
Expand All @@ -415,7 +423,10 @@ impl<'a> Plot<'a> {
/// # });
/// ```
#[inline]
pub fn label_formatter(mut self, label_formatter: impl Fn(&str, &PlotPoint) -> String + 'a) -> Self {
pub fn label_formatter(
mut self,
label_formatter: impl Fn(&str, &PlotPoint, Option<(Id, usize)>) -> String + 'a,
) -> Self {
self.label_formatter = Some(Box::new(label_formatter));
self
}
Expand Down Expand Up @@ -1572,6 +1583,7 @@ impl<'a> Plot<'a> {
items::rulers_and_tooltip_at_value(
&plot_ui.response,
value,
None,
"",
&plot,
&mut cursors,
Expand Down
2 changes: 1 addition & 1 deletion examples/custom_axes/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ impl CustomAxesExample {
}
};

let label_fmt = |_s: &str, val: &PlotPoint| {
let label_fmt = |_s: &str, val: &PlotPoint, _id: Option<(egui::Id, usize)>| {
format!(
"Day {d}, {h}:{m:02}\n{p:.2}%",
d = day(val.x),
Expand Down
23 changes: 23 additions & 0 deletions examples/userdata_points/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
[package]
name = "userdata_points"
version = "0.1.0"
authors = ["Nicolas <[email protected]>"]
license.workspace = true
edition.workspace = true
rust-version.workspace = true
publish = false

[lints]
workspace = true

[dependencies]
eframe = { workspace = true, features = ["default"] }
egui_plot.workspace = true
env_logger = { workspace = true, default-features = false, features = [
"auto-color",
"humantime",
] }
examples_utils.workspace = true

[package.metadata.cargo-shear]
ignored = ["env_logger"] # used by make_main! macro
3 changes: 3 additions & 0 deletions examples/userdata_points/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Userdata Points Example

TODO
3 changes: 3 additions & 0 deletions examples/userdata_points/screenshot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions examples/userdata_points/screenshot_thumb.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading