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

+14 -1
View File
@@ -1265,6 +1265,8 @@ void Plot::build_crosshair() {
crosshair.active = crosshair_.active;
crosshair.vertical = Rect{};
crosshair.horizontal = Rect{};
crosshair.stroke = 0.0f;
crosshair.dash = Vec2{};
crosshair.panel = Rect{};
if (!crosshair_.active) {
crosshair.rows.clear();
@@ -1286,7 +1288,18 @@ void Plot::build_crosshair() {
// rule: the box is where the line may be drawn, and Task 1's clip never has to trim one
// that already fits. The lines are placed through the primary axis pair, like the grid and
// a region's fill -- one crosshair is one column and one row of the data area.
const f32 stroke = style_.device(style_.line_width_px);
//
// The stroke and the dash are resolved *here*, once, from the crosshair's own override where
// it has one and the global style otherwise, and converted to device pixels through
// `device()`. The boxes below and the renderer's strokes are then one set of numbers rather
// than two that must be kept in step (spec §17): `stroke` is the device width, `dash` the
// device (on, off) pair with `off <= 0` meaning solid.
const CrosshairStyle& cs = crosshair_.style;
const f32 stroke = style_.device(cs.width >= 0.0f ? cs.width : style_.crosshair_width);
crosshair.stroke = stroke;
crosshair.dash =
Vec2{style_.device(cs.dash_on >= 0.0f ? cs.dash_on : style_.crosshair_dash_on),
style_.device(cs.dash_off >= 0.0f ? cs.dash_off : style_.crosshair_dash_off)};
const f32 half = 0.5f * stroke;
if (crosshair_.vertical) {
const f32 at =