使用 transition.end() 承诺链接转换
Chaining transitions using the transition.end() promise
我正在尝试在 transition.end()
承诺解决时通过调用我的 update
函数来链接转换。以下代码段位于此 update
函数中。可以在 https://jsfiddle.net/fmgreenberg/1npLeguh/10/.
中找到完整示例,此片段是其中的一部分
let t = d3
.transition()
.duration(3000)
.end()
.then(() => update(newData));
问题是转换几乎是瞬间发生的,然后可视化在那里停留约 3 秒,直到再次调用更新。为什么是这样?如果我注释掉代码片段的最后两行,转换将花费预期的 3 秒。 (当然,在这种情况下只有一个转换,因为我已经删除了循环。)
不命名转换实例,而是在转换选择本身中使用承诺:
d3.select("#figure")
.selectAll("circle")
.data(newData, d => d)
.transition()
.duration(3000)
.attr("cx", (_, i) =>
i < N ? (i + 1) * (2 * r + s) : 300 - (i - N + 1) * (2 * r + s)
)
.end()
.then(() => update(newData));
这是更新后的 JSFiddle:https://jsfiddle.net/k9gf8ybL/
和对应的S.O。片段:
let N = 5;
let r = 5;
let s = 2;
let data = d3.range(2 * N);
d3.select("#figure")
.selectAll("circle")
.data(data)
.enter()
.append("circle")
.attr("cx", (_, i) =>
i < N ? (i + 1) * (2 * r + s) : 300 - (i - N + 1) * (2 * r + s)
)
.attr("cy", 26)
.attr("r", r)
.attr("stroke", "blue")
.attr("fill", d => (d < N ? "white" : "black"));
update(data);
function update(data) {
let I = data.slice(0, N);
let J = data.slice(N, 2 * N);
let i = randInt(N);
let x = I[i];
let j = randInt(N);
let y = J[j];
let newData = [
...I.slice(0, i),
...I.slice(i + 1),
y,
...J.slice(0, j),
...J.slice(j + 1),
x
];
d3.select("#figure")
.selectAll("circle")
.data(newData, d => d)
.transition()
.duration(3000)
.attr("cx", (_, i) =>
i < N ? (i + 1) * (2 * r + s) : 300 - (i - N + 1) * (2 * r + s)
)
.end()
.then(() => update(newData));
}
function randInt(n) {
return Math.floor(Math.random() * n);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.9.0/d3.min.js"></script>
<svg id="figure" viewBox="0 0 300 50" style="background-color: papayawhip; border-radius: 1rem" xmlns="http://www.w3.org/2000/svg"></svg>
但是,如果出于任何原因您仍想使用命名转换实例,只需使用更常见的 on("end"...)
方法而不是 end()
承诺:
let t = d3
.transition()
.duration(3000)
.on("end", () => {
update(newData)
});
然后:
selection.transition(t)
//etc...
这是采用这种方法的 JSFiddle:https://jsfiddle.net/8od3vkc1/
我正在尝试在 transition.end()
承诺解决时通过调用我的 update
函数来链接转换。以下代码段位于此 update
函数中。可以在 https://jsfiddle.net/fmgreenberg/1npLeguh/10/.
let t = d3
.transition()
.duration(3000)
.end()
.then(() => update(newData));
问题是转换几乎是瞬间发生的,然后可视化在那里停留约 3 秒,直到再次调用更新。为什么是这样?如果我注释掉代码片段的最后两行,转换将花费预期的 3 秒。 (当然,在这种情况下只有一个转换,因为我已经删除了循环。)
不命名转换实例,而是在转换选择本身中使用承诺:
d3.select("#figure")
.selectAll("circle")
.data(newData, d => d)
.transition()
.duration(3000)
.attr("cx", (_, i) =>
i < N ? (i + 1) * (2 * r + s) : 300 - (i - N + 1) * (2 * r + s)
)
.end()
.then(() => update(newData));
这是更新后的 JSFiddle:https://jsfiddle.net/k9gf8ybL/
和对应的S.O。片段:
let N = 5;
let r = 5;
let s = 2;
let data = d3.range(2 * N);
d3.select("#figure")
.selectAll("circle")
.data(data)
.enter()
.append("circle")
.attr("cx", (_, i) =>
i < N ? (i + 1) * (2 * r + s) : 300 - (i - N + 1) * (2 * r + s)
)
.attr("cy", 26)
.attr("r", r)
.attr("stroke", "blue")
.attr("fill", d => (d < N ? "white" : "black"));
update(data);
function update(data) {
let I = data.slice(0, N);
let J = data.slice(N, 2 * N);
let i = randInt(N);
let x = I[i];
let j = randInt(N);
let y = J[j];
let newData = [
...I.slice(0, i),
...I.slice(i + 1),
y,
...J.slice(0, j),
...J.slice(j + 1),
x
];
d3.select("#figure")
.selectAll("circle")
.data(newData, d => d)
.transition()
.duration(3000)
.attr("cx", (_, i) =>
i < N ? (i + 1) * (2 * r + s) : 300 - (i - N + 1) * (2 * r + s)
)
.end()
.then(() => update(newData));
}
function randInt(n) {
return Math.floor(Math.random() * n);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.9.0/d3.min.js"></script>
<svg id="figure" viewBox="0 0 300 50" style="background-color: papayawhip; border-radius: 1rem" xmlns="http://www.w3.org/2000/svg"></svg>
但是,如果出于任何原因您仍想使用命名转换实例,只需使用更常见的 on("end"...)
方法而不是 end()
承诺:
let t = d3
.transition()
.duration(3000)
.on("end", () => {
update(newData)
});
然后:
selection.transition(t)
//etc...
这是采用这种方法的 JSFiddle:https://jsfiddle.net/8od3vkc1/