问题描述
我正在尝试使用json对象的标签和连接器创建静态d3圆环图。我已经能够在这个中使用数组工作,但无法获得与我需要的数据对象一起出现的连接器或标签文本。
I'm trying to create a static d3 donut chart with labels and connectors from a json object. I've been able to get it to work with an array in this fiddle but can't get the connectors or label text to appear with the data object that I need.
圆环图正在运行,标签出现百分比,但我需要它们出现带有标签和连接器。我认为它与我试图映射连接器的方式有关,但无法弄清楚错误。
The donut chart is working and the labels are appearing with the percentages, but I need them to appear with the labels and connectors. I think that it has something to do with the way that I am trying to map the connectors but can't figure out the error.
代码在下面,这里也是一个工作小提琴的链接:
Code is below and also here is a link to a working 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>
推荐答案
将数据保存到变量中:
var pieData = pie(data);
并在此处使用此变量:
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")
...
这很重要,因为你扩展了数据(参见每个
方法)。您将使用扩展属性来计算连接器位置,并且您应该在两种情况下使用相同的数据集。
It's important because of you extend the data (see each
method). You will use extended properties for calculating of connectors position and you should use the same dataset for both cases.
检查。
这篇关于带连接器的D3圆环图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!