bl.ocks网站上的饼图更新示例不会更新“就地”元素:
http://bl.ocks.org/j0hnsmith/5591116
function change() {
clearTimeout(timeout);
path = path.data(pie(dataset[this.value])); // update the data
// set the start and end angles to Math.PI * 2 so we can transition
// anticlockwise to the actual values later
path.enter().append("path")
.attr("fill", function (d, i) {
return color(i);
})
.attr("d", arc(enterAntiClockwise))
.each(function (d) {
this._current = {
data: d.data,
value: d.value,
startAngle: enterAntiClockwise.startAngle,
endAngle: enterAntiClockwise.endAngle
};
}); // store the initial values
path.exit()
.transition()
.duration(750)
.attrTween('d', arcTweenOut)
.remove() // now remove the exiting arcs
path.transition().duration(750).attrTween("d", arcTween); // redraw the arcs
}
相反,它只是将新的数组值视为全新数据并相应地调整图表大小。
我创造了一个非常简单的小提示:
如果按“添加”,它会向数组中添加一个随机int:这可以按预期工作。
如果按'删除',唯一转出的元素始终是进入饼图的最后一个元素。简而言之,它的行为就像一个LIFO堆栈。 预期的行为是相关的饼弧被转换出来。
是否可以将对象一致性应用于馅饼?我也试过添加一个关键功能(没有在小提琴上演示),但这只是打破了(奇怪的是,它与我的堆叠图形工作正常)。
谢谢。
答案 0 :(得分:11)
此问题的最简单解决方案是将缺失值设置为零,而不是像Part III系列示例的Pie Chart Update那样完全删除它们。然后您免费获得object constancy:您在更新中拥有相同数量的元素,顺序相同。
或者,如果您想要像Part IV中那样进行数据连接,则必须告诉D3输入弧应从进入的位置,以及退出弧应退出 。一个合理的策略是从相反的数据中找到最接近的相邻弧:对于给定的进入弧,找到旧数据中最近的相邻弧(转换前);同样,对于给定的退出弧,在新数据中找到最接近的相邻弧(转换后)。
继续这个例子,假设您在不同地区展示苹果销售,并希望切换到显示橙子。您可以使用以下键函数来维持对象的恒定性:
function key(d) {
return d.data.region;
}
(假设您使用的是d3.layout.pie,它会封装原始数据并将其公开为d.data
。)
现在说当你转换到橘子时,你有以下旧数据和新数据:
var data0 = path.data(), // retrieve the old data
data1 = pie(region.values); // compute the new data
对于索引为i
的每个进入弧(d
为data1[i]
),您可以按顺序逐步查看data1
中的先前数据,看看是否可以找到匹配data0
:
var m = data0.length;
while (--i >= 0) {
var k = key(data1[i]);
for (var j = 0; j < m; ++j) {
if (key(data0[j]) === k) return data0[j]; // a match!
}
}
如果找到匹配项,则输入的弧可以从匹配弧的结束角开始。如果找不到前一个匹配项,则可以查找以下匹配的弧。如果没有匹配,则两个数据集之间没有重叠,因此您可以从角度0°输入弧线,或者进行交叉淡化。您也可以将此技术应用于退出弧。
总结一下,这里是Part V:
答案 1 :(得分:0)
好的,找到了解决方案。 诀窍是以这种方式传递密钥:
path = path.data(pie(dataset), function (d) {return d.data}); // this is good
而不是传递它,或以错误的方式传递它:
path = path.data(pie(dataset, function (d) {return d.data})); // this is bad
这是一个更新的小提琴,在右弧上进行工作转换! :)