docs: split rows share one y axis
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
b8177cc25a
commit
fa9f0c6da9
8 files changed
+86
-40
No files matched your search
@@ -123,27 +123,40 @@ Part of [CLAUDE.md](../../CLAUDE.md). These are rules that cost a defect to lear
|
||||
y), and the **vertical cursor pair is one shared time drawn in every cell** (`cursors_aligned`).
|
||||
A split is an arrangement of more plots, not a second time scale: nothing about the time axis changes
|
||||
(see [invariants-time-axis-and-window.md](invariants-time-axis-and-window.md)).
|
||||
- **Per-cell y.** Each cell has its own y axis (auto or fixed), its own horizontal rulers and its own
|
||||
fit; a wheel or axis drag acts on the cell under the pointer, an x gesture on any bottom-row cell
|
||||
moves the shared window. The cursors pane's ruler label is `plot 2a` for a plot of a split row and
|
||||
`row N` (the plot index) for one of an unsplit row, so the pane reads the same as before until a row
|
||||
is split.
|
||||
- **One y per figure row.** The cells of a figure row share one y range (the plotter's
|
||||
`Figure::set_share_row_y(true)`, which `rebuild_all()` sets before the cells are populated): one y
|
||||
axis (auto or fixed), one pair of horizontal rulers, one fit. A wheel or axis drag in any cell moves
|
||||
the row, an x gesture on any bottom-row cell moves the shared window. The host therefore acts on the
|
||||
**figure row** of a plot it is given (`set_y_auto`, `set_y_range`, `fit_all`, the Auto/Fixed dialog,
|
||||
`row_unit`, which joins the units of every cell and reads "" if they differ). The rulers are stored on
|
||||
the row's first plot index, copied to the other cells by `sync_cursors()` / `insert_cell()` /
|
||||
`rebuild_all()` and placed in every cell by `place_cursors()`. The cursors pane lists **one ruler line
|
||||
per figure row**: `row N` with N the 1-based figure row for a split row, and the 0-based plot index
|
||||
for an unsplit row (the pane read that before splitting existed). Readouts and measurements stay per
|
||||
trace and per plot index; only the axis is shared.
|
||||
- **Bottom-row x labels only.** The plotter gives every plot that is not in the last figure row
|
||||
`XStrip::None`; the cells of the bottom row each keep their strip, so a middle-drag on the axis
|
||||
works in any of them. The `t0` caption goes on those cells too.
|
||||
- **One left gutter.** The y gutter is one maximum for the whole figure with the same reserved floor
|
||||
as before (`Figure::set_min_y_gutter()`), **not a per-column one**: a per-column gutter would make a
|
||||
cell's width depend on its labels, which "layout must not depend on content" forbids. A cell whose y
|
||||
labels are narrower than the gutter simply has a wider margin.
|
||||
- **Widths are weights with a floor.** The plotter keeps 64 px logical per cell and a column gap
|
||||
(`kColGap`, 6 px); the editor's drag is stricter (below). A weight is a share of what is
|
||||
left *after* the floors, so cells of `{3, 1}` read 533:220 in a 756 px figure, not 3:1, and the
|
||||
editor's 96 px drag floor is a floor on the *width*, not on the share. Because a cell's width is
|
||||
- **One left gutter, on the first cell only.** The y gutter is one maximum for the whole figure with the
|
||||
same reserved floor as before (`Figure::set_min_y_gutter()`). It is carried by the first cell of each
|
||||
row alone: `Figure::layout` gives every other cell `YStrip::None` from its column index (structurally,
|
||||
never from what it holds), which forces its y label width, title width and reserved floor to 0. A
|
||||
`None` cell contributes 0 to the common maximum, so a split row's non-first cells cannot widen the
|
||||
gutter and a row's gutter does not depend on how many cells it has. A per-column gutter sized by the
|
||||
labels would make a cell's width depend on its content, which "layout must not depend on content"
|
||||
forbids. A row whose labels are narrower than the gutter simply has a wider margin. The weights apply
|
||||
to **plot widths**, not cell rects (below).
|
||||
- **Widths are weights with a floor.** The plotter keeps 64 px logical per plot and a column gap
|
||||
(`kColGap`, 6 px); the editor's drag is stricter (below). The floors and the weights act on **plot widths**: the row's y gutter (carried by the first
|
||||
cell) is taken off the row width first, then the cells share the rest, so equal weights give equal plot
|
||||
areas and the first cell's rect is its gutter plus its plot width. A weight is a share of what is
|
||||
left *after* the gutter and the floors, so cells of `{3, 1}` read 546:207 (rects) in a 756 px
|
||||
figure, not 3:1, and the editor's 96 px drag floor is a floor on the plot *width*, not on the share. Because a cell's width is
|
||||
`64 + extra * weight / total` and not proportional to its weight, `layout_col_apply()` does not scale
|
||||
the pair's weights by the width ratio: it keeps the pair's weight sum `S` from the drag's *start*
|
||||
(`layout_col_drag_start`) and gives the left cell `S * (want_left - 64) / (pair - 128)`, clamped to
|
||||
`[0.001, 0.999]` (the plotter refuses non-positive weights; `0.5` if the pair is not wider than 128).
|
||||
`want_left` is the pointer's width clamped to `[96, pair - 96]` logical px. The divider therefore
|
||||
`want_left` and the pair are plot widths (`layout_col_drag_begin` subtracts the first cell's `y_axis_width + y_title_width` from its rect); `want_left` is the pointer's width clamped to `[96, pair - 96]` logical px. The divider therefore
|
||||
follows the pointer, the shrinking cell reads 96 px at the extreme and the pair keeps its total width
|
||||
(the split probe's `col-drag` line asserts all three). `kPlotterMinCellPx` (64) mirrors the plotter's
|
||||
`kMinCellWidthLogical`; both are logical px (the plotter scales it by `ui_scale`, which is
|
||||
|
||||
Reference in new issue
Block a user