1
0
mirror of https://github.com/emilk/egui.git synced 2026-09-02 06:40:06 -04:00

plot: Tick placement of opposite axes and digit constraints

This commit is contained in:
Johannes Schiffer
2022-11-14 23:16:18 +01:00
committed by JohannesProgrammiert
parent ffb1a45651
commit 9d76be1131
3 changed files with 114 additions and 39 deletions

View File

@@ -1,6 +1,7 @@
use std::f64::consts::TAU;
use std::ops::RangeInclusive;
use egui::plot::{AxisBools, GridInput, GridMark, PlotResponse};
use egui::plot::{AxisBools, AxisConfig, GridInput, GridMark, PlotResponse};
use egui::*;
use plot::{
Arrows, Bar, BarChart, BoxElem, BoxPlot, BoxSpread, CoordinatesFormatter, Corner, HLine,
@@ -263,7 +264,12 @@ impl LineDemo {
ui.ctx().request_repaint();
self.time += ui.input(|i| i.unstable_dt).at_most(1.0 / 30.0) as f64;
};
let mut plot = Plot::new("lines_demo").legend(Legend::default());
let mut plot = Plot::new("lines_demo")
.axes(vec![
AxisConfig::default(plot::Axis::X).label("x".to_string()),
AxisConfig::default(plot::Axis::Y).label("y".to_string()),
])
.legend(Legend::default());
if self.square {
plot = plot.view_aspect(1.0);
}
@@ -514,6 +520,28 @@ impl CustomAxisDemo {
100.0 * y
}
let x_fmt = |x, _digits, _range: &RangeInclusive<f64>| {
if x < 0.0 * MINS_PER_DAY || x >= 5.0 * MINS_PER_DAY {
// No labels outside value bounds
String::new()
} else if is_approx_integer(x / MINS_PER_DAY) {
// Days
format!("Day {}", day(x))
} else {
// Hours and minutes
format!("{h}:{m:02}", h = hour(x), m = minute(x))
}
};
let y_fmt = |y, _digits, _range: &RangeInclusive<f64>| {
// Display only integer percentages
if !is_approx_zero(y) && is_approx_integer(100.0 * y) {
format!("{:.0}%", percent(y))
} else {
String::new()
}
};
let label_fmt = |_s: &str, val: &PlotPoint| {
format!(
"Day {d}, {h}:{m:02}\n{p:.2}%",
@@ -526,8 +554,19 @@ impl CustomAxisDemo {
ui.label("Zoom in on the X-axis to see hours and minutes");
let axes = vec![
AxisConfig::default(plot::Axis::X)
.tick_formatter(x_fmt)
.label("Percent".to_string()),
AxisConfig::default(plot::Axis::Y)
.tick_formatter(y_fmt)
.max_digits(4)
.label("Time".to_string()),
];
Plot::new("custom_axes")
.data_aspect(2.0 * MINS_PER_DAY as f32)
.axes(axes)
.x_grid_spacer(CustomAxisDemo::x_grid)
.label_formatter(label_fmt)
.show(ui, |plot_ui| {
@@ -973,3 +1012,11 @@ impl ChartsDemo {
.response
}
}
fn is_approx_zero(val: f64) -> bool {
val.abs() < 1e-6
}
fn is_approx_integer(val: f64) -> bool {
val.fract().abs() < 1e-6
}