bro*_*000 46
我也是d3的新手,并且正在努力完成关键功能.我没有发现Tristan Reid的答案很有启发性,因为它并没有真正谈论关键功能.
让我们通过一个例子,首先没有关键功能,然后用.
这是我们在应用javascript之前的初始html.我们有两个div,没有数据附加到任何东西.
<body>
<div>** First div **</div>
<div>** Second div **</div>
</body>
Run Code Online (Sandbox Code Playgroud)
让我们添加几行javascript.
var arr1 = [35, 70, 24, 86, 59];
d3.select("body")
.selectAll("div")
.data(arr1)
.enter()
.append("div")
.html(function(d) { return d });
Run Code Online (Sandbox Code Playgroud)
我们的HTML现在是什么样的?这是html以及相关数据的值(添加了注释).
<body>
<div>** First div ** </div> <!-- data: 35 -->
<div>** Second div ** </div> <!-- data: 70 -->
<div>24</div> <!-- data: 24 -->
<div>86</div> <!-- data: 86 -->
<div>59</div> <!-- data: 59 -->
</body>
Run Code Online (Sandbox Code Playgroud)
的数据()调用匹配的div的阵列与由使用的密钥的值的数组.用于数组的默认键是索引.所以这些是使用的密钥.
selected divs (by text) key data elements key
----------------------- --- ------------- ---
** First div ** 0 35 0
** Second div ** 1 70 1
24 2
86 3
59 4
Run Code Online (Sandbox Code Playgroud)
通过键,两个数据元素在所选div中具有匹配 - 具有键0和1的那些.匹配的div被绑定到数据,但没有其他任何事情发生.
没有匹配键的所有数据元素都传递给enter().在这种情况下,键2,3和4不匹配.因此,这些数据元素将传递给enter(),并为每个数据元素添加一个新的div.附加的div也绑定到它们各自的数据值.
让我们改变我们的javascript,保留我们的东西,但添加几行.我们将使用数据调用(使用不同的数组)执行相同的选择,但这次使用键功能.注意arr1和arr2之间的部分重叠.
var arr1 = [35, 70, 24, 86, 59];
d3.select("body")
.selectAll("div")
.data(arr1) // no key function
.enter()
.append("div")
.html(function(d) { return d });
var arr2 = [35, 7, 24, 2];
d3.select("body")
.selectAll("div")
.data(arr2, function(d) { return d }) // key function used
.enter()
.append("div")
.html(function(d) { return "new: " + d});
Run Code Online (Sandbox Code Playgroud)
生成的html看起来像这样(添加了注释):
<body>
<div>** First div** </div> <!-- data: 35 -->
<div>** Second div ** </div> <!-- data: 70 -->
<div>24</div> <!-- data: 24 -->
<div>86</div> <!-- data: 86 -->
<div>59</div> <!-- data: 59 -->
<div>new: 7</div> <!-- data: 7 -->
<div>new: 2</div> <!-- data: 2 -->
</body>
Run Code Online (Sandbox Code Playgroud)
对data()的第二次调用使用函数返回的值作为键.对于所选元素,该函数返回一个值,该值是从第一次调用data()时已经绑定到它们的数据派生的.也就是说,他们的关键是基于他们的绑定数据.
对于第二个data()调用,用于匹配的键看起来像这样.
selected divs (by text) key data elements key
----------------------- --- ------------- ---
** First div ** 35 35 35
** Second div ** 70 7 7
24 24 24 24
86 86 2 2
59 59
Run Code Online (Sandbox Code Playgroud)
没有匹配键的数据元素是7和2.这些数据元素被传递给enter().所以我们得到两个新的div附加到正文.
好的,现在让我们回顾原帖.OP表示data()调用与函数之间没有区别.这可能是因为 - 正如Tristan Reid建议的那样 - 关键函数被用在没有绑定数据的html元素上.当没有绑定数据时,将没有匹配的键,因此所有数据元素都将传递给enter()函数.
通过这个例子帮助我了解选择,键和绑定数据之间的关系.希望它会对其他人有所帮助.
Tri*_*eid 13
关键功能解释了如何将数据连接到元素.如果您不提供默认键功能,则使用索引.
要理解这一切,请考虑d3 selectAll/data正在执行两个匹配阶段.第一个是选择器,例如d3.selectAll('div'),它将匹配所有div.第二个是数据连接,data([1,2,3])它正在查找具有与传入的数据匹配的数据属性的元素.重点是因为我认为理解这一点对于从d3中获得充分利益至关重要.
这是一个展示差异的例子(也是一个小提琴).
function id (d) { return d; }
d3.select('.no-key').selectAll('div')
.data([1,2,3])
.enter().append('div')
.text(id);
d3.select('.yes-key').selectAll('div')
.data([1,2,3], id)
.enter().append('div')
.text(id);Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div class='no-key'>
<div class='a'>already here</div>
</div>
<br/>
<div class='yes-key'>
<div>already here</div>
</div>Run Code Online (Sandbox Code Playgroud)
我赞同其他答案的努力,但这个答案不需要解析控制台,它显示了功能的实际差异.
为什么会出现这种差异?以下是血腥的细节:
如果您这样做d3.selectAll('div'),则选择所有div.如果你这样做.data([1,2,3]),你将这些数据加入到那些div:但是连接没有键功能,所以它不是要查看div是否有[1,2,3]作为数据元素,它是只是要使用它找到的前3个div.
相反.data([1,2,3], function(d){return d;}),如果您这样做,您的关键函数会将[1,2,3]与div中的数据进行匹配,因此除非您有现有的具有数据元素的div,否则您将无法匹配任何现有的div.
所有这些的例子都在.enter().append('div'),其中当然添加了在上述匹配中找不到的任何必要的div.这是所有这些enter().append业务的底线:它增加了(数据元素的数量) - (与关键功能匹配的现有元素的数量)
希望这可以帮助!
| 归档时间: |
|
| 查看次数: |
17823 次 |
| 最近记录: |