前言
前端可视化有着一个完整的知识体系。
可视化的发展从CSS
,到SVG
,再到Canvas
,并不是一个后者取代前者的递进关系,而是彼此互补的共存关系。
倘若不能构建一个完整的前端可视化知识体系,会在开发中发现许多矛盾的点。
例如:SVG
在性能上不如Canvas
,却能在图表库的竞争中,占据主导地位。
让我们从高度封装的图表库开始,由浅入深,逐步打开前端可视化的世界。
图表库
时间截止到2024年1月17日,github
上总共存在55种图表库。
想要选出适合业务需求的图表库还是比较困难的。
D3
以功能强大而著称,然而作为偏底层的图表库,哪怕实现最简单的图表也需要数十行代码。
高度封装(对图表进行抽象)的图表库,以更低的开发成本,在实际项目中更受青睐。
Observable Plot(D3的亲儿子)
D3
官方建议在一般情况下使用Observable Plot
。
Observable Plot
基于SVG
实现,对图表进行了抽象,能够用一个方法生成D3
几十行代码才能实现的图表。
优点在于和主流框架Vue
/React
都有着比较好的结合性。
能够借助Vue
/React
的内部方法,生成Vue
/React
组件在项目中使用。
缺点在于不能够开箱即用,需要先调用Vue
/React
方法封装组件,再引入业务代码中使用。
ECharts(国内使用最多的图表库)
ECharts
基于ZRender
实现。
区别于其他图表库,不是基于SVG
实现,就是基于Canvas
实现。
Echarts
借助ZRender
可以选择SVG
渲染器或者Canvas
渲染器(默认是Canvas
渲染器)。
js
import * as echarts from 'echarts';
// 使用 Canvas 渲染器(默认)
var chart = echarts.init(containerDom, null, { renderer: 'canvas' });
// 等价于:
var chart = echarts.init(containerDom);
// 使用 SVG 渲染器
var chart = echarts.init(containerDom, null, { renderer: 'svg' });
在需要创建很多ECharts
实例的情况下,建议使用SVG
渲染。因为Canvas
在JS
中绘画完成后,图片会存在内存里,占用大量内存,在没有完善垃圾回收的情况下,在移动端很容易出现内存爆满,页面崩溃的情况。
在数据量庞大,图形十分复杂的情况下,建议使用Canvas
渲染。因为SVG
会被渲染成DOM
,而Canvas
是在JS
中生成图片,DOM
性能开销大于JS
。
ECharts
的灵活性,比较适用于追求极致体验的项目。
ECharts
的问题,也是大多数基于Canvas
实现的图表库的问题。
主流框架Vue
/React
都是先执行方法,再渲染DOM
,而ECharts
和Canvas
都是先获取DOM
,再将渲染的图片挂载到DOM
上,这个过程在框架中只能等第一次渲染完成后,再调用勾子进行,造成二次渲染,而且更新时,要避免再次渲染;卸载时,要注意垃圾回收,存在一定的心智负担。
Recharts
在介绍Reacharts
之前,先看一组数据。
github
上最受欢迎的React
图表库:
github
上下载量最高的React
图表库:
github
上社区最活跃的React
图表库:
Recharts
占据三榜第一。
与框架有高结合度,类似UI组件,开箱即用,还有着强大的社区支持。
与Observable Plot
类似,对D3
进行了二次封装,基于SVG
实现,避免了Canvas
与框架结合度差的尴尬。
比Observable Plot
更纯粹,舍弃了对Vue
的兼容,内置React
方法进一步封装成React
组件,能够在项目中直接使用。
D3
D3
基于SVG
实现,封装思路与写法上都与JQury
类似。
arduino
d3.create("svg").attr("width", width).attr("height", height)
核心在于数据驱动视图,开发者只需要关心数据部分,DOM
操作由框架完成。
D3
没有对图表的抽象,只有点、运动轨迹、时间等基本概念,根据这些基本元素来制作图表,哪怕最简单的图表,也需要数十行代码来实现。
因此,衍生出了大量基于D3
二次封装的图表库,以节省开发成本。
一般不作为主力图表库使用,适用于封装一些定制化的图表,作为主力图表库的补充。
SVG
定义
SVG
(Scalable Vector Graphics,可缩放矢量图形)最大的特点在于矢量化,用公式存储图形信息,从而有了体积小和放大不失真的特点。
不同于Canvas
渲染成图片,会被渲染成DOM
元素,进而又衍生出三个特点。
1、 支持事件处理,有良好的交互性。
2、 包含文本信息,能够被搜索引擎捕获,提高网站的曝光度。
3、 能够通过CSS
进行样式微调,实现一图多用。
适用场景:矢量图标、移动端H5
。
倘若能在追求最小体积的移动端H5
项目中,避免引入臃肿的图表库,手写一个SVG
图表,定能让主管刮目相看。
SVGO
SVGO
(SVG Optimizer,SVG优化器)是一个用于优化SVG
的node.js
库。
日常开发用到的SVG
图标,大都由UI工具产生,包含了图形介绍、版本信息、工具信息等与渲染无关的内容。
SVGO
通过删除这些内容,只保留核心的图形渲染信息,从而实现了体积压缩。
安装: npm i -g svgo
处理单个文件: svgo one.svg two.svg -o one.min.svg two.min.svg
批量处理:svgo -f path/to/directory\_with\_svgs -o path/to/output\_directory
随便找了个SVG
压缩一下看看效果。
压缩前(体积是88.88kB):
压缩后(体积是26.81kB):
文件体积缩小了70%,效果还是比较显著的。
结束语
第一次尝试出一个系列专题,理论上应该从CSS
开始讲,由于最近要做技术选型,先研究了SVG
,CSS
篇会尽快补上。