如何在tsv中将第一行放入表格中,并将其余部分放入t3中

时间:2014-02-13 14:42:32

标签: javascript d3.js

我正在尝试通过创建表来学习D3。下面的代码是我到目前为止的代码。

假设我的TSV数据有3列,我只想要第一行(来自数据的3个对象)=>在我的thead部分 其余的(我的数据的第四个对象)进入tbody部分

d3.text("test.tsv",  function(text) {
    var data = d3.tsv.parseRows(text);

var table = d3.select("body").append("table"), 
      thead = table.append("thead"),
      tbody = table.append("tbody");

 var hrows = thead.selectAll("tr")
      .data(data)
      .enter()
      .append("tr");



      var hcells = hrows.selectAll("th")
      .data(function(row) {
        return d3.range(Object.keys(row).length).map(function(column, i) {
          return row[Object.keys(row)[i]];
          });
        })
      .enter()
      .append("th")
      .text(function(d) { return d; });

// ============
      var rows = tbody.selectAll("tr")
      .data(data)
      .enter()
      .append("tr");


      var cells = rows.selectAll("td")
      .data(function(row) {
        return d3.range(Object.keys(row).length).map(function(column, i) {
          return row[Object.keys(row)[i]];
          });
        })
      .enter()
      .append("td")
      .text(function(d) { return d; });
 });

1 个答案:

答案 0 :(得分:3)

正如Lars在评论中所说,只在标题部分中获取标题行只是在数据连接中只提供了那么多数据。

但是,您的嵌套数据加入相当混乱,并建议您可能无法理解您的数据正在做什么,所以让我们分解它:

每当您执行d3数据连接(d3.selectAll("something").data(dataset))时,数据集必须是一个数组,并且数组的每个元素都被分配给不同的DOM元素。数组的内容可以是单值,复杂对象或子数组;无论哪种方式,他们都会被分配。

如果数据连接是嵌套选择(前一个选择的每个元素中的元素选择),则可以将子选择的数据集定义为函数。在这种情况下,传递给函数的值是 parent 元素的数据,期望的返回值是数组,表示该父元素的子元素的所有数据

最简单的嵌套选择是当您的原始数据集只是一个数组数组时。这是d3.tsv.parseRows(text)创建的数据结构:文件中的每一行都变成了一个字符串数组,文件中的所有行都被收集到一个顶级数组中。

这与d3.tsv.parse(text)d3.tsv(filename, function)返回的结构不同,后者都将第一行作为列名读取,不包含数据中的该行,并返回所有其他行作为具有基于列名称的命名属性的对象。您在嵌套选择数据连接中使用的函数旨在用于命名对象。它仍然可以工作,因为数组的键只是它的数字索引,但这是很多不必要的工作。

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; });

在任一嵌套选择中,函数从父项(表示行的数组)中获取数据,并返回它,以便数据连接将该数组拆分为每个<th>的单个元素。或<td>单元格。

为了进行比较,原始数据中的复杂代码加入:

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

假设该行是一个对象,找出其中有多少个键(Object.keys(row).length),创建一个从0到1的整数数组(d3.range(number)),然后创建一个新数组,其中每个元素是将整数数组中的值传递给函数(array.map(function))的结果。该函数接受传入的整数(column)或它在数组中的索引(i,它将是相同的整数),用它来查找行的键列表中的相应值,然后使用该键从行对象中找到相应的值。

同样,由于Javascript数组也只是对象,这是有效的 - 但它是一种非常迂回的方式来创建一个与row数组相同的数组。