I can reanimate the chart using a setTimeout
(at the bottom, on the created event) by using chart.update.bind(chart)
.
Can anyone suggest a way I can pass new data into that chart object? Maybe with a prototype method? Or Should I just create a whole new chart object and redraw it?
Ultimately I just want a chart that changes data automatically with a nice animation, primarily for aesthetic purposes.
var chart = new Chartist.Line('.ct-chart-main', {
labels: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'],
series: [
[1, 4, 5, 12, 4, 3, 2, 4, 5, 1]
]
}, {
low: 0,
showArea: true,
fullWidth: true,
width: '600px',
height: '250px',
lineSmooth: Chartist.Interpolation.cardinal({
tension: 1
})
});
chart.on('created', function() {
if(window.__exampleAnimateTimeout) {
clearTimeout(window.__exampleAnimateTimeout);
window.__exampleAnimateTimeout = null;
}
window.__exampleAnimateTimeout = setTimeout(chart.update.bind(chart), 5000);
});
chart.on('draw', function(data) {
if(data.type === 'point') {
var circle = new Chartist.Svg('circle', {
cx: [data.x], cy:[data.y], r:[5],
}, 'ct-circle');
data.element.replace(circle);
}
if(data.type === 'line' || data.type === 'area') {
data.element.animate({
d: {
begin: 2000 * data.index,
dur: 1000,
from: data.path.clone().scale(1, 0).translate(0, data.chartRect.height()).stringify(),
to: data.path.clone().stringify(),
easing: Chartist.Svg.Easing.easeOutQuint
}
});
}
});
chart.on('created', function() {
if(window.__exampleAnimateTimeout) {
clearTimeout(window.__exampleAnimateTimeout);
window.__exampleAnimateTimeout = null;
}
window.__exampleAnimateTimeout = setTimeout(chart.update.bind(chart), 5000);
});
You should be able to update your chart with the following:
chart.update(newData)
Here is an example of how I was able to pass new data to an example chart: Note, this uses recursion to demonstrate the concept, to use the function standalone remove the setTimout line.
function updateChart(chart,data,point,length) {
if(data.series[0].length >= length) {
data.series[0].shift();
}
data.series[0].push(point);
chart.update(data);
setTimeout(() => { updateChart(chart,data,getRandomInt(20),length) }, 1000);
}
Entire demo code:
<!DOCTYPE html>
<html>
<head>
<style>
html,
body {
margin: 50px;
padding: 20;
}
h2 {
text-align: center;
}
</style>
<link rel="stylesheet" href="//cdn.jsdelivr.net/chartist.js/latest/chartist.min.css">
<script src="//cdn.jsdelivr.net/chartist.js/latest/chartist.min.js"></script>
</head>
<body>
<h2>
Chartist.js Updating with New Data
</h2>
<div class="ct-chart ct-perfect-fourth"></div>
</body>
</html>
<script>
var data = {
series: [[5, 4, 3, 7, 5, 10]]
};
function getRandomInt(max) {
return Math.floor(Math.random() * Math.floor(max));
}
function updateChart(chart,data,point,length) {
if(data.series[0].length >= length) {
data.series[0].shift();
}
data.series[0].push(point);
chart.update(data);
setTimeout(() => { updateChart(chart,data,getRandomInt(20),length) }, 1000);
}
// We are setting a few options for our chart and override the defaults
var options = {
// Don't draw the line chart points
showPoint: true,
// Disable line smoothing
lineSmooth: false,
// X-Axis specific configuration
axisX: {
// We can disable the grid for this axis
showGrid: true,
// and also don't show the label
showLabel: true
},
// Y-Axis specific configuration
axisY: {
// Lets offset the chart a bit from the labels
offset: 60,
// The label interpolation function enables you to modify the values
// used for the labels on each axis. Here we are converting the
// values into million pound.
labelInterpolationFnc: function(value) {
return '$' + value + 'm';
}
}
};
// All you need to do is pass your configuration as third parameter to the chart function
var cid = new Chartist.Line('.ct-chart', data, options);
setTimeout(() => { updateChart(cid, data, getRandomInt(20), 10) }, 1000);
</script>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With