chart.js 流数据插件数据格式或配置错误

chart.js streaming data plugin data format or config error

我正在尝试使用 nagix 的 chart.js-plugin-streaming 插件实现一个实时流式数据图表,该图表读取每秒输出最后几个数据点的页面。

我正在读取 URL 中的数组,因为图表 "resolution" 会根据连接到后端的传感器而变化。其中一些输出 1/秒,但其中一些输出 10/秒,在第二种情况下,每秒刷新图表 10 次听起来不是个好主意,这既是因为处理能力(旧计算机)和数量发送到传感器的请求数。

所以我的 URL 为最后 20 个数据点(大约 2 到 20 秒的数据)输出一个 objects 的数组,我每秒刷新图表 1 次。

我希望图表只会附加新点,但我的行为很奇怪。我检查了时间戳,它们是正确的。

使用简单的 jQuery $.get() 调用 Django 视图 URL 获取数据数组,每次调用都会生成数组。

这是 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},
]

下次调用时,输出将删除第一个点,数组将 "scroll" 并在尾端显示 1 个新点。

数组里面的objects格式为:{"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秒长)

似乎图表在每次获取新数据时都创建了一个新行,而不是转储上一行?我不确定它如何在内部处理数据。

在这一点上,我不确定到底是什么问题。图表 sort-of 有效,因为它确实创建了一条对图表准确的线,但它似乎将数组中的第一个点与数组中的最新点连接在一起。您可以在 GIF 中看到此行为。

这是因为你每秒在onRefresh()中推送20个数据点,但是20个数据点中只有一个数据点是新的,其余的都是已经插入的数据点。即使存在具有相同时间戳的相同数据,此插件也不会删除数据,因此您会看到该行一遍又一遍地迭代相同的点。

解决方法是在插入数组时将最新时间戳存储在数组中,并在下一次 onRefresh 调用中过滤掉旧数据,以便仅将新数据推送到 chart.data.datasets[0].data.