Skip to content

feat(overview): an activity grid, one cell per history bucket - #97

Closed
Fl0p wants to merge 1 commit into
mainfrom
flo-596-overview-histogram
Closed

feat(overview): an activity grid, one cell per history bucket#97
Fl0p wants to merge 1 commit into
mainfrom
flo-596-overview-histogram

Conversation

@Fl0p

@Fl0p Fl0p commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

A GitHub-contributions-style Span activity grid leads the Overview, under the KPI row. A line chart answers how much and when; it does not answer what does a week here look like, which is the rhythm question a telemetry front door gets asked most.

The grid

The selected range picks both the lattice and the bucket width it fetches — one bucket, one cell, no client-side re-bucketing:

Range Grid Cell granularity Window tiled
Year, All 53 × 7, column-major day day 371 days
Month 31 × 6, column-major 4 h 4h 31 days
Week 24 × 7, row-major 1 h hour 7 days
Day 24 × 6, column-major 10 min 10m 24 hours

On Year/All that is the identical request the History block already makes, so SWR serves both from one fetch.

Deviation from the ticket, deliberate: it asked for 27 × 7 on the week grid. 27 hour-columns × 7 rows is 189 hours = 7.875 days — it tiles neither a week nor a day, so no column would be a fixed hour and no row a fixed day, and the grid would drift three hours per row. 24 × 7 is exactly the 7-day window and is the shape 27 × 7 was reaching for. Rationale in the ADR.

API

GET /api/v1/history takes two more bucket widths, granularity=10m and 4h. Additive; no existing caller changes; an unrecognised width still falls back to day rather than 400ing. Like hour, both are answered from spans alone and report the shortfall in covered_sincedaily_usage buckets whole UTC days and cannot produce a sub-day bucket. bucket is now documented as a UTC wall-clock label floored to the width.

Two judgement calls worth reviewing

  • Absent ≠ empty. The lattice is fixed but the window is rolling, so the leading edge and the rest of today were never queried. Those cells are drawn as an outline with no fill. An empty cell means "we looked and found nothing"; conflating the two is how a heatmap invents a quiet weekend.
  • Quartiles, not max-relative. Scaling against the busiest cell was built first and renders a working week as one flat block of full-intensity cells — against a 722-span peak a 200-span day and a 700-span day are both "busy", on a linear ramp and on a log ramp alike. The scale moved to frontend/src/lib/heat.ts; the History page's calendar and hour-of-day heatmaps had a private copy and now read the same five steps.

Verification

  • go vet ./... and go test ./... green (golang:1.23-bookworm, CGO on). Four new tests pin the two widths' bucket labels in UTC, the raw-only rule, and the unknown-width fallback.
  • npm run build (tsc + vite) green.
  • Rendered in Chromium against a seeded instance (35 516 spans / 672 sessions / 120 days) at all five ranges in light and dark: correct cell counts (371/186/168/144 + labels), correct footers, zero console errors.

Follow-up, not in this PR

docs/assets/dashboard-overview.png still shows the pre-grid Overview. The Overview shape is also changing on flo-595-overview-activity-block; one re-shoot after both land beats two conflicting ones.

ADR-0016

🤖 Generated with Claude Code

@coderabbitai

coderabbitai Bot commented Aug 21, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 6717da28-d7d0-40ad-8f6f-c9a74b57af8a


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

The Overview charts activity as a line, which answers "how much and when"
but not "what does a week here look like" — the rhythm question a telemetry
front door gets asked most.

A Span activity grid now leads the page, under the KPI row. The range picks
both the lattice and the bucket width it fetches: 53x7 day cells over a year
and over All, 31x6 four-hour cells over a month, 24x7 hourly cells over a
week, 24x6 ten-minute cells over a day. Each tiles its window exactly and
each is about 115px of cells, so switching range does not move the page.

/history grows two sub-day bucket widths, 10m and 4h, so the grid asks for
exactly the cell it draws instead of re-bucketing an hourly series in the
page — which could not have produced a ten-minute cell at all. Both are
additive, both stay raw-only like hour and report covered_since, and an
unrecognised width still falls back to day.

Cells outside the queried window are drawn as an outline, never as an empty
cell: an empty cell means we looked and found nothing, an outline means we
did not look. The scale is cut at the quartiles of the cells in view rather
than against the busiest one, which rendered a working week as one flat block
of full-intensity cells, and it moves to lib/heat.ts where the History page's
two heatmaps now read the same five steps.

Co-Authored-By: Daedalus <daedalus@agents.flopbut.local>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@Fl0p
Fl0p force-pushed the flo-596-overview-histogram branch from a82896e to 05f040c Compare August 21, 2026 17:51
Fl0p pushed a commit that referenced this pull request Aug 21, 2026
A GitHub-contributions-style Span activity block now leads the
Overview, directly under the KPI row: a fixed lattice of cells, one
/history bucket each, so the page's pulse reads at a glance. The range
picks both the grid and the bucket width it fetches — 53x7 day cells on
Year and All, 31x6 four-hour cells on Month, 24x7 hourly cells on Week
(the requested 27x7 is 189 hours and tiles neither a week nor a day;
the transpose keeps one block shape), 24x6 ten-minute cells on Day.
/history accepts granularity=10m and granularity=4h, additive and
raw-only like hour, reporting the raw floor in covered_since. Cells
outside the queried window draw as outlines, never as zeros. The
five-step heat scale moves to frontend/src/lib/heat.ts, cut at the
quartiles of the cells in view rather than against the busiest cell,
and the History calendar and hour-of-day heatmaps adopt it. ADR-0016
records the week-grid transpose, the endpoint choice and the ramp.

Squash of PR #97, implemented by Daedalus, reviewed and approved by
Prospero.

Co-Authored-By: Prospero <prospero@agents.flopbut.local>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@Fl0p

Fl0p commented Aug 21, 2026

Copy link
Copy Markdown
Contributor Author

Squash-merged to main as a43e972 (local squash per the identity rule; both product calls approved — see FLO-596). Branch deleted.

@Fl0p Fl0p closed this Aug 21, 2026
@Fl0p
Fl0p deleted the flo-596-overview-histogram branch August 21, 2026 18:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant