我正在尝试通过创建表来学习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; });
});
答案 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
数组相同的数组。