feat(plot): horizontal rulers alongside the vertical cursors
This commit is contained in:
1 parent
2d819c4228
commit
63f9655ae1
11 files changed
+514
-29
No files matched your search
@@ -197,6 +197,16 @@ class Plot {
|
||||
u32 add_y_axis(const AxisDesc& desc);
|
||||
u32 add_trace(const TraceDesc& desc);
|
||||
u32 add_cursor(f64 x, Color color);
|
||||
/// Adds a horizontal ruler at a data y (spec §14): the same instrument as `add_cursor()`
|
||||
/// turned a quarter turn. It spans the axes' width at `y`, is grabbable and draggable
|
||||
/// along y with the very same hit radius, and reports `CursorOrientation::Horizontal`.
|
||||
///
|
||||
/// `y` is on y axis 0, as `add_cursor()`'s `x` is on x axis 0. Its snap is `HRulerSnap`,
|
||||
/// not `SnapMode`: a series is sampled in x, so the nearest *tick* of the y axis is the
|
||||
/// only grid a y ruler can land on (`set_cursor_h_snap()`). It takes the next free id in
|
||||
/// the one `cursors_` sequence both orientations share, so a vertical cursor added after
|
||||
/// it is that id plus one.
|
||||
u32 add_h_ruler(f64 y, Color color);
|
||||
/// Measures the interval between two cursors over the series of `trace`.
|
||||
u32 add_measure(u32 cursor_a, u32 cursor_b, u32 trace = 0);
|
||||
u32 add_annotation(const Annotation& annotation);
|
||||
@@ -233,6 +243,14 @@ class Plot {
|
||||
const Axis& y_axis(u32 axis) const;
|
||||
const Trace& trace(u32 id) const;
|
||||
const Cursor& cursor(u32 id) const;
|
||||
/// The device coordinate a cursor's marker sits at: the column of its `x` for a vertical
|
||||
/// cursor, the row of its `y` for a horizontal ruler -- the one coordinate its own
|
||||
/// orientation owns, mapped through the axis that coordinate is in. The one place that
|
||||
/// choice is made, so the hit test the controller runs and the stroke the renderer stages
|
||||
/// cannot disagree about where a cursor is (see CursorOrientation), and a host can place
|
||||
/// its own tooltip or status line on the same number. 0.0f for an id that names no cursor,
|
||||
/// like every other accessor here.
|
||||
f32 cursor_screen_coordinate(u32 id) const;
|
||||
const Annotation& annotation(u32 id) const;
|
||||
/// The region with that id, or a default-constructed one: as everywhere else on
|
||||
/// this class, a stale id reads a default rather than out of bounds.
|
||||
@@ -361,12 +379,43 @@ class Plot {
|
||||
|
||||
// --- cursors and measurements -----------------------------------------
|
||||
|
||||
/// Moves a cursor and invalidates the measurements that depend on cursors.
|
||||
/// A SnapMode::NearestSample cursor is pulled onto the nearest sample of the
|
||||
/// first visible trace on its x axis.
|
||||
/// Moves a **vertical** cursor along x, and invalidates the measurements that depend
|
||||
/// on cursors. A `SnapMode::NearestSample` cursor is pulled onto the nearest sample of
|
||||
/// the first visible trace on its x axis.
|
||||
///
|
||||
/// A horizontal ruler's `x` is not a coordinate of its: this is *ignored* for one, so
|
||||
/// the dead field of an orientation can never be written behind its back (see
|
||||
/// CursorOrientation). `set_cursor_y()` is the ruler's half of the pair.
|
||||
void set_cursor_x(u32 id, f64 x);
|
||||
/// Sets the snap of a **vertical** cursor, re-placing it under the new rule at once.
|
||||
/// Ignored for a horizontal ruler, whose snap is `HRulerSnap` -- see
|
||||
/// `set_cursor_h_snap()`.
|
||||
void set_cursor_snap(u32 id, SnapMode mode);
|
||||
|
||||
/// Moves a **horizontal** ruler along y, re-placing it under its own snap rule.
|
||||
///
|
||||
/// Ignored for a vertical cursor -- `y` is not its coordinate -- and stored verbatim for
|
||||
/// a ruler, exactly as `set_cursor_x()` stores a `Free` cursor's x: a y outside the axis'
|
||||
/// range is a position the *renderer* skips, not one this store refuses, which is what
|
||||
/// lets a caller park a ruler off range on purpose. The *drag* is what clamps: a pointer
|
||||
/// that has left the axes has no data under it, so `input::Controller` keeps a dragged
|
||||
/// ruler on its axis' range rather than storing a coordinate no pointer could reach
|
||||
/// (see `Controller::move_cursor()`).
|
||||
void set_cursor_y(u32 id, f64 y);
|
||||
/// Sets the snap of a **horizontal** ruler: `NearestTick` pulls its y onto the nearest
|
||||
/// tick of its y axis' tick set -- majors and minors alike, the one list the axis
|
||||
/// refreshed -- and `Free` leaves it where it is.
|
||||
///
|
||||
/// The tick set it snaps to is the *last* `layout()`'s, because ticks are generated there
|
||||
/// and nowhere else: snapping does not recompute them, so the library keeps one tick
|
||||
/// computation rather than two. On the drag path that is the frame's own set --
|
||||
/// `input::Controller::on_pointer()` lays the plot out before every event it applies --
|
||||
/// while a caller that moves a y range and then sets a ruler's y *without* laying out
|
||||
/// snaps against the previous set, one frame stale. Laying the plot out refreshes it.
|
||||
///
|
||||
/// Ignored for a vertical cursor, whose snap is `SnapMode` -- see `set_cursor_snap()`.
|
||||
void set_cursor_h_snap(u32 id, HRulerSnap mode);
|
||||
|
||||
/// The measurement for `id`. Re-evaluated only when a cursor moved, when the
|
||||
/// measure was added, or when the series underneath it changed: a different
|
||||
/// series, a longer one, or a sliding window whose sample count stayed the same
|
||||
@@ -559,6 +608,13 @@ class Plot {
|
||||
/// `c.x` pulled onto the nearest sample when the cursor asks to snap: the same one
|
||||
/// rule, applied to the axis the cursor names.
|
||||
f64 snapped_x(const Cursor& c) const;
|
||||
/// `c.y` pulled onto the nearest tick of `c.axis_y`'s tick set when the ruler asks to
|
||||
/// snap, else `c.y` -- `HRulerSnap`'s one rule and the only place a ruler's snap is
|
||||
/// decided. The tick set is the last `layout()`'s (see `set_cursor_h_snap()`), and the
|
||||
/// nearest of it wins with a tie going to the lower tick; an axis that has not been laid
|
||||
/// out yet, one holding no ticks, and a `y` that is not a number all leave the value as
|
||||
/// it is rather than inventing a tick to land on.
|
||||
f64 snapped_y(const Cursor& c) const;
|
||||
/// Measures every visible region into `layout_.regions`: the fill's clipped
|
||||
/// interval, one grab tab per bound, and the label's line box. Also the place a
|
||||
/// region's pixel geometry is derived -- the controller hit-tests what this
|
||||
|
||||
Reference in new issue
Block a user