尝试路径补间时 d3 路径被绘制两次
d3 path is being drawn twice while attempting path tween
我正在使用这种技术在 d3 中补间路径:
https://bl.ocks.org/mbostock/5649592
我正在为节点之间的弧线设置动画。我的数据如下所示:
this.transfers = [[1, 480, 0, 5], [2, 0, 480, 20], [3, 0, 720, 5], [3, 240, 720, 5], [3, 480, 720, 5], [5, 480, 0, 5]];
代码的目标是可视化游戏玩法。上面每个内部数组的第一个元素是游戏的回合,接下来的两个是转移一些点的节点的 x 坐标——第一个节点拱向第二个——第四个是转移的点数.我正在尝试对参与传输的节点之间的弧进行补间编程,弧从一个节点扫到另一个节点。这是补间弧的代码:
this.linkAnimation = this.svg.append('g')
.selectAll('path')
.data (self.transfers)
.enter()
.append('path')
.attr('fill', 'none');
this.timedAnimation();
timedAnimation( ) {
for (let j = 0; j < this.rounds+1; j++ ) {
this.linkAnimation = this.linkAnimation
.transition() // transition for delay between rounds
.delay(2000)
.attr('d', (t, i) => {
if (j == t[0]) {
let denominator = (t[1] < t[2])? 1.75 : 2; // to keep forward and reverse arcs from tracing the same path
return ['M', t[1], self.height, 'A',
(t[1] - t[2])/2, ',',
(t[1] - t[2])/denominator, 0, 0, ',',
t[1] < t[2] ? 1 : 0, t[2], ',', self.height]
.join(' ');
}
})
.attr('stroke-width', d => this.linkWidth(d[3]))
.call(this.transition);
}
}
transition(path) {
path.transition()
.duration(2000)
.attrTween("stroke-dasharray", self.tweenDash);
}
tweenDash(path) {
let l = this.getTotalLength(),
i = d3.interpolateString("0," + l, l + "," + l);
if (l == 0) { return; } else {
return function(t) { return i(t); };
}
问题是每个圆弧连续绘制两次。它在补间弧出现之前完全绘制(未补间)一次。
在动画开始时你必须初始化stroke-dasharray
。
为初始破折号选择一个非常大的尺寸,大于您要绘制的任何路径长度。
.attr('stroke-width', d => this.linkWidth(d[3]))
.attr('stroke-dasharray', "0,1000000")
.call(this.transition);
我正在使用这种技术在 d3 中补间路径: https://bl.ocks.org/mbostock/5649592
我正在为节点之间的弧线设置动画。我的数据如下所示:
this.transfers = [[1, 480, 0, 5], [2, 0, 480, 20], [3, 0, 720, 5], [3, 240, 720, 5], [3, 480, 720, 5], [5, 480, 0, 5]];
代码的目标是可视化游戏玩法。上面每个内部数组的第一个元素是游戏的回合,接下来的两个是转移一些点的节点的 x 坐标——第一个节点拱向第二个——第四个是转移的点数.我正在尝试对参与传输的节点之间的弧进行补间编程,弧从一个节点扫到另一个节点。这是补间弧的代码:
this.linkAnimation = this.svg.append('g')
.selectAll('path')
.data (self.transfers)
.enter()
.append('path')
.attr('fill', 'none');
this.timedAnimation();
timedAnimation( ) {
for (let j = 0; j < this.rounds+1; j++ ) {
this.linkAnimation = this.linkAnimation
.transition() // transition for delay between rounds
.delay(2000)
.attr('d', (t, i) => {
if (j == t[0]) {
let denominator = (t[1] < t[2])? 1.75 : 2; // to keep forward and reverse arcs from tracing the same path
return ['M', t[1], self.height, 'A',
(t[1] - t[2])/2, ',',
(t[1] - t[2])/denominator, 0, 0, ',',
t[1] < t[2] ? 1 : 0, t[2], ',', self.height]
.join(' ');
}
})
.attr('stroke-width', d => this.linkWidth(d[3]))
.call(this.transition);
}
}
transition(path) {
path.transition()
.duration(2000)
.attrTween("stroke-dasharray", self.tweenDash);
}
tweenDash(path) {
let l = this.getTotalLength(),
i = d3.interpolateString("0," + l, l + "," + l);
if (l == 0) { return; } else {
return function(t) { return i(t); };
}
问题是每个圆弧连续绘制两次。它在补间弧出现之前完全绘制(未补间)一次。
在动画开始时你必须初始化stroke-dasharray
。
为初始破折号选择一个非常大的尺寸,大于您要绘制的任何路径长度。
.attr('stroke-width', d => this.linkWidth(d[3]))
.attr('stroke-dasharray', "0,1000000")
.call(this.transition);