figure: cells of a row can share one y range
This commit is contained in:
1 parent
73f610b136
commit
25c3381551
6 files changed
+214
-7
No files matched your search
@@ -102,12 +102,16 @@ struct Axis {
|
||||
/// group stops following or the row leaves it.
|
||||
bool live_owner = false;
|
||||
f64 live_owner_newest = 0.0;
|
||||
/// Set while this plot is a member of a `Figure` x link group (`Figure::link_x()`
|
||||
/// writes it, `unlink_row()` clears it). The group owns the shared x window *and*
|
||||
/// its follow state -- `Figure::link_x()` refuses a `Live` member joiner -- so
|
||||
/// `Plot::set_x_follow(Live)` on this axis is refused after linking too, rather
|
||||
/// than letting a later call put the member's axis back into a state the group
|
||||
/// cannot drive (see `Plot::set_x_follow()`).
|
||||
/// Set while this axis is a member of a `Figure` link group. On an x axis that is
|
||||
/// an x link group (`Figure::link_x()` writes it, `unlink_row()` clears it): the
|
||||
/// group owns the shared x window *and* its follow state -- `Figure::link_x()`
|
||||
/// refuses a `Live` member joiner -- so `Plot::set_x_follow(Live)` on this axis is
|
||||
/// refused after linking too, rather than letting a later call put the member's
|
||||
/// axis back into a state the group cannot drive (see `Plot::set_x_follow()`).
|
||||
/// On a y axis it is the row's shared-y group (`Figure::set_share_row_y()`): the
|
||||
/// group, not the plot, owns the range *and* the auto scale state, so
|
||||
/// `Plot::autoscale_axes()` skips the axis and the figure fits the union of the
|
||||
/// members' traces instead.
|
||||
bool link_member = false;
|
||||
/// Ticks for the last `refresh()`, ascending, majors and (when asked) minors.
|
||||
std::vector<Tick> ticks;
|
||||
|
||||
@@ -314,6 +314,22 @@ class Figure {
|
||||
/// A group's follow state. `Off` for group 0 and for a group that does not exist.
|
||||
XFollow x_link_follow(u32 group) const noexcept;
|
||||
|
||||
/// Makes the cells of every split row (two or more) share their y axis 0: one range
|
||||
/// and one auto scale state per row, default off. A range set on any member -- a
|
||||
/// wheel, a drag, `Plot::set_y_range()` -- becomes the row's and is pushed to all of
|
||||
/// its cells at the next `layout()`; the row is auto or manual as one, and while it is
|
||||
/// auto it fits the union of every cell's visible traces (a cell with none is ignored;
|
||||
/// padding and log handling are the plot's own, via `Plot::fit_y_bounds()`). The group,
|
||||
/// not the plot, owns auto scale: members' own autoscale is suppressed, because each
|
||||
/// would fit only its own traces and the cells would fight over the range. Turning it
|
||||
/// on or off forgets the groups' state; a row of one cell is never a group.
|
||||
void set_share_row_y(bool on);
|
||||
bool share_row_y() const noexcept { return share_row_y_; }
|
||||
/// Whether figure row `row` is auto scaled as a group. True for a row that is not a
|
||||
/// group -- fewer than two cells, sharing off, or a row that does not exist -- so
|
||||
/// "auto" is also the answer when there is no shared state to be manual.
|
||||
bool row_y_auto(u32 row) const noexcept;
|
||||
|
||||
private:
|
||||
/// One link group: the range its members share, the scroll state behind that
|
||||
/// range while it follows, the rows in it (ascending) and, in step with them, the
|
||||
@@ -370,6 +386,21 @@ class Figure {
|
||||
/// a following group's window, push both to all members.
|
||||
void sync_x_links();
|
||||
|
||||
/// A split row's shared y axis: the range last pushed to its cells (the value the
|
||||
/// next frame compares each cell against, so a gesture is told from the group's own
|
||||
/// write -- the same device as `XLink::pushed`), whether the group has been
|
||||
/// initialised from its first cell, and whether it is auto scaled.
|
||||
struct RowY {
|
||||
Range pushed{};
|
||||
bool have = false;
|
||||
bool auto_scale = true;
|
||||
};
|
||||
/// Advances every split row's y group for this frame: adopt what a cell was changed
|
||||
/// to (a range or an auto flag), fit the union of the cells' traces while the group
|
||||
/// is auto, push the result to all cells. Runs before any `Plot::layout()`, which is
|
||||
/// where a plot would otherwise autoscale on its own.
|
||||
void sync_row_y();
|
||||
|
||||
/// Fills the row bookkeeping (`cells_per_row_`, `row_first_`, `cell_weights_`) from a
|
||||
/// per-row cell count, clamping each to at least one. Does not touch `plots_`, which the
|
||||
/// constructors size from `total_cells()`.
|
||||
@@ -381,6 +412,8 @@ class Figure {
|
||||
/// index of row r's first cell and the last entry the plot count.
|
||||
std::vector<u32> row_first_;
|
||||
std::vector<std::vector<f32>> cell_weights_;
|
||||
bool share_row_y_ = false;
|
||||
std::vector<RowY> row_y_;
|
||||
f32 col_gap_ = 0.0f;
|
||||
/// What `plot()` yields for a row that does not exist, so a stale row can be used
|
||||
/// without reading out of bounds. Owned rather than a static, so one figure's
|
||||
|
||||
@@ -435,6 +435,20 @@ class Plot {
|
||||
/// does not exist. Not for callers outside the figure: a `Plot` that is not in a
|
||||
/// figure never has a linked axis.
|
||||
void set_x_link_member(u32 axis, bool linked) noexcept;
|
||||
/// The y-side twin of `set_x_link_member()`: publishes that this y axis is a member
|
||||
/// of its row's shared-y group (`Figure::set_share_row_y()`). A linked y axis is
|
||||
/// never fitted by `layout()` -- the group owns its range and auto scale, and fits
|
||||
/// the union of every member's traces -- but a gesture or `set_y_range()` still
|
||||
/// writes it, which is how the group learns of a change. A no-op for an axis that
|
||||
/// does not exist. Not for callers outside the figure.
|
||||
void set_y_link_member(u32 axis, bool linked) noexcept;
|
||||
/// Union of the bounds of the visible traces bound to y axis `axis`: what a shared-y
|
||||
/// group collects from each member. False -- and `out` untouched -- when none.
|
||||
bool y_data_bounds(u32 axis, Range& out) const;
|
||||
/// Fits y axis `axis` to `bounds` the way `auto_fit_y()` fits it to its own traces
|
||||
/// (same padding, same log handling), leaving `auto_scale` alone. False -- range
|
||||
/// untouched -- when the axis does not exist or cannot be fitted to `bounds`.
|
||||
bool fit_y_bounds(u32 axis, Range bounds);
|
||||
|
||||
/// Data -> pixels for one axis, built from the axis' range, log flag and the
|
||||
/// current layout. Always invertible: a collapsed range or a collapsed axes
|
||||
|
||||
Reference in new issue
Block a user