我正在创建一个包含D3的表,该表来自CSV
文件。我没有问题使行匹配CSV
中的每一行,但我有一列具有冗长的文本数据。为了便于阅读,我希望将该列放在跨越整个表格的其他单元格中:
<table>
...
<tr>
<td>col1</td><td>col2</td>...<td>colN</td>
</tr>
<tr>
<td colspan="N">lengthy text</td>
</tr>
...
</table>
然而,D3似乎没有一个好方法来添加兄弟元素。我已经读过其他地方(d3.js - how to insert new sibling elements)迭代已经创建的第一个兄弟元素并添加第二个...但是我需要在兄弟姐妹中添加源行中的数据。
如果我尝试:
var row = mytable.enter().append("tr").attr("class","firstrow");
var row2 = mytable.enter().append("tr").attr("class","secondrow");
所有的第二个箭头都会在所有的第一个之后被追加。
如果我尝试:
var row = mytable.enter().append("tr").attr("class","firstrow");
var row2 = mytable.insert("tr").attr("class","secondrow");
第二轮被追加到第一个内部。
这与上面的结果相同:
var row = mytable.enter().append("tr").attr("class","firstrow");
var row2 = mytable.insert("tr","tr").attr("class","secondrow");
感谢任何帮助!
编辑: 对于那些想要玩的人来说,这就是整个shebang:
function createTable(source, title, columns, hook) {
var tableOutput = d3.select(hook).append("table");
var headingRow = tableOutput.append("tr");
var datasets = [source];
var tableHeadings = headingRow.selectAll(".column_headings")
.data(columns)
.enter().append("th").text(function (d) {return d;}).attr("class","column_headings");
var tableChart = function(source) {
d3.csv(source, function(d) {
return {
thing1: +d.thing1,
thing2: d.thing2,
lengthything: d.lengthything, //the text that needs to go in the second row
link: d.link //wrap a link around lenthything
};
},
function(error, data) {
//do the table
var mytable = tableOutput.selectAll().data(data);
var row = mytable.enter().append("tr").attr("class","firstrow");
var row2 = mytable.insert("tr","tr").attr("class","secondrow");
row.append("td").attr("class","numeric").text(function(d) { return d.thing1 });
row.append("td").text(function(d) { return d.thing2 });
});
};
tableChart(datasets[0]);
}
答案 0 :(得分:1)
重组您的数据。不要让N尺寸数据数组中的每个对象对应一行,而是修改数据,以便在现有行之间添加N个新行,其中每个新行是包含冗长文本的对象和标识符您可以用它来区分它与其他行。
答案 1 :(得分:1)
我明白了。我不认为这有一种严格的D3方式(尽管D3只能回答)。
function(error, data) {
//do the table
var mytable = tableOutput.selectAll().data(data);
var row = mytable.enter().append("tr").attr("class","firstrow");
//var row2 = mytable.insert("tr","tr").attr("class","secondrow");
//the above is replaced with:
d3.selectAll("tr.firstrow").each(function(d) {
p = this.parentNode; //grab the parent table element
r = document.createElement("tr");
r.setAttribute("class","secondrow");
c = document.createElement("td");
c.setAttribute("colspan","8");
a = document.createElement("a");
a.setAttribute("href",d.link);
a.innerText = d.message;
//glue everything together
c.appendChild(a);
r.appendChild(c);
//insert the second row after the first
p.insertBefore(r,this.nextSibling);
});
row.append("td").attr("class","numeric").text(function(d) { return d.thing1 });
row.append("td").text(function(d) { return d.thing2 });
});
它丑陋但有效。有没有人有更干净/更有效的方法呢?