fix(plot): a degenerate range cannot strand a live axis, and the demo's follow check fails the run

This commit is contained in:
Martino Ferrari committed 2026-09-28 13:14:50 +02:00
1 parent 77e861f79e
commit 7d2349555d
6 files changed
+146 -13

No files matched your search

+5 -2
View File
@@ -57,8 +57,11 @@ struct Axis {
/// units, under `XFollow::Live`. Stored rather than implied by the range,
/// because the range is recomputed from the series' newest x on every frame:
/// this is the part of the view the user chose, so it is the part that survives
/// the recompute. `Plot::set_x_offset()` is the only way in, and clamps it to
/// what the traces still retain.
/// the recompute. Three things write it, all of them through one clamp: a pan or
/// a zoom through `Plot::set_x_range()`, which derives it from the range the
/// gesture asked for, `Plot::set_x_offset()` for a caller that states it
/// directly, and `Plot::layout()`'s placement, which re-clamps it against the
/// retained window every frame. `Plot::x_offset()` reads it back.
f64 offset = 0.0;
/// Ticks for the last `refresh()`, ascending, majors and (when asked) minors.
std::vector<Tick> ticks;
+12 -1
View File
@@ -170,6 +170,13 @@ class Plot {
void set_y_range(u32 axis, Range r);
/// Re-arms (or disarms) the per-layout auto scaling of one axis.
///
/// On an x axis that is armed `XFollow::Live` and has a live edge, this switch is
/// inert: `layout()` leaves that axis to the follow path and never fits it (see
/// `set_x_follow()`), so an axis that reads `auto_scale == true` -- including the
/// `AxisDesc` default -- can still be one whose window is not being fitted. The
/// follow state wins because following is the more specific statement about that
/// axis, and `auto_fit_x()` is what frames such an axis.
void set_x_auto_scale(u32 axis, bool on);
void set_y_auto_scale(u32 axis, bool on);
@@ -184,7 +191,11 @@ class Plot {
/// Arming an axis that has a live edge places its window at the live edge at
/// once, so `x_range()` reports the window the next layout will produce; the span
/// it starts from is the span the axis already had, so a caller that wants the
/// retained window framed calls `auto_fit_x()`. Turning `Live` off leaves the
/// retained window framed calls `auto_fit_x()`. An axis whose stored span is not
/// a span -- a range a caller left degenerate while the axis was `Off`, which this
/// setter does not second-guess -- has no window to place and nothing to follow
/// with; arm it and call `auto_fit_x()`, and note that a range set *under* `Live`
/// cannot leave it in that state (see `set_x_range()`). Turning `Live` off leaves the
/// axis exactly where it is: the last live window becomes an ordinary stored
/// range, and `auto_scale` is untouched.
///