有人知道一种"冲洗"过渡的方法.我的转换定义如下:
this.paths.attr('transform', null)
.transition()
.duration(this.duration)
.ease(d3.easeLinear)
.attr('transform', 'translate(' + this.xScale(translationX) + ', 0)')
Run Code Online (Sandbox Code Playgroud)
我知道我能做到
this.paths.interrupt();
Run Code Online (Sandbox Code Playgroud)
停止过渡,但这并没有完成我的动画.我希望能够"刷新"立即完成动画的过渡.
如果我理解正确(我可能不会),那么没有开箱即用的解决方案.但是,我相信如果selection.interrupt()
您正在寻找的形式,您可以以相对简单的方式构建功能.
为此,您需要为访问转换数据(位于:)的d3选择创建新方法selection.node().__transition
.转换数据包括补间数据,计时器和其他转换细节,但最简单的解决方案是将持续时间设置为零,这将强制转换结束并将其置于最终状态:
__transition数据变量可以有空槽(变量号),这可能会导致firefox中的悲伤(据我所知,当使用forEach循环时),所以我使用了key方法来获取非空包含转换的插槽.
d3.selection.prototype.finish = function() {
var slots = this.node().__transition;
var keys = Object.keys(slots);
keys.forEach(function(d,i) {
if(slots[d]) slots[d].duration = 0;
})
}
Run Code Online (Sandbox Code Playgroud)
如果使用延迟,您还可以使用以下内容触发定时器回调:if(slots[d]) slots[d].timer._call();
,因为将延迟设置为零不会影响转换.
使用此代码块调用selection.finish()
哪个将强制转换到其结束状态,单击一个圆圈以调用该方法:
d3.selection.prototype.finish = function() {
var slots = this.node().__transition;
var keys = Object.keys(slots);
keys.forEach(function(d,i) {
if(slots[d]) slots[d].timer._call();
})
}
var svg = d3.select("body")
.append("svg")
.attr("width", 500)
.attr("height", 500);
var circle = svg.selectAll("circle")
.data([1,2,3,4,5,6,7,8])
.enter()
.append("circle")
.attr("cx",50)
.attr("cy",function(d) { return d * 50 })
.attr("r",20)
.on("click", function() { d3.select(this).finish() })
circle
.transition()
.delay(function(d) { return d * 500; })
.duration(function(d) { return d* 5000; })
.attr("cx", 460)
.on("end", function() {
d3.select(this).attr("fill","steelblue"); // to visualize end event
})
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.12.0/d3.min.js"></script>
Run Code Online (Sandbox Code Playgroud)
当然,如果您想保留方法d3-ish,请返回选择,以便您可以在之后链接其他方法.为了完整起见,您需要确保完成转换.通过这些添加,新方法可能如下所示:
d3.selection.prototype.finish = function() {
// check if there is a transition to finish:
if (this.node().__transition) {
// if there is transition data in any slot in the transition array, call the timer callback:
var slots = this.node().__transition;
var keys = Object.keys(slots);
keys.forEach(function(d,i) {
if(slots[d]) slots[d].timer._call();
})
}
// return the selection:
return this;
}
Run Code Online (Sandbox Code Playgroud)
这是一个更完整的实现的block.
以上是D3的第4版和第5版.要在版本3中复制它有点困难,因为定时器和转换在版本4中稍作重写.在版本3中,它们不太友好,但是可以通过稍微修改来实现行为.为了完整起见,这是d3v3示例的一个块.