-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Customize grid spacing in plots #1180
Conversation
I realized that having a fixed step size may not be flexible enough. Consider e.g. using months as input -- it would be nice if there could be a grid line at every beginning of a month. Now months are 28, 29, 30 or 31 days long, so equidistant grid lines won't cut it. Instead, grid spacers have the following function signature: fn get_step_sizes(input: GridInput) -> Vec<GridMark>; with: pub struct GridInput {
/// Min/max of the visible data range (the values at the two edges of the plot,
/// for the current axis).
pub bounds: (f64, f64),
/// Ratio between the diagram's bounds (in plot coordinates) and the viewport
/// (in frame/window coordinates), scaled up to represent the minimal possible step.
/// This is a good value to be used as the smallest of the returned steps.
pub bounds_frame_ratio: f64,
}
/// One mark (horizontal or vertical line) in the background grid of a plat.
pub struct GridMark {
/// X or Y value in the plot.
pub value: f64,
/// The (approximate) distance to the next value of same thickness.
/// Determines how thick the grid line is painted at that point.
pub step_size: f64,
} So for any given range (called Since this may be a bit tedious to implement for more simple cases, I provided two convenience functions:
The results of those two functions can be passed to |
# Conflicts: # egui/src/widgets/plot/mod.rs
Fixed conflicts, merged latest master. |
# Conflicts: # CHANGELOG.md # egui/src/widgets/plot/mod.rs # egui_demo_lib/src/apps/demo/plot_demo.rs
Any feedback on this? 🙂 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a nice feature to have, but it could do with a more motivated demo
egui/src/widgets/plot/mod.rs
Outdated
/// ```ignore | ||
/// next_power(0.01, 10) == 0.01 | ||
/// next_power(0.02, 10) == 0.1 | ||
/// next_power(0.2, 10) == 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// ```ignore | |
/// next_power(0.01, 10) == 0.01 | |
/// next_power(0.02, 10) == 0.1 | |
/// next_power(0.2, 10) == 1 | |
/// ``` | |
/// assert_eq!(next_power(0.01, 10.0), 0.01); | |
/// assert_eq!(next_power(0.02, 10.0), 0.1); | |
/// assert_eq!(next_power(0.2, 10.0), 1.0); |
use the power of the doc-tests!
(and if precision is a problem, use a power-of-two as base
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately, that would require making this function public -- and I'm not sure if that's worth it just for doc tests (and where it would belong in that case).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh right, you cannot doctest private functions 🤦
But perhaps this could belong in emath
anyway
Added a new plot category called
For this reason, I removed the custom axis formatting from the bar chart I added back in the day, as it seemed too artificial there. The new demo uses time on the X axis (days, hours, minutes) and percent on the Y axis: egui-grid-spacer.mp4 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for the slow (re)review! It looks great, but the changelog line needs to move up!
Implemented feedback (besides One issue with the new minute base unit is that the default view is very much zoomed in.
|
# Conflicts: # CHANGELOG.md
That was a sneaky merge conflict, a few minutes after my push 😁 Also removed the colon here in the changelog: `ComboBox`:es --> `ComboBox`es I assume that was a typo? Because further below you also used `DragValue`s without any colon. If not, I'll revert. |
Not for "generator" functions (
I don't think so, but we should add it |
Hello. fn next_power() have this assert_ne!(value, 0.0); // can be negative (typical for Y axis) This create random panic on runtime, when used plot with boxed zoom. I think this happing when boxed zoom create to small zone and plot cant calculate new grid. I don`t shure, because cant stable repeating this bug. Perhaps need some simple protected of zero, but i dont sure where exactly need this protection
|
Description
Adds two
Plot
methodsx_grid_spacer()
andy_grid_spacer()
, which customize the distance between the plot's background grid. The default is the log-10 grid, but occasionally, it can be useful to have different subdivision than 10. Example use cases:I added a small example just to visualize it. It's definitely not the best, but maybe we can improve this in the future, in a separate PR.
Implementation
While providing a customization API, this PR also refactors the hardcoded log-10 logic a bit, making it slightly more modular and easier to understand.
The customization function look as follows:
where
bounds
are the boundaries of the visible diagram (plot coordinates), andbounds_frame_ratio
is a bounds/frame ratio, i.e how much one plot unit amounts to in the visible viewport (scaled with min step size).The built-in logarithmic spacer is implemented as follows:
Now, why an array of exactly 3 elements? In the current implementation, 3 is the number of different thicknesses, with which the grid lines are rendered. The thick line for the largest unit (e.g. 10s), the medium for the middle one (e.g. 1s), and the thin line for the smallest unit (e.g. 0.1s).