我正在d3中构建一个饼图。在这里,我非常特别需要将标签挤出,并在切片刻度上附加水平线。 这是我的代码
svg.selectAll("g.arc")
.data(pie)
.enter()
.append("text")
.attr("text-anchor", "middle")
.attr("x", function(d) {
var a = 180-(d.startAngle + (d.endAngle - d.startAngle)/2)-45 - Math.PI/2;
d.cx = Math.cos(a) * (radius - 75);
return d.x =(width/3)+ Math.cos(a) * (oldRadius - 20);
})
.attr("y", function(d) {
var a = 180-(d.startAngle + (d.endAngle - d.startAngle)/2)-45 - Math.PI/2;
d.cy = Math.sin(a) * (radius - 75);
return d.y =(height/2)- Math.sin(a) * (oldRadius - 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("g.arc")
.data(pie)
.enter()
.append("path")
.attr("class", "pointer")
.style("fill", "none")
.style("stroke", "black")
.attr("marker-end", "url(#circ)")
.attr("d", function(d,i) {
alert(d.cx);
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;
}
});
为此,我需要使用d变量中的某些值,如cx,ox,sx。我在第一个代码块中构建图表时设置这些值。 问题是当我在打印标签和刻度时尝试检索这些值时,我得到“未定义”的值。任何人都可以指出我在这里做错了什么,我需要改变一些东西吗? 提前致谢
答案 0 :(得分:0)
小提琴在这里会有所帮助...... 我怀疑问题是你在追加路径时不需要以下两行:
.data(pie)
.enter()
这是重置数据。如果您只选择弧,svg.selectAll(" g.arc"),修改后的数据应该可用。
这是一个片段,其中的值不是未定义的(尽管使用上面的数学,这些行很不稳定)。
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<style>
body {
font: 10px sans-serif;
}
.arc path {
stroke: #fff;
}
</style>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<script>
var width = 200,
height = 200,
radius = Math.min(width, height) / 2;
var color = d3.scale.ordinal()
.range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);
var data = [
{age: "<5", population: "2704659"},
{age: "5-13", population: "4499890"},
{age: "14-17", population: "2159981"},
{age: "18-24", population: "3853788"},
{age: "25-44", population: "14106543"},
{age: "45-64", population: "8819342"},
{age: "≥65", population: "612463"}];
var arc = d3.svg.arc()
.outerRadius(radius - 10)
.innerRadius(0);
var pie = d3.layout.pie()
.sort(null)
.value(function(d) { return d.population; });
var svg = d3.select("body").append("svg")
.attr("width", 600)
.attr("height", 600)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
data.forEach(function(d) {
d.population = +d.population;
});
var g = svg.selectAll(".arc")
.data(pie(data))
.enter().append("g")
.attr("class", "arc");
g.append("path")
.attr("d", arc)
.style("fill", function(d) { return color(d.data.age); });
var oldRadius = radius / 2;
svg.selectAll("g.arc")
.append("text")
.attr("text-anchor", "middle")
.attr("x", function (d) {
var a = 180 - (d.startAngle + (d.endAngle - d.startAngle) / 2) - 45 - Math.PI / 2;
d.cx = Math.cos(a) * (radius - 75);
d.x = (width / 3) + Math.cos(a) * (oldRadius - 20);
return d.x;
})
.attr("y", function (d) {
var a = 180 - (d.startAngle + (d.endAngle - d.startAngle) / 2) - 45 - Math.PI / 2;
d.cy = Math.sin(a) * (radius - 75);
d.y = (height / 2) - Math.sin(a) * (oldRadius - 20);
return d.y;
})
.text(function (d) {
return d.data.population;
})
.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("g.arc")
.append("path")
.attr("class", "pointer")
.style("fill", "none")
.style("stroke", "black")
.attr("marker-end", "url(#circ)")
.attr("d", function (d, i) {
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>
&#13;