将新数据与 d3.js 更新上的先前数据进行比较/差异 [英] Compare/Diff new data with previous data on d3.js update
问题描述
我想表示客户端计算的当前数据集和前一个数据集之间的差异.
I'd like to represent the difference between the current data set and the previous data set, as calculated by the client.
假设我已经有三个圆圈,绑定到数据 [1, 2, 3]
.现在我想更新数据并根据新值和旧值之间的差异做一些事情?
Imagine I already have three circles, bound to the data [1, 2, 3]
. Now I'd like to update the data and do something based on the difference between the new values and the old?
var new_data = [2, 2, 2]; // This is the new data I'd like to compare with the old
svg.selectAll("circle").data(new_data)
.transition().duration(2000)
.attr("fill", "red") // e.g. I'd like to colour the circles red if the change
// is negative, blue if positive, black if no change.
.attr("r", function(d) { return d * 10; });
这是一个 JSFiddle,上面的代码设置为示例.
Here's a JSFiddle with the above code set into an example.
推荐答案
您有两个选项可以保存附加到元素的旧数据,以便在新数据连接后识别更改.
You have two options for saving the old data attached to an element in order to identify changes after a new data join.
正如您所建议的,第一个选项是使用数据属性.此 SO Q&A 描述了该方法.需要考虑的事项:
The first option, as you suggested, is to use data attributes. This SO Q&A describes that approach. Things to consider:
- 您的所有数据值都将被强制转换为字符串
- 对于数据的每个方面,您都需要一个单独的方法调用/属性
- 您正在操作 DOM,因此如果每个元素都有很多元素或数据,它可能会减慢速度
- 数据现在是 DOM 的一部分,因此可以与图像一起保存或由其他脚本访问
第二个选项是将数据存储为元素的 DOM 对象的 Javascript 属性,就像 d3 将活动数据存储为 __data__
属性.我在这个论坛帖子中讨论了这种方法.
The second option is to store the data as a Javascript property of the DOM object for the element, in the same way that d3 stores the active data as the __data__
property. I've discussed this method in this forum post.
一般方法:
selection = selection.property(" __oldData__", function(d){ return d; } );
//store the old data as a property of the node
.data(newData, dataKeyFunction);
//over-write the default data property with new data
//and store the new data-joined selection in your variable
selection.enter() /*etc*/;
selection.attr("fill", function(d) {
// Within any d3 callback function,
// you can now compare `d` (the new data object)
// with `this.__oldData__` (the old data object).
// Just remember to check whether `this.__oldData__` exists
// to account for the just-entered elements.
if (this.__oldData__) { //old data exists
var dif = d.value - this.__oldData__.value;
return (dif) ? //is dif non-zero?
( (dif > 0)? "blue" : "red" ) :
"black" ;
} else {
return "green"; //value for new data
}
});
selection.property("__oldData__", null);
//delete the old data once it's no longer needed
//(not required, but a good idea if it's using up a lot of memory)
您当然可以为旧的数据属性使用任何名称,只是为了避免弄乱浏览器的任何原生 DOM 属性,在其周围放置大量_"字符只是惯例.
You can of course use any name for the old data property, it's just convention to throw a lot of "_" characters around it to avoid messing up any of the browser's native DOM properties.
这篇关于将新数据与 d3.js 更新上的先前数据进行比较/差异的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!