【问题标题】:How to update both the content and location of text labels on a D3 pie chart如何更新 D3 饼图上文本标签的内容和位置
【发布时间】:2014-10-08 19:27:08
【问题描述】:

我正在尝试用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] 存储在一个闭包中,这样我就可以访问pathtext 等变量。

此函数的path.data 部分有效;饼图正确调整其楔形。但是,text.each 部分没有。

我应该如何让文本节点同时更新它们的值和位置?

fiddle

【问题讨论】:

    标签: javascript d3.js


    【解决方案1】:

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

    让它工作的最好方法可能是在更新时使用相同的模式。也就是说,不要像现在那样只更新绑定到path 元素的数据,而是更新g 元素的数据。然后您可以.select() 后代pathtext 元素,它们将再次将新数据继承给它们。然后就可以按照通常的方式设置属性了。

    这需要对您的代码进行一些更改。特别是,应该有一个用于g 元素选择的变量,而不仅仅是paths,以使事情变得更容易:

    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

    【讨论】:

    • 昨晚我真的意识到了我的问题(以为我解决了问题——猜不出来);不过,您的答案非常好,并且肯定会对未来的访客有所帮助,因此您提供了答案很好。我最终解决了它somewhat differently,以便graphs 可以实时更新。我通过一个辅助函数makeGraphs 遍历了所有不同的饼图,并分别设置它们。我返回了一个函数,这样我仍然可以通过闭包访问textpath
    猜你喜欢
    • 2016-03-22
    • 1970-01-01
    • 2017-10-24
    • 2014-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多