javascript - d3 Nested Selections - Table Appending Works in d3.v2 but not in d3.v3 -
problem
i appending existing table dynamically following example in d3 api reference. problem is, code works when include d3.v2.js, doesn't work when switch d3.v3.js.
when using d3.v2, appends expect to. when using d3.v3, first object in sessions
gets appended , rest found. have created 2 fiddles showing different behavior.
fiddles
the code using append items in sessions
table hurricanes
shown here:
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
<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 guidelines regarding switching 2.0 3.0 haven't found of use.
question
why using d3.v3.js change way table being appended? , can fix it?
thanks!
there 2 problems lead strange result getting.
the first issue have existing elements on page have no data bound them, when make initial selection, selecting 5 existing tr
elements. means should expect .enter()
selection empty, , no new elements created.
the second issue results first. since there no data bound existing elements, when key function gets called, checks values associated existing elements, , gets undefined
. seems d3.v2 , d3.v3 handle error differently, in both cases error, , .enter()
selection ends containing 1 element in case of d3.v3, , 5 elements in case of d3.v2.
you can see happening logging value of d
console in key function:
d3.select('#hurricanes').select('tbody').selectall('tr') .data(sessions, function(d) { console.log(d); return d; })
you notice output
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 working in d3.v2, not case. getting different errant result. since there 5 objects in data array, should expect have 5 tr
elements in output after data joined. in other words, there should nothing in .enter()
selection, because there same number of tr
elements there datapoints in dataset.
if remove key function, d3 revert binding data index, rather key. when notice expected result of 5 elements both d3 versions:
now data bound existing elements. there's problem now, because bound data not being reflected in elements themselves. in other words, row says 'andrew 1992' bound data {name: 'fred' year: 2014}
, , on down line. update new values need select existing nodes , use .text()
function update elements newly bound data.
leave aside though, because that's not you're trying accomplish anyways. want have 10 elements in output, original 5, , 5 newly created dataset. either need to:
(1) add entries 'andrew', 'bob', 'irene', 'katrina', , 'ivan'
sessions
data, remove existing html elements representing them, , build complete table data. or
(2) create empty selection within
tbody
, append new elements that: 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; });
i hope helps. if want read on nested selections , key functions, here couple excellent posts mike bostock himself:
Comments
Post a Comment