快速响应的交互式图表/图形:SVG,画布,其他?


114

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

http://www.planethunters.org/classify

完全缩小时大约有2000点。尝试使用底部的手柄放大一点,然后拖动以平移。您会发现它非常不稳定,除非您有一台非常快的计算机,否则您在一个内核上的CPU使用率可能会高达100%。对焦点区域的每次更改都需要重绘到原图,这相当慢,而且绘制的点数更多时更糟。

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

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

d3.js源自Protovis,它是基于SVG的,被认为在渲染动画方面更好。但是,我对性能有多好以及性能上限有疑问。因此,我也在考虑使用基于画布的库(例如KineticJS)进行更全面的大修。但是,在我深入研究一种或另一种方法之前,我想听听有人用如此大量的数据完成了类似的Web应用程序,并征求了他们的意见。

最重要的是性能,其次是增加其他交互功能和对动画进行编程的重点。一次最多可能不会超过2000个点,每个点上都有很小的误差线。放大,缩小和平移需要平滑。如果最新的SVG库在这方面是不错的,那么使用d3的便利性可能会超过KineticJS等的增加的设置。但是,如果使用canvas具有巨大的性能优势,尤其是对于计算机速度较慢的人,那么我绝对会喜欢这样。

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


“最重要的是性能,其次是增加其他交互的便利性”,画布+1
philipp 2012年

问题是,SVG在大多数浏览器中是否足以容纳2k点+其他图表元素?如果是这样,并且速度缓慢是由于protovis的弱点,那么我宁愿坚持使用SVG。
安德鲁·毛

1
Mike Bostock已经给出了一个很好的答案。对于一些额外的相关信息,您可以检查出这两个资源: stackoverflow.com/questions/5882716/html5-canvas-vs-svg-vs-div/... blogs.msdn.com/b/ie/archive/2011/04/22 / ...
乌米特

8
后续:我已经使用SVG / canvas混合方法实现了这一点,其中SVG负责轴和网格线,而canvas可以非常快速地渲染点。超级快!
安德鲁·毛

Answers:


183

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

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

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

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

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

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

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


哇,这是一个很棒的答案,来自可视化大师!我认为我必须坚持语义缩放,在我的计算机上,基于画布的渲染器在平移/缩放时可能比SVG版本快得多(可能与浏览器的实现有关吗?)。您所说的关于将SVG与画布用作内部循环的内容恰好是我想要确认的内容,并且代码示例仅是一笔可观的收获。非常感谢!
安德鲁·毛

只是想到要在不同的浏览器上尝试语义缩放示例:Chrome,两者都非常快,我无法分辨出区别;IE:SVG稍慢;Firefox(最新评论):与画布相比,SVG速度慢。我想这也使决定变得复杂,但使画布渲染成为安全的选择。还有一个问题:使用KineticJS而不是canvas是否会直接影响性能?
安德鲁·毛

1
安德鲁,有点晚了,但这是我在FF的经历:正在赶上来。我以前运行FF 15和D3 SVG过渡的速度很快就开始变慢。但是每个新版本的速度都大大提高了。现在,我使用的是FF 18 beta,与17相比它的速度更快。不确定它是否像铬一样光滑。
user2503795

@AndrewMao嗨,安德鲁,我遇到了一种情况,似乎渲染是瓶颈。我需要平移和缩放一些点以及大约6000条曲线路径。stackoverflow.com/questions/17907769/svg-path-rendering-speed / ...但是当Bostock说“尽可能多地保留SVG,并且仅将Canvas用于“内部循环””时,我不太理解Bostock。不过看了四个例子。你能给我一些启发吗?
kakacii

@kakacii在所有浏览器中的转换是否同样缓慢?如果是这样,我会说您要么使用了错误的代码,要么达到了浏览器渲染的极限。如果您可以发布一些代码,我可能会提供帮助。mbostock指的是使用SVG来简化操作,仅在必要时才使用canvas,因为这样会使代码更加复杂。但是,诸如KineticJS之类的库已在某种程度上简化了该过程。
安德鲁·毛

8

我认为,就您而言,画布和svg之间的决策不像“骑马”或驾驶“保时捷”之间的决策。对我来说,这更像是关于汽车颜色的决定。

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

  • 画一颗星星
  • 加一个星星
  • 删除星星

花费线性时间。因此,如果您对框架的决定是好的,那它会快一些,否则会慢一些。

如果继续假设该框架运行很快,那么很明显的是,由于大量的恒星而导致性能下降,而处理它们却是所有框架都无法为您做的事情,至少我不知道对这个。

我要说的是,问题的根源导致了计算几何的基本问题,即:范围搜索和另一种计算机图形学:详细程度

为了解决您的性能问题,您需要实现一个好的预处理器,该预处理器可以非常快速地找到要显示的恒星,并且也许可以根据缩放将聚集在一起的恒星聚在一起。唯一可以使您的视图生动生动的方法是,使绘制的星星数量尽可能少。

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

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

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


7

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

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

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

因此,持续15分钟:900点(每秒数据点)x2(线和条形组合图)x4图=总计7200点。

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

同样,刷新时间为5秒,与Highcharts相比,CanvasJS渲染的响应速度更快。

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

也就是说,对于脱机报告,我会选择Highcharts,因为它的API更灵活。

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

当性能非常关键时,应考虑使用画布。SVG具有灵活性。并不是说画布框架不是灵活的,而是要为画布框架分配更多的工作来获得与svg框架相同的功能。



0

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.