首页 文章

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

提问于
浏览
111

我正在尝试选择合适的技术来更新项目,该项目基本上可以在可缩放的可缩放图形中渲染数千个点 . 使用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,是supposed to be better at rendering animations . 但是,我也在考虑使用像KineticJS这样的基于画布的库进行更彻底的检修 . 但是,在我使用一种方法或另一种方法之前,我想听听那些使用这么多数据做过类似Web应用程序并得到他们意见的人 .

最重要的是性能,第二个重点是易于添加其他交互功能和编程动画 . 一次可能不会超过2000个点,每个点上的误差小 . Zooming in, out, and panning around need to be smooth. 如果最新的SVG库在这方面还不错,那么使用d3的方便性可能会超过KineticJS的增加设置等 . 但是如果使用画布有巨大的性能优势,特别是对于计算机速度较慢的人来说,那么我当然更愿意这样做 .

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

我注意到有些用户使用了d3.js manipulation combined with canvas rendering的混合体 . 但是,我无法在网上找到很多关于此的文档或与该帖子的OP联系 . 如果有人有任何使用DOM-to-Canvas(democode)实现的经验,我也想听听你的意见 . 它似乎是一个很好的混合体,能够操纵数据并对如何渲染数据进行自定义控制(以及性能),但我想知道是否必须将所有内容加载到DOM中仍然会减慢速度 .

我知道有一些与此类似的现有问题,但它们都没有提出同样的问题 . 谢谢你的帮助 .

Follow-up :我最终使用的实现是在https://github.com/zooniverse/LightCurves

4 回答

  • 8

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

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

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

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

    Yet there is no magic bullet for performance, and these four possible approaches don't begin to cover the full space of possibilities. 例如,您可以组合几何和语义缩放,使用几何方法进行平移(更新"transform"属性)并仅在缩放时重绘单个圆 . 您甚至可以将这些技术中的一种或多种与CSS3变换结合起来以添加一些硬件加速(如hierarchical edge bundling example中所述),尽管实现起来可能很棘手并且可能会引入视觉伪像 .

    不过,我个人的偏好是 keep as much in SVG as possible, and use Canvas only for the "inner loop" when rendering is the bottleneck . SVG有很多开发方便的东西 - 比如CSS,数据连接和元素检查器 - 从Canvas开始往往是不成熟的优化 . 将Canvas与SVG结合起来,就像Facebook IPO可视化一样链接,是一种灵活的方式来保留大部分这些便利,同时仍然可以获得最佳性能 . 我还在Cubism.js中使用了这种技术,其中时间序列可视化的特殊情况非常适合位图缓存 .

    如这些示例所示,您可以将D3与Canvas一起使用,即使D3的某些部分是特定于SVG的 . 另见force-directed graphcollision detection example .

  • 180

    我认为在 your case 画布和svg之间的决定并不像是“骑马”或驾驶“保时捷”之间的决定 . 对我来说,这更像是关于汽车颜色的决定 .

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

    • 画一个明星,

    • 添加星星和

    • 删除一颗星

    采取线性时间 . 所以,如果您对框架的决定是好的,那么它会更快,否则会慢一点 .

    如果你继续假设框架速度很快,那么很明显导致性能不足的是大量的星星并处理它们是框架无法为你做的事情,至少我不知道对这个 .

    我想说的是问题的根源导致计算几何的基本问题,即:range searching和另一个计算机图形:level of detail .

    为了解决您的性能问题,您需要实现一个良好的预处理器,它能够非常快速地找到要显示的星星,并且可能能够根据缩放比例聚集在一起的星星 . 让你的视野生动而快速的唯一因素就是尽可能地保持星星的数量 .

    正如你所说,最重要的是性能,而不是我倾向于使用canvas,因为它没有DOM操作 . 它还提供了使用webGL的机会,这大大提高了图形性能 .

    顺便问一下:你查了paper.js?它使用画布,但模拟矢量图形 .

    PS:In this Book你可以在网上找到关于图形的非常详细的讨论,技术,画布,SVG和DHTML的优缺点 .

  • 7

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

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

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

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

    使用Chrome分析器,使用CanvasJS,内存从未超过30MB,而Highcharts内存使用率超过600MB .

    另外,刷新时间为5秒CanvasJS渲染比Highcharts更具响应性 .

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

    那说对于离线报告,我会使用Highcharts,因为它更灵活的API .

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

    当性能非常关键时,应考虑画布 . SVG的灵活性 . 并不是画布框架不灵活,但是为了获得与svg框架相同的功能,它需要为canvas框架做更多的工作 .

  • 3

    也可以查看Meteor Charts,它 Build 在超级快速KineticJS框架之上:http://meteorcharts.com/

相关问题