我基于示例here在d3 v3中创建了一个森伯斯特。我无法理解在以下情况下attrTween()无法正常工作的原因。
path.transition()
.duration(750)
.attrTween("d", function(d) {
var xd = d3.interpolate(x.domain(), [d.x, d.x + d.dx]),
yd = d3.interpolate(y.domain(), [d.y, 1]),
yr = d3.interpolate(y.range(), [d.y ? 20 : 0, radius]);
return function(d, i) {
var p = i
? function(t) { return arc(d); }
: function(t) { x.domain(xd(t)); y.domain(yd(t)).range(yr(t)); return arc(d); };
return p
};
})
单击任意弧时出现以下错误。
错误:属性d:预期的moveto路径命令(“ M”或“ m”),“函数(t){x…”。
但是,如下定义函数
arcTween()
并像这样调用.attrTween("d", arcTween(d))
可以正常工作。function arcTween(d) {
var xd = d3.interpolate(x.domain(), [d.x, d.x + d.dx]),
yd = d3.interpolate(y.domain(), [d.y, 1]),
yr = d3.interpolate(y.range(), [d.y ? 20 : 0, radius]);
return function(d, i) {
return i
? function(t) { return arc(d); }
: function(t) { x.domain(xd(t)); y.domain(yd(t)).range(yr(t));return arc(d); };
};
}
最佳答案
工作代码使用函数声明来定义function arcTween(d) { }
。在.attrTween("d", arcTween(d))
中使用此函数实际上将执行该函数,并从封闭函数d
中传入参数click(d)
,这是绑定到用户单击的元素的数据。此调用用于捕获/关闭插值器d
,xd
和yd
中的值yr
,这些值又在返回的内部函数中使用。此返回的函数是由.attrTween()
执行以返回用于过渡的插值器的函数。
在您的代码中,尝试内联函数声明时,您对上述外部函数的调用丢失了。因此,由于函数嵌套太深,您最终将获得无效的返回值。
但是,有一种简单的方法可以使您的代码正常工作:只需在内联函数后添加(d)
即可执行该代码,就像执行以前的代码一样。
function click(d) { // This d is what needs to be captured
path.transition()
.duration(750)
.attrTween("d", function(d) {
// var... // This is where the outer d is closed over/captured
return function(d, i) { // This is another d not to be confused with the outer one
// ...
};
}(d)) // This will execute the function passing in click's d
}
请查看更新的Plunk以获取有效的演示。