例如,在 html<table>
中, a<tr>
可能包含<th>
and <td>
。您如何将数据绑定到将创建偶数列 as<th>
和奇数列的行选择<td>
?
4 回答
所以,这似乎也不完美,但总是有 html() 方法。
var d = [['a','b','c','d']];
var r = d3.select('#myTable').selectAll('tr')
.data(d);
r.enter().append('tr').html(function(d) {
var i, s = '';
for (i = 0; i < d.length; i += 1) {
s += (i%2===0) ? '<th>' : '<td>';
s += d[i];
s += (i%2===0) ? '</th>' : '</td>';
}
return s;
});
据我所知,你是对的——在标准的 D3 习语中没有办法做到这一点。selection.append()
据推测,一旦可以采取功能,这将是可能的:
选择。附加(名称)
添加具有指定名称的新元素...名称必须指定为常量,尽管将来我们可能允许添加现有元素或函数以动态生成名称。
希望这样的函数能够采用标准(data, index)
参数,并解决这个问题。否则,目前,我无法从单个.enter()
选择中创建不同的元素 -.enter()
仅支持.append
、.insert
和.select
,它们都不能接受函数参数。
您可以通过将数据转换为元组并双重附加到.enter()
选择中来获得您想要的一些东西,如下所示:http: //jsfiddle.net/xuJ6w/4/
// munge data
var tuples = data.map(function(row) {
var newRow = [],
x;
// create array of objects
for (x=0; x<row.length; x+=2) {
newRow.push({
label: row[x],
value: row[x+1]
})
}
return newRow;
});
var rows = d3.select('table').selectAll('tr')
.data(tuples);
rows.enter().append('tr');
var cellPairs = rows.selectAll('.cell')
.data(function(d) { return d; });
var entry = cellPairs.enter();
entry.append('th')
.attr('class', 'cell')
.text(function(d) {
return d.label;
});
entry.insert('td', 'th + th')
.attr('class', 'cell')
.text(function(d) {
return d.value;
});
但正如您所见,当调用更新时:
cellPairs
.style('background', '#CCC');
仅更新最后附加的节点,因此数据尚未完全绑定。
我能想到的最好的方法是通过应用基于数据索引的类来使<td>
外观看起来像 a :<th>
var d = ['a','b','c','d','e','f','g'];
var tr = d3.select("#myTableRow").selectAll("td")
.data(d).enter().append("td")
.text(function(d) { return d; })
.classed("thLike", function(d,i) { return i%2===0; });
CSS:
.thLike {
font-weight: bold;
}
https://github.com/mbostock/d3/wiki/Selections#wiki-data
选择器也可以相交(“.this.that”表示逻辑 AND)或联合(“.this, .that”表示逻辑 OR)。
所以,这样的事情可能对你有用。我还没有测试过(如果这个选择不起作用,您可以将相同的类添加到每个 TD/TH 单元格并使用 选择它TR .myClass
):
var cells = tableRow.selectAll("TD, TH").data(data);
cells.enter().each(d, i) {
var cell = d3.select(this);
cell.append(i%2 ? "TD" : "TH");
})