feat(plot): the readout marker snaps to the sample it quotes, and the value mode is a choice
The mark was placed at the *pointer's* x with the quoted sample's y, so with the nearest-sample readout it sat off the datum horizontally -- and further off the deeper the zoom. `CrosshairRow` now carries the data `x` the value belongs to and the marker is placed from it, so in `NearestSample` the mark lands on the sample the panel is quoting. `Style::crosshair_marker_px` (9) and `crosshair_marker_width` (1.5) replace the renderer's hard-coded 3 px arm and 1 px stroke: a snapped mark lands among a trace's own sample dots (`marker_px`, 3) and at that size would read as one more sample rather than as the answer to the question the hover asks. `CrosshairValue` makes the previous behaviour reachable rather than deleted. The two modes answer different questions -- `NearestSample` "which datum is under the pointer", `Interpolated` "what is the signal at this instant" -- and only the caller knows which it is asking, so the plot offers both with the sample as the default. `crosshair_interpolate()` is restored for it. `Plot::crosshair_point()` is the lookup with both coordinates, public because a host that draws instruments of its own needs the same snap and a second rule for it would drift from this one; `crosshair_value()` delegates to it.
This commit is contained in:
1 parent
c028f48fa0
commit
c960decaea
9 files changed
+372
-78
No files matched your search
+22
-13
@@ -1522,19 +1522,28 @@ void Renderer::draw_crosshair_lines(const Plot& plot, const PlotLayout& layout)
|
||||
flush_lines(data, style_.crosshair, stroke, crosshair.dash);
|
||||
}
|
||||
|
||||
// A small cross at each trace's intersection, in the trace's own colour -- opaque, like a
|
||||
// legend's swatch, so a trace drawn at 15% still has a marker that can be seen. The arm
|
||||
// length is a logical size like every other marker's, and the position is the layout's: a
|
||||
// marker for a sample far outside the visible y range is staged where the trace is and the
|
||||
// axes clip keeps it inside, rather than being skipped by a range test of this layer's own.
|
||||
const f32 arm = style_.device(3.0f);
|
||||
for (const CrosshairRow& row : crosshair.rows) {
|
||||
if (!row.valid) continue;
|
||||
Color color = plot.trace(row.trace).color;
|
||||
color.a = 1.0f;
|
||||
lines_.add_segment({row.marker.x - arm, row.marker.y}, {row.marker.x + arm, row.marker.y});
|
||||
lines_.add_segment({row.marker.x, row.marker.y - arm}, {row.marker.x, row.marker.y + arm});
|
||||
flush_lines(pixel_mapping(), color, style_.device(1.0f));
|
||||
// A cross at each trace's readout point, in the trace's own colour -- opaque, like a legend's
|
||||
// swatch, so a trace drawn at 15% still has a mark that can be seen. The position is the
|
||||
// layout's, and in the default `CrosshairValue::NearestSample` that is the *quoted sample*
|
||||
// rather than the pointer's column: a mark for a sample outside the visible range is staged
|
||||
// where that sample is and the axes clip keeps it inside, rather than being skipped by a range
|
||||
// test of this layer's own.
|
||||
//
|
||||
// `crosshair_marker_px` is the cross' full extent and is larger than `marker_px`, which dots a
|
||||
// trace's own samples at a deep zoom -- a snapped mark lands among those dots and has to read
|
||||
// as the one the panel is quoting. `0` across draws nothing, so a caller can have the panel
|
||||
// and the lines without the marks.
|
||||
const f32 arm = 0.5f * style_.device(style_.crosshair_marker_px);
|
||||
const f32 mark_stroke = style_.device(style_.crosshair_marker_width);
|
||||
if (arm > 0.0f) {
|
||||
for (const CrosshairRow& row : crosshair.rows) {
|
||||
if (!row.valid) continue;
|
||||
Color color = plot.trace(row.trace).color;
|
||||
color.a = 1.0f;
|
||||
lines_.add_segment({row.marker.x - arm, row.marker.y}, {row.marker.x + arm, row.marker.y});
|
||||
lines_.add_segment({row.marker.x, row.marker.y - arm}, {row.marker.x, row.marker.y + arm});
|
||||
flush_lines(pixel_mapping(), color, mark_stroke);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user