I’m trying to create a table in D3 that updates with new data. This mostly works.
Somehow I’m not getting any columns in newly added rows (so initially the table is empty).
What am I doing wrong?
See: https://jsfiddle.net/yev4kujn/21/
JavaScript
x
17
17
1
var rows = tableBody.selectAll("tr").data(data);
2
rows.exit().remove();
3
rows.enter().append("tr");
4
5
var cells = rows.selectAll("td")
6
.data(function(d, i) {
7
return Object.values(d);
8
});
9
cells.exit().remove();
10
cells.enter().append("td")
11
.text(function(d) {
12
return d;
13
});
14
cells.text(function(d) {
15
return d;
16
});
17
Advertisement
Answer
In D3 selections are immutable. Therefore, when you do this…
JavaScript
1
2
1
rows.enter().append("tr")
2
… you are not changing what rows
is: it keeps being an update selection, which is empty when the function runs for the first time. So, when you come to…
JavaScript
1
2
1
var cells = rows.selectAll("td")
2
… there are no <tr>
s to append the <td>
s.
All that being said, you have to change what rows
is:
JavaScript
1
2
1
rows = rows.enter().append("tr").merge(rows);
2
Now rows
contains the entered elements.
Here is your code with that change:
JavaScript
1
60
60
1
var data1 = [{
2
"name": "Steve",
3
"age": "34"
4
},
5
{
6
"name": "Brian",
7
"age": "44"
8
},
9
{
10
"name": "Amy",
11
"age": "45"
12
}
13
];
14
15
var data2 = [{
16
"name": "Jennifer",
17
"age": "54",
18
"adult": "no"
19
},
20
{
21
"name": "Mike",
22
"age": "14",
23
"flowers": "yes"
24
}
25
];
26
27
var toggle = true;
28
29
function update() {
30
if (toggle) {
31
updateTable(data1);
32
} else {
33
updateTable(data2);
34
}
35
toggle = !toggle;
36
}
37
38
39
var tableBody = d3.select("#tableBody");
40
update();
41
42
function updateTable(data) {
43
44
var rows = tableBody.selectAll("tr").data(data);
45
rows.exit().remove();
46
rows = rows.enter().append("tr").merge(rows);
47
48
var cells = rows.selectAll("td")
49
.data(function(d, i) {
50
return Object.values(d);
51
});
52
cells.exit().remove();
53
cells.enter().append("td")
54
.text(function(d) {
55
return d;
56
});
57
cells.text(function(d) {
58
return d;
59
});
60
}
JavaScript
1
14
14
1
td {
2
border: 2px solid green;
3
}
4
5
th {
6
border: 2px solid red;
7
}
8
9
tr {
10
border: 2px solid blue;
11
display: block;
12
padding: 3px;
13
margin: 2px;
14
}
JavaScript
1
19
19
1
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
2
<p>
3
This button toggles between two datasets:
4
</p>
5
<button onclick="update()">
6
Toggle
7
</button>
8
9
<table>
10
<thead>
11
<tr>
12
<th>Col 1</th>
13
<th>Col 2</th>
14
<th>Col 3</th>
15
</tr>
16
</thead>
17
<tbody id="tableBody">
18
</tbody>
19
</table>