我尝试使用json对象的标签和连接器创建静态d3圆环图。我已经能够使用此fiddle中的数组,但无法使用我需要的数据对象显示连接符或标签文本。
圆环图正在运行,标签显示百分比,但我需要它们与标签和连接器一起显示。我认为它与我试图映射连接器的方式有关,但无法弄清楚错误。
代码如下,此处还有一个工作小提琴的链接:https://jsfiddle.net/hef1u71o/
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<script src="https://d3js.org/d3.v3.min.js"></script>
<script>
var data = [{
percentage: 19,
label: 'Consulting'
},{
percentage: 3,
label: 'Consumer Goods'
},{
percentage: 5,
label: 'Energy/Chemical/Gas'
},{
percentage: 3,
label: 'Entrepreneurship'
},{
percentage: 1,
label: 'Environment & Sustainability'
},{
percentage: 19,
label: 'Financial Services'
},{
percentage: 3,
label: 'General Management'
},{
percentage: 6,
label: 'Government'
},{
percentage: 7,
label: 'Hospital/Health Care/Health Services'
},{
percentage: 2,
label: 'Human Resources'
},{
percentage: 4,
label: 'IT'
},{
percentage: 2,
label: 'International Development'
},{
percentage: 3,
label: 'Manufacturing/Operations'
},{
percentage: 4,
label: 'Marketing/PR/Advertising'
},{
percentage: 1,
label: 'Media/Sports/Entertainment'
},{
percentage: 7,
label: 'Nonprofit/Education/Special Org.'
},{
percentage: 6,
label: 'Other'
},{
percentage: 2,
label: 'Research & Development'
},{
percentage: 4,
label: 'Sales/Business Development'
},];
var width = 300,
height = 300,
radius = Math.min(width, height) / 2;
var color = d3.scale.ordinal()
.range(["#243668", "#2b7eb4", "#186b97", "#6391a1", "#d2c5b7", "#9c9286", "#5b5b59"]);
var pie = d3.layout.pie()
.sort(null)
.value(function(d) { return d.percentage; });
var arc = d3.svg.arc()
.innerRadius(radius - 100)
.outerRadius(radius - 50);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var path = svg.selectAll("path")
.data(pie(data))
.enter().append("path")
.attr("fill", function(d, i) { return color(i); })
.attr("d", arc);
svg.selectAll("text").data(pie(data))
.enter()
.append("text")
.attr("text-anchor", "middle")
.attr("x", function(d) {
var a = d.startAngle + (d.endAngle - d.startAngle)/2 - Math.PI/2;
d.cx = Math.cos(a) * (radius - 75);
return d.x = Math.cos(a) * (radius - 20);
})
.attr("y", function(d) {
var a = d.startAngle + (d.endAngle - d.startAngle)/2 - Math.PI/2;
d.cy = Math.sin(a) * (radius - 75);
return d.y = Math.sin(a) * (radius - 20);
})
.text(function(d) { return d.value; })
.each(function(d) {
var bbox = this.getBBox();
d.sx = d.x - bbox.width/2 - 2;
d.ox = d.x + bbox.width/2 + 2;
d.sy = d.oy = d.y + 5;
});
svg.append("defs").append("marker")
.attr("id", "circ")
.attr("markerWidth", 6)
.attr("markerHeight", 6)
.attr("refX", 3)
.attr("refY", 3)
.append("circle")
.attr("cx", 3)
.attr("cy", 3)
.attr("r", 3);
svg.selectAll("path.pointer").data(pie(data)).enter()
.append("path")
.attr("class", "pointer")
.style("fill", "none")
.style("stroke", "black")
.attr("marker-end", "url(#circ)")
.attr("d", function(d) {
if(d.cx > d.ox) {
return "M" + d.sx + "," + d.sy + "L" + d.ox + "," + d.oy + " " + d.cx + "," + d.cy;
} else {
return "M" + d.ox + "," + d.oy + "L" + d.sx + "," + d.sy + " " + d.cx + "," + d.cy;
}
});
</script>
</body>
</html>
答案 0 :(得分:3)
将数据保存到变量中:
svg.selectAll("text").data(pieData)
.enter()
.append("text")
.attr("text-anchor", "middle")
.attr("x", function(d) {
var a = d.startAngle + (d.endAngle - d.startAngle)/2 - Math.PI/2;
d.cx = Math.cos(a) * (radius - 75);
return d.x = Math.cos(a) * (radius - 20);
})
.attr("y", function(d) {
var a = d.startAngle + (d.endAngle - d.startAngle)/2 - Math.PI/2;
d.cy = Math.sin(a) * (radius - 75);
return d.y = Math.sin(a) * (radius - 20);
})
.text(function(d) { return d.value; })
.each(function(d) { // !!! you extent the dataset here
var bbox = this.getBBox();
d.sx = d.x - bbox.width/2 - 2;
d.ox = d.x + bbox.width/2 + 2;
d.sy = d.oy = d.y + 5;
});
在这里使用此变量:
svg.selectAll("path.pointer").data(pieData).enter()
.append("path")
.attr("class", "pointer")
...
在这里:
each
这很重要,因为你扩展了数据(参见{{1}}方法)。您将使用扩展属性来计算连接器位置,并且您应该对两种情况使用相同的数据集。
检查working demo。