[更新] 经过另一次测试后,我发现我对密钥的理解是错误的,密钥匹配的工作方式是:
当D3尝试匹配DOM和数据时,它将使用该键功能提取标识符,
,它取出数据值并使用该值(可能是对象)为DOM元素生成密钥(如果密钥函数使用数据,否则只运行该键函数并给出一个键值而不管它是什么),我曾经认为它只是将另一个属性存储为DOM元素中的键,只是简单地将该值用作键,但实际上它应用了该键函数并根据当前绑定数据计算密钥。
,它直接使用每个数据来生成密钥,类似于DOM。
如果计算出的密钥相互匹配,那么没有任何东西触及这个元素,在所有匹配之后如果找不到匹配,则将DOM放入exit()或将数据放入更新(用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键功能as explained here
很陌生当我尝试这样的代码时:
<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 _”+ index的键。测试:
有没有人可以帮助我如何使D3像我期望的那样工作?我不想更新现有的“更新集合”内的任何内容,D3会变成按钮0 1 2,而是我只想添加一个缺少的元素,将其插入按钮2。
答案 0 :(得分:1)
您只使用索引作为键,并且在不同的调用中进行更改。特别是,指数清单不会有漏洞。因此,对于第二次调用,带有数据3的按钮具有索引2,并且在删除一个按钮时没有索引3。所以它的索引3不匹配。
要使其正常工作,请使用键功能中的实际数据:
.data([0,1,2,3], function(d) { return d; })