引入D3库
<script src="https://d3js.org/d3.v7.min.js"></script>
创建容器
<div id="chart-container" style="width:600px; height:400px"></div>
const dataset = [ { category: '电子产品', value: 42 }, { category: '服装服饰', value: 28 }, { category: '家居用品', value: 19 }, { category: '图书音像', value: 11 } ];
const width = 600; const height = 400; const radius = Math.min(width, height) / 2.5;
const colorScale = d3.scaleOrdinal() .domain(dataset.map(d => d.category)) .range(d3.schemeCategory10);
const svg = d3.select("#chart-container") .append("svg") .attr("width", width) .attr("height", height) .append("g") .attr("transform", `translate(${width/2},${height/2})`);
const pie = d3.pie() .value(d => d.value) .sort(null);
const arc = d3.arc() .innerRadius(0) .outerRadius(radius);
const arcs = svg.selectAll("path") .data(pie(dataset)) .enter() .append("path") .attr("d", arc) .attr("fill", d => colorScale(d.data.category)) .attr("stroke", "#fff") .attr("stroke-width", 2);
const labelArc = d3.arc() .outerRadius(radius - 40) .innerRadius(radius - 40); svg.selectAll("text") .data(pie(dataset)) .enter() .append("text") .attr("transform", d => `translate(${labelArc.centroid(d)})`) .attr("text-anchor", "middle") .text(d => d.data.category);
arcs.on("mouseover", function(event, d) { d3.select(this) .transition() .duration(200) .attr("transform", "scale(1.05)"); });
arcs.on(“mouseout”, function() {
d3.select(this)
.transition()
.duration(200)
.attr(“transform”, “scale(1)”);
});
2. **动画呈现**
```javascript
arcs.transition()
.duration(800)
.attrTween("d", function(d) {
const interpolate = d3.interpolate(
{ startAngle: 0, endAngle: 0 },
d
);
return t => arc(interpolate(t));
});
添加ARIA标签
svg.selectAll("path") .attr("role", "img") .attr("aria-label", d => `${d.data.category}: ${d.data.value}%`);
支持键盘导航
arcs.attr("tabindex", "0") .on("focus", handleFocus) .on("blur", handleBlur);
(注:本文代码经D3.js v7环境测试通过,适用于现代浏览器,实现时请确保数据格式正确,并根据实际需求调整视觉参数)