具有动态更新的d3.js可重用饼图

具有动态更新的d3.js可重用饼图,d3.js,D3.js,我正在尝试创建一个可重用的饼图,并将动态转换作为一项学习任务。我正在编写Chris Viau的d3.js可恢复组件电子书。 我遇到的问题基本上不是更新,而是创建多个饼图。我想知道我是否不明白d3.dispatch是如何工作的,或者我是否把饼字符的工作方式搞砸了。它创建多个圆,而不是使用随机值动态更新单个饼图 这是我的名片 谢谢 js代码如下: d3.edge = {}; d3.edge.donut = function module() { var width = 460,

我正在尝试创建一个可重用的饼图,并将动态转换作为一项学习任务。我正在编写Chris Viau的d3.js可恢复组件电子书。 我遇到的问题基本上不是更新,而是创建多个饼图。我想知道我是否不明白d3.dispatch是如何工作的,或者我是否把饼字符的工作方式搞砸了。它创建多个圆,而不是使用随机值动态更新单个饼图

这是我的名片

谢谢

js代码如下:

d3.edge = {};

d3.edge.donut = function module() {

    var width = 460,
        height = 300,
        radius = Math.min(width, height) / 2;

    var color = d3.scale.category20();


   var dispatch = d3.dispatch("customHover");
   function graph(_selection) {
       _selection.each(function(_data) {    
            var pie = d3.layout.pie()
                .value(function(_data) { return _data; })
                .sort(null);

            var arc = d3.svg.arc()
                .innerRadius(radius - 100)
                .outerRadius(radius - 50);

            if (!svg){
                var svg = d3.select(this).append("svg")
                    .attr("width", width)
                    .attr("height", height)
                    .append("g")
                    .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
            }
            var path = svg.selectAll("path")
                .data(pie)
              .enter().append("path")
                .attr("fill", function(d, i) { return color(i); })
                .attr("d", arc)
                .each(function(d) {this._current = d;} );

            path.transition()
                  .ease("elastic")
                  .duration(750)
                  .attrTween("d", arcTween);              

            function arcTween(a) {
              var i = d3.interpolate(this._current, a);
              this._current = i(0);
              return function(t) {
                return arc(i(t));
              };
            }
        });

    }
    d3.rebind(graph, dispatch, "on");
    return graph;
}

donut = d3.edge.donut();
var data = [1, 2, 3, 4];
var container = d3.select("#viz").datum(data).call(donut);

function update(_data) {
    data = d3.range(~~(Math.random() * 20)).map(function(d, i) {
        return ~~(Math.random() * 100);
    });
    container.datum(data).transition().ease("linear").call(donut);
}

update();
setTimeout( update, 1000);

出现多个SVG的主要原因是您没有检查是否已经有一个SVG正确。您依赖于正在定义的变量
svg
,但只有在检查是否已定义之后才能定义它

更好的方法是选择要查找的元素并检查该选择是否为空:

var svg = d3.select(this).select("svg > g");
if (svg.empty()){ // etc
此外,除了输入选择外,还需要处理代码中的更新和退出选择。完成jsfiddle