D3更新零值的饼图数据

D3更新零值的饼图数据

问题描述:

我正在使用动态JSON Feed更新饼图。我的更新函数在下面

I am updating a pie chart with a dynamic JSON feed. My update function is below

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时,圆弧和标签消失。

When the JSON has 0 values for all objects, the arcs and labels disappear. Exactly what I want to happen.

问题是当我传递一个新的JSON后,一个充满了零,标签回来和补间等,但弧从来没有重新绘制。

The problem is when I pass a new JSON after one that was full of zeros, the labels come back and tween etc but the arcs never redraw.

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

Any suggestions on correcting my update function so that the arcs redraw correctly after they their d values have been pushed to zero?

- 编辑 -

Lars建议下面我使用.enter()完全一样的方式, 。我试着这样做,但结果没有改变。请参阅下面的新更新功能。

Lars suggested below that I use the .enter() exactly in the same way as I did when I created the graph. I tried doing this but the results did not change. See new update function below.

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


在D3中的错误 - 如果一切都为零,饼图布局返回 NaN 的角度,这会导致绘制路径时出错。作为解决方法,您可以检查一切是否为零,并单独处理此情况。我已修改您的更改函数,如下所示。

You've actually hit a bug in D3 there -- if everything is zero, the pie layout returns angles of NaN, which cause errors when drawing the paths. As a workaround, you can check whether everything is zero and handle this case separately. I've modified your change function as follows.

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 此处