1、了解可视化
(1)什么是可视化
可视化是将数据组织成易于为人所理解和认知的结构,然后用图形的方式形象地呈现出来的理论、方法和技术。实现可视化有两个关键要素,一个是数据,另一个是图形。如果要考虑在计算机上呈现,那还要加上交互。
(2)Web 前端与可视化的区别
不同点
a.技术栈不同
Web 开发主要以 HTML 来描述结构,以 CSS 来描述表现,以 JavaScript 来描述行为。而可视化则较少涉及 HTML 和 CSS,它更多地要同浏览器的 Canvas、SVG、WebGL 等其他图形 API 打交道。
b.Web 开发着重于处理普通的文本和多媒体信息,渲染普通的、易于阅读的文本和多媒体内容,而可视化开发则着重于处理结构化数据,渲染各种相对复杂的图表和图形元素。
相同点
a.可视化与 Web 前端一样,最终都是以图像呈现在浏览器上,因此有许多通用的方法论。
b.二者都使用 JavaScript,而且都是浏览器端的 JavaScript。
c.与 Web 前端一样,可视化领域也有丰富的 JavaScript 工具和活跃的生态
(3)工具
工具可视化领域的工具可视化领域经过多年的发展,有非常多丰富的工具。我们可以把这些工具大体上分为四类,分别是:
a.专业呈现各种类型图表的图表库:ECharts,或者类似的Chartist、Chart.js;
b.专业处理地图、地理位置的可视化地理库:社区中比较成熟的 GIS 库也不少,比较常见的像Mapbox、Leaflet、Deck.gl、CesiumJS;
c.专业处理视觉呈现的渲染库:如果要绘制其他更灵活的图形、图像或者物理模型,我们常用的一些图表库就不一定能完成了。这个时候,我们可以用ThreeJS、SpriteJS这样比较通用的渲染库(实际上图表库或 GIS 地图库本身底层渲染也基于这些渲染库)。我们可以选择通用的图形库,比如,2D 渲染可以选择 SpriteJS,3D 渲染可以选择 ThreeJS、BabylonJS 以及 SpriteJS3D 扩展等等。
d.处理数据的数据驱动框架:它们更专注于处理数据的组织形式,而将数据呈现交给更底层的图形系统(DOM、SVG、Canvas)或通用图形库(SpriteJS、ThreeJS)去完成。
2、图形
(1)实现可视化的 4 种方式
方式一:传统的 HTML + CSS
方式二:声明式 SVG
方式三:指令式 Canvas2D
1、Canvas 元素和 2D 上下文
对浏览器来说,Canvas 也是 HTML 元素,我们可以用 canvas 标签将它插入到 HTML 内容中。比如,我们可以在 body 里插入一个宽、高分别为 512 的 canvas 元素。
<body> <canvas width="512" height="512"></canvas></body>
画布宽高
Canvas 的 HTML 属性宽高为画布宽高
样式宽高
CSS 样式宽高为样式宽高
canvas { width: 256px; height: 256px;}
因为画布宽高决定了可视区域的坐标范围,所以 Canvas 将画布宽高和样式宽高分开的做法,能更方便地适配不同的显示设备。
2、Canvas 的坐标系
Canvas 的坐标系和浏览器窗口的坐标系类似,它们都默认左上角为坐标原点,x 轴水平向右,y 轴垂直向下。那在我们设置好的画布宽高为 512*512 的 Canvas 画布中,它的左上角坐标值为(0,0),右下角坐标值为(512,512) 。这意味着,坐标(0,0)到(512,512)之间的所有图形,都会被浏览器渲染到画布上。
注意,上图中这个坐标系的 y 轴向下,意味着这个坐标系和笛卡尔坐标系不同,它们的 y 轴是相反的。
3、利用 Canvas 绘制几何图形
第一步,获取 Canvas 上下文。
const canvas = document.querySelector('canvas');
const context = canvas.getContext('2d');
我们拿到的 context 对象上会有许多 API,它们大体上可以分为两类:一类是设置状态的 API,可以设置或改变当前的绘图状态,比如,改变要绘制图形的颜色、线宽、坐标变换等等;另一类是绘制指令 API,用来绘制不同形状的几何图形。
第二步,用 Canvas 上下文绘制图形。
const rectSize = [100, 100];
context.fillStyle = 'red';
context.beginPath();
context.rect(0.5 * canvas.width, 0.5 * canvas.height, ...rectSize);
context.fill();
context.rect 是绘制矩形的 Canvas 指令,它的四个参数分别表示要绘制的矩形的 x、y 坐标和宽高。在这里我们要绘制的正方形宽高都是 100,所以后两个参数是 100 和 100。
我要将正方形填充成红色,这一步通过调用 context.fillStyle 指令就可以完成。然后,我们要调用一个 beginPath 的指令,告诉 Canvas 我们现在绘制的路径。接着,才是调用 rect 指令完成绘图。最后,我们还要调用 fill 指令,将绘制的内容真正输出到画布中。
5、如何将画出来的正方形处于坐标中心
第一种做法是,我们可以让 rect 指令的 x、y 参数,等于画布宽高的一半分别减去矩形自身宽高的一半。这样,我们就把正方形的中心点真正地移动到画布中心了。
context.rect(0.5 * (canvas.width - rectSize[0]), 0.5 * (canvas.height - rectSize[1]), ...rectSize);
第二种做法是,我们可以先给画布设置一个平移变换(Translate),然后再进行绘制。
context.translate(-0.5 * rectSize[0], -0.5 * rectSize[1]);
这种做法记得把画布状态给恢复回来
提供两种方式:
第一种是反向平移
// 平移
context.translate(-0.5 * rectSize[0], -0.5 * rectSize[1]);
... 执行绘制
// 恢复
context.translate(0.5 * rectSize[0], 0.5 * rectSize[1]);
Canvas 上下文还提供了 save 和 restore 指令
context.save(); // 暂存状态
// 平移
context.translate(-0.5 * rectSize[0], -0.5 * rectSize[1]);
... 执行绘制
context.restore(); // 恢复状态
利用 Canvas 绘制矩形的过程。总结为了 5 个步骤:
1、获取 Canvas 对象,通过 getContext(‘2d’) 得到 2D 上下文;
2、设置绘图状态,比如填充颜色 fillStyle,平移变换 translate 等等;
3、调用 beginPath 指令开始绘制图形;
4、调用绘图指令,比如 rect,表示绘制矩形;
5、调用 fill 指令,将绘制内容真正输出到画布上。
如何用 Canvas 绘制层次关系图?
优缺点
总结