d3js-visualization

安装量: 55
排名: #13432

安装

npx skills add https://github.com/bbeierle12/skill-mcp-claude --skill d3js-visualization

D3.js Visualization Core Concepts Selection and Data Binding // Select elements const svg = d3.select('#chart') .append('svg') .attr('width', width) .attr('height', height);

// Bind data to elements svg.selectAll('rect') .data(data) .join('rect') .attr('x', (d, i) => i * barWidth) .attr('y', d => height - scale(d.value)) .attr('width', barWidth - 1) .attr('height', d => scale(d.value));

Scales // Linear scale (continuous → continuous) const xScale = d3.scaleLinear() .domain([0, d3.max(data, d => d.value)]) .range([0, width]);

// Band scale (discrete → continuous) const xScale = d3.scaleBand() .domain(data.map(d => d.name)) .range([0, width]) .padding(0.1);

// Time scale const xScale = d3.scaleTime() .domain([startDate, endDate]) .range([0, width]);

// Color scale const colorScale = d3.scaleOrdinal(d3.schemeCategory10);

Axes // Create axes const xAxis = d3.axisBottom(xScale); const yAxis = d3.axisLeft(yScale);

// Append to SVG svg.append('g') .attr('class', 'x-axis') .attr('transform', translate(0, ${height})) .call(xAxis);

svg.append('g') .attr('class', 'y-axis') .call(yAxis);

Common Chart Types Bar Chart function createBarChart(data, container, options = {}) { const { width = 600, height = 400, margin = { top: 20, right: 20, bottom: 30, left: 40 } } = options;

const innerWidth = width - margin.left - margin.right; const innerHeight = height - margin.top - margin.bottom;

const svg = d3.select(container) .append('svg') .attr('width', width) .attr('height', height);

const g = svg.append('g') .attr('transform', translate(${margin.left},${margin.top}));

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

const yScale = d3.scaleLinear() .domain([0, d3.max(data, d => d.value)]) .nice() .range([innerHeight, 0]);

// Bars g.selectAll('.bar') .data(data) .join('rect') .attr('class', 'bar') .attr('x', d => xScale(d.name)) .attr('y', d => yScale(d.value)) .attr('width', xScale.bandwidth()) .attr('height', d => innerHeight - yScale(d.value)) .attr('fill', 'steelblue');

// Axes g.append('g') .attr('transform', translate(0,${innerHeight})) .call(d3.axisBottom(xScale));

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

return svg.node(); }

Line Chart function createLineChart(data, container, options = {}) { const { width = 600, height = 400, margin = { top: 20, right: 20, bottom: 30, left: 40 } } = options;

const innerWidth = width - margin.left - margin.right; const innerHeight = height - margin.top - margin.bottom;

const svg = d3.select(container) .append('svg') .attr('width', width) .attr('height', height);

const g = svg.append('g') .attr('transform', translate(${margin.left},${margin.top}));

const xScale = d3.scaleTime() .domain(d3.extent(data, d => d.date)) .range([0, innerWidth]);

const yScale = d3.scaleLinear() .domain([0, d3.max(data, d => d.value)]) .nice() .range([innerHeight, 0]);

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

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

// Dots g.selectAll('.dot') .data(data) .join('circle') .attr('class', 'dot') .attr('cx', d => xScale(d.date)) .attr('cy', d => yScale(d.value)) .attr('r', 4) .attr('fill', 'steelblue');

// Axes g.append('g') .attr('transform', translate(0,${innerHeight})) .call(d3.axisBottom(xScale));

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

return svg.node(); }

Pie/Donut Chart function createPieChart(data, container, options = {}) { const { width = 400, height = 400, innerRadius = 0, // 0 for pie, > 0 for donut } = options;

const radius = Math.min(width, height) / 2;

const svg = d3.select(container) .append('svg') .attr('width', width) .attr('height', height);

const g = svg.append('g') .attr('transform', translate(${width / 2},${height / 2}));

const color = d3.scaleOrdinal(d3.schemeCategory10);

const pie = d3.pie() .value(d => d.value) .sort(null);

const arc = d3.arc() .innerRadius(innerRadius) .outerRadius(radius - 10);

const arcs = g.selectAll('.arc') .data(pie(data)) .join('g') .attr('class', 'arc');

arcs.append('path') .attr('d', arc) .attr('fill', d => color(d.data.name));

arcs.append('text') .attr('transform', d => translate(${arc.centroid(d)})) .attr('text-anchor', 'middle') .text(d => d.data.name);

return svg.node(); }

Interactivity Tooltips // Create tooltip const tooltip = d3.select('body') .append('div') .attr('class', 'tooltip') .style('position', 'absolute') .style('visibility', 'hidden') .style('background', 'white') .style('padding', '10px') .style('border-radius', '4px') .style('box-shadow', '0 2px 4px rgba(0,0,0,0.2)');

// Add to elements bars.on('mouseover', function(event, d) { tooltip .style('visibility', 'visible') .html(<strong>${d.name}</strong><br/>Value: ${d.value}); }) .on('mousemove', function(event) { tooltip .style('top', (event.pageY - 10) + 'px') .style('left', (event.pageX + 10) + 'px'); }) .on('mouseout', function() { tooltip.style('visibility', 'hidden'); });

Transitions // Animate on data update bars.transition() .duration(750) .attr('y', d => yScale(d.value)) .attr('height', d => innerHeight - yScale(d.value));

// Staggered animation bars.transition() .delay((d, i) => i * 50) .duration(500) .attr('opacity', 1);

Zoom and Pan const zoom = d3.zoom() .scaleExtent([1, 8]) .on('zoom', (event) => { g.attr('transform', event.transform); });

svg.call(zoom);

Best Practices Performance Use join() instead of enter/update/exit for cleaner code Throttle resize handlers Use CSS for simple styling Avoid excessive DOM updates Accessibility Add aria-label to SVG Use role="img" for decorative charts Provide data tables as alternatives Ensure sufficient color contrast Data Formatting // Parse dates const parseDate = d3.timeParse('%Y-%m-%d'); data.forEach(d => { d.date = parseDate(d.dateString); });

// Format numbers const formatNumber = d3.format(',.0f'); const formatCurrency = d3.format('$,.2f'); const formatPercent = d3.format('.1%');

返回排行榜