我试图使用d3.js
创建一个如下所示的饼图:
请注意,标签位于pie chart的边缘。最初,我能够绘制饼图并正确放置文本节点(小提琴只显示一个饼图;但是,假设它们都有适用的数据,这是合适的,就像这个一样)。但是,当我去调整数据时,我似乎不能.attr(translate, transform)
将它们放到饼图边缘的正确区域(或者对它们做任何事情):
changeFunctions[i] = function (data, i) {
path.data(pie(data))
.transition()
.duration(750)
.attrTween("d", arcTween);
text.each(function (d, num) {
d3.select(this)
.text(function (t) {
return t.data.name+". "+(100 * t.data.votes/totalVotes).toFixed(0) + "%";
})
/*
.attr("transform", function (d) {
//console.log("the d", d)
var c = arc.centroid(d),
x = c[0], y = c[1],
h = Math.sqrt(x * x + y * y);
return "translate(" + (x/h * 100) + ',' + (y/h * 100) + ")";
})*/
.attr("opacity", function (t) {
return t.data.votes == 0 ? 0 : 1;
});
})
}
我省略了绘制饼图的通用代码;它在jsfiddle中。基本上,我在for
循环中绘制每个饼图并将此函数changeFunctions[i]
存储在闭包中,以便我可以访问path
和{{1}等变量}。
此功能的text
部分有效;饼图正确调整其楔形。但是,path.data
部分没有。
我应该如何让文本节点更新其值和位置?
答案 0 :(得分:2)
更新text
元素时,还需要更新绑定到它们的数据,否则不会发生任何事情。创建元素时,您将数据绑定到包含弧段和文本的g
元素。然后添加path
和text
,数据将“继承”到这些元素。在设置这些元素的属性时,您通过引用d
来利用这一事实。
使其工作的最佳方法可能是在更新时使用相同的模式。也就是说,不是仅更新当前正在执行的绑定到path
元素的数据,而是更新g
元素的数据。然后,您可以.select()
后代path
和text
元素,这些元素将再次向其继承新数据。然后,您可以按常规方式设置属性。
这需要对代码进行一些更改。特别是,g
元素选择应该有一个变量,而不仅仅是path
的变量使事情更容易:
var g = svg.selectAll("g.arc")
.data(pie(data));
g.enter()
.append("g").attr("class", "arc");
var path = g.append("path");
changeFunction
代码更改如下:
var gnew = g.data(pie(data));
gnew.select("path")
.transition()
.duration(750)
.attrTween("d", arcTween);
现在,要更新text
,您只需选择它并重置属性:
gnew.select("text")
.attr("transform", function(d) { ... });
完整演示here。