home / skills / benchflow-ai / skillsbench / d3-visualization

This skill turns structured data into deterministic D3.js visualizations, producing standalone HTML/SVG outputs suitable for offline reports.

npx playbooks add skill benchflow-ai/skillsbench --skill d3-visualization

Review the files below or copy the command above to add this skill to your agents.

Files (5)
SKILL.md
6.1 KB
---
name: d3js-visualization
description: Build deterministic, verifiable data visualizations with D3.js (v6). Generate standalone HTML/SVG (and optional PNG) from local data files without external network dependencies. Use when tasks require charts, plots, axes/scales, legends, tooltips, or data-driven SVG output.
---

# D3.js Visualization Skill

Use this skill to turn structured data (CSV/TSV/JSON) into **clean, reproducible** visualizations using **D3.js**. The goal is to produce **stable outputs** that can be verified by diffing files or hashing.

## When to use

Activate this skill when the user asks for any of the following:

- “Make a chart/plot/graph/visualization”
- bar/line/scatter/area/histogram/box/violin/heatmap
- timelines, small multiples, faceting
- axis ticks, scales, legends, tooltips
- data-driven SVG output for a report or web page
- converting data to a static SVG or HTML visualization

If the user only needs a quick table or summary, **don’t** use D3—use a spreadsheet or plain markdown instead.

---

## Inputs you should expect

- One or more local data files: `*.csv`, `*.tsv`, `*.json`
- A chart intent:
  - chart type (or you infer the best type)
  - x/y fields and aggregation rules
  - sorting/filtering rules
  - dimensions (width/height) and margins
  - color rules (categorical / sequential)
  - any labeling requirements (title, axis labels, units)
- Output constraints:
  - “static only”, “no animation”, “must be deterministic”, “offline”, etc.

If details are missing, **make reasonable defaults** and document them in comments near the top of the output file.

---

## Outputs you should produce

Prefer producing **all of** the following when feasible:

1. `dist/chart.html` — standalone HTML that renders the visualization
2. `dist/chart.svg` — exported SVG (stable and diff-friendly)
3. (Optional) `dist/chart.png` — if the task explicitly needs a raster image

Always keep outputs in a predictable folder (default: `dist/`), unless the task specifies paths.

---

## Determinism rules (non-negotiable)

To keep results stable across runs and machines:

### Data determinism
- **Sort** input rows deterministically before binding to marks (e.g., by x then by category).
- Use stable grouping order (explicit `Array.from(grouped.keys()).sort()`).
- Avoid locale-dependent formatting unless fixed (use `d3.format`, `d3.timeFormat` with explicit formats).

### Rendering determinism
- **No randomness**: do not use `Math.random()` or `d3-random`.
- **No transitions/animations** by default (transitions can introduce timing variance).
- **Fixed** `width`, `height`, `margin`, `viewBox`.
- Use **explicit tick counts** only when needed; otherwise rely on D3 defaults but keep domains fixed.
- Avoid layout algorithms with non-deterministic iteration unless you control seeds/iterations (e.g., force simulation). If a force layout is required:
  - fix the tick count,
  - fix initial positions deterministically (e.g., sorted nodes placed on a grid),
  - run exactly N ticks and stop.

### Offline + dependency determinism
- Do **not** load D3 from a CDN.
- Pin D3 to a specific version (default: **[email protected]**).
- Prefer vendoring a minified D3 bundle (e.g., `vendor/d3.v7.9.0.min.js`) or bundling with a lockfile.

### File determinism
- Stable SVG output:
  - Avoid auto-generated IDs that may change.
  - If you must use IDs (clipPath, gradients), derive them from stable strings (e.g., `"clip-plot"`).
- Use LF line endings.
- Keep numeric precision consistent (e.g., round to 2–4 decimals if needed).

---

## Recommended project layout

If the task doesn't specify an existing structure, use:

```
dist/
  chart.html        # standalone HTML with inline or linked JS/CSS
  chart.svg         # exported SVG (optional but nice)
  chart.png         # rasterized (optional)
vendor/
  d3.v7.9.0.min.js  # pinned D3 library
```

---

## Interactive features (tooltips, click handlers, hover effects)

When the task requires interactivity (e.g., tooltips on hover, click to highlight):

### Tooltip pattern (recommended)

1. **Create a tooltip element** in HTML:
```html
<div id="tooltip" class="tooltip"></div>
```

2. **Style with CSS** using `.visible` class for show/hide:
```css
.tooltip {
    position: absolute;
    padding: 10px;
    background: rgba(0, 0, 0, 0.8);
    color: white;
    border-radius: 4px;
    pointer-events: none;  /* Prevent mouse interference */
    opacity: 0;
    transition: opacity 0.2s;
    z-index: 1000;
}

.tooltip.visible {
    opacity: 1;  /* Show when .visible class is added */
}
```

3. **Add event handlers** to SVG elements:
```javascript
svg.selectAll('circle')
    .on('mouseover', function(event, d) {
        d3.select('#tooltip')
            .classed('visible', true)  // Add .visible class
            .html(`<strong>${d.name}</strong><br/>${d.value}`)
            .style('left', (event.pageX + 10) + 'px')
            .style('top', (event.pageY - 10) + 'px');
    })
    .on('mouseout', function() {
        d3.select('#tooltip').classed('visible', false);  // Remove .visible class
    });
```

**Key points:**
- Use `opacity: 0` by default (not `display: none`) for smooth transitions
- Use `.classed('visible', true/false)` to toggle visibility
- `pointer-events: none` prevents tooltip from blocking mouse events
- Position tooltip relative to mouse with `event.pageX/pageY`

### Click handlers for selection/highlighting

```javascript
// Add 'selected' class on click
svg.selectAll('.bar')
    .on('click', function(event, d) {
        // Remove previous selection
        d3.selectAll('.bar').classed('selected', false);
        // Add to clicked element
        d3.select(this).classed('selected', true);
    });
```

CSS for highlighting:
```css
.bar.selected {
    stroke: #000;
    stroke-width: 3px;
}
```

### Conditional interactivity

Sometimes only certain elements should be interactive:
```javascript
.on('mouseover', function(event, d) {
    // Example: Don't show tooltip for certain categories
    if (d.category === 'excluded') {
        return;  // Exit early, no tooltip
    }
    // Show tooltip for others
    showTooltip(event, d);
})
```

---

Overview

This skill builds deterministic, verifiable data visualizations using D3.js (v6/v7-compatible patterns) and produces standalone HTML and SVG (optionally PNG) without external network dependencies. It focuses on stable, reproducible outputs that can be diffed or hashed for verification. The outputs are placed in a predictable dist/ folder and include inline comments documenting defaults.

How this skill works

The skill ingests local CSV/TSV/JSON files and a chart intent (type, fields, dimensions, color and aggregation rules) and generates a self-contained HTML file plus an exported SVG. It enforces determinism by sorting data, using fixed width/height/viewBox, avoiding randomness and transitions, and pinning a vendored D3 bundle. When needed it also includes deterministic grouping, stable IDs, and clear comments for any assumptions or defaults.

When to use it

  • Create bar, line, scatter, area, histogram, box/violin, heatmap, or timeline charts from local data files
  • Produce static, offline visualizations for reports or archival that must be diff-friendly and reproducible
  • Need SVG output for inclusion in documents or further processing (PDF/LaTeX pipelines)
  • Require axes, scales, legends, tooltips, faceting, or small multiples with deterministic layout
  • Convert structured data to a standalone HTML visualization without CDN dependencies

Best practices

  • Sort and group data deterministically (e.g., sort by x then category) before binding to marks
  • Pin D3 to a specific vendored version and include it in vendor/ (no CDN calls)
  • Keep fixed dimensions, viewBox, and avoid animations or random seeds unless explicitly controlled
  • Derive any IDs (clipPaths, gradients) from stable strings and keep numeric formatting consistent
  • Document reasonable defaults near the top of generated files and allow simple overrides via comments

Example use cases

  • Generate dist/chart.html and dist/chart.svg from monthly sales.csv for automated reporting
  • Produce a deterministic scatter plot from experiment.json that can be hashed for CI checks
  • Render small multiples (facets) for comparative dashboards exported as stable SVGs
  • Create a tooltip-enabled offline HTML for stakeholder review while ensuring outputs are reproducible
  • Convert a heatmap derived from local TSV into a standalone SVG for publication figures

FAQ

Can I include interactivity like tooltips?

Yes — tooltips and click handlers are supported, but interactivity is implemented deterministically (no transitions) and tooltip DOM/CSS patterns are included so outputs remain stable.

How do you guarantee the visualization is deterministic?

By sorting input rows, using stable grouping orders, avoiding randomness and animations, fixing dimensions, pinning the D3 bundle, and producing stable IDs and numeric precision in the output SVG/HTML.