【问题标题】:How to update pie chart using d3.js如何使用 d3.js 更新饼图
【发布时间】:2013-08-04 22:02:27
【问题描述】:

我有两个不同的数据集,我正在尝试使用第一个数据集创建饼图,然后监听一个事件并转换到第二个数据集。

我可以使用此代码从第一组数据成功创建饼图

var data = [[70, 30],[60, 40],[50, 50],[95, 5],[87, 13]];

progress.pie.vars.svg = d3.select( progress.pie.vars.pieEl ).selectAll("svg")
          .data(data)
          .enter()
          .append("svg")
            .attr("width", 150)
            .attr("height", 150)
          .each(function(d) { this.currentAngles = d; }); // store the initial angles;

progress.pie.vars.path = progress.pie.vars.svg.selectAll("path")
          .data(function(d, i){ return pie(d) })
          .enter().append("path")
            .attr("fill", function(d, i) { return color(i); })
            .attr("transform", "translate(" + 75 + ", " + 75 + ")")
            .attr("d", arc);

注意:我在这里使用的是硬编码数据,我可以使用 JSON 进行复制,但我想简化一些事情,以便让转换工作。

这会创建 svg 并将它们呈现在页面上,但是当我使用其他数据集并尝试更新路径时会出现问题。像这样……

var data = [[60, 40], [10, 10, 10, 70], [30, 70], [25, 25, 25, 25], [30, 35, 35]];

progress.pie.vars.svg = progress.pie.vars.svg.selectAll("svg")
          .data(data);

progress.pie.vars.path = progress.pie.vars.path
          .data(function(d, i){ return pie(d) })
          .enter().append("path")
            .transition()
            .duration(5000);

我研究过 d3 通用更新模式,但我还不太了解。

如果有人对如何解决我的问题或改进我的代码有任何建议,那么非常感谢:)

谢谢

【问题讨论】:

    标签: javascript d3.js


    【解决方案1】:

    由于progress.pie.vars.svg 包含新添加的元素,您不需要selectAll("svg")。这将选择您的svg 元素下的任何svg 元素。您应该可以直接在您的选择上调用data

    对于progress.pie.vars.path 数据绑定,看起来您只是在处理用于添加新路径的输入案例(尽管您没有像处理原始饼图那样分配d 路径属性)。您需要为新数据添加新弧并为更新数据更新弧。您可以通过将更新选择与输入选择分开来做到这一点:

    progress.pie.vars.path = progress.pie.vars.path
        .data(function(d, i){ return pie(d) });
    
    progress.pie.vars.path.enter().append("path");
    
    progress.pie.vars.path.attr("d", arc);
    

    添加到输入选择的新节点会隐式添加到更新选择中,以便最后一行将在新节点和现有节点上运行。 (注意这不处理退出)。

    您应该查看 Mike Bostock 的优秀教程 Thinking With Joins

    【讨论】:

    • 感谢您的回答,它澄清了一些事情。现在一切正常,除了每次代码重绘所有路径时。我想增强它来做这样的事情bl.ocks.org/mbostock/5681842。我可以在这里粘贴更多代码供您查看吗?我遇到的唯一问题是饼图由于某种原因没有转换。
    • 不确定这是否是您当前的问题,但您需要一个自定义补间来很好地插入弧角。查看您链接到的示例中的 arcTween()。
    • 弧确实插值正确,但它只是没有过渡。在这里,我存储 angle ,取自我链接到的示例。 .attrTween("d", progress.pie.tweenPie).each(function(d) { this._current = d; });
    • 这是我的 arcTween 版本tweenPie: function(b) { var arc = d3.svg.arc() .innerRadius(progress.pie.vars.innerRadius) .outerRadius(progress.pie.vars.outerRadius); b.innerRadius = 0; var i = d3.interpolate(this._current, b); this._current = i(0); return function(t) { return arc(i(t)); }; }
    • 嗯,如果你的 attrTween() 出现在调用链中的 transition() 之后,它应该做它的事情。你能链接到最终代码所在的 bl.ocks 或 jsFiddle 吗?
    猜你喜欢
    • 2017-10-08
    • 1970-01-01
    • 2013-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-10
    • 1970-01-01
    • 2018-06-14
    相关资源
    最近更新 更多