2013-11-26 2 views
3

Я пытаюсь создать многоразовую круговую диаграмму с динамическими переходами в качестве учебной задачи. Я работаю над электронной книгой d3.js resuable, написанной Крисом Виау. Проблема, с которой я сталкиваюсь, в основном не обновляется, а создает несколько круговых диаграмм. Мне интересно, не понимаю ли я, как работает d3.dispatch, или я что-то испортил в том, как должен работать символ пирога. Он создает несколько кругов вместо динамического обновления одной круговой диаграммы со случайными значениями.d3.js многоразовая круговая диаграмма с динамическими обновлениями

вот мой jsfiddle.

http://jsfiddle.net/seoulbrother/Upcr5/

спасибо!

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); 

ответ

6

Основная причина несколько SVGs появляться в том, что вы не проверить, если есть один уже правильно. Вы полагаетесь на определенную переменную svg, но определяете ее только после проверки ее определения.

Лучший способ это выбрать элемент, который вы ищете, и проверить, пуст ли, что выбор:

var svg = d3.select(this).select("svg > g"); 
if (svg.empty()){ // etc 

Кроме того, вам нужно обрабатывать обновления и выхода выбор в вашем коде в дополнение к введите ввод. Полный jsfiddle here.

Смежные вопросы