保持D3数据中的顺序 [英] Keeping order in D3 data

查看:107
本文介绍了保持D3数据中的顺序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据我的理解,更新d3数据的正确方法是将其传递到选择的 .data()

From what I understand the proper way to update d3 data is by passing it into the selection's .data().

我获得的数据不是有序的,也不是一致的。所以我非常需要使用update / add / remove逻辑。所以在d3项中, .data() .enter() .exit )(right?)。

The data that I obtain is not ordered, or consistant for that matter. So I heavily need to use the update / add / remove logics. So in d3 terms that's .data() with .enter() and .exit() (right?).

所以我想做的是使用一个javascript字典而不是一个数组,是我的唯一标识符。但我似乎不能这样做。假的例子:

So what I'd like to do is to use a javascript dictionary instead of an array, where the key is my unique identifier. But I can't seem to do that. A fake example:

data_one[0] = 'Dogs';
data_one[1] = 'Cats';

d3.selectAll('circle').data(data_one).enter().attr(...)

我第二次运行这个数据可能是相同的,但顺序不同。我想用与之前相同的属性来表示它。我不想复制我的代码,但如果我只是做.data(data_two),那么错误的圈子会更新新的数据。

The second time I run this my data may be same but in different order. I want to represent it with the same attributes as before. I don't want to duplicate my code, but if I just do .data(data_two) then wrong circles get updated with the new data.

任何方式?

推荐答案

这是键函数的目的, selection.data :它可让您维护 object constancy 通过控制哪个数据绑定到哪个元素。例如,假设您有一个表示水果的对象数组:

This is the purpose of the key function, the second argument to selection.data: it lets you maintain object constancy by controlling which datum gets bound to which element. For example, say you had an array of objects representing fruit:

var fruits = [
  {name: "orange", value: 200},
  {name: "apple", value: 124},
  {name: "banana", value: 32}
];

首次创建元素时,不需要键功能,现有元素,因此您可以使用标准的selectAll-data-enter-append模式:

When you first create the elements, you don’t need a key function because there aren’t any existing elements, and so you can use the standard selectAll-data-enter-append pattern:

var div = d3.select("body").selectAll(".fruit")
    .data(fruits)
  .enter().append("div")
    .attr("class", "fruit")
    .text(function(d) { return d.name + ": " + d.value; });

此操作的结果是:

<body>
  <div class="fruit">orange: 200</div>
  <div class="fruit">apple: 124</div>
  <div class="fruit">banana: 32</div>
</body>

但现在让我们说你的数据发生变化,你想更新以反映新数据。这些新数据可能采用不同的顺序,并且可能添加或删除一些元素:

But now let’s say your data changes, and you want to update to reflect the new data. This new data may be in a different order, and some elements may be added or removed:

var fruits2 = [
  {name: "apple", value: 124},
  {name: "lemon", value: 17},
  {name: "banana", value: 32},
  {name: "strawberry", value: 1465}
];

苹果和香蕉都在原始数据中,所以我们想保留它们。这称为更新选择。草莓和柠檬是新的;这是输入选项。最后,橙色消失,形成 选择

The apple and banana were in the original data, and so we want to keep them. This is called the update selection. The strawberry and lemon are new; this is the enter selection. And lastly the orange went away, forming the exit selection.

使用引用 / code>属性的数据,我们可以分配新数据到旧元素的意图。然后我们可以创建进入的水果,并删除退出的水果:

Using a key function that refers to the name property of the datum, we can assign the new data to the old elements as intended. Then we can create the entering fruit and remove the exiting fruit:

var div = d3.select("body").selectAll(".fruit")
    .data(fruits2, function(d) { return d.name; });

div.enter().append("div")
    .attr("class", "fruit")
    .text(function(d) { return d.name + ": " + d.value; });

div.exit().remove();

这称为一般更新模式。 (你可以第一次这样做;它是selectAll-data-enter-append模式的更一般形式。)结果是:

This is called the general update pattern. (You could have done this the first time around; it’s the more general form of the selectAll-data-enter-append pattern.) The result is:

<body>
  <div class="fruit">apple: 124</div>
  <div class="fruit">banana: 32</div>
  <div class="fruit">lemon: 17</div>
  <div class="fruit">strawberry: 1465</div>
</body>

当选择 div 数据 fruit2 ,DOM中的顺序不会 ,因为输入的元素附加到正文的末尾。 (selection.append没有任何奇特的逻辑来保证排序;它只是将新的元素追加到父的结尾。)当使用SVG时,我们经常不关心DOM元素的顺序,因为一切都是绝对定位的。如果您关心订单,可以使用选择.order 在输入之后修复它:

While the order of the selection div matches the data fruit2, the order in the DOM does not because the entering elements were appended to the end of the body. (selection.append doesn’t have any fancy logic to guarantee ordering; it just appends new elements to the end of the parent.) When using SVG, we often don’t care about the order of DOM elements because everything is positioned absolutely. If you do care about the order, you can use selection.order to fix it after entering:

div.order(); // make the DOM element order match the selection

此外,在此示例中,对更新选择进行任何更改,因为苹果和香蕉的值没有更改。如果更新数据也发生变化,可以直接从上面的selection.data调用中进行selection.attr和selection.text的链调用。

Also, in this example, we don’t need to make any changes to the update selection, because the values for apple and banana didn’t change. If the updating data also changes, you can make chain calls to selection.attr and selection.text directly off of the selection.data call above.

这篇关于保持D3数据中的顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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