如何更新D3饼图上文本标签的内容和位置

时间:2014-08-15 01:26:13

标签: javascript d3.js

我试图使用d3.js创建一个如下所示的饼图:

enter image description here

请注意,标签位于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部分没有。

我应该如何让文本节点更新其值和位置?

fiddle

1 个答案:

答案 0 :(得分:2)

更新text元素时,还需要更新绑定到它们的数据,否则不会发生任何事情。创建元素时,您将数据绑定到包含弧段和文本的g元素。然后添加pathtext,数据将“继承”到这些元素。在设置这些元素的属性时,您通过引用d来利用这一事实。

使其工作的最佳方法可能是在更新时使用相同的模式。也就是说,不是仅更新当前正在执行的绑定到path元素的数据,而是更新g元素的数据。然后,您可以.select()后代pathtext元素,这些元素将再次向其继承新数据。然后,您可以按常规方式设置属性。

这需要对代码进行一些更改。特别是,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