布局 = 数据转换 主要用d3.layout.xxx生成转换器定义转换规则
const dataSet = [120, 260, 400, 330, 300];
const width = 700, height = 500, padding = {top: 60, left: 30};
const svg = d3.select("body").append("svg").attr("width", width + padding.left * 2).attr("height", height + padding.top * 2);
// 定义布局(数据转换规则)
// pie的转换规则会用value给的值转换成endAngle padAngle startAngle 和数值value
const pie = d3.layout.pie().value(function (d) {
return d;
});
const pieData = pie(dataSet);
const color = d3.scale.category10();
const arcPath = d3.svg.arc().innerRadius(0).outerRadius(width / 3);
svg.append("g").attr("transform", "translate(300,250)")
.selectAll("path").data(pieData).enter().append("path").attr("class", "path")
// 初始化
.attr("d", function (d) {
return arcPath({
endAngle: d.endAngle,
padAngle: d.endAngle - d.startAngle - 1,
startAngle: d.startAngle
});
})
.attr("fill", function (d, i) {
return color(i);
})
// 执行过渡
.transition().duration(2000).ease("bounce-out")
.attr("d", function (d) {
return arcPath(d);
});
svg.append("g").selectAll("text").data(pieData).enter().append("text")
// 初始化
.attr("transform", function (d) {
// arcPath.centroid(弧角度对象)获取到一个相对当前弧中心的
// 此时饼图的父元素g在300,250
// 所以需要把文字也移动到该然后用centroid计算出相对圆心的距离的数组然后设置translate平移过去
return "translate(300,250)" + "translate(" + arcPath.centroid(d) + ")";
}).attr("text-anchor", "middle").attr("stroke", "purple")
.text(function (d) {
return d.value;
});
// 绑定事件
svg.selectAll(".path").on("mouseover", function (d) {
d3.select(this).transition().duration(300).ease("bounce").attr("d", function (d) {
arcPath.outerRadius(width / 3 + 30);
return arcPath(d);
})
}).on("mouseout", function (d) {
d3.select(this).transition().duration(300).ease("bounce").attr("d", function (d) {
arcPath.outerRadius(width / 3);
return arcPath(d);
})
});
结果
注:centroid