Charts in Motion

Person standing in the dark looking up at a sky full of light

There are many ways to display variations in data. Highcharts lets you do this in a single chart by defining properties like color, point size, and positioning. But what if you wanted to visualize variations by simply pressing a button to watch the data move?

Dancing with the Charts

Implementing this with Highcharts fairly simple, due to the open API and the way updates to the data is managed. Calling the update() function on a point object with the new data value as the argument updates the point and redraws the chart. Alternatively, simply call the setData() function on a series object and provide an array of the new data as the argument. This, in turn, calls point.update() on each point in the series, and redraws the chart at the end. Either way, Highcharts updates the chart painlessly, and smoothly animates the change.

HTML Elements

In the demos provided, we have used an <input> element with type=”range” for the interactive progress-bar, a <button> element for the play/pause-button, and an <output> element to display the current value.

<div id="play-controls">
   <button id="play-pause-button" class="fa fa-play" title="play"></button>
   <input id="play-range" type="range" value="0" min="0" max="6"></input>
   <output id="play-output" for="play-range" name="year">2005</output>
</div>

Functions

Three simple functions are used to modify the chart: update(), play() and pause(). The update() function updates the chart according to the value of the progress-bar input. It also takes an optional increment (integer) argument, which modifies the input value before updating. The play() function starts updating the chart by calling update() at set intervals with new data. The pause() function stops the process of updating the chart.

/**
* Update the chart. This happens either on updating (moving) the range input,
* or from a timer when the timeline is playing.
*/
function update(increment) {
   var input = $('#play-range')[0],
       output = $('#play-output')[0];

   if (increment) {
       input.value = parseInt(input.value) + increment;
   }
   chart.series[1].setData(dataSequence[input.value].data); // Increment dataset (updates chart)
   output.innerHTML = dataSequence[input.value].name // Output value
   if (input.value >= input.max) { // Auto-pause
       pause($('#play-pause-button')[0]);
   }
}
/**
* Play the timeline.
*/
function play(button) {
   button.title = 'pause';
   button.className = 'fa fa-pause';
   chart.sequenceTimer = setInterval(function () {
       update(1);
   }, 800);
}
/**
* Pause the timeline, either when the range is ended, or when clicking the pause button.
* Pausing stops the timer and resets the button to play mode.
*/
function pause(button) {
   button.title = 'play';
   button.className = 'fa fa-play';
   clearTimeout(chart.sequenceTimer);
   chart.sequenceTimer = undefined;
}

Binding Inputs

To connect user input to the functions, a click event on the play/pause button is bound to call play() if the chart is not playing, and pause() if it is playing, and an input event on the progress-bar is bound to call update()

/**
* Toggle play and pause from the button
*/
$('#play-pause-button').bind('click', function () {
   if (chart.sequenceTimer === undefined) {
       play(this);
   } else {
       pause(this);
   }
});
/**
* Update the chart when the input is changed
*/
$('#play-range').bind('input', function () {
   update();
});

Usage

A typical usage, as shown in the demos above, would be making a playable timeline (or time-lapse), which displays data changing over time. This is, however, not the only application. Depending on what you want to visualize and how you structure your data, you can display data changing over any axis. Take for example, the demo below:

Instead of moving over time, this chart’s data mutates according to speed limits in Norway. Fork a demo and try moving data over age groups, interest rates, product prices, or any other variable you can think of.

Motion Charts Plugin

For a simpler setup with smoother progress-bar movement and more advanced features, we have developed a plugin for Highcharts, Highmaps, and Highstock available at https://www.highcharts.com/plugin-registry/single/40/Motion