JSFiddle - React, Tailwind, and code Playground

by Robodude

HTML

<script src="https://cdn.jsdelivr.net/bluebird/latest/bluebird.min.js"></script>
<svg id="test" height="200" width="200"></svg>

JavaScript

var data = [1,2,3,4,5];
var radius = 1.5;
function _endAll(selection, callback) {
    if (selection.size() === 0) {
        callback();
    }
    
    var n = 0;
    selection
    .each(function () { ++n; })
    .each("end", function () { if (!--n) callback.apply(this, arguments); });
};

function _draw(radius){
    console.log("_draw");
    var selection = d3.select("#test").selectAll("circle").data(data);
    
    selection.enter().append("circle")
    .attr("cx", 0)
    .attr("cy", 0)
    .attr("r", 0);
    
    var updatePromise = new Promise(function(r){
        selection.transition().duration(250)
            .attr("cx", function(d){return d * 10})
            .attr("cy", function(d){return d * 10})
            .attr("r", function(d){return radius})
            .call(_endAll, function () {
                console.log("update done");
                return r();
            });
    });
    

    var exitPromise = new Promise(function(r){
        selection.exit().transition().duration(1000)
            .attr("cx", 0)
            .attr("cy", 0)
            .attr("r", 0)
            .remove()
            .call(_endAll, function () {
                console.log("exit done");
                return r();
            });
    });

    return Promise.all([updatePromise, exitPromise]);
};

_draw(radius).then(function(){
    console.log("1 done");
});

setTimeout(function(){

    data.pop();

    _draw(radius * 2).then(function(){
        console.log("2 done");
    });
    
}, 1000);