Alex
Alex

Reputation: 51

How to implement asynchronous inside d3

I want to change the color of the circles after a period of time. I tried to use setTimeout, but it doesn't work. Is there any way to solve the problem?

var circles = svg.selectAll("circle").data(data)
                .enter().append("circle")
                .attr("r", "10")
                .attr("fill","lightblue")

circles.attr('fill',function(){
            setTimeout(function(){return "red"},2000)
         })

Upvotes: 0

Views: 827

Answers (1)

Onel Harrison
Onel Harrison

Reputation: 1334

Gerardo's comment explains why using setTimeout in the way that you did does not work and presents the alternative approach of using d3.transition.

StackSlave's comment explains how to correctly use setTimeout to solve the problem.

See the example below for approaches to solving your problem.

const data = [10, 15, 20, 30, 35];

const radius = 10; // px
const yPos = 35; // px

const svg = d3.select('svg');

const circles = svg.selectAll("circle").data(data)
  .enter().append("circle")
  .attr("r", radius)
  .attr("transform", function(d, i) {
     return `translate(${(i+1) * 3 * radius}, ${yPos})`; 
   })
   .attr("fill", "lightblue");

// using setTimeout
setTimeout(function() {
  circles.attr("fill", "red");
}, 2000);

// using d3
circles
  .transition()
  .duration(2000)
  .ease(() => 0) // disable fading
  .style("fill", "red");

// using d3 - recommended (see Gerardo's comment below)
circles
  .transition()
  .duration(0)
  .delay(2000)
  .style("fill", "red");

Checkout the d3.transition docs to learn more.

Upvotes: 2

Related Questions