Commit Graph
1 Commits
Author SHA1 Message Date
Alex BandClaude Opus 5.5 8b5ca5735c fix(analytics): Packets / Hour readable on long histories (#2193) (#2194)
Fixes #2193.

## Problem
On an instance that keeps months of packets, the Overview tab's Packets
/ Hour chart becomes unreadable: 2,932 hourly bars in 720 units of plot,
a date label every day, and the hours with no packets (which the server
leaves out) squeezed off the axis.

## Before and after
Both use the real `/api/analytics/rf` answer from the instance in the
issue (2,933 hourly buckets over 124 days), served to the page in place
of the fixture's own.

**Before** (master, page on "All data"):


![before](https://raw.githubusercontent.com/A13xB0/CoreScope/e3cdf135/2026-10/pph-2193/before-desk.png)

**After**, same data:


![after](https://raw.githubusercontent.com/A13xB0/CoreScope/7862abd8/2026-10/pph-2193/after-desk.png)

Phone: <img
src="https://raw.githubusercontent.com/A13xB0/CoreScope/7862abd8/2026-10/pph-2193/after-phone.png"
width="300">

**A short store** (an instance holding 7 days in memory, plus a few old
packets a day for weeks before that because they were heard again). The
chart starts where the real data does (this shot predates the "since
MM-DD" note now in the title when that crop applies):

![short
store](https://raw.githubusercontent.com/A13xB0/CoreScope/7862abd8/2026-10/pph-2193/short-store.png)

## Change
All in `public/analytics.js`; no API change.
- **`packetsPerHourCard()`** replaces the inline block:
- rolls the hours up to hourly, 6-hourly, daily or weekly bars, at most
180, and titles the card to match (Packets / Day);
  - counts missing hours as zero;
  - puts about 10 labels on round UTC times;
- **under "All data" only**, starts on the first UTC day with at least
2% of a typical recent day (the median of the seven days before the last
one), at its first hour with a tenth of a typical hour, and says "since
MM-DD" in the title when that cuts anything. Scanning forward, an outage
after the start is never taken for it. In a picked window (1h to 30d)
the server has already cut the data, so nothing is cropped and a quieter
early stretch stays visible.
- **Theme refresh before the data** (separate commit; this also happens
on master without the new chart): every load fires `theme-refresh` about
300 ms after the theme resolves, and the page re-rendered the current
tab on it. When the analytics answers came later (a busy or
just-restarted server), the Overview was drawn from an empty object and
threw `Cannot read properties of undefined (reading
'totalTransmissions')`. It now skips that refresh until the data has
landed; `loadAnalytics()` renders the tab with the current theme when it
does.

The span is still picked by the page's time window.

## Tests
- `tests/unit/test-issue-2193-packets-per-hour.js` (in `test-all.sh`,
red then green): 122 days gives 123 daily bars with 4 to 12 labels; 7
days gives 168 hourly bars; missing hours are drawn as zero; the chart
starts at the data, not at the stragglers, and not after an outage; in a
picked window nothing is cropped (90 days with 30 quiet ones gives 91
bars); a cropped chart says "since MM-DD" and an uncropped one does not;
no data says so.
- `tests/unit/test-analytics-theme-refresh-before-data.js` (in
`test-all.sh`): drives `init()` with answers that never land, fires the
`theme-refresh` handler, and checks that nothing throws and the tab is
not re-rendered. Without the guard it fails with the production error.
- `sh test-all.sh` passes; the #1925 neighbour-graph theme-refresh test
and the analytics chart test still pass; the screenshots show no page
errors and no sideways scroll at 1280 px or 390 px.

## Later
- The 2% floor, the tenth-of-an-hour start and the 180-bar cap are
hardcoded. Per AGENTS.md rule 8 they can move to the customizer in a
later step.
- Edge bars are partial periods (data starting at 17h gives a 7-hour
first day; the last bar is still filling), and weekly bars align on
epoch weeks (Thursday). Both are left as they are here.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01KaR4xu8gVykQBkH8yG8m6H

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 11:46:28 +02:00