2013-11-12 4 views
1

Я обновляю круговую диаграмму с динамическим каналом JSON. Моя функция обновления нижеD3 update pie data с нулевыми значениями

function updateChart(data) { 
arcs.data(pie(data)); // recompute angles, rebind data 

arcs.transition() 
    .ease("elastic") 
    .duration(1250) 
    .attrTween("d", arcTween) 

sliceLabel.data(pie(data)); 

sliceLabel.transition() 
    .ease("elastic").duration(1250) 
    .attr("transform", function (d) { 
    return "translate(" + arc2.centroid(d) + ")"; 
}) 
    .style("fill-opacity", function (d) { 
    return d.value == 0 ? 1e-6 : 1; 
}); 
} 

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

Когда JSON имеет 0 значений для всех объектов, дуги и метки исчезают. Именно то, что я хочу, произойдет.

Проблема заключается в том, что я передаю новый JSON после того, как он был заполнен нулями, метки возвращаются и твики и т. Д., Но дуги никогда не перерисовываются.

Любые предложения по исправлению моей функции обновления, чтобы правильно перерисовать дуги после того, как их значения d были сдвинуты на нуль?

- редактировать -

Ларс предложил ниже, я использую (Введите желанную) точно так же, как я сделал, когда я создал граф. Я попытался сделать это, но результаты не изменились. См. Новую функцию обновления ниже.

this.updatePie = function updateChart(data) { 
arcs.data(pie(data)) 
    .enter() 
    .append("svg:path") 
     .attr("stroke", "white") 
     .attr("stroke-width", 0.5) 
     .attr("fill", function (d, i) { 
     return color(i); 
}) 
    .attr("d", arc) 
    .each(function (d) { 
    this._current = d 
}) 
arcs.transition() 
    .ease("elastic") 
    .duration(1250) 
    .attrTween("d", arcTween) 
sliceLabel.data(pie(data)); 
sliceLabel.transition() 
    .ease("elastic").duration(1250) 
    .attr("transform", function (d) { 
    return "translate(" + arc2.centroid(d) + ")"; 
}) 
    .style("fill-opacity", function (d) { 
    return d.value == 0 ? 1e-6 : 1; 
}); 
} 
function arcTween(a) { 
var i = d3.interpolate(this._current, a); 
this._current = i(0); 
return function (t) { 
    return arc(i(t)); 
}; 
} 
+0

Вам нужно обработать '.enter()' так же, как вы, когда вы изначально создаете круговую диаграмму. –

+0

Lars Я попробовал добавить функцию .enter() к функции обновления. Он находится в том же виде, что и при первоначальном создании графика. Это не совсем трюк. Не удалось ли заменить функцию .enter() в функции обновления? – snowgage

+0

Ой, подождите, вы на самом деле не снимаете пустые сегменты, не так ли? Не могли бы вы разместить где-нибудь полный пример? Мне кажется, что ваш исходный код должен работать. –

ответ

7

Вы действительно ударил ошибку в D3 есть - если все равно нуль, то расположение пирог возвращает углы NaN, которые вызывают ошибки при рисовании пути. В качестве обходного пути вы можете проверить, все ли ноль, и обрабатывать этот случай отдельно. Я изменил вашу функцию change следующим образом.

if(data.filter(function(d) { return d.totalCrimes > 0; }).length > 0) { 
    path = svg.selectAll("path").data(pie(data)); 
    path.enter().append("path") 
     .attr("fill", function(d, i) { return color(d.data.crimeType); }) 
     .attr("d", arc) 
     .each(function(d) { this._current = d; }); 
    path.transition().duration(750).attrTween("d", arcTween); // redraw the arcs 
} else { 
    path.remove(); 
} 

Полный jsbin here.

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