Reputation: 1436
I have a table that will be populated with data when I click a button. Below is the Snippet:
function myFunction() {
myTable = d3.select("#mytable");
myTable.selectAll("td").remove();
var rows = add_temp_rows(myTable);
}
function add_temp_rows(table) {
data = [{"a" : get_rand_temp(),
"b" : get_rand_temp()
},
{"a" : get_rand_temp(),
"b" : get_rand_temp()
},
{"a" : get_rand_temp(),
"b" : get_rand_temp()
}];
var rows = table
.select('tbody')
.selectAll('tr')
.data(data);
rows.enter()
.append("tr")
.merge(rows);
rows.exit().remove();
rows.selectAll("td")
.data(function (d) {
return [d.a, d.b];
})
.enter()
.append('td')
.text(function (d) {
return d;
});
return rows;
}
function get_rand_temp() {
var precision = 100;
return Math.floor(Math.random() * (10 * precision - 1 * precision) + 1 * precision) / (1*precision);
}
<!DOCTYPE html>
<head>
<title>Test</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- bootstrap -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css"
integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
</head>
<body>
<div class="container">
<div class="row">
<button onclick="myFunction()">Try it</button>
<div id="FilterableTable2" class="col-8">
<div class="table-responsive">
<table class="table table-striped table-dark" id="mytable">
<thead class='thead-dark'>
<tr>
<th>Col1</th>
<th>Col2</th>
</tr>
</thead>
<tbody>
<tr>
<td>test</td>
<td>test2</td>
</tr>
<tr>
<td>test3</td>
<td>test4</td>
</tr>
<!--<tr>
<td>test</td>
<td>test2</td>
</tr>
<tr>
<td>test3</td>
<td>test4</td>
</tr>
-->
</tbody>
</table>
</div>
</div>
</div>
</div>
<!-- jQuery -->
<script src="https://code.jquery.com/jquery-3.5.1.min.js"
integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
<!-- D3 -->
<script src="https://d3js.org/d3.v4.min.js"></script>
<!-- <script src="https://d3js.org/d3.v5.min.js"></script> -->
<script src="js/main.js"></script>
</body>
Now I have several issues:
May I know how to fix this? I'm migrating from D3 v3 to v4, there are many breaking changes. Ideally what I want is that, every click will change the table to display the correct rows of data.
Upvotes: 2
Views: 60
Reputation: 8769
The mistake is that during the first call, the object rows does not contain new tr's created with .enter(), even though .merge(row) command d3js.org. So rows.selectAll("td") does not affect new tr's. Newly created tr's are selected during the second call.
So to be effective as soon as the first call, the solution is to call .selectAll("td") just after .merge(row).
//...
rows.enter()
.append("tr")
.merge(rows)
.selectAll("td")
.data(function (d) {
return [d.a, d.b];
})
.enter()
.append('td')
.text(function (d) {
return d;
});
//...
<!DOCTYPE html>
<head>
<title>Test</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- bootstrap -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css"
integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
</head>
<body>
<div class="container">
<div class="row">
<button onclick="myFunction()">Try it</button>
<div id="FilterableTable2" class="col-8">
<div class="table-responsive">
<table class="table table-striped table-dark" id="mytable">
<thead class='thead-dark'>
<tr>
<th>Col1</th>
<th>Col2</th>
</tr>
</thead>
<tbody>
<tr>
<td>test</td>
<td>test2</td>
</tr>
<tr>
<td>test3</td>
<td>test4</td>
</tr>
<!--<tr>
<td>test</td>
<td>test2</td>
</tr>
<tr>
<td>test3</td>
<td>test4</td>
</tr>
-->
</tbody>
</table>
</div>
</div>
</div>
</div>
<!-- jQuery -->
<!-- script src="https://code.jquery.com/jquery-3.5.1.min.js"
integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script -->
<!-- D3 -->
<!-- script src="https://d3js.org/d3.v4.min.js"></script -->
<script src="https://d3js.org/d3.v5.min.js"></script>
<!-- script src="js/main.js"></script -->
<script>
function myFunction() {
myTable = d3.select("#mytable");
myTable.selectAll("td").remove();
var rows = add_temp_rows(myTable);
}
function add_temp_rows(table) {
data = [{"a" : get_rand_temp(),
"b" : get_rand_temp()
},
{"a" : get_rand_temp(),
"b" : get_rand_temp()
},
{"a" : get_rand_temp(),
"b" : get_rand_temp()
}];
var rows = table
.select('tbody')
.selectAll('tr')
.data(data);
rows.enter()
.append("tr")
.merge(rows)
.selectAll("td")
.data(function (d) {
return [d.a, d.b];
})
.enter()
.append('td')
.text(function (d) {
return d;
});
rows.exit().remove();
return rows;
}
function get_rand_temp() {
var precision = 100;
return Math.floor(Math.random() * (10 * precision - 1 * precision) + 1 * precision) / (1*precision);
}
</script>
</body>
</html>
Upvotes: 2