D3.js d3:DOM元素实际上没有绑定到数据(?)

D3.js d3:DOM元素实际上没有绑定到数据(?),d3.js,selection,D3.js,Selection,我完全被这搞糊涂了。我看了一个字母示例,其中更新的元素根据字母在数据集中的位置改变其位置 现在我想用div元素(”.item的)复制类似的东西。到目前为止,我已经: var displayData = function() { // DATA JOIN var items = d3.select('#data').selectAll('.item'); items = items.data(data); // UPDATE items.transition

我完全被这搞糊涂了。我看了一个字母示例,其中更新的元素根据字母在数据集中的位置改变其位置

现在我想用div元素(
”.item的
)复制类似的东西。到目前为止,我已经:

var displayData = function() {
    // DATA JOIN
    var items = d3.select('#data').selectAll('.item');
    items = items.data(data);
    // UPDATE
    items.transition().duration(500)
        .style('left', function(d, i) {
            return positions[i].left + "px";
        }).style('top', function(d, i) {
            return positions[i].top + "px";
        });

    // ENTER
    var div = items.enter().append('div')
        .attr('class', 'item')
        .style('left', function(d, i) {
            return positions[i].left + "px";
        }).style('top', function(d, i) {
            return positions[i].top + "px";
        })
        .style('opacity', 1e-6)
        .transition().duration(TRANSITION_DURATION)
        .style('opacity', 1);

    // EXIT
    items.exit().transition().duration(500).style('opacity', 0).remove();
}
位置
是一个简单的对象数组,具有预先计算的位置(它们根据屏幕大小而变化),例如:

因此,给定一个包含四个数据对象的数组
data=[{a}、{b}、{c}、{d}]
,上述代码在第一次调用时生成一个2x2的
div.item
s网格

现在,当我将数据更改为
data=[{b},{a}]
时会发生什么让我感到困惑。在数据联接之后,
如下所示:

[Array[2]
0: div.item
1: div.item
length: 2
parentNode: div#data
__proto__: Array[0]
]
div.item
0的
\uuuu data\uuuu
指向对象
{b}
,我认为这是正确的,但是我无法进行第一个和第二个元素交换位置,因为它们“忘记”了它们的旧位置


另一个场景:假设我将原始数据更改为
data=[{b},{a},{e}]
,也就是说,我引入了一个新元素
{e}
。然后我想交换前两个元素(带有转换),首先删除第三个元素(
{c}
),然后淡入新的第三个元素(
{e}
)。这可能吗?我做错了什么/我误解了什么?

在阅读了更多的问题和示例后,我发现这个问题与对象恒常性有关(请参阅)。我必须在
data
函数中指定某个键:

items = items.data(data, function(d){ return d.key; );
我建议你读书

您的示例与原始示例的不同之处在于绑定数据时没有使用键函数。如果不指定键函数,它将默认使用元素的位置(索引)来确定哪些元素是相同的(因此应该保留以供更新选择),哪些应该添加/删除

从:

如果未指定键函数,则指定数组中的第一个基准将指定给当前选择中的第一个图元,第二个基准将指定给第二个选定图元,依此类推


因此,我建议使用一个键函数,以便在绑定新数据时添加、更新和删除正确的元素。

感谢您提供了更好的解释(与我的简短回答相比)。我现在添加了按键功能,它可以根据需要工作,尽管我仍在使用
I
查找位置。我想我误解了您使用位置的方式,我将从答案中删除该部分。:)
items = items.data(data, function(d){ return d.key; );