在同一系列中流动合并具有相同x轴的点

时间:2012-11-19 16:36:36

标签: javascript highcharts highstock

我目前正在使用highstock来绘制全天基于时间的可用项目总数(然后实时更新)。

如果两个项目总数同时发生变化,那么在高股票中我得到一个差异的垂直条:

Same time y-axis change

因此,在我的示例图像中,我们从4299个事物开始,然后删除了53个项目并添加了50个(技术上同时,但是两个不同的事务并且是两个点)。净差为-3。 (或换句话说,我得到{x:5:44:15和y:4246,更改:-53},{x:5:44:15,y:4296,更改:50})。

所以我的问题: 是否有可能在highstock中合并这些点以摆脱垂直条并使用4296作为显示值?我希望我可以使用工具提示格式化器来循环“this.points”并在工具提示中显示-53的变化和50的变化,这样用户就可以看到导致净变化为-3的原因。

如果这是不可能的,我将自己合并这些点并传递所有相关信息以生成我想要的工具提示(和图表外观),但是想看看我是否可以利用所有首先是highstock的功能 - 并将这些点分开。

谢谢!

编辑::

new Highcharts.StockChart({
                        chart : {
                            renderTo : 'realTimeChart',
                            zoomType: 'x',
                            backgroundColor: '#feffdd',
                            style: {
                                fontFamily: 'Segoe UI'
                            },
                            type: 'spline'
                        },

                        plotOptions: {
                            area: { animation: false },
                            arearange: { animation: false },
                            areaspline: { animation: false },
                            areasplinerange: { animation: false },
                            bar: { animation: false },
                            column: { animation: false },
                            columnrange: { animation: false },
                            gauge: { animation: false },
                            line: { animation: false },
                            pie: { animation: false },
                            scatter: { animation: false },
                            series: { animation: false },
                            spline: { animation: false }
                        },

                        xAxis: {
                            ordinal: false
                        },

                        tooltip: {
                            animation: false,
                            formatter: function() {
                                var p = '';

                                p += '<span style="font-size: 9px;">' + Highcharts.dateFormat('%A, %b %e, %Y %H:%M:%S', this.x) +'</span><br/>';
                                $.each(this.points, function(i, point){
                                    p += '<span style="color:' + this.series.color + '">' + this.series.name + '</span>: <b>'+ this.y +'</b>';
                                    if (point.point.where) {
                                        p += '<br />' + point.point.where + ' changed by ' + point.point.change + (point.point.who ? ' (' + point.point.who + ')' : '');
                                    }
                                });

                                return p;

                            }
                        },

                        rangeSelector: {
                            buttons: [{
                                count: 30,
                                type: 'minute',
                                text: '30M'
                            }, {
                                count: 1,
                                type: 'hour',
                                text: '1H'
                            }, {
                                count: 6,
                                type: 'hour',
                                text: '6H'
                            }, {
                                type: 'all',
                                text: 'Day'
                            }],
                            inputEnabled: false,
                            selected: 1
                        },

                        exporting: {
                            enabled: false
                        },

                        series : [{
                            name : 'Available',
                            data : data,
                            lineWidth: 1,
                            states: {
                                hover: {
                                    enabled: false
                                }
                            }
                        }]

数据采用我之前显示的格式,但x实际上是以纪元为单位的毫秒:

data = [
        {x: 123456789, y: 2000, where: 'Location', change: 40, who: 'Joe'},
        {x: 123456789, y: 1960, where: 'Location', change: -40, who: 'Bob'},
        ...
    ];

1 个答案:

答案 0 :(得分:0)

只是想跟进我如何轻松绕过探测器。我没有按秒排列,而是决定将点数组合到最近的分钟(所以我有几分钟)。

然后,对于每个点,我将该分钟块中包含的实际点数组作为新参数传递,并更新该分钟块的y值。然后我使用工具提示格式化程序显示该分钟块内的所有更改及其实际更改时间。这给了我一个更流畅的图形,而不是相同x轴的所有这些硬垂直点。

为了方便地更改特定x轴点的数据点,我在series.data数组中为highcharts保留了一个单独的小块位置数组,这样如果我需要更新一个块,我知道确切地说那个时间序列在哪里。

以下是我完成任务的方法: 我创建了引用数组:

var pointIndex = {};

我根据当天的历史数据创建了初始数据系列(通过ajax拉入):

var data = [];
var time = Math.floor(actual_time / 60000) * 60000;
pointIndex[time] = data.push({x: time, y: items_available, change: [{when: actual_time}]});

所以actual_time是自纪元以来的毫秒数(当偶数变化发生时),然后我将其舍入到最接近的分钟以获得分钟时间块,更改是将保存所有实际点的参数。工具提示。

所以当我添加一个新点时,我会检查是否存在分钟块,如果不存在,请添加一个新点,否则更新旧点:

var time = (new Date()).getTime();
var point = Math.floor(time / 60000) * 60000;
if (pointIndex[point]) {
    var change = chart.series[0].data[pointIndex[point]].change;
    change.push({when: time});
    chart.series[0].data[pointIndex[point]].update({x: point, y: items_available, change: change});
} else {
    pointIndex[point] = chart.series[0].data.length;
    chart.series[0].addPoint({x: point, y: items_available, change: [{when: time}]}, false, false);
}

(在所有情况下,我在完成更新点后都会刷新实际图表。)

希望这能帮助那些在同一位置找到自己的人!

编辑::(忘记格式化程序):

tooltip: {
    animation: false,
    formatter: function() {
        var p = '';

        p += '<span style="font-size: 9px;">' + Highcharts.dateFormat('%A, %b %e, %Y %H:%M', this.x) +'</span><br/>';
        $.each(this.points, function(i, point){
            p += '<span style="color:' + this.series.color + '">' + this.series.name + '</span>: <b>'+ this.y +'</b>';
            if (point.point.change) {
                for(var j = 0; j < point.point.change.length; ++j) {
                    p += '<br />Change at: ' + new Date(point.point.change[j].when).toTimeString();
                }
            }
        });

        return p;

    }
}