我正在尝试实现实时流数据图表,该数据图表使用nagix的chart.js-plugin-streaming插件读取每秒输出最后几点数据的页面。
我正在读取URL中的数组,因为图表“分辨率”会根据连接到后端的传感器而变化。其中有些每秒输出1,但有些每秒输出10,在第二种情况下,每秒刷新图表10次听起来不是个好主意,这是因为处理能力(旧计算机)和数量发送到传感器的请求数量。
因此,我的URL为最后20个数据点(大约2至20秒的数据)输出一个对象数组,然后每秒刷新图表1次。
我希望图表只附加新的点,但是我的行为很奇怪。我检查了时间戳,它们是正确的。
使用对Django视图URL的简单jQuery $.get()
调用获取数据数组,每次调用该数组时都会生成该数组。
这是一个1 /秒传感器的每次呼叫的URL输出示例:
[
{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},
]
下次调用时,输出将删除第一个点,数组将“滚动”,并且在尾端将显示一个新点。
数组中的对象的格式为:{"y": <float>, "x": <timestamp-in-ms>}
我的图表配置:
$(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);
});
在这一点上它是可行的,除了我有奇怪的行为,一条线会将第一个点连接到所有后续点:
Example GIF(GIF大小太大,大约40秒长)
似乎图形每次获取新数据时都在创建新行,而不是转储前一行?我不确定它如何在内部处理数据。
在这一点上,我不确定到底是什么问题。图表排序之所以起作用,是因为它确实创建了一条与图形精确的线,但随后看起来好像是将数组中的第一个点与数组中的最新点连接在一起。您可以在GIF中看到此行为。
答案 0 :(得分:1)
这是因为您每秒在onRefresh()
中推送20个数据点,但是20个点中只有一个数据点是新数据,其余数据点已经插入。即使存在具有相同时间戳的相同数据,该插件也不会对数据进行重复数据删除,因此您会看到该行不断重复相同的点。
一种解决方法是在插入数组时将最新时间戳存储在您的数组中,并在下一个onRefresh
调用中过滤掉较旧的数据,以便仅将新数据推送到chart.data.datasets[0].data
。