Hover-scrubber on projection charts — cursor reveals predicted time/% (parked 2026-05-24)

DARE.CO.UK · PARKED SKETCH · 2026-05-24

Mirrored from ~/.claude/.../memory/parked_sketch_hover_scrubber_projection_chart_2026-05-24.md. This is a design sketch parked for future build — read for context, not as a current deliverable.

Mousing over the projection line (or anywhere on the trend chart) surfaces a tooltip with the predicted timestamp + percentage complete + estimated PNG count at that x-coordinate. Cursor becomes a scrubber along the projected path. Same SVG, +JS event handler. Lifts to batch-status template + any future chart with a projection layer.


Dan 2026-05-24: “if you mouse over the predicted path of either graph, the cursor can calculate the predicted time/percentage-complete/number-estimated-to-be-completed, it’s like a layer of insight that your mind doesnt have to run.”

What this adds

The projection line on the trend chart visually answers “when will we finish?” The hover-scrubber answers a richer question at any x-coordinate: “if I’m wondering what state we’ll be in at 9am tomorrow / next Monday / when I get home Friday, point at that x and see.”

The math the eye otherwise runs (interpolate x → t, project count via pace, format both) becomes free.

Two reading modes — and the inverse insight Dan flagged

Dan 2026-05-24 extending: “the math can be derived, to assess on what day/date, roughly 75% will be achieved, at current trajectory. That’s where data-viz really adds layers of value.”

This unlocks two complementary hover modes:

Mode Cursor input Answer
Forward Cursor at time-axis position (X) At that time we’ll be at N% (Y count)
Inverse Cursor at count-axis position (Y) We’ll reach that count on T (X date)

Both are derivable from the same projection slope. Cursor proximity to axis decides which one is active, OR show both lines (vertical guide + horizontal guide forming a crosshair at the projection intersection).

Default milestone annotations (no hover needed)

Even better — render the milestone-crossings as fixed annotations on the projection line so the answer is visible on first view, no interaction required:

Three small dots along the projection line with date labels. Static SVG, no JS, no library. Adds the milestone-crossing insight on first paint; hover-scrubber adds the arbitrary-point insight as a richer layer on top.

Two-tier value: - Tier 1 (zero-effort) — fixed milestone annotations. Always-on. Answers most “when will we hit X%” questions before they’re asked. - Tier 2 (hover) — scrubber for the exact arbitrary point. Pays off when Tier 1’s coarseness isn’t enough.

Implementation shape

Pure JS event handler on the SVG (no library). On mousemove:

  1. Translate event.offsetX back to a time via the chart’s x-axis range
  2. If the cursor is between now and ETA, compute: - predicted_count = current_count + pace_per_hour × hours_since_now - predicted_pct = 100 × predicted_count / target - predicted_ts = now + hours_since_now
  3. Render a vertical guideline + a small floating callout
  4. On mouseleave, hide the callout

Approx ~40 lines of inline JS. SVG already has the data it needs (data-attributes on key elements or recalculate from chart constants).

Where it lives

Chart Hover behavior
Trend chart (status pages) Hover anywhere → vertical guideline at cursor + floating tooltip showing <predicted-time-ET> · <count> · <pct>
Bullet chart Hover on the bands → tooltip shows what percentage cluster + projected timestamp to reach that band’s right edge
Future · vehicle TCO grouped bar Hover on a bar segment → show category total + share of vehicle’s lifetime
Future · category spend stacked area Hover on a year × category cell → show year total + cumulative-to-date

Why this is a “future-pattern-rationalization-pending” build

Three reasons not to ship inline today:

  1. Pattern home not chosen. Inline JS in pa_job_status_render.py works but doesn’t help when the Harvest renderer wants the same thing. Belongs in assets.gf.cx/charts/hover-scrubber.js as a primitive — but that primitive doesn’t exist yet (per parked_sketch_d3_comparison_primitives_2026-05-24.md).
  2. Specificity threshold. Current status page has one trend chart with two points (start, last); hover-scrubber pays off when the trend has more substance — once 50+ history points accumulate, the chart will be data-dense enough that hover-insight actually answers questions the eye couldn’t quickly.
  3. Other primitives to build first. Cards-as-primitive, charts-as-primitive — both blocking before this layer pays off cleanly.

Build trigger

Build when ALL of: - Cards-as-primitive lands (so the chart container is consistent) - A second surface needs a projection chart with the same hover behavior (e.g. vehicle TCO trend, harvest spend trajectory) - A status page has 30+ history points (enough density to scrub)

Estimated cost (when triggered)

Layer Effort
Tier 1 — fixed milestone annotations (25/50/75/100%) in SVG ~30 min — pure server-side render, no JS
Tier 2 — hover-scrubber JS handler + floating tooltip ~1 hour
Tier 2 — inverse mode (count-axis hover) ~30 min
Integration into pa_job_status_render.py + replication to Harvest renderer ~30 min
Tier 1 alone ~30 min — ship first, biggest payoff per minute
Full Tier 1 + Tier 2 ~2.5 hours

Cross-references

The aphorism

Static charts answer the question once. Hover-aware charts answer every question you didn’t know you had until your cursor was there.

Source: parked_sketch_hover_scrubber_projection_chart_2026-05-24.md · Rendered 2026-05-24 06:31