I'm trying to implement a realtime streaming data chart that reads off a page that outputs the last few points of data every second, using the chart.js-plugin-streaming plugin by nagix.
I am reading off of an array in a URL because the chart "resolution" changes depending on which sensor is attached to the backend. Some of them output 1/second, but some of them output 10/second, and in the second case, refreshing the chart 10 times per second doesn't sound like a good idea, both because of processing power (old computers) and number of requests sent to the sensors.
So my URL outputs an array of objects for the last 20 points of data (roughly 2 to 20 seconds worth of data), and I refresh the chart 1 time a second.
I was hoping that the chart would just append only the new points, but I'm having weird behaviour. I've checked the timestamps and they are correct.
The data array is fetched using a simple jQuery $.get() call to the Django view URL that generates the array each time it is called.
This is an example of the URL output per call, for a 1/second sensor:
[
{y: 0.74, x: 1558531380957},
{y: 0.96, x: 1558531379950},
{y: 1.08, x: 1558531378942},
{y: 1.11, x: 1558531377939},
{y: 1.13, x: 1558531376932},
{y: 1.1, x: 1558531375930},
{y: 0.59, x: 1558531374914},
{y: 0.75, x: 1558531373911},
{y: 1.25, x: 1558531372902},
{y: 0.75, x: 1558531371898},
{y: 0.85, x: 1558531370893},
{y: 0.59, x: 1558531369889},
{y: 0.4, x: 1558531368887},
{y: 1.08, x: 1558531367879},
{y: 1.31, x: 1558531366871},
{y: 0.63, x: 1558531365866},
{y: 1.19, x: 1558531364859},
{y: 1.26, x: 1558531363854},
{y: 0.92, x: 1558531362848},
{y: 1.31, x: 1558531361837},
]
The next time it is called, the output will have removed the first point, the array would "scroll" and 1 new points will be show up at the tail end.
The objects inside the array have format: {"y": <float>, "x": <timestamp-in-ms>}
My chart config:
$(document).ready(function() {
var chartColors = {
red: 'rgb(255, 99, 132)',
blue: 'rgb(54, 162, 235)'
};
var color = Chart.helpers.color;
var config = {
type: 'line',
data: {
datasets: [{
label: 'Z-Score',
backgroundColor: color(chartColors.blue).alpha(0.75).rgbString(),
borderColor: chartColors.red,
fill: false,
lineTension: 0,
data: []
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
title: {
display: false,
},
scales: {
xAxes: [{
type: 'realtime',
realtime: {
duration: 60000,
refresh: 1000,
delay: 2000,
pause: false,
ttl: undefined,
frameRate: 48,
onRefresh: function(chart) {
var data = []
$.get( "{% url 'live_z_score' %}", function(zScoreJSON) {
data = zScoreJSON
Array.prototype.push.apply(
chart.data.datasets[0].data, data
);
});
}
}
}],
yAxes: [{
scaleLabel: {
display: true,
labelString: 'value'
}
}]
},
tooltips: {
mode: 'nearest',
intersect: false
},
hover: {
mode: 'nearest',
intersect: false
}
}
};
var ctx = document.getElementById('myChart').getContext('2d');
window.myChart = new Chart(ctx, config);
});
At this point it sort of works, except I'm having weird behaviour where a line would connect the first point to all subsequent points:
Example GIF (GIF size was too large, it's about 40 seconds long)
It seems like the graph is creating a new line each time it fetches new data, instead of dumping the previous line? I'm not sure how it handles data internally.
At this point I'm not sure exactly what the problem might be. The chart sort-of works, as it does create a line that is accurate to the graph, but then it seems like it's joining the first point in the array together with the latest point in the array. You can see this behaviour in the GIF.
