Javascript d3.js:将数据从父节点传递到子节点onclick事件
我正在使用d3制作一个堆叠条形图 由于,我正在使用parentNode将与父节点关联的数据绑定到子节点 数据是一个数组,每个条对应一个对象(例如“likes”)。然后,每个对象包含一个值数组,这些值驱动每个条的各个矩形:Javascript d3.js:将数据从父节点传递到子节点onclick事件,javascript,d3.js,Javascript,D3.js,我正在使用d3制作一个堆叠条形图 由于,我正在使用parentNode将与父节点关联的数据绑定到子节点 数据是一个数组,每个条对应一个对象(例如“likes”)。然后,每个对象包含一个值数组,这些值驱动每个条的各个矩形: data = [{ key = 'likes', values = [ {key = 'blue-frog', value = 1}, {key = 'goodbye', value = 2}
data = [{
key = 'likes', values = [
{key = 'blue-frog', value = 1},
{key = 'goodbye', value = 2}
]
}, {
key = 'dislikes, values = [
{key = 'blue-frog', value = 3},
{key = 'goodbye', value = 4}
]
}]
图表工作正常,父度量数据绑定到子svg属性也正常:
// Create canvas
bars = svg.append("g");
// Create individual bars, and append data
// 'likes' are bound to first bar, 'dislikes' to second
bar = bars.selectAll(".bar")
.data(data)
.enter()
.append("g");
// Create rectangles per bar, and append data
// 'blue-frog' is bound to first rectangle, etc.
rect = bar.selectAll("rect")
.data(function(d) { return d.values;})
.enter()
.append("rect");
// Append parent node information (e.g. 'likes') to each rectangle
// per the SO question referenced above
rect.attr("metric", function(d, i, j) {
return rect[j].parentNode.__data__.key;
});
这样就可以为每个矩形创建工具提示,上面写着“likes:2”。到目前为止还不错
问题是如何将此相同信息与单击事件关联,建立在以下基础上:
rect.on("click", function(d) {
return _this.onChartClick(d);
});
// or
rect.on("click", this.onChartClick.bind(this));
这是有问题的,因为onChartClick方法需要访问绑定数据(d)和图表执行上下文(“this”)。如果没有,我可以切换执行上下文并在onChartClick方法中调用d3.select(this).attr(“metric”)
我的另一个想法是将度量作为一个附加参数传递,但是这里使用函数(d,I,j)的技巧似乎不起作用,因为它在单击事件发生之前不会运行
你能建议一个解决方案吗?rect.on(“单击”,this.onChartClick.bind(this))代码>不起作用,因为您没有传递函数,而是传递函数的返回值(通过附加(this)
)
如果要传递此
和数据(d
),请尝试以下操作:
// assuming you have this somewhere earlier
var onChartClick = function () {}
// change your parent click to
rect.on("click", function(d) {
return onChartClick.call(this, d);
});
您可以使用闭包保留对父数据的引用,如下所示:
bar.each(function(dbar) { // dbar refers to the data bound to the bar
d3.select(this).selectAll("rect")
.on("click", function(drect) { // drect refers to the data bound to the rect
console.log(dbar.key); // dbar.key will be either 'likes' or 'dislikes'
});
});
更新:
有关访问DOM结构中不同级别的各种方法,请参见下文。混搭!查看此的实时版本并尝试单击.rect divs:
另一种方法可以是f.e传递一个对象/json,或者在我的例子中传递一个类实例,该类实例创建一个矩形到事件中,以访问事件内部
var rect = svgContainer.append("rect");
rect.datum(this);
rect.on('click', function(d){
alert(d);
alert(d.id); // etc.
});
谢谢你,布莱恩。我正在努力解决的问题不仅仅是传递数据和这个,而是传递数据,这个和度量信息(例如“likes”)。likes的值是(即2),但是键(即“likes”)位于数据的顶层。这意味着“喜欢”被绑定到第一个条,“不喜欢”被绑定到第二个条等等。然后绑定到条内每个矩形的是例如{key='bluefrog',value=1},也就是说,没有关于“喜欢”的信息。我可以更改数据,但这在多个地方使用,所以我更愿意找到另一种方法。谢谢。这很有帮助。我恐怕仍然停留在如何在这个中间引用OnCuttCutter函数。它存在于整个图表/类上下文中,而不是矩形。我只是在看它。真正的大师级!我需要花一点时间来理解它,并确保我理解它。我在想,你认为这个问题的标题应该是什么?好的。第一个(也是基本的)问题。chartdivs怎么了?打电话(chart)?chartdivs不是函数,但调用的语法是。我肯定我错过了一些简单的东西。有一件事可能会让人困惑,那就是在d3代码中,你会遇到两种不同类型的“调用”方法:d3选择的方法:selection.call(function[,arguments…])(),还有Javascript的function方法:fun.call(thisArg[,arg1[,arg2[,…])(),所以,这是您正在查看的selection.call方法。chartdivs是一个d3.selection,我们在其上调用函数图。这种构造在D3中被大量使用。
var rect = svgContainer.append("rect");
rect.datum(this);
rect.on('click', function(d){
alert(d);
alert(d.id); // etc.
});