ai-infrastructure-hugg…
Hugging Face Inference SDK patterns for TypeScript/Node.js — InferenceClient setup, chat completion, text generation, streaming,…
D3.js data visualization — selections, data joins, scales, axes, shapes, transitions, force layouts, geo projections, framework integration
Claude Code
$ npx -y skills add agents-inc/skills --skill web-dataviz-d3 --agent claude-code
Codex
$ npx skills add agents-inc/skills --skill web-dataviz-d3 -a codex -y
Cursor
$ npx skills add agents-inc/skills --skill web-dataviz-d3 -a cursor -y
Gemini CLI
$ npx skills add agents-inc/skills --skill web-dataviz-d3 -a gemini-cli -y
GitHub Copilot
$ npx skills add agents-inc/skills --skill web-dataviz-d3 -a github-copilot -y
OpenCode
$ npx skills add agents-inc/skills --skill web-dataviz-d3 -a opencode -y
Windsurf
$ npx skills add agents-inc/skills --skill web-dataviz-d3 -a windsurf -y
name: web-dataviz-d3 description: D3.js data visualization — selections, data joins, scales, axes, shapes, transitions, force layouts, geo projections, framework integration
> **Quick Guide:** D3 v7 is pure ES modules, so import from the individual packages (`d3-selection`, `d3-scale`, `d3-shape`) rather than the `d3` bundle. `selection.join()` replaces manual enter/update/exit chains. Scales map a data domain to a visual range, axes render tick marks from a scale, and shape generators turn data arrays into SVG path strings. `d3-transition` extends the selection prototype by side effect, so `.transition()` does not exist until it is imported. The largest decision is who owns the DOM — D3, or the component framework around it.
**Detailed Resources:**
---
Two systems writing the same elements is the failure both branches avoid — pick one owner per SVG subtree.
---
<critical_requirements>
**Join data with `selection.join()`.** One call covers enter, update and exit, where the manual `enter().append().merge()` chain silently drops updates whenever `.merge()` is forgotten.
**Import from the individual modules — `d3-selection`, `d3-scale`, `d3-shape`.** `import * as d3 from "d3"` pulls 240KB+ of packages the chart never calls, and none of it tree-shakes.
**Pass a key function to `.data(array, key)` whenever elements have identity.** Without one D3 binds by index, so a sort or a removal re-binds every element to the wrong datum.
**Type selections and scales through their generics** — `Selection<SVGRectElement, Datum, ...>`, `ScaleLinear<number, number>`. D3's defaults widen to `any` at the first untyped `selectAll`, and the datum type is what makes accessor callbacks checkable.
</critical_requirements>
---
**Auto-detection:** d3, d3-selection, d3-scale, d3-shape, d3-axis, d3-transition, d3-force, d3-geo, d3-zoom, d3-brush, d3-drag, d3-array, d3-scale-chromatic, d3-hierarchy, selection.join, scaleLinear, scaleBand, scaleTime, scaleOrdinal, axisBottom, axisLeft, forceSimulation, forceManyBody, geoPath, geoMercator, curveMonotoneX, PieArcDatum, D3ZoomEvent
**Applies to:**
**Handled elsewhere:**
---
<philosophy>
D3 is a visualization grammar rather than a charting library: primitives for binding data to elements and deriving visual attributes from it. Maximum control, more code.
The pipeline is **select → bind → join → encode → annotate → animate**. Scales are the hinge — everything visual is a function of data through a scale, so a chart that hardcodes pixel arithmetic has skipped the one abstraction D3 exists to provide.
</philosophy>
---
<decision_framework>
Bar / line / area chart -> d3-selection, d3-scale, d3-axis, d3-shape, d3-array Pie / donut chart -> d3-shape (pie + arc), d3-scale Force-directed graph -> d3-force, d3-selection, d3-drag Geographic map -> d3-geo, d3-selection, d3-scale Animated updates -> d3-transition, d3-ease, d3-interpolate Zoom or brush -> d3-zoom or d3-brush, d3-selection Tree / treemap / pack -> d3-hierarchy, d3-selection
Scale-by-data-type is a lookup rather than a decision — see [reference.md](reference.md).
</decision_framework>
---
<patterns>
Bind an array to elements, then let `.join()` create, update and remove them as the array changes.
import { select } from "d3-selection";
select(svgElement)
.selectAll<SVGRectElement, BarData>("rect")
.data(data, (d) => d.id) // key function binds by identity, not index
.join("rect")
.attr("y", (_, i) => i * (BAR_HEIGHT + BAR_GAP))
.attr("width", (d) => xScale(d.value))
.attr("height", BAR_HEIGHT);`.join()` also ta
The official skills marketplace for Agents Inc. 230+ skills covering everything from React and Prisma to Redis, ElevenLabs, and infrastructure tooling. Pick the skills that match your stack and install them via Claude Code. Need more control?
Hugging Face Inference SDK patterns for TypeScript/Node.js — InferenceClient setup, chat completion, text generation, streaming,…
LiteLLM proxy server setup, TypeScript client patterns via OpenAI SDK, model routing, fallbacks, load balancing, spend tracking,…
Serverless GPU compute platform for AI model deployment — web endpoints, GPU functions, model serving, and TypeScript client…
Local LLM inference with the Ollama JavaScript client -- chat, streaming, tool calling, vision, embeddings, structured output,…
Replicate SDK patterns for TypeScript/Node.js -- client setup, predictions, streaming, webhooks, file handling, model versioning,…
Together AI SDK patterns for TypeScript — client setup, chat completions, streaming, structured output, function calling,…
You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…
Ask which skill or flow fits your situation. A router over the skills in this repo.