Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

D3: Add element after delay, then transition

Tags:

d3.js

I have a very large csv file that that I'm visualizing with D3.js. One of the data fields is a timestamp, so (rather than display all this information at once) I want to create an svg element (based on the other data fields) after a delay proportional to the timestamp, and then fade it out over three seconds. Because of the size of the data, I cannot create all the elements up front, even if they are invisible; each element should only exist for three seconds. The desired effect is a bunch of dots popping into existence and then fading away.

My best attempt is below. The strategy is to use two transitions: a delay, and then the fade transition. It doesn't seem to work but rather creates all the elements all at once (the fading works though).

d3.csv(datafile).get(function(error, rows) {
        for (var i = rows.length; i--;){
                var d = rows[i];
                plot.select("foo") // empty selection
                    .transition()
                    .delay(/*expression with d.timestamp*/)
                    .call(function(){
                        plot.append("circle")
                            .attr(/*several, snip */)
                            .style("opacity", 1)
                            .transition()
                            .duration(3000)
                            .style("opacity", 0)
                            .remove()
                    });
        }

    });

EDIT April 2015 Having learned a lot since asking the question, the obvious thing seems to be to insert everything immediately with 0 opacity. Then create a duration 0, variable delay transition to snap to 1 opacity, and then fade from there. Also use nested selections to avoid the explicit for-loop. I haven't tried it but it should work.

like image 432
mgold Avatar asked Mar 20 '23 20:03

mgold


1 Answers

Have you tried using setTimeout instead?

        rows.forEach(function(d, i){
            setTimeout(function(){
                    plot.append("circle")
                        .attr(/*several, snip */)
                        .style("opacity", 1)
                        .transition()
                        .duration(3000)
                        .style("opacity", 0)
                        .remove()
            }, /*expression with d.timestamp*/);
        })
like image 156
Adam Pearce Avatar answered Mar 29 '23 10:03

Adam Pearce