Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use timer in d3 V3?

I have a function triggerWave() which makes the points on the canvas animate in the wave form. I am using d3.ease('quad-in') for easing and I would like to use d3.timer() to make the triggerWave() function call over 200ms timeframe. I am out of luck in finding the tutorials or examples on d3.timer.

triggerWave() {
  //function logic
  let count = 0;
  let xScale = d3.scale.linear().range([1,2]); // want the value to change from 1 to 2.
  let zScale = d3.scale.linear().domain([0, 200]); // 200 ms.
  let value = xScale(d3.ease('quad-in')(zScale(count)));
  if(count < 200){
   count++;
   d3.timer(() => triggerWave());
  } else {
    // do something
  }
  this.wave.next({currentFrame: value});
}

When I call d3.timer() as above, the triggerWave() function gets called infinite times and never stops. I want to manipulate or control the time. In my case, I want the timer() to be triggered for 200ms.

How can I understand how to use the d3.timer() function?

like image 484
Tums Avatar asked Aug 02 '17 22:08

Tums


2 Answers

(EDIT: I totally and completely missed the huge, big "V3" which is right there, in the title of the question. Sorry. I'll keep this answer here as reference for v4 users)

Since you are calling triggerWave inside the triggerWave function itself, you don't need d3.timer, but d3.timeout instead. According to the API, d3.timeout:

Like timer, except the timer automatically stops on its first callback. A suitable replacement for setTimeout that is guaranteed to not run in the background. The callback is passed the elapsed time.

Also, pay attention to the fact that you are reseting count every time the function runs, which will not work. Set its initial value outside the function.

Here is a demo with those changes. I'm calling the function every 200 ms, until count gets to 50:

var p = d3.select("p")
var count = 0;

triggerWave();

function triggerWave() {
  p.html("Count is " + count)
  if (count < 50) {
    count++;
    d3.timeout(triggerWave, 200)
  } else {
    return
  }
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<p></p>

You can also keep track of the total elapsed time, using the argument passed to triggerWave by d3.timeout:

var p = d3.select("p")
var count = 0;
var elapsed = 0;
var format = d3.format(".2")

triggerWave();

function triggerWave(t) {
  elapsed = t ? elapsed + t : elapsed;
  p.html("Count is " + count + ", and the elapsed time is " + format(elapsed/1000) + " seconds")
  if (count < 50) {
    count++;
    d3.timeout(triggerWave, 200)
  } else {
    return
  }
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<p></p>

Since you are using D3 v3, and as there is no d3.timeout in v3, you can do the same approach using vanilla JavaScript: setTimeout.

Here is a demo:

var p = d3.select("p")
var count = 0;

triggerWave();

function triggerWave() {
  p.html("Count is " + count)
  if (count < 50) {
    count++;
    setTimeout(triggerWave, 200)
  } else {
    return
  }
}
<script src="https://d3js.org/d3.v3.min.js"></script>
<p></p>
like image 65
Gerardo Furtado Avatar answered Oct 22 '22 15:10

Gerardo Furtado


In version 3, there is no d3.timer.stop() function. You have to return true after a certain period of time to stop the timer.

In Gerardo's answer, he explained fabulously how to use the d3 timeout which would be a valid solution to your problem i.e., to call the function over and over for a certain period of time. But looking at your comments on Gerardo's answer, I think you are looking for something else.

Here's what I came up with and I think this is what you are looking for:

You can create an another function called as activateTriggerWave() which will be invoked on the button click and inside this function, you can call your triggerWave() method using the d3 timer.

function activateTriggerWave() {
  d3.timer(elapsed => {
  this.triggerWave();
  if(elapsed >= 200){
    return true; // this will stop the d3 timer. 
  }
});
}

triggerWave() {
 // here you can do whatever logic you want to implement.
}

I hope this helps.

like image 40
ShellZero Avatar answered Oct 22 '22 15:10

ShellZero