在d3 for javascript中,如何为数据创建不同的元素?

时间:2012-08-27 14:33:19

标签: javascript d3.js binding html-table

例如,在html <table>中,<tr>可能包含<th><td>。如何将数据绑定到行选择,该行选择甚至会创建<th>列,奇数为<td>

4 个答案:

答案 0 :(得分:3)

所以,这似乎也不完美,但总是有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;
}​​​​​​​​​​​​​​​);

答案 1 :(得分:2)

据我所知,你是正确的 - 在标准的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');

仅更新最后添加的节点,因此数据尚未完全绑定。

答案 2 :(得分:1)

我能想到的最好的方法是通过根据数据索引应用类来使<td>看起来像<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;
}

答案 3 :(得分:0)

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