问题描述
我正在使用动态 JSON 提要更新饼图.我的更新功能如下
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 之后传递一个新的 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
的角度,即绘制路径时会导致错误.作为一种解决方法,您可以检查一切是否为零并单独处理这种情况.我已将您的 change
函数修改如下.
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.
这篇关于D3 用零值更新饼图数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!