How to draw circles at different times with D3js?

南楼画角 提交于 2019-12-06 15:35:48

Use setTimeout. Here is the working code snippet.

var nodes = [{
        "name": "6",
        "x": 207,
        "y": 305
    }, {
        "name": "7",
        "x": 404,
        "y": 310
    }, {
        "name": "8",
        "x": 420,
        "y": 510
    }, {
        "name": "9",
        "x": 540,
        "y": 126
    }, {
        "name": "10",
        "x": 350,
        "y": 150
    }, {
        "name": "11",
        "x": 177,
        "y": 320
    }, {
        "name": "12",
        "x": 200,
        "y": 190
    }, {
        "name": "13",
        "x": 170,
        "y": 150
    }, {
        "name": "14",
        "x": 107,
        "y": 510
    }, {
        "name": "15",
        "x": 104,
        "y": 150
    }, {
        "name": "16",
        "x": 104,
        "y": 150
    }, {
        "name": "17",      
        "x": 310,
        "y": 160
    }, {
        "name": "18",      
        "x": 120,
        "y": 110
    }, {
        "name": "19",
        "x": 619,
        "y": 145
    }, {
        "name": "20",
        "x": 148,
        "y": 107
    }, {
        "name": "21",
        "x": 575,
        "y": 107
    }];


var width = 500,
    height = 400;

var color = d3.scale.category20();

var svg = d3.select("#map").append("svg")
    .attr("width", width)
    .attr("height", height);

nodes.forEach(function(d, i) {
    setTimeout(function() {
        svg.append("circle")
            .datum(d)
            .attr("class", "node")
            .attr("cx", function(d) {
                return d.x;
            })
            .attr("cy", function(d) {
                return d.y;
            })                 
            .attr("r", "10")
            .style("fill", function(d) {
                return color(i);
            });               
    }, 500 * i);
});
.node {
  stroke: #fff;
  stroke-width: 1.5px;
}

.overlay {
  fill: none;
  pointer-events: all;
}

#map{
    border: 2px #555 dashed;
    width:500px;
    height:400px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<body>
    <div id="map"></div>
</body>

You can use the standard javascript methods setTimeout or setInterval to append the circles one by one with a variable delay depending on the circle index.

Or, you could create all the circles on enter normally using the standard d3 syntax but with opacity set to 0 and just add a .transition() with delay dependent on the index that sets opacity to 1

Here's a working jsfiddle of the latter option: http://jsfiddle.net/pg5m3m3n/5/

Extract:

canvas.selectAll('circle')
    .data(data)
    .enter()
    .append('circle')
    .attr({
        'cx': function(d) { return d.x; },
        'cy': function(d) { return d.y; },
        'r': 10,
        'opacity': 0
    })
    .transition().delay(function(d,i) { return i*50; })
    .attr('opacity',1);

The pros of this is that it uses d3 syntax and it's just 2 lines of code more than the normal append, the con is that the circles are actually added immediately and only become visible one by one, which may give performance issues if the number of circles to append is huge.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!