Reputation: 13
I have created a bar chart with d3, that pulls bar sizes from the array. So I am trying to animate shifting between adjacent bars with a function swapper, which works, but only once. Bars are swapping places on the first call but would ignore the second call. I think that the problem is that second call to the function is executed before first transition is finished. How do i make second call to wait for the first one to finish?
const data = utils.generateRandomArray(25,45);
const width = "500px";
const height = "300px";
const graph1 = d3.select("#graph1").append("svg")
.attr("height", height)
.attr("width", width)
.attr("style", "border: 1px solid black");
utils.renderGraph(graph1, data);
utils.renderGraph(graph2, data);
const bar1 = graph1.select(".bar-1");
const bar2 = graph1.select(".bar-2");
const bar3 = graph1.select(".bar-3");
const bar4 = graph1.select(".bar-4");
function swapper(bar1,bar2){
bar1.transition()
.delay(1000)
.duration(2000)
.attr("x", `${bar2.attr("x")}`);
bar2.transition()
.delay(1000)
.duration(2000)
.attr("x", `${bar1.attr("x")}`);
}
swapper(bar1,bar2);
swapper(bar1,bar2);
Upvotes: 1
Views: 50
Reputation: 196296
Have a look at .end()
Returns a promise that resolves when every selected element finishes transitioning. If any element’s transition is cancelled or interrupted, the promise rejects.
So perhaps something like
async function swapper(bar1,bar2){
const bar1Transition = bar1.transition()
.delay(1000)
.duration(2000)
.attr("x", `${bar2.attr("x")}`);
const bar2Transition = bar2.transition()
.delay(1000)
.duration(2000)
.attr("x", `${bar1.attr("x")}`);
return Promise.all([bar1Transition.end(), bar2Transition.end()]);
}
swapper(bar1,bar2).then( () => {
return swapper(bar1,bar2);
});
Upvotes: 1