简体   繁体   English

d3嵌套选择-表附加在d3.v2中有效,但在d3.v3中无效

[英]d3 Nested Selections - Table Appending Works in d3.v2 but not in d3.v3

Problem 问题

I am appending to an existing table dynamically following the example in the D3 API reference . 我将按照D3 API参考中示例动态添加到现有表 The problem is, this code works when I include d3.v2.js, but doesn't work when I switch to d3.v3.js. 问题是,当我包含d3.v2.js时,此代码有效,但是当我切换至d3.v3.js时,此代码不起作用。

When using d3.v2, everything appends as I would expect it to. 使用d3.v2时,所有内容都会按我期望的那样追加。 When using d3.v3, only the first object in sessions gets appended and the rest are nowhere to be found. 使用d3.v3时,仅会添加sessions的第一个对象,而其他位置则找不到。 I have created two fiddles showing the different behavior. 我创建了两个显示不同行为的小提琴。

Fiddles 小提琴

The code I am using to append the items in sessions to the table hurricanes is shown here: 我使用追加中的项目的代码sessionshurricanes如下所示:

Javascript 使用Javascript

var sessions = [
    {name: 'Fred',     year: 2014},
    {name: 'Bill',     year: 1970},
    {name: 'Pookie',   year: 1892},
    {name: 'Hurry',    year: 1941},
    {name: 'Nick',     year: 1953}
];

d3.select('#hurricanes').select('tbody').selectAll('tr')
        .data(sessions, function(d) { return d; })
    .enter().append('tr')
        .selectAll('td')
        .data(function(d) { return d3.values(d); })
    .enter().append('td')
        .text(function(d) { return d; });

HTML HTML

<table id='hurricanes'>
  <tbody>
    <tr>
      <td>Andrew</td>
      <td>1992</td>
    </tr>
    <tr>
      <td>Bob</td>
      <td>1991</td>
    </tr>
    <tr>
      <td>Irene</td>
      <td>2011</td>
    </tr>
    <tr>
      <td>Katrina</td>
      <td>2005</td>
    </tr>
    <tr>
      <td>Ivan</td>
      <td>2004</td>
    </tr>
  </tbody>
</table>

I have read the guidelines regarding switching from 2.0 to 3.0 but I haven't found anything of use. 我已经阅读了有关从2.0切换到3.0指南,但没有发现任何用处。

Question

Why does using d3.v3.js change the way the table is being appended? 为什么使用d3.v3.js会更改表的添加方式? And what can I do to fix it? 而我该如何解决呢?

Thanks! 谢谢!

There are two problems that lead to the strange result you are getting. 有两个问题导致您得到奇怪的结果。

The first issue is that you have existing elements on your page that have no data bound to them, so when you make your initial selection, you are selecting the 5 existing tr elements. 第一个问题是页面上现有元素没有绑定数据,因此,当您进行初始选择时,将选择5个现有tr元素。 This means that we should expect the .enter() selection to be empty, and no new elements will be created. 这意味着我们应该期望.enter()选择为空,并且不会创建任何新元素。

The second issue results from the first. 第二个问题来自第一个。 Since there is no data bound to the existing elements, when your key function gets called, it checks for the values associated with the existing elements, and gets back undefined . 由于没有数据绑定到现有元素,因此在调用键函数时,它将检查与现有元素关联的值,并返回undefined It seems that d3.v2 and d3.v3 handle this error differently, but in both cases it is an error, and the .enter() selection ends up containing one extra element in the case of d3.v3, and 5 extra elements in the case of d3.v2. 似乎d3.v2和d3.v3处理此错误的方式有所不同,但在两种情况下都是错误,对于.enter().enter()选择最终包含一个额外的元素,而在.enter()包含5个额外的元素。 d3.v2的情况。

You can see that this is happening by logging the value of d to the console in your key function: 您可以通过在关键函数中将d的值记录到控制台中来看到这种情况:

d3.select('#hurricanes').select('tbody').selectAll('tr')
  .data(sessions, function(d) { 
     console.log(d);
     return d; 
  })

You will notice that the output is 您会注意到输出为

undefined
undefined
undefined
undefined
undefined
Object {name: "Fred", year: 2014}
Object {name: "Bill", year: 1970}
Object {name: "Pookie", year: 1892}
Object {name: "Hurry", year: 1941}
Object {name: "Nick", year: 1953}

You say that it is working in d3.v2, but that is not the case. 您说它正在d3.v2中工作,但事实并非如此。 You are simply getting a different errant result. 您只是得到了不同的错误结果。 Since there are only 5 objects in your data array, you should expect to only have 5 tr elements in your output after the data is joined. 由于数据数组中只有5个对象,因此连接数据后,输出中应该只有5个tr元素。 In other words, there should be nothing in the .enter() selection, because there are already the same number of tr elements as there are datapoints in your dataset. 换句话说, .enter()选择中不应包含任何内容,因为tr元素的数量与数据集中的数据点数量相同。

If you remove the key function, d3 will revert to binding the data by index, rather than by key. 如果删除键功能,则d3将还原为按索引而不是按键绑定数据。 When you do this you will notice that you now get the expected result of 5 elements with both d3 versions: 当您执行此操作时,您会注意到在d3和d2两种版本中,您现在都可以获得5个元素的预期结果:

d3.v2 JSFiddle d3.v2 JSFiddle

d3.v3 JSFiddle d3.v3 JSFiddle

Now the data is bound to the originally existing elements. 现在,数据已绑定到最初存在的元素。 But there's a problem now, because the bound data is not being reflected in the elements themselves. 但是现在有一个问题,因为绑定的数据没有反映在元素本身中。 In other words, the row that says 'Andrew 1992' is bound to data {name: 'Fred' year: 2014} , and so on down the line. 换句话说,写着'Andrew 1992'的行绑定到数据{name: 'Fred' year: 2014} ,依此类推。 To update to the new values you would need to select the existing nodes and use the .text() function to update the elements with their newly bound data. 要更新为新值,您将需要选择现有节点并使用.text()函数以其新绑定的数据更新元素。

Leave that all aside though, because that's not what you're trying to accomplish anyways. 不过,请将其放在一边,因为无论如何这都不是您要尝试完成的事情。 You want to have 10 elements in your output, the original 5, and 5 newly created from the dataset. 您要在输出中包含10个元素,原始5个元素,以及从数据集中新创建的5个元素。 To do that you either need to: 为此,您要么需要:


(1) Add entries for 'Andrew', 'Bob', 'Irene', 'Katrina', and 'Ivan' to the sessions data, remove the existing html elements representing them, and then build a complete table from the data. (1)sessions数据中添加“ Andrew”,“ Bob”,“ Irene”,“ Katrina”和“ Ivan”的条目,删除代表它们的现有html元素,然后从该数据中构建完整的表。

Method 1 JSFiddle 方法1:JSFiddle


OR 要么
(2) Create an empty selection within the tbody and append the new elements to that: (2)tbody创建一个空选择,并将新元素附加到其中:

 d3.select('#hurricanes').select('tbody').selectAll('.new-entry') .data(sessions) .enter().append('tr') .attr('class', 'new-entry') .selectAll('td') .data(function(d) { return d3.values(d); }) .enter().append('td') .text(function(d) { return d; }); 

Method 2 JSFiddle 方法2:JSFiddle


I hope that helps. 希望对您有所帮助。 If you want to read up on nested selections and key functions, here are a couple excellent posts from Mike Bostock himself: 如果您想阅读嵌套选择和关键功能,以下是Mike Bostock本人的几篇精彩文章:

Nested Selections 嵌套选择

Object Constancy 对象常数

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM