fix: a cursor readout quotes the nearest stored sample, not a value between two

The crosshair and the cursors pane's mix values are one library call, and it
interpolated linearly between the two samples bracketing the pointer. That is
wrong twice over here. Ingest decimation is a boxcar average over `time_stride`
samples, so a number computed between two stored samples is a second, undeclared
estimate laid over the first that nothing on screen or in an export holds. And
past the sample spacing the polyline is a line the renderer drew, so quoting a
point on it reports the drawing rather than the data.

The fix is upstream and unconditional (plotter c028f48): `crosshair_span()`'s `t`
selects the nearer end instead of blending, with a tie reading the earlier
sample. `CrosshairRow::marker` is placed from the same y, so the dot follows the
quoted sample.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Martino FerrariandClaude Opus 4.6 committed 2026-10-05 13:45:21 +02:00
1 parent ec93a9831d
commit d03c9fb443
5 files changed
+37 -7

No files matched your search

+18 -4
View File
@@ -1139,10 +1139,24 @@ is what made a dragged cursor spring to where it had been. A ruler is per row: e
two different values, and the pane names the row.
`mix` needs no rulers: it reports the value the trace actually has at each marker, read
through the library's `Plot::crosshair_value()` — the two bracketing samples,
interpolated — so it is the answer to "what is this signal at these two times" rather
than "drag a ruler until it crosses the trace". A readout is `--` when the trace has
nothing at that time and `partial` when only one of the two markers is over samples.
through the library's `Plot::crosshair_value()` — **the nearer of the two bracketing
samples**, never a number between them — so it is the answer to "which datum of this
signal is at these two times" rather than "drag a ruler until it crosses the trace". A
readout is `--` when the trace has nothing at that time and `partial` when only one of
the two markers is over samples.
The value used to be a linear interpolation between the brackets, which is upstream's
old convention and was wrong for this app in two ways at once. The samples here are
**already averaged** — ingest decimation is a boxcar over `time_stride` samples (see
"Decimation at ingest is an average") — so a number computed *between* two of them is a
second, undeclared estimate laid over the first, and nothing on screen or in an export
holds it. And at a zoom past the sample spacing it is visibly not the datum the pointer
is over: the polyline between two samples is a straight line the renderer drew, and
quoting a point on it reports the drawing rather than the data. A tie reads the earlier
sample. The fix is upstream and unconditional (`deps/plotter`, `crosshair_span()`'s `t`
is now a selector rather than a blend factor), so the library's own hover crosshair
changed with the pane — which is the point, since both are the same lookup and a user
comparing them must not see two numbers.
The readouts are a **table**: a header naming the columns, then one row per instrument —
`| who | A | B | delta |`. The first row is the two times and their difference, and the