feat(plot): the figure crosshair marks the hovered row, and the stroke is thin, dashed and configurable

This commit is contained in:
Martino Ferrari committed 2026-09-28 20:17:01 +02:00
1 parent cae672bc99
commit eee7c34dd5
12 files changed
+166 -12

No files matched your search

+22 -2
View File
@@ -18,7 +18,12 @@ uniform vec2 u_viewport; // render target size, pixels
uniform float u_width; // stroke width, pixels
out float v_dist; // signed distance to the segment axis, pixels
out float v_along; // distance travelled from a_p0, pixels
// Distance travelled from a_p0, pixels -- and the dash's phase anchor. Both of the
// crosshair's lines are staged from an *axes edge* (its vertical from `y_range.min`,
// the axes' bottom; its horizontal from `x_range.min`, the axes' left), so a dash measured
// from here is measured from a fixed edge of the rect: it does not crawl as the view pans
// or zooms, and a stationary crosshair renders identically frame to frame.
out float v_along;
void main() {
vec2 p0 = a_p0 * u_scale + u_offset;
@@ -52,14 +57,29 @@ void main() {
)";
const char* const kLineFS = R"(#version 330 core
in float v_dist; // signed distance to the segment axis, pixels
in float v_dist; // signed distance to the segment axis, pixels
in float v_along; // distance travelled from a_p0, pixels
uniform float u_width; // stroke width, pixels
uniform vec4 u_color;
uniform vec2 u_dash; // dash pattern in pixels: x = ink, y = gap; y <= 0 is solid
out vec4 o_color;
void main() {
// The dash (spec §17): a fragment-shader discard, never new geometry -- the vertices
// stay in data space and the pattern is one per-draw uniform. `v_along` interpolates the
// distance from `a_p0` across the quad in pixels, so `mod` measures the pattern along the
// line rather than in screen space, which is what keeps it anchored to the segment while
// the view pans. `y <= 0` is solid, so every other stroke in the library -- grid, traces,
// axis lines, regions, cursors, the legend border -- draws unchanged by this uniform's
// default.
if (u_dash.y > 0.0) {
float period = u_dash.x + u_dash.y;
if (period > 0.0 && mod(v_along, period) >= u_dash.x) {
discard; // in the gap of the pattern
}
}
float half_w = u_width * 0.5;
float d = abs(v_dist);
if (d > half_w + 1.0) {