从零构建前端可视化知识体系:SVG篇

前言

前端可视化有着一个完整的知识体系。

可视化的发展从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渲染。因为CanvasJS中绘画完成后,图片会存在内存里,占用大量内存,在没有完善垃圾回收的情况下,在移动端很容易出现内存爆满,页面崩溃的情况。

在数据量庞大,图形十分复杂的情况下,建议使用Canvas渲染。因为SVG会被渲染成DOM,而Canvas是在JS中生成图片,DOM性能开销大于JS

ECharts的灵活性,比较适用于追求极致体验的项目。

ECharts的问题,也是大多数基于Canvas实现的图表库的问题。

主流框架Vue/React都是先执行方法,再渲染DOM,而EChartsCanvas都是先获取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优化器)是一个用于优化SVGnode.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开始讲,由于最近要做技术选型,先研究了SVGCSS篇会尽快补上。

相关推荐
云天徽上9 天前
【目标检测】图像处理基础:像素、分辨率与图像格式解析
图像处理·人工智能·目标检测·计算机视觉·数据可视化
我不吃饼干9 天前
鸽了六年的某大厂面试题:你会手写一个模板引擎吗?
前端·javascript·面试
涵信9 天前
第一节 布局与盒模型-Flex与Grid布局对比
前端·css
我不吃饼干9 天前
鸽了六年的某大厂面试题:手写 Vue 模板编译(解析篇)
前端·javascript·面试
前端fighter9 天前
为什么需要dependencies 与 devDependencies
前端·javascript·面试
veminhe9 天前
HTML5 浏览器支持
前端·html·html5
前端fighter9 天前
Vuex 与 Pinia:全面解析现代 Vue 状态管理的进化之路
前端·vue.js·面试
snow@li9 天前
vue3-ts-qrcode :安装及使用记录 / 配置项 / 效果展示
前端·javascript·vue.js
GISer_Jing9 天前
React Next快速搭建前后端全栈项目并部署至Vercel
前端·react.js·前端框架
伍哥的传说9 天前
React 轻量级状态管理器Zustand
前端·javascript·react.js·小程序·前端框架·ecmascript