You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

114 lines
14 KiB
Markdown

2 years ago
# 42 | 如何整理出我们自己的可视化工具集?
你好,我是月影。
我们知道可视化虽然可以认为是前端的一个小分支但总体来说它也是一个比较有广度的领域从内容上大体包括数据图表、图形绘制、地理信息可视化、3D场景和数字孪生应用等等从设备上包括移动端、PC浏览器和可视化大屏等等。
作为刚刚入门可视化领域的工程师,我们经常会因为知识面不够广、工具不够丰富,而寄望于用单一的工具来解决我们遇到的所有问题,所谓“手里有锤子,看什么都像是钉子”。想想也知道,这并不能很好地处理所有的可视化应用。因为,一旦我们选择了错误的、不适合于当前场景的工具,就会让最终实现的结果不理想,或者开发效率不高。
因此,想要成为一名优秀的可视化工程师,我们必须要知道如何丰富自己手中的工具集,来应对各种场景和挑战。丰富工具集,并不意味着我们需要从头开发一切适合各种场景使用的工具。大部分时候,我们可以利用行业发展和社区的力量,站在巨人的肩膀上,使用各种成熟的工具,来更好地完成我们的项目。
那今天,我带你一起系统地梳理目前行业里,适合可视化应用的优秀且成熟的工具,来丰富你的工具箱,让你在面对各种可视化需求时能够游刃有余。
首先我们来看看可视化应用的主体需求分类搞清楚了这些我们才能选择出更合适的工具来完成这些需求。根据可视化场景主体需求一般可以分成5种分别是绘制基本图形、绘制基础图表、绘制关系图和流程图、绘制地理信息以及绘制三维模型和数字孪生应用。接下来我就一一来说。
![](https://static001.geekbang.org/resource/image/88/a8/8869a44444710e25556fd1b801a400a8.jpeg)
## 选择绘制基本图形的工具
我们先来说说绘制基本图形要选择的工具。简单情况下我们用浏览器原生的四类基本图形系统就可以完成绘制分别是HTML/CSS、SVG、Canvas和WebGL。
HTML/CSS比较简单也有很多丰富的前端领域的工具这里就不多说了。SVG原生的API使用起来也并不复杂不过我们也可以用一些成熟的绘图库它能够让我们更方便地绘制各种图形。我比较推荐 [Snap.svg](http://snapsvg.io/) 这个库它提供的API能够非常方便地绘制各种SVG图形。尤其值得赞扬的是它提供了一套[交互式教学文档](http://snapsvg.io/start/),能够让你快速上手整个库的使用。
如果你使用Canvas和WebGL来绘制图形可选的工具就比较多了。比较成熟的2D渲染引擎包括 [Fabric.js](https://github.com/fabricjs/fabric.js)、[Pixi.js](https://github.com/pixijs/pixi.js) 等比较成熟的2D/3D引擎包括 [SpriteJS](https://spritejs.org/#/)、[P5.js](https://github.com/processing/p5.js) 等以及比较成熟的3D引擎包括 [ThreeJS](https://github.com/mrdoob/three.js)、[Babylon.js](https://github.com/BabylonJS/Babylon.js) 等。这些库各有特点,它们的官方使用文档和示例都比较完善,我建议你多花一些时间去学习它们的使用方法。这能帮助你在绘制基本图形的时候,灵活选用适合的库。
另外既然说到了Canvas2D绘制图形那我还要提一下[Rough.js](https://github.com/rough-stuff/rough)这个库。这是个非常有特点的库,它能够绘制出带有手绘风格的图形,比如,我们在[第5课](https://time.geekbang.org/column/article/255584)就使用过它。
我刚才说的这些工具对于绘制基本的2D/3D图形来说已经足够了。但是功能相对更强大和丰富的库体积也会更大一些使用上也会复杂一些所以我们还是应该根据实际需求复杂程度来灵活选择。
## 选择绘制基础图表的工具
绘制基础图表是可视化项目中很常见的需求,我们可以采用图表库和数据驱动框架来完成。常用的成熟图表库包括 [ECharts](https://echarts.apache.org/)、[Chart.js](https://github.com/chartjs/Chart.js)、[Highcharts](https://github.com/highcharts/highcharts)、[AntV G2](https://antv-2018.alipay.com/zh-cn/g2/3.x/index.html) 这4种。大部分图表库在使用上大同小异效果也差别不大好像选什么都没有差别。但在选择图表库的时候我们也需要考虑底层的图形系统或图形库这关系到复杂图表渲染和交互的性能另外在同时需要绘制图表和基本图形的时候选择统一的图形系统可以保持一致性也能更好地实现图表与图形的协同交互。
这里我就说几个常见的搭配组合。如果你使用SpriteJS作为底层图形库还可以选择[QCharts](https://www.qcharts.cn/#/home)。如果你是在移动端设备渲染图表,可以考虑使用[AntV F2](https://antv-2018.alipay.com/zh-cn/f2/3.x/index.html),这是一个专为移动端场景设计的图表库。如果你要绘制更加灵活的图表,以及关系图和流程图,可以选择数据驱动框架,例如[D3.js](https://github.com/d3/d3)。不过D3.js虽然很好用但它是一个足够复杂的框架如果你希望在可视化领域深入发展最好能再多花一些时间彻底掌握它的使用方法。
最后,我还想再说说[Vega](https://vega.github.io/vega/)这个库。这也是一个图表库它定义了一套基于JSON规范的可视化语法以声明式的方式来绘制各种图表。最关键的是Vega定义可视化语法规范的思路对我们自己设计和实现图表库有着非常大的借鉴意义。如果你打算自己设计一套图表库我希望你能好好研究一下Vega相信你会有所收获的。
## 选择绘制关系图和流程图的工具
接着,我们再来说一类特殊的图表,比如关系图、流程图、脑图等等。我们一般将它们单独归为一类应用,称为图可视化。
图可视化怎么实现呢?我们在[第38课](https://time.geekbang.org/column/article/291822)里使用D3.js实现过相关的例子。除了D3.js以外还有一类直接绘制这些图形的图可视化库常用的有[Mermaid.js](https://github.com/mermaid-js/mermaid)、[Sigma.js](http://sigmajs.org/)以及[AntV G6](https://antv-2018.alipay.com/zh-cn/g6/3.x/index.html)等等。
其中Mermaid.js量级更轻主要是以声明的方式来绘制各种流程图。而Sigma.js和AntV G6的功能更丰富实现的图可视化不仅类型更多还能包含复杂的用户交互效果。
此外,还有一个特殊的库[Dagre](https://github.com/dagrejs/dagre)。它是绘制流程图的底层库,主要是用来计算图的元素布局,使用它再结合图形库,我们就能自己实现一个绘制流程图的图可视化库。这个图可视化库实现起来也不是很难,我把这个任务留在本节课的末尾,你可以试着去挑战一下。
## 选择地理信息可视化工具
前面两节课我们一起完成了3D地理信息可视化的实战。地理信息可视化是可视化项目中很重要的一类应用大部分可视化大屏应用场景都会包含地图或者3D地球因为许多数据本就和地理信息相关。由于需求很多因此市场上有许多地理信息可视化的库可供我们选择。
比较成熟的地理信息可视化库包括[MapBox](https://www.mapbox.com/)、[MapTalks](https://maptalks.org/)、[Leaflet.js](https://leafletjs.com/)、[MapV](https://github.com/huiyan-fe/mapv)、[AntV L7](https://antv-2018.alipay.com/zh-cn/l7/1.x/index.html)等等它们都支持简单的geoJSON、topoJSON数据和分片加载的瓦片地图。另外d3的子模块[d3-geo](https://github.com/d3/d3-geo)也能够处理地理信息可视化,尤其是它提供了多种地图投影,非常适合与其他库联动,实现各种不同的地图场景应用。
总体而言地理信息可视化是可视化领域里比较复杂的方向这些地理信息可视化库的功能也较为丰富使用场景很多如果详细来讲的话内容足够支撑起一门单独的课程了。我们前面花了3节课来讲的地理信息可视化案例其实也只是给地理信息可视化应用开了一个头如果你有兴趣深入学习可以通过这些地理信息可视化库再结合实战来真正深入掌握地理信息可视化的方法这也是成为优秀可视化工程师的必经之路。
## 处理三维模型和数字孪生应用
在学习3D图形的绘制的时候我讲到3D绘制一般有两种方式一种是加载静态的3D模型数据然后将3D物体渲染出来。这些3D模型数据通常是通过设计工具离线生成的。这种应用场景在游戏领域比较常见。
[![](https://static001.geekbang.org/resource/image/1a/37/1af60e98b43a3b35a6e42e75d38e8937.jpeg "SpriteJS加载的3D模型数据图片来源spritejs.org")](https://spritejs.org/demo/#/3d/fox)
另一类则是动态加载3D几何模型用前面绘制基本图形的工具就可以实现。在可视化应用中这类场景通常更普遍。
[![](https://static001.geekbang.org/resource/image/be/f9/be76cd097e373b9c225dd361f58ee2f9.jpeg "动态加载的几何图形图片来源OGL")](https://oframe.github.io/ogl/examples/?src=scene-graph.html)
不过在可视化领域中有一类应用也会用到非常多的3D模型那就是数字孪生应用。所谓数字孪生是对物理世界实体或系统的数字化表达。简单来说就是在虚拟世界中通过3D渲染来还原真实物理世界这需要我们将现实世界中的物体模型化为虚拟世界中的3D几何体。
[![](https://static001.geekbang.org/resource/image/3b/fa/3bf6256eabca8c8d5a0bcd152154fdfa.jpeg "物理世界和数字孪生示意图图片来源36kr.com")](https://36kr.com/p/1723581366273)
在这样的应用场景中,有时候我们可以考虑采用游戏的方式,使用游戏引擎和框架,例如[Unity](https://store.unity.com/products/unity-pro?gclid=CjwKCAjwq_D7BRADEiwAVMDdHsaPnsc1S8jvT8yY47lLFn_jH6WvSTdhlDwf5RJtrC6Leu3LN--2HhoCUqIQAvD_BwE)或者[虚幻引擎](https://www.unrealengine.com/zh-CN/)来完成我们的可视化应用。当然,这也就进入了另一个领域,游戏创作的领域。这部分内容,我们简单了解一下就可以了。
## 要点总结
可视化有着丰富的使用场景大致上可以分为5类分别是绘制基本图形、绘制基础图表、图可视化、地理信息可视化以及数字孪生。
这些场景各自有适合的工具库和框架可供我们选择,我在这里整理了一个脑图,供你在具体应用中参考。
![](https://static001.geekbang.org/resource/image/4d/53/4d546e0ff09bfa513767ba71612c5e53.jpg)
这是我们专栏最后一个模块的最后一节课了在这几个月的时间里我们先后学习了图形学与数学、视觉基础、视觉高级以及数据处理的相关知识。其中我们通过一些可视化实战学习了部分图形系统与图形库和工具的使用这当中主要包括SpriteJS、D3.js、QCharts等等。这和我们这节课列出的各类工具相比可以说是非常少了。
我想有的同学可能会有疑问,还有这么多的工具我们并没有详细来讲,那我学习到这里,算是真正入门可视化了吗?我想说的是,工具和库都是为我们服务的,正确使用这些工具和库的基础,其实就是我们前面学过的图形学与数学基础、视觉呈现技术,以及数据处理的原则,这些内容才是可视化的本质。而上层的工具和库的使用虽然复杂,但并不难,基本上照着文档学习和实践,就能够一步步掌握。
而如果缺少扎实的基础,那么在使用工具遇到缺失功能或者性能问题的时候,你就可能会束手无策。因此,这门课,更多的还是为你打好基础,领你进入可视化的世界,今后的路,就要靠你自己一步一步地走了。
## 小试牛刀
今天我特意提到了Dagre这个库。它是一个基础库经常用来给流程图的元素布局不涉及渲染的部分。你能用它作为基础再以SpriteJS为渲染引擎来实现一个高效、强大的流程图库吗提示在API方面你可以借鉴Mermaid.js
除此之外这节课我们介绍的工具和库非常多你肯定很难在短时间内完全掌握但我也不希望你只是泛泛了解。所以我希望你能选择自己最感兴趣的同类库中的两个库利用我之前在GitHub仓库里留的北京天气和空气质量数据分别使用它们做一些可视化应用比较两个库在使用上的不同以及各自的优、劣势。
欢迎把你实现的效果分享到留言区,也欢迎你把自己在工具整理上的心得体会分享出来,我们一起交流!
* * *
## 推荐阅读
\[1\] [Snap.svg](http://snapsvg.io/)、\[2\] [Fabric.js](https://github.com/fabricjs/fabric.js)、\[3\] [Pixi.js](https://github.com/pixijs/pixi.js)
\[4\] [SpriteJS](https://spritejs.org/#/)、\[5\] [P5.js](https://github.com/processing/p5.js)、\[6\] [ThreeJS](https://github.com/mrdoob/three.js)
\[7\] [Babylon.js](https://github.com/BabylonJS/Babylon.js)、\[8\] [Rough.js](https://github.com/rough-stuff/rough)、\[9\] [ECharts](https://echarts.apache.org/)
\[10\] [Chart.js](https://github.com/chartjs/Chart.js)、\[11\] [Highcharts](https://github.com/highcharts/highcharts)、\[12\] [AntV G2](https://antv-2018.alipay.com/zh-cn/g2/3.x/index.html)
\[13\] [QCharts](https://www.qcharts.cn/#/home)、\[14\] [AntV F2](https://antv-2018.alipay.com/zh-cn/f2/3.x/index.html)、\[15\] [Vega](https://vega.github.io/vega/)
\[16\] [Mermaid.js](https://github.com/mermaid-js/mermaid)、\[17\] [Sigma.js](http://sigmajs.org/)、\[18\] [AntV G6](https://antv-2018.alipay.com/zh-cn/g6/3.x/index.html)
\[19\] [Dagre](https://github.com/dagrejs/dagre)、\[20\] [MapBox](https://www.mapbox.com/)、\[21\] [MapTalks](https://maptalks.org/)
\[22\] [Leafletjs](https://leafletjs.com/)、\[23\] [MapV](https://github.com/huiyan-fe/mapv)、\[24\] [AntV L7](https://antv-2018.alipay.com/zh-cn/l7/1.x/index.html)
\[25\] [d3-geo](https://github.com/d3/d3-geo)、\[26\] [Unity](https://store.unity.com/products/unity-pro?gclid=CjwKCAjwq_D7BRADEiwAVMDdHsaPnsc1S8jvT8yY47lLFn_jH6WvSTdhlDwf5RJtrC6Leu3LN--2HhoCUqIQAvD_BwE)、\[27\] [Unreal Engine](https://www.unrealengine.com/zh-CN/)