数据集成:注意事项和概述
开始使用图表库时,首先需要考虑的是如何集成自有时间序列数据。
时间序列数据有许多不同形式(和众多潜在来源):
-
您的数据可能来自贵公司创建的数据库或源,或是基于订阅的第三方数据供应商连接。 您的数据可能是静态的,也可能根据直播源(流数据)动态更新。
-
您的数据可能足够小,可以单次加载,也可能足够大,需要分页(如随着用户滚动页面,加载更多数据)。
-
您的数据也许是从远程服务器异步拉取,或是从输入流推送。
-
最后,您的数据格式可能与库要求的格式类似,也可能需要大量计算、转换或集合。
-
要将您的数据录入图表,总是需要一些自定义操作。本教程将概述该操作……把数据导入图表的原理。
注意:对于以下每种情况,都有相应的教程参考。这些额外教程将补充与提供更多细节和示例代码。建议大家阅读相关教程:ChartIQ OHLC 数据格式(教程 - InputDataFormat.html)及周期性和您的主数据(教程 - Periodicity.html)。 这些教程内容涵盖先将您的数据做成正确格式,再导入图表。
术语
首先,我们来解释一些术语——(您可能不完全理解所有这些术语,但随着深入查阅数据集成教程,这些术语会变得越来越明确)。
-
图表 - 是指控制和显示图表 CIQ.ChartEngine 的库对象 CIQ.ChartEngine。有时图表实例也指。
-
静态数据初始化 - 是指创建图表时,使用一组固定数据初始化图表。
-
拉取数据 - 是指通过一组回调函数从您的应用程序请求数据。这些回调函数通过创建“quotefeed”进行设置。A quotefeed 是您将编写的软件“桥”。可以将图表视为您提供的桥代码客户端。也可以将“拉取数据”看做一个事件驱动模型。建议采用“拉取”方法。
-
推送数据 - 是指应用程序(即您的代码)将数据发送到图表,采用简单的方法调用图表 API。“静态初始化”即推送数据。数据流到图表也是推送数据。通常来说,静态初始化和推送流数据是一起的。外部时间序列流更新 通过 web 套接字送达时被附加到图表的右侧。
-
流数据 - (有时亦称“实时”数据)是指随着时间推移的连续数据 更新,不论是采用拉取还是推送的方式。
-
分页 - 是指图表请求一个较旧的时间序列数据“页面”的情况,通常发生在用户滚动页面越过图表的左边缘之时。图表开始时考虑分页数据,允许用户返回历史记录而无需超载浏览器。
尽管集成场景有众多可能,但是几乎每个场景都可以归结为以下三种情况的组合。每种情况在单独教程中完整介绍。通过支持这三种情况,库提供了整合您的数据所需的一切。
案例 1:静态数据初始化
静态初始化是将数据变成图表的最简单方式,直接将一组时间序列数据传到新图表即可。如果使用其他图表库,那么您可能用到了静态初始化。静态初始化方法最为简单,但也 最有限,无法满足大多数需求。对于非常大的数据集或实时数据更新,静态初始化无法满足需求。
只有在同时满足以下两个条件时才使用静态初始化:
- 只使用历史时间序列数据(即无需实时更新)
- 时间序列数据集非常小,可以放到一个数据请求中(通常少于 20000 条数据)。
即使您的集成需求仅限于以上情况,请记住,您的应用程序还必须管理符号条目和菜单事件,以决定何时获取数据。
静态数据集成详细教程 Static Data Integration Tutorial 中列举了各种示例来详细说明该情况。
案例 2:从远程数据服务器拉取数据
** 建议方法 **
“拉取”数据是最常见的用例,对大多数应用程序而言也是最佳方法。如果您的数据集很大或需要实时更新,那么“拉取”模式会更容易实现。图表使用这种方法时,也更容易构建 UI(菜单)。
拉取是通过构建一个“quotefeed”对象实现的。quotefeed 即您提供的软件“桥”,将数据从远程数据服务器传送至图表。
作为库的用户,您在 JavaScript 中构建一个 quotefeed 对象,然后将它附加到图表引擎。附加之后,图表引擎使用它来获取图表所需的数据。(接近 quotefeed 的设计模式是 The Bridge Pattern)。 下图所示的以下序列概括了每次图表需要 quotefeed 的数据时的情况。
- 图表向 quotefeed 调用 Fetch 请求。“Fetch 请求”在库调用您提供的其中一个自定义 quotefeed 函数(回调)时发生。
- (您编写的) Fetch 函数向远程数据服务器发出数据请求——来自库的获取请求始终对应一个服务器数据请求。通常而言,服务器请求是通过一个 AJAX 函数调用发出的 HTTP Get 消息。
- 远程数据服务器响应请求的数据。该响应触发您的自定义事件处理程序(嵌入 quotefeed 中),根据需要转换和格式化数据。
- 然后,事件处理程序调用图表的回调函数,从响应消息传入格式化数据。

为何使用拉取方法
我们建议采用拉取方式的原因在于它减少了作为开发人员需要跟踪的大量“状态”。下面举一个极端示例:假如用户选择了一个股票代码和几个比较代码。它们可能会请求一个需要多个股票代码的“方程图”(AAPL + MSFT / IBM)。可能启用一项相对价格研究,这需要额外加载一个股票代码。所有这些股票代码均需要流数据来更新,需要分页时必须全部重新加载。要跟踪所有这些条件势必相当复杂!然而,使用拉取方法(事件模式)时,图表会跟踪一切信息。您需要做的只有编写一个函数代码,响应图表的数据请求。
不使用拉取方法的原因通常有二:
-
您的数据非常简单,可以采用静态初始化处理(案例 1)。
-
您的数据服务器不支持请求 - 响应协议(即您的服务器不是 Ajax)。注意:Websockets 最好是通过高级版本的 quotefeed 支持,因为高级版本提供订阅和退订回调函数。请参阅下文中的“罕见案例” 。
更详细的 quotefeed 构建说明请见 Quotefeed Tutorial。
案例 3:从连续的流源推送数据
在最后一个案例中,假设您的应用程序(自行)与流服务器(如 WebSocket)上的连续源建立连接。一般该案例与案例 1(静态初始化)或案例 2 (quotefeed) 结合使用。
建立连接后,您创建自有事件处理程序来处理连续源传入的每个数据包。每次收到包时,您将之发给图表。在该用例中,库不直接联系服务器——它只知道 数据定期从您的 JavaScript 代码推送过来。
以下两步序列(如图所示)概括了整个序列。
- 远程源发送一个流数据包(一般通过 Websocket),这(针对每个包)触发事件处理程序。
- 您的事件处理程序处理数据包(根据需要转换和格式化)之后,调用图表引擎的附加数据函数调用,从数据包传入格式化数据。

注意:对于 Websocket,quotefeed 高级版本综合了“推送”和“拉取”两种方式。简化“拉取”,但增添了一个订阅模式来管理连续的流服务。请参阅下文“高级组合案例”一节。
与流服务器集成的更多详情请见 流数据集成教程 Steaming-Data Integration Tutorial.
案例 4:高级组合案例
以上案例支持大多数 ChartIQ 的客户群且效果良好,但在某些情况下需要更加灵活。因此,图表库允许综合使用以上案例,这就表示可以根据需要混合搭配上述原理来满足不寻常的要求,以及功能有限的服务器。
例如,创建图表时可以传入一组历史数据的一部分,其余的历史数据将在需要时通过 quotefeed 拉取(如使用分页),与流数据通过 web 套接字到达时直接附加。
与流服务器集成的更多详情请见 Steaming-Data Integration Tutorial.
结合数据加载方法请见高级 Advanced Data Integration Tutorial.
考虑 CORS
独立于图表库但与数据集成到浏览器相关的是跨源限制 (CORS) 问题。简单来说,aaa.com 网站上的 HTML 页面不能自动从 bbb.com 访问数据。这一限制是所有浏览器的默认行为,所以如果您想“混搭”数据,请查看 CORS.md 了解浏览器的要求和如何克服 CORS 限制。
