Skip to content Skip to sidebar Skip to footer

How To Put First Row In Tsv To Row Thead In Table And The Rest Go To Tbody With D3

I'm trying to learn D3 by creating a table. The code below is what I have so far. Say my TSV data has 3 columns, I only want the first row ( 3 object from data ) => to be in my

Solution 1:

As Lars said in the comments, getting only the header row in the header section is simply a matter of only giving that much data in the data join.

However, your nested data join is rather confusing and suggests you might not understand what your data is doing, so let's break it down:

Whenever you do a d3 data join (d3.selectAll("something").data(dataset)), the dataset has to be an array, and each element of the array gets assigned to a different DOM element. The contents of the array can be single values, complex objects, or sub-arrays; they get assigned as they are either way.

If the data join is a nested selection (a selection of elements within each element of a previous selection), then you can define the dataset for the sub-selection as a function. In that case, the value passed to the function is the data for the parent element, and the expected return value is an array representing all the data for the children of that parent.

The easiest nested selections are when your original dataset is just an array of arrays. That's the data structure created by d3.tsv.parseRows(text): each row from the file is turned into an array of strings, and all the rows in the file are collected into a top-level array.

That's a different structure from what is returned by d3.tsv.parse(text), or d3.tsv(filename, function) which both read the first row as column names, don't include that row in the data, and return all the other rows as objects with named properties based on the column names. The functions you are using in your nested selection data joins are designed for use with named objects. It will still work, since the keys of an array are just it's numerical indices, but it's a lot of unnecessary work.

var hrows = thead.selectAll("tr")
      .data(data[0]) //the first row of the data file
      .enter()
      .append("tr");

var hcells = hrows.selectAll("th")
      .data(function(row) { return row; }) //row is already an array
      .enter()
      .append("th")
      .text(function(d) { return d; });


var rows = tbody.selectAll("tr")
      .data(data.slice(1)) //a slice of the data array, starting from index 1
      .enter()
      .append("tr");

var cells = hrows.selectAll("td")
      .data(function(row) { return row; })
      .enter()
      .append("td")
      .text(function(d) { return d; });

In either nested selection, the function takes the data from the parent (an array representing the row), and returns it, so that the data join will split up that array into it's individual elements one for each <th> or <td> cell.

For comparison, the complex code in your original data join:

  .data(function(row) {
    return d3.range(Object.keys(row).length).map(function(column, i) {
      return row[Object.keys(row)[i]];
      });

Assumes that the row is an object, finds out how many keys are in it (Object.keys(row).length), creates an array of integers from zero to one less than that number (d3.range(number)), and then creates a new array where each element is the result of passing a value from that array of integers to a function (array.map(function)). The function takes the passed in integer (column) OR it's index in the array (i, which will be the same integer), uses it to find the corresponding value in the list of keys for the row, then uses that key to find the corresponding value from the row object.

Again, since Javascript arrays are also just objects, this works -- but it's a very roundabout way to create an array that's identical to the row array.

Post a Comment for "How To Put First Row In Tsv To Row Thead In Table And The Rest Go To Tbody With D3"