试图了解 D3 .data 键函数的工作原理

Trying to understand how D3 .data key function works

本文关键字:工作 函数 了解 D3 data      更新时间:2023-09-26

[更新] 经过另一次测试,事实证明我对键的理解是错误的,键匹配的工作方式是:

当 D3 尝试匹配 DOM 和数据时,它将使用该键函数来提取标识符,

    从 DOM 中,它取出数据值并使用该值(
  1. 可能是对象(为 DOM 元素生成键(如果键函数使用该数据,否则只需运行该键函数并给出一个键值,不管它是什么(,我曾经认为它只是将另一个属性存储为 DOM 元素中的键,只需将该值用作键, 但实际上它应用了该键函数并根据当前绑定数据计算键。

  2. 从新数据中,它直接使用每个基准面来生成密钥,类似于来自 DOM 的数据。

如果计算出的键相互匹配,那么这个元素上什么都没有涉及,毕竟匹配如果找不到匹配,那么要么把 DOM 放到 exit(( 中,要么把数据放到 update(带有一个 plce 持有者

用于附加的 DOM(。

我在这里添加了类似的代码,以方便其他人理解这一点。基本的区别是这次我使用具有包含属性的对象数组,该数组可以用作生成键的键函数

function addbtn(){
    var keys = [];
    var data = [
        {
            id:0,
            value:"a"
        },
        {
            id:1,
            value:"b"
        },
        {
            id:2,
            value:"c"
        },
        {
            id:3,
            value:"d"
        }
    ]
    var btns = d3.select(".body")
        .selectAll("button")
        .data(data, function(d, i){
           // D3 will take out __data__ from each element, and use its __data__.id as key, 
           // same to the data to be bind, it takes each datum from that data array 
           // and use its id as key to match element's key if matched, go to next, until either there is data left or element left.
           // So when I remove button 2, the comparing will find the element with data id 2 missing( there is data left),
           //so it will put a place holder for an element which will bind the data 2
            return d.id;
        });
    btns.enter()
        .append("button")
        .text(function(d, i){
            return d.value;
        });
    btns.exit().remove();
}

我对 D3 键功能很陌生,如此处所述

当我尝试这样的代码时:

<button onclick="addbtn()">Add New Button</button>
<div class="body"></div>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.14/d3.js"></script>
    <script type="text/javascript">
function addbtn(){
    var keys = [];
    var btns = d3.select(".body")
        .selectAll("button")
        .data([0,1,2,3], function(d, i){
            var k = i;
            keys.push(k);
            return "key_"+k;
        });
    btns.enter()
        .append("button")
        .text(function(d, i){
            return d;
        });
    btns.exit().remove();
}
</script>

我对key的理解是,它是一个绑定到数据和 DOM 元素的值,使它们具有可比性。如果数据和元素具有相同的键值(通过一定的比较算法(,则它们被匹配和绑定。(这就是我认为它的工作原理,但我不确定我的理解是否正确(。

在我的实验中,我指定了返回"key_"+索引的键。要测试:

  1. 第一次单击后,按预期附加了 4 个按钮。
  2. 我手动删除按钮 2,然后再次单击。
  3. 我以为键匹配会发现带有 key_2 的按钮丢失,因此它会附加一个带有 key_2 的按钮并将数据 2 绑定到它。 令人惊讶的是,它会在按钮后附加数据 3。

谁能帮助如何使 D3 像我期望的那样工作?我不想更新 D3 变成按钮 0 1 2 的现有"更新集合"中的任何内容,而是只想添加一个缺少的元素,将其作为按钮 2 插入。

您仅使用索引作为键,并且在不同的调用中会发生变化。特别是,索引列表永远不会有漏洞。因此,对于第二次调用,数据为 3 的按钮具有索引 2,并且没有索引 3,因为您删除了一个按钮。因此,不匹配的是索引 3。

要使其正常工作,请使用键函数中的实际数据:

.data([0,1,2,3], function(d) { return d; })