10

我正在尝试将延迟加载与Highstock 中的动态更新数据结合起来。这个想法是拥有一个大的历史实时图表(包含数百万个数据点),同时实时更新(如果用户滚动到右边缘)。

为了防止在延迟加载数据时循环加载,我需要设置:

navigator : {
  adaptToUpdatedData: false
}

但是,使用此设置,向图表添加新数据点不再更新导航器,这使我根本无法看到这些新数据点(因为我无法滚动过去最右侧的条目)。我也尝试将这些新数据点添加到导航器系列中,但导航器仍然没有更新。我还尝试以编程方式更改导航器系列的 xAxis 中的最大值,但无济于事。

我怎样才能使这项工作?

4

2 回答 2

13

我花了几个星期来解决这个问题,这很棘手。延迟加载是一件非常简单的事情(请参阅http://www.highcharts.com/stock/demo/lazy-loading上的“170 万点异步加载”演示)或添加新数据点,但两者需要一点技巧。

首先,我将详细说明我最终得到的解决方案。不要将 adaptToUpdatedData 设置为 false,只需将其省略即可。您将要做的所有工作都需要更改生成数据的后端代码。从本质上讲,返回到 Highstock 的数据将始终是您拥有的全部数据范围,但是对于当前正在查看的窗口,您将拥有高分辨率的数据点,但之前范围内的数据点的分辨率较低在这个窗口之后。像往常一样将新数据点添加到数据的末尾(请参阅http://www.highcharts.com/stock/demo/dynamic-update上的“动态更新数据”演示)

这确保了当添加新数据点时,导航器也将被更新。但是,它也使您不必加载全部数据点(因为之前和之后的范围仅包含低分辨率的数据点)。在将数据返回到 highstocks 图表之前,您需要编写将数据正确平均为更少数据点的代码。

在 setExtremes 处理函数(当用户滚动导航器时调用该函数)中,我有代码发出 AJAX 请求以将新数据添加到 Highstocks 图表。我还有使用 setInterval() 每 10 秒获取新数据点的代码。您需要一个变量来跟踪 setInterval() 更新何时发生,因为如果它向图表添加新数据点,这也将最终调用 setExtremes 处理程序函数,然后再发出另一个 AJAX 请求。您的 setExtremes 处理程序中的 AJAX 请求仅应在 setInterval() 更新未发生时运行。(很容易出现一些导致 AJAX 数据请求无限循环的错误。)

您还需要 AJAX 数据请求中的变量,以便后端代码知道请求是来自 setInterval() 还是来自您的 setExtremes 处理程序(当用户滚动导航器时),以便它知道它是否应该只返回请求时间范围内的数据(对于 setInterval() 请求)或对整个数据范围进行低/高分辨率平均(对于 setExtremes 处理程序请求)。

我不认为这些变量完全消除了竞争条件的可能性。

您描述的问题是正确的:您不能将 adaptToUpdatedData 设置为 false 并添加新数据点,因为导航器不会更新。这可以防止您将导航器滚动到新点。但是如果你不设置它,当你请求新的(和更小的)数据范围时,导航器会更新以适应这个范围。导航器和主图表将显示相同范围的数据,使导航器无用。

不幸的是,塞巴斯蒂安的回答不起作用。更新 series[0] 不会影响导航器,因为将 adaptToUpdatedData 设置为 false 会禁用导航器重绘自身。

这种低/高分辨率方法是一种 hack,但这是我发现的唯一可行的方法(在经历了六种左右不起作用的其他方法之后)。如果 Highstocks 团队可以添加这个就太好了功能到他们的图书馆。

于 2013-07-15T19:36:14.033 回答
0

我也遇到了这个问题,在尝试了很多解决方案之后,我找到了一个真正适合我的解决方案。

我使用了一个包含最大值的全局变量,xAxis当我更新图表时,我验证新xAxis值是否大于maxX变量。

如果它是真的,那么我maxX用新的点更新 ,然后我使用 ,然后chart.xAxis.setExtremes (chart.xAxis.min, maxX);我重新绘制图表。

有了这两件事,图表将模拟动态数据的延迟加载,但另一个问题出现了:范围选择器和导航器没有更新。解决方案是:

chart.rangeSelector.buttons[0].setState(2);
chart.rangeSelector.clickButton(0,0,true);

这两行代码再次启用范围选择器,一切正常。

于 2014-10-10T19:01:13.353 回答