D3.js 刷新D3V4转换

D3.js 刷新D3V4转换,d3.js,transition,D3.js,Transition,是否有人知道“刷新”过渡的方法。 我的过渡定义如下: this.paths.attr('transform', null) .transition() .duration(this.duration) .ease(d3.easeLinear) .attr('transform', 'translate(' + this.xScale(translationX) + ', 0)') 我知道我能做到 this.paths.interrupt(); 停止过渡,但这并没有完成我的动画

是否有人知道“刷新”过渡的方法。 我的过渡定义如下:

this.paths.attr('transform', null)
  .transition()
  .duration(this.duration)
  .ease(d3.easeLinear)
  .attr('transform', 'translate(' + this.xScale(translationX) + ', 0)')
我知道我能做到

this.paths.interrupt();
停止过渡,但这并没有完成我的动画。我希望能够“刷新”过渡,这将立即完成动画。

如果我理解正确(我可能不理解),没有现成的解决方案可以做到这一点,而不需要深入了解。但是,我相信如果
selection.interrupt()
是您正在寻找的形式,您可以以相对简单的方式构建功能

为此,您需要为访问转换数据的d3选择创建一个新方法(位于:
selection.node()。\u transition
)。转换数据包括关于tweens、计时器和其他转换细节的数据,但最简单的解决方案是将持续时间设置为零,这将强制转换结束并将其置于结束状态:

_u_transitiondata变量可能有空槽(一个变量编号),这可能会在firefox中造成麻烦(据我所知,在使用forEach循环时),因此我使用了一种keys方法来获取包含转换的非空槽

如果使用延迟,您还可以使用以下命令触发计时器回调:
If(slots[d])slots[d]。timer.\u call(),因为将延迟设置为零不会影响转换

使用您调用的
selection.finish()
代码块(该代码块将强制转换到其结束状态),单击一个圆圈以调用该方法:

d3.selection.prototype.finish=function(){
var slots=this.node();
var keys=Object.keys(插槽);
键。forEach(函数(d,i){
if(slots[d])slots[d]。timer._call();
})	
}
var svg=d3.选择(“主体”)
.append(“svg”)
.attr(“宽度”,500)
.attr(“高度”,500);
var circle=svg.selectAll(“circle”)
.数据([1,2,3,4,5,6,7,8])
.输入()
.附加(“圆圈”)
.attr(“cx”,50)
.attr(“cy”,函数(d){返回d*50})
.attr(“r”,20)
.on(“单击”,函数(){d3.select(this).finish()})
圆圈
.transition()
.delay(函数(d){返回d*500;})
.duration(函数(d){返回d*5000;})
.attr(“cx”,460)
.on(“结束”,函数(){
d3.选择(this).attr(“fill”,“steelblue”);//以可视化结束事件
})
是一个很好的例子。然而,出于好奇,我相信不需要扩展原型,也可以使用
.on(“interrupt”
作为侦听器来完成

在这里,我无耻地复制Andrew代码,用于转换和获取目标属性

selection.on("click", function() {
    d3.select(this).interrupt()
})

transition.on("interrupt", function() {
    var elem = this;
    var targetValue = d3.active(this)
        .attrTween("cx")
        .call(this)(1);
    d3.select(this).attr("cx", targetValue)
})
以下是演示:

var svg=d3.选择(“svg”)
var circle=svg.selectAll(“circle”)
.数据([1,2,3,4,5,6,7,8])
.输入()
.附加(“圆圈”)
.attr(“cx”,50)
.attr(“cy”,函数(d){
返回d*50
})
.attr(“r”,20)
.on(“单击”,函数(){
d3.选择(此).interrupt()
})
圆圈
.transition()
.延迟(功能(d){
返回d*500;
})
.持续时间(功能(d){
返回d*5000;
})
.attr(“cx”,460)
.on(“中断”,函数(){
var elem=这个;
var targetValue=d3.激活(此)
.attrTween(“cx”)
.调用(本)(1);
d3.选择(this).attr(“cx”,targetValue)
})


Nice,我曾尝试过这种方法,但尽管有一些非常强烈的咒骂,我还是不能完全让它起作用。我同意这种方法,因为我喜欢它引导我采用的另一种方法,这可能有点过分,但它会触发“结束”事件,并使所有属性都得到相当简单的转换(我最近一直喜欢搞乱d3的内部结构)。谢谢大家!我将接受Gerardo的回答,因为我不太喜欢扩展原型。如果我可以问一个小问题……在你的例子中,你改变
cx
并使用
attrween('cx')。调用(这个)(1)
,如果我使用
.attr>,这会变成什么('transform','translate('+this.xScale(translationX)+',0)
相反?@Gabriel我认为你应该接受Andrew的,但这没什么大不了的,在s.O,被接受的答案并不重要,重要的是向上投票(这就是社区如何表明答案是好的和有用的)。关于你的子问题,它不会起作用,因为你会将该值添加到x位置。因此,例如,如果你在圆即将完成转换时单击该圆,你会将整个x值添加到该圆中。看一看:再次感谢你的回答。我更新了你的JSFiddle以实现我想要的。此解决方案在d3 v4上非常有效。是吗对于版本3,是否可以做同样的事情?@Will,当然-由于v3对转换和计时器的处理方式(以及我的评论),时间稍微长了一点,但仍然非常简洁。行为是一样的(基于我的基本测试),这里是a.Andrew,感谢v3的示例。我实际上正在尝试刷新x轴和y轴转换,而这些转换对象没有计时器属性。如果元素使用d3转换,则它有计时器,但标记的输入/退出有点复杂,我没有预料到。我的v4/v5代码也没有处理轴。虽然可能会进行一些修改,以使该操作与轴一起工作,但为轴
g
的子级使用中断(或删除它们)可能更容易axis的
g
并再次呼叫axis。这里有一个。虽然这不是非常令人满意,但值得向axis提出这个具体问题以获得一些新的关注。Andrew,谢谢你的帮助。仍在测试它。它与Chrome一起工作,但不与PhantomJs一起。如果我发现了一些东西,它将更新。如果你有兴趣,请提供一些提示我相信它。
selection.on("click", function() {
    d3.select(this).interrupt()
})

transition.on("interrupt", function() {
    var elem = this;
    var targetValue = d3.active(this)
        .attrTween("cx")
        .call(this)(1);
    d3.select(this).attr("cx", targetValue)
})