Skip to main content

d3-viz

Creating interactive data visualisations using d3.js. This skill should be used when creating custom charts, graphs, network diagrams, geographic visualisations, or any complex SVG-based data visualisation that requires fine-grained control over visual elements, transitions, or interactions. Use this for bespoke visualisations beyond standard charting libraries, whether in React, Vue, Svelte, vanilla JavaScript, or any other environment.

Ir a la instalación

Datos de origen

Repositorio
tomevault-io/claude-code-plugins
Última actividad en el origen
6 de abril de 2026 a las 08:18
Idioma detectado de SKILL.md
inglés
Estrellas
3
Forks
2

Opciones de instalación

De forma predeterminada está seleccionado el prompt que primero revisa el origen. Puedes cambiar a un comando directo o descargar una copia local.

Revisa los archivos de origen

Lee SKILL.md y los archivos complementarios que muestra SkillsMP antes de decidir si quieres instalarlo.

Mostrando SKILL.md

SKILL.md
Instrucciones de origen · Vista previa de solo lectura
name
d3-viz
description
Creating interactive data visualisations using d3.js. This skill should be used when creating custom charts, graphs, network diagrams, geographic visualisations, or any complex SVG-based data visualisation that requires fine-grained control over visual elements, transitions, or interactions. Use this for bespoke visualisations beyond standard charting libraries, whether in React, Vue, Svelte, vanilla JavaScript, or any other environment.
# D3.js Visualisation ## Overview This skill provides guidance for creating sophisticated, interactive data visualisations using d3.js. D3.js (Data-Driven Documents) excels at binding data to DOM elements and applying data-driven transformations to create custom, publication-quality visualisations with precise control over every visual element. The techniques work across any JavaScript environment, including vanilla JavaScript, React, Vue, Svelte, and other frameworks. ## When to use d3.js **Use d3.js for:** - Custom visualisations requiring unique visual encodings or layouts - Interactive explorations with complex pan, zoom, or brush behaviours - Network/graph visualisations (force-directed layouts, tree diagrams, hierarchies, chord diagrams) - Geographic visualisations with custom projections - Visualisations requiring smooth, choreographed transitions - Publication-quality graphics with fine-grained styling control - Novel chart types not available in standard libraries **Consider alternatives for:** - 3D visualisations - use Three.js instead ## Core workflow ### 1. Set up d3.js Import d3 at the top of your script: ```javascript import * as d3 from 'd3'; ``` Or use the CDN version (7.x): ```html <script src="https://d3js.org/d3.v7.min.js"></script> ``` All modules (scales, axes, shapes, transitions, etc.) are accessible through the `d3` namespace. ### 2. Choose the integration pattern **Pattern A: Direct DOM manipulation (recommended for most cases)** Use d3 to select DOM elements and manipulate them imperatively. This works in any JavaScript environment: ```javascript function drawChart(data) { if (!data || data.length === 0) return; const svg = d3.select('#chart'); // Select by ID, class, or DOM element // Clear previous content svg.selectAll("*").remove(); // Set up dimensions const width = 800; const height = 400; const margin = { top: 20, right: 30, bottom: 40, left: 50 }; // Create scales, axes, and draw visualisation // ... d3 code here ... } // Call when data changes drawChart(myData); ``` **Pattern B: Declarative rendering (for frameworks with templating)** Use d3 for data calculations (scales, layouts) but render elements via your framework: ```javascript function getChartElements(data) { const xScale = d3.scaleLinear() .domain([0, d3.max(data, d => d.value)]) .range([0, 400]); return data.map((d, i) => ({ x: 50, y: i * 30, width: xScale(d.value), height: 25 })); } // In React: {getChartElements(data).map((d, i) => <rect key={i} {...d} fill="steelblue" />)} // In Vue: v-for directive over the returned array // In vanilla JS: Create elements manually from the returned data ``` Use Pattern A for complex visualisations with transitions, interactions, or when leveraging d3's full capabilities. Use Pattern B for simpler visualisations or when your framework prefers declarative rendering. ### 3. Structure the visualisation code Follow this standard structure in your drawing function: ```javascript function drawVisualization(data) { if (!data || data.length === 0) return; const svg = d3.select('#chart'); // Or pass a selector/element 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]); // Note: inverted for SVG coordinates // 4. Create and append axes const xAxis = d3.axisBottom(xScale); const yAxis = d3.axisLeft(yScale); g.append("g") .attr("transform", `translate(0,${innerHeight})`) .call(xAxis); g.append("g") .call(yAxis); // 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"); } // Call when data changes drawVisualization(myData); ``` ### 4. Implement responsive sizing Make visualisations responsive to container size: ```javascript 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); // Redraw visualisation with new dimensions drawChart(data, svg, width, height); } // Update on initial load updateChart(); // Update on window resize window.addEventListener('resize', updateChart); // Return cleanup function return () => window.removeEventListener('resize', updateChart); } // Usage: // const cleanup = setupResponsiveChart('chart-container', myData); // cleanup(); // Call when component unmounts or element removed ``` Or use ResizeObserver for more direct container monitoring: ```javascript function setupResponsiveChartWithObserver(svgElement, data) { const observer = new ResizeObserver(() => { const { width, height } = svgElement.getBoundingClientRect(); d3.select(svgElement) .attr('width', width) .attr('height', height); // Redraw visualisation drawChart(data, d3.select(svgElement), width, height); }); observer.observe(svgElement.parentElement); return () => observer.disconnect(); } ``` ## Common visualisation patterns ### Bar chart ```javascript function drawBarChart(data, svgElement) { if (!data || data.length === 0) return; const svg = d3.select(svgElement); svg.selectAll("*").remove(); 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; const g = svg.append("g") .attr("transform", `translate(${margin.left},${margin.top})`); const xScale = d3.scaleBand() .domain(data.map(d => d.category)) .range([0, innerWidth]) .padding(0.1); const yScale = d3.scaleLinear() .domain([0, d3.max(data, d => d.value)]) .range([innerHeight, 0]); g.append("g") .attr("transform", `translate(0,${innerHeight})`) .call(d3.axisBottom(xScale)); g.append("g") .call(d3.axisLeft(yScale)); 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"); } // Usage: // drawBarChart(myData, document.getElementById('chart')); ``` ### Line chart ```javascript const line = d3.line() .x(d => xScale(d.date)) .y(d => yScale(d.value)) .curve(d3.curveMonotoneX); // Smooth curve g.append("path") .datum(data) .attr("fill", "none") .attr("stroke", "steelblue") .attr("stroke-width", 2) .attr("d", line); ``` ### Scatter plot ```javascript g.selectAll("circle") .data(data) .join("circle") .attr("cx", d => xScale(d.x)) .attr("cy", d => yScale(d.y)) .attr("r", d => sizeScale(d.size)) // Optional: size encoding .attr("fill", d => colourScale(d.category)) // Optional: colour encoding .attr("opacity", 0.7); ``` ### Chord diagram A chord diagram shows relationships between entities in a circular layout, with ribbons representing flows between them: ```javascript function drawChordDiagram(data) { // data format: array of objects with source, target, and value // Example: [{ source: 'A', target: 'B', value: 10 }, ...] if (!data || data.length === 0) return; const svg = d3.select('#chart'); svg.selectAll("*").remove(); const width = 600; const height = 600; const innerRadius = Math.min(width, height) * 0.3; const outerRadius = innerRadius + 30; // Create matrix from data const nodes = Array.from(new Set(data.flatMap(d => [d.source, d.target]))); const matrix = Array.from({ length: nodes.length }, () => Array(nodes.length).fill(0)); data.forEach(d => { const i = nodes.indexOf(d.source); const j = nodes.indexOf(d.target); matrix[i][j] += d.value; matrix[j][i] += d.value; }); // Create chord layout const chord = d3.chord() .padAngle(0.05) .sortSubgroups(d3.descending); const arc = d3.arc() .innerRadius(innerRadius) .outerRadius(outerRadius); const ribbon = d3.ribbon() .source(d => d.source) .target(d => d.target); const colourScale = d3.scaleOrdinal(d3.schemeCategory10) .domain(nodes); const g = svg.append("g") .attr("transform", `translate(${width / 2},${height / 2})`); const chords = chord(matrix); // Draw ribbons g.append("g") .attr("fill-opacity", 0.67) .selectAll("path") .data(chords) .join("path") .attr("d", ribbon) .attr("fill", d => colourScale(nodes[d.source.index])) .attr("stroke", d => d3.rgb(colourScale(nodes[d.source.index])).darker()); // Draw groups (arcs) const group = g.append("g") .selectAll("g") .data(chords.groups) .join("g"); group.append("path") .attr("d", arc) .attr("fill", d => colourScale(nodes[d.index])) .attr("stroke", d => d3.rgb(colourScale(nodes[d.index])).darker()); // Add labels group.append("text") .each(d => { d.angle = (d.startAngle + d.endAngle) / 2; }) .attr("dy", "0.31em") .attr("transform", d => `rotate(${(d.angle * 180 / Math.PI) - 90})translate(${outerRadius + 30})${d.angle > Math.PI ? "rotate(180)" : ""}`) .attr("text-anchor", d => d.angle > Math.PI ? "end" : null)
Ver en GitHub
Este SKILL.md es muy grande, por eso SkillsMP muestra aqui solo la primera seccion. Ver en GitHub