Python 大d3.js图形、画布还是服务器端渲染?

Python 大d3.js图形、画布还是服务器端渲染?,python,canvas,svg,d3.js,Python,Canvas,Svg,D3.js,我使用d3.js可视化从python后端(通过Websocket)发送的timeseries数据。 一个图形的数据量通常约为120个条目(2小时的数据,每分钟1个条目)。运行良好,每分钟更新一次 但它也应该能够可视化一个月或一个月以上(可能长达一年)的数据,也可以以1分钟的间隔。 呈现如此大量的数据对于SVG来说太多了 我正在考虑以下备选方案: 在画布中渲染它。真的那么快吗 切换到另一个库,如Highchart.js(看到了一个包含~50k条目的演示) 在服务器上呈现SVG/JPG/PNG。是

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

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

我正在考虑以下备选方案:

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

您有什么建议?

请注意,d3支持使用javascript。根据我的经验,SVG绘图具有数千个时间序列数据点,效果很好(即使通过websockets以20毫秒的速度更新多个实时数据源)

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

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?'
当您想要打印时,假设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毫秒移动一次!),但它们可以很容易地处理路径。

我认为应该采用超级酷的方法。@Drogans是的,我已经在为小图做这项工作了。但我的问题是大图形(数据量巨大)…嗯…d3应该可以运行良好,有120个数据点。d3解决方案有哪些问题?Canvas非常擅长展示从一秒到另一秒变化的图表——是的,它的速度非常快。但它的交互性不强(如向下钻取或弹出信息注释)。如果要显示静态图表(已保存到图像中的图表),画布可以从在画布中显示静态图像开始,然后根据需要使用更新的数据点更新画布(您提到的可重用性)。@markE如我所述,120个数据点没有问题,但随着数据集的增长,速度会大幅降低。我更喜欢画布,这样我可以保存图形,而不必在服务器上转换SVG图像。但我的问题是,如果我必须渲染数千个数据点,画布是否能够进行渲染,或者是否有其他技术?听起来您的查看器有两个用例。我将创建另一个查看历史数据的图表。根据缩放级别和所需性能,可以使用重复的ajax调用填充图表。你可能会发现在后台加载一年的数据点是可以的!我有一个类似的例子,我正在尝试制作一个实时烛台图表,我读了一篇来自微软的帖子,上面说实时图表应该在画布上完成,在我的情况下,我需要通过websocket每秒更新蜡烛50次,在大多数情况下,蜡烛的数量不到1000支,你认为canvas对同样的东西有意义吗?或者你会使用SVG吗?在渲染实时数据时,你是否会因为图形的移动而无限地翻译SVG图表而遇到任何问题?我对SVG没有任何问题,但这是5年前的事了,我不再熟悉这些东西了!如果您打算长时间保留这些数据,我会从DOM(js中的过滤器)中删除旧的/过期的数据。从内存中,我使用了一个循环缓冲区来解决这个问题。祝你好运
// 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)));