我正在使用d3 js创建圆环图。我正在尝试向弧线添加角度标签,如下图所示
这是我的工作代码
var width = 300,
height = 300,
radius = Math.min(width, height) / 2;
var color = d3.scale.ordinal()
.range(["#6fc9e1", "#00627d", "#179bbf"]);
var biggestarc = d3.svg.arc()
.outerRadius(radius - 100)
.innerRadius(radius - 60);
var bigarc = d3.svg.arc()
.outerRadius(radius - 100)
.innerRadius(radius - 50);
var smallarc = d3.svg.arc()
.outerRadius(radius - 100)
.innerRadius(radius - 40);
/*var biggerarc = d3.svg.arc()
.outerRadius(radius - 80)
.innerRadius(radius - 70);*/
var pie = d3.layout.pie()
.sort(null)
.value(function (d) {
return d.percent;
});
var svg = d3.select("#donut").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
data = [{
"label": "Biggest",
"percent": 33
}, {
"label": "Big",
"percent": 17
}, {
"label": "Small",
"percent": 50
}]
var g = svg.selectAll(".arc")
.data(pie(data))
.enter().append("g")
.attr("class", "arc");
g.append("path")
.attr("d", function (d) {
if (d.data.label == "Biggest") {
return biggestarc(d);
} else if (d.data.label == "Big") {
return bigarc(d);
} else {
return smallarc(d);
}
})
.style("fill", function (d) {
return color(d.data.label);
});
g.append("text") //add a label to each slice
.attr("transform", function(d) {
//set the label's origin to the center of the arc
d.innerRadius = 0;
d.outerRadius = radius;
if (d.data.label == "Biggest") {
return "translate(" + biggestarc.centroid(d) + ")";
}
else if (d.data.label == "Big") {
return "translate(" + bigarc.centroid(d) + ")";
}
else{
return "translate(" + smallarc.centroid(d) + ")";
}
})
.attr("text-anchor", "middle")
.text(function(d, i) {
return data[i].percent + '%';
})

body {
font: 10px sans-serif;
}
.arc path {
stroke: #fff;
}
text {
font-size:12px
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.3.0/d3.min.js"></script>
<div id="donut"></div>
&#13;
刚刚获得this链接并尝试实现。在我探索d3 js时,正在努力做到这一点。有人可以帮我吗?
答案 0 :(得分:2)
计算所有必需的坐标将有助于您在正确的位置绘制标签和指针(path
)。
我准备回答另一个类似的问题:Donut labels with connectors
不是再次为您提供链接,而是使用该方法的代码片段(我认为它比我之前提到的polyline
方法更简单。
var width = 300,
height = 300,
radius = Math.min(width, height) / 2;
var color = d3.scale.ordinal()
.range(["#6fc9e1", "#00627d", "#179bbf"]);
var biggestarc = d3.svg.arc()
.outerRadius(radius - 100)
.innerRadius(radius - 60);
var bigarc = d3.svg.arc()
.outerRadius(radius - 100)
.innerRadius(radius - 50);
var smallarc = d3.svg.arc()
.outerRadius(radius - 100)
.innerRadius(radius - 40);
/*var biggerarc = d3.svg.arc()
.outerRadius(radius - 80)
.innerRadius(radius - 70);*/
var pie = d3.layout.pie()
.sort(null)
.value(function (d) {
return d.percent;
});
var svg = d3.select("#donut").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
data = [{
"label": "Biggest",
"percent": 33
}, {
"label": "Big",
"percent": 17
}, {
"label": "Small",
"percent": 50
}]
var piedata = pie(data);
var g = svg.selectAll(".arc")
.data(piedata)
.enter().append("g")
.attr("class", "arc");
g.append("path")
.attr("d", function (d) {
if (d.data.label == "Biggest") {
return biggestarc(d);
} else if (d.data.label == "Big") {
return bigarc(d);
} else {
return smallarc(d);
}
}).style("fill", function (d) {
return color(d.data.label);
});
g.append("text") //add a label to each slice
.attr("transform", function(d) {
//set the label's origin to the center of the arc
d.innerRadius = 0;
d.outerRadius = radius;
if (d.data.label == "Biggest") {
return "translate(" + biggestarc.centroid(d) + ")";
}
else if (d.data.label == "Big") {
return "translate(" + bigarc.centroid(d) + ")";
}
else{
return "translate(" + smallarc.centroid(d) + ")";
}
})
.attr("text-anchor", "middle")
.text(function(d, i) {
return data[i].percent + '%';
});
var labels = g.append('g').classed('labels', true);
labels.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.data.label; })
.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;
});
/* labels.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); */
labels.selectAll("path.pointer").data(piedata).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;
}
});
body {
font: 10px sans-serif;
}
.arc path {
stroke: #fff;
}
text {
font-size:12px
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.3.0/d3.min.js"></script>
<div id="donut"></div>
希望这会有所帮助。