Skip to content

D3.js - Timer API

The D3 Timer API module (d3-timer) is used for managing animations and other time-based tasks. It leverages the browser’s requestAnimationFrame API for efficient, synchronized animations that perform well and conserve resources when the page is not active.

window.requestAnimationFrame() is a browser method that tells the browser you wish to perform an animation. It requests that the browser schedule a repaint of the window for the next animation frame. The browser calls your specified callback function to update the animation before the next repaint. D3’s timer module provides a higher-level interface to this mechanism.

If you’re using the full D3 bundle, the timer API is included. For modular use, you would import d3-timer.

<html>
<head>
<script src="https://d3js.org/d3.v7.min.js"></script>
</head>
<body>
<script>
// Example: A simple timer
const myTimer = d3.timer(function(elapsed) {
console.log("Elapsed time:", elapsed, "ms");
if (elapsed > 2000) {
myTimer.stop(); // Stop the timer after 2 seconds
console.log("Timer stopped.");
}
});
</script>
</body>
</html>

In a modular environment:

import { timer, now, timeout, interval } from 'd3-timer';

The d3-timer module provides the following key methods:

Returns the current time using performance.now() if available, or Date.now() otherwise. This is the high-resolution time used by timers.

Schedules a new timer, repeatedly invoking the specified callback function. The callback is passed the elapsed time since the timer started (or since time if specified).

  • delay (optional, number): An initial delay in milliseconds before the first invocation. Defaults to zero.
  • time (optional, number): The time (from d3.now()) at which the timer should start. Defaults to d3.now() plus the delay. The timer continues until timer.stop() is called. Returns the timer object.

Restarts an existing timer with a new callback and optional delay and time. This is useful for reusing timer objects.

Stops the timer, preventing subsequent invocations of its callback.

Similar to d3.timer, but the timer automatically stops after the first invocation of the callback. This is a convenient shorthand for setTimeout behavior using requestAnimationFrame. The callback is passed the elapsed time.

Schedules a timer that invokes the callback function repeatedly at a specified delay interval.

  • delay (optional, number): The interval in milliseconds between invocations. If not specified, the timer behaves like d3.timer and calls on every frame initially. A common use is d3.interval(callback, 1000) to run every second.
  • time (optional, number): The time at which the timer should start. The callback is passed the elapsed time. Returns the timer object.

Create an HTML file, let’s call it timer_example.html, and add the following script. This example demonstrates d3.timer, d3.timeout, and d3.interval.

<!DOCTYPE html>
<html>
<head>
<title>D3.js Timer API Example</title>
<script src="https://d3js.org/d3.v7.min.js"></script>
<style>
body { font-family: sans-serif; }
.log { margin-bottom: 10px; padding: 5px; border: 1px solid #eee; }
</style>
</head>
<body>
<h3>D3.js Timer API Demonstration</h3>
<div id="output"></div>
<script>
const outputDiv = d3.select("#output");
outputDiv.append("p").attr("class", "log").text("Starting d3.timer (stops after 150ms elapsed from its start)");
const continuousTimer = d3.timer(function(elapsed) {
outputDiv.append("p").text(`d3.timer: ${elapsed.toFixed(2)} ms`);
if (elapsed > 150) {
continuousTimer.stop();
outputDiv.append("p").attr("class", "log").text("d3.timer stopped.");
}
}, 50); // Start after 50ms delay
outputDiv.append("p").attr("class", "log").text("Starting d3.timeout (runs once after 500ms)");
d3.timeout(function(elapsed) {
outputDiv.append("p").text(`d3.timeout: Ran after ${elapsed.toFixed(2)} ms`);
}, 500);
outputDiv.append("p").attr("class", "log").text("Starting d3.interval (runs every 300ms, 3 times)");
let intervalCount = 0;
const repeatingInterval = d3.interval(function(elapsed) {
intervalCount++;
outputDiv.append("p").text(`d3.interval (call ${intervalCount}): ${elapsed.toFixed(2)} ms`);
if (intervalCount >= 3) {
repeatingInterval.stop();
outputDiv.append("p").attr("class", "log").text("d3.interval stopped.");
}
}, 300); // Run every 300ms
</script>
</body>
</html>

Open this HTML file in your browser. You will see messages logged to the page as each timer fires and stops, demonstrating their different behaviors. Check the browser’s console for any errors or additional D3 logging if you encounter issues.