[英]How to put first row in tsv to row thead <th> in table and the rest go to tbody <td> with d3
我正在尝试通过创建表格来学习D3。 下面的代码是我到目前为止所拥有的。
说我的TSV数据有3列,我只希望第一行(数据中的3个对象)=>在我的thead部分中,其余的(我数据的第4个对象)进入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; });
});
正如Lars在评论中所说,仅在标头部分中获得标头行仅仅是在数据联接中仅提供那么多数据的问题。
但是,嵌套的数据联接相当混乱,建议您可能不了解数据的功能,因此我们将其分解:
每当执行d3数据d3.selectAll("something").data(dataset)
( d3.selectAll("something").data(dataset)
)时,数据集都必须是一个数组,并且数组的每个元素都将分配给另一个DOM元素。 数组的内容可以是单个值,复杂对象或子数组。 他们被分配,因为他们是任一种方式。
如果数据联接是嵌套选择 (先前选择的每个元素中的元素选择),则可以将子选择的数据集定义为函数。 在这种情况下,传递给函数的值是父元素的数据,而预期的返回值是一个表示该父元素的所有子数据的数组 。
最简单的嵌套选择是当原始数据集只是一个数组数组时。 那就是d3.tsv.parseRows(text)
创建的数据结构:文件中的每一行都变成一个字符串数组,文件中的所有行都被收集到一个顶级数组中。
这与d3.tsv.parse(text)
或d3.tsv(filename, function)
返回的结构不同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
),创建一个从零到小于该数字( d3.range(number)
)的整数数组,然后然后创建一个新数组,其中每个元素都是将整数数组中的值传递给函数( array.map(function)
)的结果。 该函数采用传入的整数( column
)或它在数组中的索引( i
,它将是相同的整数),使用它在该行的键列表中查找对应的值,然后使用该键来查找行对象的对应值。
再一次,由于Javascript数组也只是对象,因此可以工作-但这是创建与row
数组相同的数组的一种非常round回的方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.