1

動的 JSON フィードを使用して円グラフを更新しています。私の更新機能は以下です

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 を渡すと、ラベルが戻ってきてトゥイーンなどですが、アークが再描画されないことです。

ARCSが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));
};
}
4

1 に答える 1

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 を完成させます。

于 2013-11-12T17:44:50.837 に答える