Design and build mathematically rigorous, high-density, interactive data graphics and streaming telemetry visualizations following Mike Bostock's D3.js and Observable methodologies. Use when crafting custom SVG/Canvas charts, reactive streaming time-series, multi-dimensional brush-and-link coordinates, small multiples, or topological swarm graphs. NOT for generic dashboard template clones, basic spreadsheet charts, or off-the-shelf low-effort wrapper libraries.
Pro scans all 5 files and shows the line behind each finding
Scanned 9/24/2026
npx -y skills add curiositech/port-daddy --skill bostockesque-data-viz --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Bostockesque Data Viz?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/curiositech-bostockesque-data-viz)More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.
---
license: Apache-2.0
name: bostockesque-data-viz
description: Design and build mathematically rigorous, high-density, interactive data graphics and streaming telemetry visualizations following Mike Bostock's D3.js and Observable methodologies. Use when crafting custom SVG/Canvas charts, reactive streaming time-series, multi-dimensional brush-and-link coordinates, small multiples, or topological swarm graphs. NOT for generic dashboard template clones, basic spreadsheet charts, or off-the-shelf low-effort wrapper libraries.
allowed-tools: Read,Write,Edit,Bash,Grep,Glob
argument-hint: '[graphic-type: streaming|small-multiples|interactive|topological] [tech: svg|canvas|hybrid]'
metadata:
category: Data & Visualization
tags:
- data-viz
- d3
- bostock
- observable
- svg
- canvas
- epistemic-clarity
- streaming
provenance:
kind: first-party
owners:
- port-daddy
pairs-with:
- skill: data-viz-2025
reason: High-performance WebGL/Canvas rendering patterns and GPU shaders
- skill: data-viz-commercials
reason: High-impact narrative framing and animation pacing
- skill: algebraic-topology-for-agents
reason: Direct consumer of simplicial and sheaf cochain visual graph layouts
---
# Bostockesque Data Visualization: Epistemic Graphic Design
Visualizations are visual proofs and thinking engines, not marketing decorations. Every geometric mark, line segment, hue, and spatial coordinate must correspond to a verifiable invariant in the underlying data.
## Philosophy
**Great graphics are progressive disclosure machines grounded in perceptual psychophysics.** They adhere to William Playfair, Jacques Bertin, John Tukey, and Edward Tufte's foundational truth: *the visual representation must maximize the data-ink ratio while preserving structural integrity*. Following Mike Bostock's D3.js and Observable architecture, graphics separate data transformations from visual representations, employ canonical coordinate systems, and update reactively with zero DOM thrashing.
```
Three-Layer Architecture:
Layer 1: Metadata & Frontmatter (Instant activation & capability matching)
Layer 2: Lean SKILL.md (Decision trees, failure modes, shibboleths, quality gates)
Layer 3: Progressive References (Lazy-loaded streaming algorithms & perceptual rules)
```
## Decision Points
### Action Branch Selection
```
Query analysis:
├─ Contains "stream" OR "real-time" OR "telemetry" → STREAMING path
├─ Contains "facet" OR "multi-series" OR "compare" → SMALL-MULTIPLES path
├─ Contains "brush" OR "zoom" OR "link" OR "hover" → INTERACTION path
├─ Contains "simplicial" OR "topology" OR "network" → TOPOLOGICAL path
└─ General or static chart request → ENCODING path
```
### Technology Selection Tree
```
Element count & update frequency:
├─ Total marks N < 5,000 & interactive DOM needed → Pure SVG (D3 Selection)
├─ 5,000 <= N < 100,000 OR update rate >= 30fps → HTML5 Canvas 2D
├─ N >= 100,000 OR dense particle vector fields → WebGL / WebGPU
└─ High element count with SVG axis/labels → Hybrid (Canvas data layer + SVG overlay)
```
### Perceptual Encoding Hierarchy (Cleveland & McGill)
```
Visual channel priority:
├─ Quantitative Data:
│ ├─ 1. Position along a common scale (Scatter, dot plot, aligned bar)
│ ├─ 2. Position along non-aligned scales (Small multiples)
│ ├─ 3. Length (Bar chart with zero baseline)
│ ├─ 4. Direction / Slope (Line chart, sparkline)
│ ├─ 5. Angle (Use sparingly; avoid pie charts)
│ ├─ 6. Area (Bubble chart; scale radius by sqrt(value))
│ └─ 7. Color luminance / saturation (Sequential heatmaps)
└─ Nominal / Categorical Data:
├─ 1. Spatial grouping / Faceting
├─ 2. Distinct hue (Max 5-7 perceptually distinguishable categories)
└─ 3. Symbol / Shape (Secondary cue only)
```
### Visual Workflow Architecture
```mermaid
flowchart TD
A[Data Stream or Dataset] --> B{Data Points Count N?}
B -->|N < 5,000| C[SVG via DOM / D3]
B -->|5,000 <= N < 100,000| D[HTML5 Canvas 2D]
B -->|N >= 100,000| E[WebGL / WebGPU]
C --> F{Series Count K?}
F -->|K <= 3| G[Single Viewport with Monochromatic Lines]
F -->|K > 3| H[Small Multiples Grid with Shared Scales]
G --> I[Apply Canonical Margin Convention]
H --> I
I --> J[Render with Responsive viewBox]
J --> K[Bind Brush & Hover Interaction via Voronoi/Quadtree]
```
## Failure Modes
### DOM Node Thrashing
- **Detection**: Framerate drops below 30fps; browser devtools show massive Garbage Collection pauses during telemetry ingestion.
- **Symptoms**: High CPU usage, unresponsive UI, micro-stutters during zoom/pan.
- **Fix**: Replace full SVG recreation (`svg.selectAll('*').remove()`) with idiomatic D3 data joins (`selection.join(enter, update, exit)`) or migrate the data layer to HTML5 Canvas.
- **Timeline**: Chronic issue since early D3 v3 days (2012); solved in D3 v5+ by `selection.join()`.
### Rainbow Palette Banding
- **Detection**: Grayscale conversion reveals false contrast edges; color ramp contains `jet`, `rainbow`, or uncalibrated RGB interpolations.
- **Symptoms**: Viewers perceive sharp boundaries where data is continuously smooth; colorblind users cannot interpret rankings.
- **Fix**: Use monotonic luminance colormaps (`d3.interpolateViridis`, `d3.interpolateCividis`, or Swiss neutral grays with single-accent alert hues).
- **Timeline**: Formalized by Borland & Taylor (2007) and made standard by viridis in 2015.
### Spaghetti Series Occlusion
- **Detection**: Single coordinate frame contains $>5$ intersecting colored line series.
- **Symptoms**: Lines obscure each other, legends require constant eye scanning, trends are impossible to isolate.
- **Fix**: Decompose into a small-multiples grid with synchronized X and Y axes, displaying the target series in foreground and a muted aggregate swarm in the background.
- **Timeline**: Championed by Edward Tufte (1983) and formalized by Mike Bostock in Observable (2018).
### Viewport Margin Clipping
- **Detection**: Axis tick numbers, labels, or edge data points are chopped off by SVG container bounds.
- **Symptoms**: Unreadable axis values, broken layout on mobile or varying container widths.
- **Fix**: Enforce the Canonical Margin Convention with outer dimensions, inner margins, and responsive SVG `viewBox`.
- **Timeline**: Standardized by Mike Bostock in 2012 (`margin = {top, right, bottom, left}`).
### Unbounded Memory Growth in Streaming
- **Detection**: Memory footprint grows linearly over time; browser tab crashes after hours of telemetry monitoring.
- **Symptoms**: Gradual slowdown, page freezing, OOM crash in long-running dashboards.
- **Fix**: Implement a fixed-capacity circular ring buffer (`Float64Array` or bounded array splice) that retains only the active temporal window.
- **Timeline**: Core requirement for 24/7 industrial and agentic monitoring dashboards.
## Shibboleths / Anti-Patterns
### Rainbow Palette Fallacy
- **Novice**: Uses `rainbow` or `jet` color maps thinking multi-colored graphics look more "scientific" and vibrant.
- **Expert**: Rainbow palettes have non-monotonic luminance gradients that create false edges, band artifacts, and optical illusions. Uses monotonic luminance scales (Viridis, Cividis) where equal data differences map to equal perceptual differences across all viewers.
- **Timeline**: Established by Borland & Taylor (2007) and adopted across ACM/IEEE visualization standards.
### Spaghetti Chart Collapse
- **Novice**: Plots 15 overlapping colored lines on a single 400px chart and attaches an enormous legend.
- **Expert**: Facets into an array of synchronized small multiples with shared X/Y scales and a faint background swarm baseline, eliminating cognitive legend-lookup overhead.
- **Timeline**: Championed by Edward Tufte (1983) and formalized in D3 small multiples by Mike Bostock (2012).
### Truncated Bar Chart Baseline
- **Novice**: Truncates the zero baseline of a bar chart to exaggerate small percentage differences.
- **Expert**: Bar lengths encode quantity by area and length; truncating the baseline distorts the physical ratio. Uses point plots or dot charts for interval data, and strictly reserves zero-anchored bars for ratio data.
- **Timeline**: Foundational visual ethics codified by Darrell Huff (1954) and Tufte (1983).
### Imperative Mutation vs Declarative Join
- **Novice**: Clears container with `element.innerHTML = ''` on every update and redraws everything from scratch.
- **Expert**: Leverages D3's declarative `selection.join(enter => ..., update => ..., exit => ...)` to morph existing DOM nodes with smooth tweening transitions, preserving state and performance.
- **Timeline**: Introduced in D3 v5 (2018) to replace the error-prone enter/update/exit pattern.
## Worked Examples
### Example 1: Real-time Multi-Agent Telemetry Stream
**User request**: "Build a live streaming dashboard showing completion residual $r(t)$ for 5 agents updating at 10Hz."
**Step 1 - Determine Architecture**:
- 10Hz update rate over 10 minutes = 6,000 points.
- Element count fits Canvas or optimized SVG. Choose SVG with Canonical Margin Convention for sharp crisp vectors and easy styling.
- Buffer: Fixed capacity ring buffer of 300 samples (30 seconds window).
**Step 2 - Apply Canonical Margin Convention**:
```javascript
const margin = { top: 20, right: 30, bottom: 40, left: 50 };
const width = outerWidth - margin.left - margin.right;
const height = outerHeight - margin.top - margin.bottom;
const svg = d3.create("svg")
.attr("viewBox", [0, 0, outerWidth, outerHeight])
.attr("style", "max-width: 100%; height: auto; font: 12px sans-serif;");
const g = svg.append("g")
.attr("transform", `translate(${margin.left},${margin.top})`);
```
**Step 3 - Define Resilient Scales & Path Generator**:
```javascript
const x = d3.scaleTime().domain(d3.extent(buffer, d => d.timestamp)).range([0, width]);
const y = d3.scaleLinear().domain([0, d3.max(buffer, d => d.residual) * 1.15]).range([height, 0]);
const line = d3.line()
.defined(d => !isNaN(d.residual))
.x(d => x(d.timestamp))
.y(d => y(d.residual))
.curve(d3.curveMonotoneX);
```
**Step 4 - Update via Keyed Join**:
Update the path `d` attribute smoothly without replacing the DOM hierarchy. Attach a subtle threshold guide line at $r_{\text{crit}} = 1.0$.
- **What novice would miss**: Recreating the entire SVG on every tick, causing memory leak and blinking UI; omitting `curveMonotoneX`, producing harsh jagged spikes.
- **What expert catches**: Ring buffer memory stability, responsive `viewBox`, monotonic scale clamping, and subtle opacity fill below the residual line.
### Example 2: Small Multiples Faceted Residuals
**User request**: "Compare the convergence trajectories of 8 different swarm topologies over 100 epochs."
**Step 1 - Decomposition**:
Avoid the spaghetti plot trap. Compute global domain across all 8 topologies: $x \in [0, 100]$, $y \in [0, \max(r)]$.
**Step 2 - Grid Dimensioning**:
Create a 4x2 small multiples grid. Each cell gets identical inner dimensions (width: 180, height: 120) and identical scale domains so visual slopes are directly comparable.
**Step 3 - Visual Layering**:
- Background layer in every cell: Render all 8 runs in ultra-light muted gray (`#e5e7eb`, opacity 0.35) as context.
- Foreground layer in each cell: Render the specific topology in crisp dark indigo (`#1e1b4b`, stroke width 2).
**Step 4 - Direct Labeling**:
Title each small multiple cell directly with its topology name and final residual $r(100)$, eliminating external legend lookups.
- **What novice would miss**: Different Y-axis scales per subplot (making calm runs look volatile and volatile runs look calm); external legend requiring 8 color lookups.
- **What expert catches**: Common unified scales across all subplots, background contextual swarm silhouette, zero-overhead direct labeling.
### Example 3: Linked Quadtree Brush on Simplicial Complex & Time-Series
**User request**: "Build an interactive complex viewer where dragging a brush on the timeline highlights the active AST locks on the topological network."
**Step 1 - Data Coordination**:
Expose a shared reactive state `selectedInterval = [t0, t1]`.
**Step 2 - Timeline Brush**:
```javascript
const brush = d3.brushX()
.extent([[0, 0], [width, height]])
.on("brush end", ({ selection }) => {
if (!selection) return;
const [t0, t1] = selection.map(xScale.invert);
dispatch.call("timeChange", null, { t0, t1 });
});
```
**Step 3 - Network Highlighting**:
Simplicial complex nodes have AST lock intervals. Listen to `timeChange`:
```javascript
dispatch.on("timeChange", ({ t0, t1 }) => {
nodes.classed("active-lock", d => d.lockStart <= t1 && d.lockEnd >= t0);
edges.classed("contested", d => d.hasContention(t0, t1));
});
```
- **What novice would miss**: Quadratic DOM lookups on every mousemove event without debounce or quadtree indexing.
- **What expert catches**: Decoupled event dispatcher (`d3.dispatch`), CSS class toggle rather than inline attribute manipulation, and crisp visual feedback.
## Quality Gates
- [ ] `SKILL.md` exists and is under 500 lines.
- [ ] Frontmatter contains required `name` and `description` fields adhering to `[What][When to use] NOT [Exclusions]`.
- [ ] At least 3 temporal anti-patterns using Novice/Expert/Timeline template.
- [ ] All file references in `SKILL.md` actually exist on disk in the skill directory.
- [ ] Visual workflow diagram uses valid Mermaid syntax.
- [ ] Canonical Margin Convention strictly adhered to in all SVG examples.
- [ ] Color scales avoid rainbow/jet and enforce monotonic luminance (Viridis/Cividis or Swiss neutral).
- [ ] 5 positive trigger test queries pass.
- [ ] 5 negative trigger test queries pass.
### Activation Test Suite
**Positive Queries (Must Activate)**:
1. "Design an interactive D3 SVG streaming chart for our agent telemetry."
2. "Build a small multiples grid to compare multi-agent swarm convergence metrics."
3. "Create a high-density Bostock-style data visualization for topological residuals."
4. "How do I implement a brush-and-link interactive chart with D3 margin conventions?"
5. "Visualize a 2D simplicial complex with reactive AST lock states in SVG/Canvas."
**Negative Queries (Must NOT Activate)**:
1. "How do I format an Excel spreadsheet bar chart?" (Use standard office tools)
2. "Build a standard React Admin dashboard using Material UI template." (Use `admin-dashboard`)
3. "Write an automated Playwright test for user login." (Use `playwright-e2e-tester`)
4. "Rent an A100 GPU cluster on Vast.ai." (Use `vast-ai-gpu-clusters`)
5. "Solve the simplicial boundary matrix in Python." (Use `algebraic-topology-for-agents`)
## References & Progressive Disclosure
Read these reference files only when the specific domain context demands deep technical execution:
| File | Load When | Why |
|---|---|---|
| `references/d3-streaming-recipes.md` | Handling live streams, animations, or sliding windows | Provides `selection.join()`, circular ring buffers, and smooth transitions |
| `references/epistemic-design-rules.md` | Choosing visual encodings, layout, or color maps | Cleveland-McGill perceptual accuracy rankings and small-multiples guidelines |
## NOT-FOR Boundaries
**This skill should NOT be used for**:
- Generic enterprise BI dashboards or off-the-shelf template clones (e.g. standard Metabase/Tableau/AdminLTE).
- Low-effort black-box wrapper libraries (e.g., vanilla Chart.js, highcharts) when precision mathematical control is needed.
- Static spreadsheet charts or PowerPoint graphic styling.
- Purely non-visual backend data pipelines without rendering requirements.
**Delegate to these skills instead**:
- For high-performance WebGL/WebGPU shaders & large particle meshes → `data-viz-2025`
- For commercial pitch deck framing & motion narrative → `data-viz-commercials`
- For algebraic topology derivations & boundary operator solves → `algebraic-topology-for-agents`
- For full-stack application data dashboard scaffolding → `building-data-apps`
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!