// 003 — Interactive Data Visualization

THE DATA
MOVES.

Three D3.js charts built like product interfaces. A live FPS monitor, an interactive scatter plot, a force-directed graph with drag and hover. Real data, real interaction, designed with intention.

build.2026.05 v1.0.0 3 live charts · D3.js v7 [ ACTIVE ]
// The Brief

D3.js is a decision engine disguised as a charting library. Every visual property — axis color, label size, transition timing — is a manual call. The brief forced the question: three chart types, live data, one visual language. What are the actual decisions?

The constraint: D3 uses presentation attributes, not CSS. Design tokens don't inherit. Every color, every opacity, every stroke width had to be applied at the render layer — not the style sheet. The result is a tighter coupling between data and design than most component libraries allow.

The force graph was the hardest. Nodes, links, labels, and drag state updating at 60fps while staying legible. That's the one worth looking at.

// 01 — Performance Monitor D3.js · live-updating · 1.2s interval

Render Performance

Frame rate over time. Live simulation — 60fps target, realistic jank spikes. Hover for exact values.

FPSMonitor · 60 data points [ LIVE ]
60 fps
target: 60fps
avg: —
low: —
// Design rationale Performance data is operational material. A Design Engineer watches this — it's the proof that the interaction craft ships at speed. The signal color tracks the fps line. Drops to red when it drops below 45.
// 02 — Decision Impact Matrix D3.js · filterable · hover-annotated

Complexity × Impact

Every design decision from this portfolio mapped by implementation complexity and perceived impact. Size = lines of code. Hover any point for details.

DecisionMatrix · 16 decisions [ INTERACTIVE ]
// Design rationale The best decisions cluster top-left: high impact, low complexity. The scroll scrub and streaming text both live there. The force graph is top-right: worth the cost. Showing this data is itself a design decision.
// 03 — Component Dependency Graph D3 force simulation · drag · hover

AI Interface Patterns — Dependency Graph

All 12 nodes of the AI Interface Pattern set. Hover to highlight connections. Drag to explore. The topology is the architecture.

ComponentGraph · 12 nodes · 16 edges [ INTERACTIVE ]
component
hook
util
// Design rationale Dependency graphs expose architecture visually. This is the real topology of the design system — not a diagram made in Figma, but the actual import structure rendered as a force simulation. The physics are real.
// 04 — Portfolio Metrics build.2026.05

By the Numbers

The portfolio in raw numbers. Every line earned.

0
Lines of code
across 3 shipped projects
0
Interactive components
designed and built in code
0
GSAP timelines
scroll-driven + entrance
0
Days to build
concept to live demo
// In review
// Craft decisions
  • The FPS line changes color at 45fps and 52fps. Same data, three meanings — green lane, yellow lane, red lane. You read the health from the color, not the number.
  • Scatter dots size by √loc × 1.4. Linear sizing buries small items; log sizing exaggerates. Square-root keeps hierarchy readable across 16 points.
  • Force-graph hover dims unconnected nodes to 12% fill and 20% stroke. The connected subgraph stays full opacity. Highlighting by suppression — easier to read than highlighting by addition.
  • Stat counter eases with 1 - (1-t)³. Numbers slow as they approach the target. Linear counters feel mechanical; this lands.
// What I'd do differently
  • The FPS chart is simulated. A real implementation would measure actual frame deltas via requestAnimationFrame — different design problem, harder spikes to read.
  • The scatter has no zoom or focus state. Past 16 points the dots collide. The next version is brush-zoom — D3 has it, this didn't need it.
  • Force graph runs a fresh simulation on every page load. Production should serialize settled positions and start from rest — saves ~600ms of unsettled wiggling on first paint.
  • No keyboard navigation on any chart. Tab order skips them entirely. Charts are interactive UI; they need keyboard equivalents or they fail an audit.
// PALETTE