当我在下面的示例中看到传递给步骤3的数据绑定函数的索引值时,我有点意外:
1)创建两个包装器div,其数据数组绑定到每个
2)创建两个"子div"在每个包装器中,每个
都绑定一个数组3)将p元素附加到每个" sub-div"
由于元素的嵌套方式,我希望在步骤3中看到0,1的索引传递给数据绑定函数。相反,我看到索引为0,1,2,3。
var data = d3.select("#data");
var idx = d3.select("#indexes");
//---- STEP 1
//create two divs with [1, 4] and [7, 10] bound
var dbox = data.selectAll("tbody").data([[1, 4], [7, 10]]);
dbox.enter().append("div").text(function(d,i){return "Group " + i });
dbox.exit().remove();
dbox.style({"clear":"both","padding":"5px","border":"1px solid #dddddd","overflow":"hidden","margin-bottom":"10px"});
//---- STEP 2
//create sub-divs
var tr = dbox.selectAll("div").data(function(d,i){
return d.map(function(d,i,a){ return [d, d+1, d+2]; }); //return an array of arrays [[x,y,z], [a,b,c]]
});
tr.enter().append("div").text(function(d,i){return "Index " + i});
tr.exit().remove();
tr.style({"clear":"both","overflow":"hidden","padding":"2px","border":"1px dotted #dddddd","margin-top":"5px"});
//---- STEP 3
//add text (and record indexes in the "INDEXES" section)
//since the tr selection is grouped--with two "tr" divs per "dbox", I expected to see indexes of 0,1 only, instead I see 0, 1, 2, 3.
var td = tr.selectAll("p").data(function(d,i){
idx.append("p").text(i); //track the indexes
return d;
})
td.enter().append("p");
td.exit().remove();
td.text(function(d,i){return d}).style({});

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div id="data">
</div>
<div id="indexes" style="clear:both;padding-top:20px;">
<p>INDEXES</p>
</div>
&#13;
答案 0 :(得分:0)
我认为这里的混淆是当使用.attr()或.style()等方法对选择进行操作时,传递给function参数的索引表示其父组中元素的索引。
使用.data()方法绑定数据时,传递给function参数的索引表示父元素的索引。这就是Lars在评论中所得到的。
我认为这是有道理的,因为D3选择使用固定的两级层次结构(虽然听起来像change in the future}。因此,当您绑定新数据时,选择的层次结构会发生变化。即父元素不再嵌套在选择中。
这是一个澄清的例子:
var L1 = d3.select("div#boxes");
L1.append("p").text("Level 1");
var L2 = L1.selectAll("div").data([1,2]);
L2.enter().append("div");
L2.append("p").text(function(d,i){return "Level 2"})
var L3 = L2.selectAll("div").data(function(d,i){
return [i,i];
});
L3.enter().append("div");
L3.append("p").text(function(d,i){return "Level 3 - Index during data binding: "+d+". Index after appended: "+i+"." })
var L4 = L3.selectAll("div").data(function(d,i){
return [i,i];
});
L4.enter().append("div");
L4.append("p").text(function(d,i){return "Level 4 - Index during data binding: " +d+". Index after appended: "+i+"."})
&#13;
div{
padding:5px;
margin:5px;
border:1px solid #555555;
}
p{
font-family:Arial, Helvetica, sans-serif;
font-size:13px;
}
#indexes p{
float:left;
margin-left:5px;
}
}
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div id="boxes">
</div>
&#13;
答案 1 :(得分:0)
selectAll
只是将选择中的所有元素提升为父节点(忽略组结构),并将提供的选择器依次应用于每个新的父节点,以在它们上形成新的组。在此之后,在选择前面的父节点中没有引用,该状态丢失。
tr.selectAll("p")
将tr
(2x2 = 4个)中的所有div提升为父节点,并根据绑定到它们的数据形成输入选择。所以有4个组(每个div在tr
中有一个),每个组有3个成员(父div上绑定的数据的第一个维度长度为3)。对先前父节点的引用将被丢弃。
如果values
selection.data(
values
中的 )
是一个函数,那么它是d
argument是组父组绑定的数据,i
是组索引。
如果 values
不是函数,则相同的数据绑定到每个组。