11

我正在使用 d3.js 来可视化从我的 python 后端(通过 Websocket)发送的时间序列数据。一张图表的通常数据量约为 120 个条目(2 小时数据,每分钟 1 个条目)。这运行良好,每分钟更新一次。

但它也应该能够以 1 分钟的间隔可视化一个月或更长时间(可能长达一年)的数据。渲染如此大量的数据对于 SVG 来说太多了。

我正在考虑以下替代方案:

  • 在画布中渲染它。真的有那么快吗?
  • 切换到像 Highchart.js 这样的另一个库(看到一个大约 50k 条目的演示)
  • 在服务器上渲染 SVG/JPG/PNG。有使用 phantom.js 渲染 d3.js 服务器端的经验吗?我想重用已经编写好的图形模型。但它也可以是任何其他能够呈现数据的库(使用 python 生成图形)

你会推荐什么?

4

1 回答 1

4

请注意,d3 支持使用 javascript 的缓冲数组。根据我的经验,具有数千个时间序列数据点的 SVG 绘图运行良好(即使通过 websocket 以 20 毫秒的时间更新多个实时数据源)。

例如,如果您将所有数据打包在 Python 中;您可能不需要在实时视图中执行此操作,因为您的更新速度相对较慢:

import struct
# fake data point
p = [56435367, 200, 1]
# <=little endian, d=float64 (for time), d=float64
msg_str = struct.pack('<' + 'd' * len(p), *p)
print(msg_str)
b'\x00\x00\x008\x15\xe9\x8aA\x00\x00\x00\x00\x00\x00i@\x00\x00\x00\x00\x00\x00\xf0?'

然后通过您的 websocket 访问 javascript,您可以在其中执行以下操作:

this.ws.onmessage = function(e){
    // Just pump the raw bytes straight into CircularBuffer
    graph.databuffer.push(e.data);
    ...

当你想绘图时,假设 g 是你对 D3 svg 的引用:

// Get a Float64Array containing all the values
var series_data = graph.databuffer.get_array_stream();
g.attr("d", graph.line(d3.zip(time, series_data)));

当然,如果您预先拥有所有数据,这应该会更容易。您是否在绘制点而不是单一路径?我发现浏览器很难绘制数以万计的单独圆圈(特别是如果它们都每 20 毫秒移动一次!),但它们可以很容易地处理路径。

于 2013-07-30T01:37:24.697 回答