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.

インストールへ移動

ソース情報

リポジトリ
tomevault-io/claude-code-plugins
ソースの最終更新活動
2026年4月6日 08:18
検出された SKILL.md の言語
英語
スター
3
フォーク
2

インストール方法

デフォルトでは、最初にソースを確認する Prompt が選択されています。直接コマンドに切り替えるか、ローカルコピーをダウンロードすることもできます。

ソースファイルを確認

インストールを決める前に、SKILL.md と SkillsMP に表示されている付属ファイルをお読みください。

SKILL.md を表示中

SKILL.md
ソースの指示 · 読み取り専用プレビュー
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)
GitHubで見る
この SKILL.md は非常に大きいため、SkillsMP では最初のセクションだけを表示しています。 GitHubで見る