说是否有这样的表:
var data = [
['Orange', 'Orange', [6,3,3,2,5]],
['Apple', 'Red', [6,2,6,5,5]],
['Grape', 'Purple', [9,1,2,3,1]]
]
我希望字符串表示为字符串,但数字数组表示为D3折线图。如果它只是我关心的文字,我可以selectAll
td
元素并插入一些文字。
var tcells = trows
.selectAll("td")
.data(function(d, i) { return d; })
.enter()
.append("td")
.text(function(d, i) { return d; });
第3列是文字,因此我想用图表更新它,或者添加另一列图表。说lines
是一个创建折线图的函数,我想调用lines()
,因为它会从每个行的第3列传递数据。
trows.selectAll("td")
.data(function(d) {return d[2]}) // scope out data from 3rd column
.enter()
.append("td")
//.call(lines([3,8,2,5,8,4])); // this works
.call(lines); // this doesn't
我的D3知识不稳定所以我不清楚数据和选择是如何通过的。
以下是完整代码: jsfiddle link
答案 0 :(得分:1)
您将selection.call(func)
方法与selection.each(func)
方法混淆。
call
是一种方便的方法,用于调用接受选择作为参数的函数。 trows.call(lines)
等同于lines(trows)
,但它可以是方法链的一部分。
each
用于为选择中的每个元素调用一次函数,将数据和索引作为参数传递。
至于为什么trows.call(lines([3,8,2,5,8,4]))
"工作",它只是有点工作。您使用硬编码数据数组调用函数lines
,但该函数不返回任何内容,因此选择本身没有call
。 (如果您不了解其中的区别,可以find this answer useful。)
您的方法目前也只将线图附加到正文,它不会将其插入表格中。您有以下代码,您承认它们不起作用:
// dynamic selection doesn't
this.append("td").append('svg')
.attr('width', width).attr('height', height)
.append('path').attr('class','line')
.datum(data).attr('d', line);
有几个原因导致失败:
lines([3,8,2,5,8,4])
,this
值将不会被设置,因此将指向window对象; each
方法调用该函数(设置this
值),this
也会指向DOM节点,而不是您可以调用的选项d3方法; enter()
选项中调用它,而您还没有添加新节点爱好。总之,为了让事情顺利进行:
在主程序中,在创建新的each
元素后,使用lines
来调用<td>
函数:
trows.selectAll("td.graph")
//use a class so you don't re-select the existing <td> elements
.data(function(d) {return [d[2]];})
// the value returned by a data function must always be an array
// containing data objects for each new element you create --
// you only want one element containing the entire data array,
// not individual elements for each number, so wrap it in another array
.enter()
.append("td")
.attr("class", "graph")
.each(lines);
在lines
函数中,重新选择this
元素(现在将指向刚刚创建的<td>
),并将迷你线SVG附加到其中:
d3.select(this).append('svg')
.attr('width', width)
.attr('height', height)
.append('path')
.attr('class','line')
.datum(data)
.attr('d', line);
http://jsfiddle.net/Lgq6ct9f/9/
(通过其他一些清理,所以你不会在主程序中间有一个功能定义)