数据渲染--->canvas 和 SVG实现对比
数据渲染技术对比
选择什么作为承载我们可视化结果的容器,同时选择什么样的绘制技术来渲染这些数据。往往面对不同的可视化需求,不同量级的数据,我们需要选择不同的渲染技术,渲染技术的选择和学习也是其中一个难点。毫无疑问,作为前端这个领域,承载我们可视化的结果容器就是现代浏览器。在现代浏览器中可以完成可视化的绘制技术至少有4个:HTML、Canvas2D、SVG、WebGL。HTML 的绘制不够灵活,WebGL 主要针对三维场景的可视化(虽然也可以进行二维可视化,我们之后会了解到),所有主流的 2D 可视化的绘制技术主要有两种: Canvas2D 和 SVG。
Canvas2D 和 SVG 的使用方式不同,针对的场景也不同,接下来我们就分别说说。
Canvas2D
通过绘制一个矩形和 hello world 来看看 Canvas2D 的使用方式。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<canvas id="canvas"></canvas>
<script>
// 获得 canvas 容器元素
const canvas = document.getElementById("canvas");
// 设置 canvas 的样式宽高
// 样式宽高决定了 canvas 在画布上呈现的大小
canvas.style.width = 400 + "px";
canvas.style.height = 200 + "px";
// 设置 canvas 画布宽高
// 这个宽高是可以绘制区域的大小
// 样式宽高是默认等于画布宽高的
canvas.width = 400;
canvas.height = 200;
// 获得绘制的上下文
// 之后的 API 都是通过调用 context
const context = canvas.getContext("2d");
// 绘制一个矩形
context.fillStyle = "red"; // 设置填充颜色
context.strokeStyle = "yellow"; // 设置边框的颜色
context.lineWidth = 10; // 设置边框的宽度
context.strokeRect(0, 0, 100, 100); // 绘制边框
context.fillRect(5, 5, 95, 95); // 绘制填充颜色
// 绘制一段文字
context.fillStyle = "black"; // 设置文字的颜色
context.font = "25px PingFangSC-Regular, sans-serif"; // 设置文字的大小和字体
context.fillText("hello world", 150, 100); // 绘制文字
</script>
</body>
</html>
当然 Canvas2D 的能力肯定不止绘制矩形和文字,更多的基本图形:圆形、线段和路径这些我们之后会涉及,但绘制方式都大同小异。首先,我们设置一些绘制的样式,然后调用绘制命令来绘制拥有这些样式的视觉元素。所以其实 Canvas 的 API 主要分为两类,一类是设置状态的 API: context.fillStyle = 'red' ,另一类是绘制的 API:context.fillRect(0, 0, 10, 10) 。
SVG
接下来,我们再看看第二种绘图方式:SVG(Scalable Vector Graphics),可缩放矢量图,它是浏览器支持的一种基于 XML 语法的图像格式。相对于 Canvas2D 这种指令式的绘图系统来讲,SVG 是一种声明式的绘图系统,它的使用方式和普通的 DOM 元素非常像,所以使用起来比较简单。下面我们通过绘制和上面相同的内容来看看 SVG 的使用方法.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<svg
xmlns="http://www.w3.org/2000/svg"
version="1.1"
width="400"
height="200"
viewBox="0, 0, 400, 200"
>
<rect
height="95"
width="95"
x="5"
y="5"
stroke="yellow"
stroke-width="10"
fill="red"
/>
<text
fill="black"
font-family="PingFangSC-Regular, sans-serif"
font-size="25"
x="150"
y="100"
>
hello world
</text>
</svg>
</body>
</html>
SVG VS Canvas2D
就这样,不知不觉,我们就用 SVG 和 Canvas2D 从 0 到 1 绘制了一个简单的条形图,而且效果几乎一模一样。那么,它们分别有什么特点,以及分别适合什么样的绘制场景呢?
SVG 的优点是方便交互,因为它也有 DOM 结构,可以方便地监听事件。但是性能方面却有所影响:如果我们要绘制的图形非常复杂,这些元素节点的数量就会非常多。而节点数量多,就会大大增加 DOM 树渲染和重绘所需要的时间。
相比来说,Canvas 交互实现就不太容易,因为对每个图形的拾取(判断鼠标点位置在哪个图形上)需要开发者自己实现(很多渲染引擎会解决这个问题,我们后面会看到),但是它的绘制性能却相对较优。
所以当数据量不大且侧重交互的情况,用 SVG 比较合适;当数据量较大的时候用 Canvas 比较合适。