D3更新零值的饼图数据

时间:2013-11-12 15:46:14

标签: d3.js

我正在使用动态JSON Feed更新饼图。我的更新功能在

之下
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之后传递一个新的JSON时,标签会返回并补间等,但弧线永远不会重绘。

有关更正我的更新功能的任何建议,以便在它们的d值被推到零后正确重绘弧线吗?

- 编辑 -

Lars在下面建议我使用.enter()的方式与我创建图表时的方式相同。我试过这样做,但结果没有改变。请参阅下面的新更新功能。

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

1 个答案:

答案 0 :(得分:8)

你实际上在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