- Cull connections whose thin middle would render below ~0.8px
(MIN_WMID); drop external source/exit nodes whose connectors are
all culled, while site page nodes always stay
- Bead simulation persists across data reloads: emitters keyed per edge
direction, beads tracked by progress, so unrelated count changes no
longer reshuffle bead positions
- Bead speed relative to span length: constant 1.5s traversal per edge
- Top lane labeled with a house icon; all lane labels left-aligned just
past the source pill (half height on near-vertical branch lanes), with
guides running to the lane end so long slugs are never truncated
- Charts render as single SVGs with axis labels inside the viewBox,
replacing the stretched plot + HTML overlay labels
- Rolling ranges end at now, t0 aligned to UTC day; bucket size follows
the window (6h up to 31 days) so "all" at its 30-day minimum renders
identically to "month"
- X labels always centered on their true position; no edge-align shifting
- rangeWindow simplified to rolling spans ending at now
- TransitionGraph "all" visual scale floored at the 30-day plot minimum
- Edge widths grow logarithmically with the connection count (~1 px at
a single count, uncapped); connections below 1% of total traffic are
pruned, bounding the graph to ~100 edges.
- Beads: per-direction flows emitted at a rate linear in the count,
each bead simulated independently in JS (no in-flight limit), offset
onto right-hand lanes so opposing flows don't collide, running under
the node circles with a glow.
- External links: referer origins as a node row above the map, exit
origins fanned outwards from their source page.
- Transitions are now stored per 5-minute bucket (sparse
from -> to -> bucket -> count) so the graph filters by time range
like the other series; legacy analytics files are discarded.
Add server-side visit analytics collection, a public-page ping endpoint,
and a full-screen AnalyticsView for admins.
Backend:
- Add pagerite/analytics.py: Analytics/Visit model, Store, and persistence
- Wire /_a ping endpoint and GET /_api/analytics into pagerite/app.py
Frontend:
- Add full-screen AnalyticsView with visitor charts and transition map
- Add VisitorCharts and TransitionGraph subcomponents
- Add analytics JS helpers in frontend/src/analytics/
- Send navigation pings from frontend/src/pagerite.js
- Mount AnalyticsView from frontend/src/main.js
- Document the feature in docs/analytics.md and update AGENTS.md