将新数据与 d3.js 更新上的先前数据进行比较/差异 [英] Compare/Diff new data with previous data on d3.js update

查看:27
本文介绍了将新数据与 d3.js 更新上的先前数据进行比较/差异的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想表示客户端计算的当前数据集和前一个数据集之间的差异.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆