How to convert D3.js datamap to an animated gif
ABeamer has its own charts component, but it can also be used to create frame-by-frame animations of other chart and map libraries.
D3.js has been widely used to create interactive animations for data science, but since its animation engine is mainly designed to be used interactively, if want you to generate the animation frames to generate animated gifs or movies by using a video capture application, you can’t guarantee the output quality nor guarantee that the animation is timely captured.
By using ABeamer on top of D3.js, you can generate high-resolution frames at a selected frame rate.
To proof the concept, we will use an D3 datamap animated with ABeamer, and use that animation to generate the frame sequence and an animated GIF.
Step-by-step tutorial
Just follow the following steps:
If ABeamer isn’t install, read here how to install it.
Create ABeamer project named
d3-datamap
:
HTML
- Add the d3, topojson and datamap script files to
index.html
beforeabeamer.min.js
.
- Add the datamap container inside
scene1
:
(The story
is ABeamer root element, and supports multiple scenes just like a theater play)
Stylesheet
- Add basic style to the
css/main.scss
file:
JavaScript
The code bellow is written in TypeScript, but you can use pure JavaScript.
- Load your data.
Since d3 datamap doesn’t supports country names, only ISO Country Codes, the first step is to load a list of Country Names and ISO Country Codes, and create JavaScript map of ISO alpha-3 per country.
In the second step, build a JavaScript array with a list of ISO alpha-3 Country codes and GDP per Capita, and call dataLoaded
with that data.
- Place the animation and render command inside
dataLoaded
.
ABeamer uses addAnimations
and addStills
to build the animation pipeline,
and story.render
to generate the file frames.
- Create a d3 datamap with bubbles as usual.
Disable all d3 animations since these animations aren’t controlled by ABeamer. In this case, set animate: false
in the bubblesConfig
.
JavaScript - Bubbles Animation
Since d3 isn’t a DOM element, we need to use ABeamer VirtualAnimator
facility to animate a d3 datamap.
Our first goal is to animate the bubbles. In order to archive this process we derive from ABeamer.SimpleVirtualAnimator
since it allow us to execute animateProps
once per frame, unlike ABeamer.VirtualAnimator
which allows to call per property change.
- First, we prepare the data:
- Second, we create the
MapAnimator
with the methodanimateProps
:
- Third, we add the
MapAnimator
to the story:
The selector
will be used animate the properties.
- Forth, we add an animation to the story:
With these 4 steps, ABeamer will execute MapAnimator.animateProps
once per frame, the number of frames is defined on ABeamer.createStory
for 2 seconds, iterating the property t
from 0
(defined by valueStart
) to 1
(the end value is 1
by default).
JavaScript - Zoom Animation
The 2nd part of the animation is to zoom to Europe.d3.js
allows zooming by using attr
with scale
.
To add this animation with need the new iterator zoom
running from 1
to 5
.
Before the zoom animation starts, the zoom
value will be 0
.
- First, change the animation code to incorporate the
zoom
animation:
- Second, change the initialization of
VirtualAnimator
code to reset thezoom
property:
- Third, change scene animations to incorporate
zoom
property animation:
With these 3 extra steps, once the bubble animation finishes, it waits for 2s and then animates the zoom for another 2s.