For example, in a html <table>
, a <tr>
may contain <th>
and <td>
. How would you bind data to a row selection that would create even columns as <th>
and odd as <td>
?
For example, in a html <table>
, a <tr>
may contain <th>
and <td>
. How would you bind data to a row selection that would create even columns as <th>
and odd as <td>
?
4 Answers
Reset to default 3So, this doesn't seem perfect either, but there's always the html() method.
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;
});
As far as I can tell, you're correct - there's no way to do this within the standard D3 idiom. Presumably this will be possible once selection.append()
can take a function:
selection.append(name)
Appends a new element with the specified name... The name must be specified as a constant, though in the future we might allow appending of existing elements or a function to generate the name dynamically.
Hopefully such a function would take the standard (data, index)
arguments, and would solve this problem. Otherwise, at the moment, there's no way I can see to create different elements off of a single .enter()
selection - .enter()
only supports .append
, .insert
, and .select
, none of which can take a function argument.
You can get some of what you want by munging the data into tuples and double-appending to the .enter()
selection, as shown here: http://jsfiddle/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;
});
But as you can see, when the update is called:
cellPairs
.style('background', '#CCC');
Only the last-appended nodes are updated, so the data hasn't been fully bound.
The best I can e up with is making a <td>
look like a <th>
by applying a class based on the index of the data:
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./mbostock/d3/wiki/Selections#wiki-data
Selectors can also be intersected (".this.that" for logical AND) or unioned (".this, .that" for logical OR).
So, something like this might work for you. I haven't tested though (if this selection doesn't work, you can just add the same class to each of the TD/TH cells and select that with 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");
})
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745654153a4638442.html
评论列表(0条)