Risks & Go/No-Go Analysis

Re-evaluated after round 2. Assessment of the canvas renderer (src/canvas-timeline.js + the src/timeline/* mixins and helper modules). Validated by test/integration.js (66 layout/logic assertions) and test/render-smoke.js (25 full render/interaction assertions), all green.

Deployment model (this re-eval assumes it): a private, internal tool, used on desktop browsers only, for single-day (24h) timelines, shipped as source / an npm package built from source. Under that model, several items that were "gaps" in the first analysis are explicitly out of scope by decision: HTML-template parity, full accessibility / screen-reader support, i18n / RTL / CJK, and touch/pinch. They are listed below for completeness but are not gating.

Verdict: GO for the stated use case. The renderer is functionally complete and hardened for internal, desktop, performance-sensitive timelines; round 2 added the missing event parity, keyboard navigation, configurable fonts, published TypeScript types, and a clean module split, and closed every defect found in two deep review passes (see §3). Still NO-GO only for externally-facing or accessibility-regulated surfaces, or apps that depend on HTML item templates — none of which apply here. Recommended path remains: validate behind the parallel-run flag (transition.html) before flipping the default.

1. Benefits

2. Risk register

Status reflects round 2. Closed = resolved this round; Scoped out = intentionally not addressed per the deployment model.

RiskSevStatus & notes
No rangechange(d) eventsClosed Added rangechange (continuous) + debounced rangechanged, plus itemover/itemout and contextmenu. Event parity gap closed.
No keyboard navigationClosed (desktop) Added focusable canvas, a focus ring, arrow-key item navigation (within-group), Shift+Arrow nudge, zoom/fit/Home/End/Esc/Enter. Not full screen-reader a11y (scoped out), but the keyboard model now exists for desktop power users.
Hardcoded font stackClosed fontFamily/fontSize options now drive all canvas text; plus an icon / sprite-atlas system and 24-hour time labels.
Minimap / axis not aligned with bodyClosed Both the time axis and minimap are now offset by the label-panel + scrollbar width so labels and the window box pixel-align with the body grid.
Follow-now setIntervalClosed (mitigated) Still a 1s timer, but it now skips ticks while the tab is hidden and is cleared in destroy(). rAF-alignment noted in optimizations.html as optional.
No published types / packagingClosed Shipped canvas-timeline.d.ts with a documented public API; package.json exposes types/exports and a clean files allowlist, so it installs as an npm package built from source. ESM-only (no UMD) — fine for the bundler-based app.
Stacking recomputed every pan/zoomOpen (acceptable) ~8ms at 10k items, measured. Mid-drag restack is now skipped (rows frozen until drop). For single-day datasets this is comfortably within budget; visible-only/incremental stacking is documented in optimizations.html but deliberately not built.
No HTML item/group templatesScoped out Canvas draws text + shapes; styling is data-driven (colors, patterns, icons, accent strips). The app does not rely on template. Rich content via DOM overlay on doubleClick/ contextmenu.
Accessibility / screen readers / i18n / RTLScoped out Private, internal, desktop, single-locale tool — ARIA/SR/RTL/CJK explicitly out of scope.
Missing item types (point, background)Open (low) Only box/range/block implemented. Map point→short range; background can be approximated with a back-layer block. Implement only if a call-site needs them.
DST / timezone in axis labelsOpen (low) Fixed-ms tick stepping can land slightly off a clean local label around DST/month boundaries. Cosmetic for a 24h same-day view. Calendar-aware stepping noted in optimizations.html.
Touch / pinchScoped out Desktop-only deployment; basic single-pointer touch still works, multi-touch pinch is not a goal.

3. What was reviewed & fixed

Round 1 added render-smoke.js, verified destroy() cleanup and instance isolation, and confirmed block stacking/hit-test ordering — no crashing defects found.

Round 2 ran two further deep review passes and fixed every defect found, each as a discrete, revertable commit (see bugs-and-issues.txt):

The renderer was also split into focused modules (layout/rendering/interaction mixins + theme/colors/ canvas-draw/time-format helpers) with no behavior change, raising readability without a build step.

4. Residual work (none gating for this deployment)

  1. Rendering scale beyond ~50k visible: visible-only/incremental stacking + a spatial index if datasets ever grow past the single-day assumption (documented, not built).
  2. Item types: add point/background only if a call-site needs them.
  3. Testing/CI: npm test runs in CI; a headless-browser pixel/interaction suite (Playwright) and a perf-regression gate would catch visual regressions the stubbed smoke test can't.
  4. DST-correct axis stepping if labels near boundaries ever matter.
  5. If scope later widens to external/regulated/mobile surfaces: a11y mirror, templates story, i18n, and touch — all currently scoped out.

5. Recommendation

GO. For a private, desktop, single-day, source-shared timeline this renderer is ready: the public API and types are documented, the known-bug list is closed, the test suite is green, and the code is modular enough to hand over as a starting point. Adopt it behind the parallel-run flag to eyeball parity on the real data, then flip the default. Revisit §4 only if the deployment scope widens beyond the assumptions above.

← Migration plan · Future ideas →