繁体   English   中英

快速响应的交互式图表/图形:SVG、Canvas 还是其他?

[英]Fast and responsive interactive charts/graphs: SVG, Canvas, other?

我正在尝试选择正确的技术来更新一个项目,该项目基本上在可缩放、可平移的图形中呈现数千个点。 当前使用 Protovis 的实现性能不佳。 在这里查看:

http://www.planethunters.org/classify

完全缩小时大约有 2000 个点。 尝试使用底部的手柄放大一点,然后拖动它来平移。 你会看到它非常不稳定,除非你有一台非常快的计算机,否则你的 CPU 使用率可能会在一个内核上达到 100%。 对焦点区域的每次更改都会调用对 protovis 的重绘,这非常慢,并且绘制的点越多越糟糕。

我想对界面进行一些更新,并更改底层的可视化技术,以提高动画和交互的响应速度。 从下面的文章中,似乎可以在另一个基于 SVG 的库或基于画布的库之间进行选择:

http://www.sitepoint.com/how-to-choose-between-canvas-and-svg/

d3.js 源于Protovis,是基于 SVG 的,应该更擅长渲染动画 但是,我怀疑它的性能上限是多少。 出于这个原因,我也在考虑使用像KineticJS这样的基于画布的库进行更全面的改革。 但是,在我深入使用一种或另一种方法之前,我想听听已经使用这么多数据完成类似 Web 应用程序的人的意见,并听取他们的意见。

最重要的是性能,其次是易于添加其他交互功能和编写动画。 一次可能不会超过 2000 个点,每个点上都有那些小误差条。 放大、缩小和平移需要平滑。 如果最新的 SVG 库在这方面表现不错,那么使用 d3 的便利性可能会超过 KineticJS 等增加的设置。但是如果使用画布有巨大的性能优势,特别是对于计算机速度较慢的人,那么我肯定更愿意走那条路。

NYTimes 使用 SVG 制作的应用程序示例,但动画仍然可以接受: http ://www.nytimes.com/interactive/2012/05/17/business/dealbook/how-the-facebook-offering-compares.html . 如果我可以获得那种性能并且不必编写自己的画布绘图代码,我可能会选择 SVG。

我注意到一些用户使用了d3.js 操作与画布渲染的混合。 但是,我在网上找不到太多关于此的文档或与该帖子的 OP 取得联系。 如果有人在执行这种 DOM 到画布(演示代码)实现方面有任何经验,我也希望收到您的来信。 它似乎是能够操作数据和对如何呈现数据(以及性能)进行自定义控制的很好的混合体,但我想知道是否必须将所有内容加载到 DOM 中仍然会减慢速度。

我知道存在一些与此类似的现有问题,但没有一个问的完全相同。 谢谢你的帮助。

跟进:我最终使用的实现是在https://github.com/zooniverse/LightCurves

幸运的是,绘制 2000 个圆是一个非常容易测试的示例。 所以这里有四种可能的实现,Canvas 和 SVG 各两个:

这些示例使用 D3 的缩放行为来实现缩放和平移。 除了圆是在 Canvas 还是 SVG 中渲染之外,另一个主要区别是您使用几何缩放还是语义缩放。

几何缩放意味着您将单个变换应用于整个视口:当您放大时,圆圈会变大。 对比语义缩放意味着您单独对每个圆应用变换:当您放大时,圆保持相同的大小,但它们会散开。 Planethunters.org 目前使用语义缩放,但考虑其他情况可能会有用。

几何缩放简化了实现:您应用一次平移和缩放,然后重新渲染所有圆。 SVG 实现特别简单,只需更新一个“transform”属性。 两个几何缩放示例的性能感觉都绰绰有余。 对于语义缩放,您会注意到 D3 比 Protovis 快得多。 这是因为它为每个缩放事件做的工作要少得多。 (Protovis 版本必须重新计算所有元素的所有属性。)基于 Canvas 的语义缩放比 SVG 快一些,但 SVG 语义缩放仍然感觉响应灵敏。

然而,性能没有灵丹妙药,这四种可能的方法并没有开始涵盖所有可能性。 例如,您可以结合几何和语义缩放,使用几何方法进行平移(更新“变换”属性),并且在缩放时仅重绘单个圆圈。 您甚至可以将这些技术中的一种或多种与 CSS3 转换相结合,以添加一些硬件加速(如分层边缘捆绑示例中所示),尽管这可能难以实现并且可能会引入视觉伪像。

不过,我个人的偏好是尽可能多保留在 SVG 中,并且在渲染成为瓶颈时仅将 Canvas 用于“内部循环” SVG 为开发提供了如此多的便利——例如 CSS、数据连接和元素检查器——以至于从 Canvas 开始通常是过早的优化。 将 Canvas 与 SVG 相结合,就像在您链接的 Facebook IPO 可视化中一样,是一种灵活的方式,可以保留大部分这些便利,同时仍然保持最佳性能。 我还在Cubism.js 中使用了这种技术,其中时间序列可视化的特殊情况非常适合位图缓存。

如这些示例所示,您可以将 D3 与 Canvas 一起使用,即使 D3 的某些部分是特定于 SVG 的。 另请参阅此力导向图和此碰撞检测示例

我认为在你的情况下,canvas 和 svg 之间的决定不像是“骑马”或驾驶“保时捷”之间的决定。 对我来说,这更像是关于汽车颜色的决定。

让我解释一下:假设,基于框架的操作

  • 画一颗星星,
  • 添加一颗星和
  • 删除一颗星

采取线性时间。 所以,如果你对框架的决定是好的,它会快一点,否则会慢一点。

如果你继续假设框架很快,那么很明显,性能的缺乏是由大量的星星造成的,并且处理它们是任何框架都无法为你做的,至少我不知道对这个。

我想说的是,问题的基础引出了计算几何的一个基本问题,即:范围搜索和另一个计算机图形学:细节层次

为了解决您的性能问题,您需要实现一个良好的预处理器,它能够非常快地找到要显示的星星,并且可能能够根据缩放将距离很近的星星聚类。 唯一能让您的视图保持生动和快速的方法是尽可能减少要绘制的星星数量。

正如您所说,最重要的是性能,而不是我倾向于使用画布,因为它无需 DOM 操作即可工作。 它还提供了使用 webGL 的机会,这大大提高了图形性能。

顺便说一句:你检查paper.js 了吗? 它使用画布,但模拟矢量图形。

PS: 在本书中,您可以找到有关 Web 图形、画布、SVG 和 DHTML 的技术、优缺点的非常详细的讨论。

我最近在一个近实时仪表板(每 5 秒刷新一次)上工作,并选择使用使用画布呈现的图表。

我们尝试了 Highcharts(基于 SVG 的 JavaScript 图表库)和 CanvasJS(基于 Canvas 的 JavaScript 图表库)。 尽管 Highcharts 是一个很棒的图表 API 并且提供了更多的功能,但我们还是决定使用 CanvasJS。

我们需要为每个图表显示至少 15 分钟的数据(可选择最多两个小时的范围)。

所以 15 分钟:900 点(每​​秒数据点)x2(线和条组合图)x4 图表 = 总共 7200 点。

使用 chrome profiler,CanvasJS 内存从未超过 30MB,而 Highcharts 内存使用量超过 600MB。

此外,刷新时间为 5 秒,CanvasJS 渲染比 Highcharts 响应更快。

我们使用一个计时器(setInterval 5 秒)进行 4 次 REST API 调用,以从连接到 Elasticsearch 的后端服务器拉取数据。 JQuery.post() 接收作为数据更新的每个图表。

也就是说,对于离线报告,我会使用 Highcharts,因为它的 API 更灵活。

还有 Zing 图表声称使用 SVG 或 Canvas,但没有看过它们。

当性能真的很关键时,应该考虑画布。 SVG 的灵活性。 并不是画布框架不灵活,而是画布框架需要做更多的工作才能获得与 svg 框架相同的功能。

也可以看看 Meteor Charts,它建立在 uber fast KineticJS 框架之上: http ://meteorcharts.com/

我还发现,当我们将带有 SVG 图形的页面打印为 PDF 时,生成的 PDF 仍然包含基于矢量的图像,而如果打印带有 Canvas 图形的页面,则生成的 PDF 文件中的图像会被光栅化。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM