d3-visualization

mattleonard16's avatarfrom mattleonard16

Create sophisticated, interactive data visualizations using D3.js. Use for custom charts, network visualizations, or when Recharts/charting libraries are insufficient.

⭐0stars🔀0forks📁View on GitHub🕐Updated Dec 29, 2025⬇️4downloads

When & Why to Use This Skill

The D3.js Visualization skill enables the creation of sophisticated, interactive, and highly customized data visualizations. It is designed for scenarios where standard charting libraries are insufficient, providing deep control over SVG, Canvas, and HTML to build complex network graphs, geographic maps, and fluid, choreographed transitions for professional data storytelling.

Use Cases

  • Developing custom network and hierarchy visualizations using force-directed layouts to represent complex data relationships.
  • Creating interactive geographic visualizations and maps with custom projections for spatial and demographic data analysis.
  • Building high-performance data dashboards that require unique visual encodings and the ability to handle large datasets efficiently.
  • Designing publication-quality interactive charts with fine-grained styling and smooth transitions for engaging data presentations.
  • Implementing advanced user interactions such as complex panning, zooming, and brushing for deep data exploration.
named3-visualization
descriptionCreate sophisticated, interactive data visualizations using D3.js. Use for custom charts, network visualizations, or when Recharts/charting libraries are insufficient.

D3.js Visualization Skill

This skill provides guidance for creating sophisticated, interactive data visualizations using D3.js.

When to Use D3.js

Use D3.js for:

  • Custom visualizations requiring unique visual encodings or layouts
  • Interactive explorations with complex pan, zoom, or brush behaviors
  • Network/graph visualizations (force-directed layouts, tree diagrams, hierarchies)
  • Geographic visualizations with custom projections
  • Visualizations requiring smooth, choreographed transitions
  • Publication-quality graphics with fine-grained styling control

Consider alternatives for:

  • Standard charts (bar, line, pie) → Use Recharts (already in your stack)
  • 3D visualizations → Use Three.js
  • Simple dashboards → Use your existing Recharts components

Core Workflow

1. Set Up D3.js

import * as d3 from 'd3';

2. Structure the Visualization Code

function drawVisualization(data, svgElement) {
  if (!data || data.length === 0) return;

  const svg = d3.select(svgElement);
  svg.selectAll("*").remove(); // Clear previous render

  // 1. Define dimensions
  const width = 800;
  const height = 400;
  const margin = { top: 20, right: 30, bottom: 40, left: 50 };
  const innerWidth = width - margin.left - margin.right;
  const innerHeight = height - margin.top - margin.bottom;

  // 2. Create main group with margins
  const g = svg.append("g")
    .attr("transform", `translate(${margin.left},${margin.top})`);

  // 3. Create scales
  const xScale = d3.scaleLinear()
    .domain([0, d3.max(data, d => d.x)])
    .range([0, innerWidth]);

  const yScale = d3.scaleLinear()
    .domain([0, d3.max(data, d => d.y)])
    .range([innerHeight, 0]); // Inverted for SVG coordinates

  // 4. Create and append axes
  g.append("g")
    .attr("transform", `translate(0,${innerHeight})`)
    .call(d3.axisBottom(xScale));

  g.append("g")
    .call(d3.axisLeft(yScale));

  // 5. Bind data and create visual elements
  g.selectAll("circle")
    .data(data)
    .join("circle")
    .attr("cx", d => xScale(d.x))
    .attr("cy", d => yScale(d.y))
    .attr("r", 5)
    .attr("fill", "steelblue");
}

3. Implement Responsive Sizing

function setupResponsiveChart(containerId, data) {
  const container = document.getElementById(containerId);
  const svg = d3.select(`#${containerId}`).append('svg');

  function updateChart() {
    const { width, height } = container.getBoundingClientRect();
    svg.attr('width', width).attr('height', height);
    drawChart(data, svg, width, height);
  }

  updateChart();
  window.addEventListener('resize', updateChart);
  return () => window.removeEventListener('resize', updateChart);
}

Common Patterns

Bar Chart

const xScale = d3.scaleBand()
  .domain(data.map(d => d.category))
  .range([0, innerWidth])
  .padding(0.1);

g.selectAll("rect")
  .data(data)
  .join("rect")
  .attr("x", d => xScale(d.category))
  .attr("y", d => yScale(d.value))
  .attr("width", xScale.bandwidth())
  .attr("height", d => innerHeight - yScale(d.value))
  .attr("fill", "steelblue");

Line Chart

const line = d3.line()
  .x(d => xScale(d.date))
  .y(d => yScale(d.value))
  .curve(d3.curveMonotoneX);

g.append("path")
  .datum(data)
  .attr("fill", "none")
  .attr("stroke", "steelblue")
  .attr("stroke-width", 2)
  .attr("d", line);

Best Practices

Data Preparation

const cleanData = data.filter(d => d.value != null && !isNaN(d.value));
const sortedData = [...data].sort((a, b) => b.value - a.value);

Accessibility

svg.attr("role", "img")
   .attr("aria-label", "Bar chart showing quarterly revenue");

svg.append("title").text("Quarterly Revenue 2024");

Consistent Styling

const colours = {
  primary: '#4A90E2',
  secondary: '#7B68EE',
  background: '#F5F7FA',
  text: '#333333',
  gridLines: '#E0E0E0'
};

svg.selectAll("text")
  .style("font-family", "Inter, sans-serif")
  .style("font-size", "12px");

Performance (>1000 elements)

  • Use canvas instead of SVG for many elements
  • Use quadtree for collision detection
  • Simplify paths with d3.line().curve(d3.curveStep)
  • Implement virtual scrolling for large lists