// package.json
{
// ...
"dependencies": {
// ...
"echarts": "^4.8.0",
"vue": "^2.6.10",
// ...
},
// ...
}
Canvas 渲染还是 SVG 渲染
1. 理论梳理
诚如 数据可视化实现方案对比分析 ,浏览器端图表库大多会选择 Canvas 或者 SVG 进行渲染。这两种渲染方式 ECharts 都有支持。
-
Canvas更适合绘制图形元素数量非常大的图表,也利于实现某些 视觉特效。如:热力图、地理坐标系或平行坐标系上的大规模线图或散点图等。
// 使用 Canvas 渲染器(默认) var chart = echarts.init(containerDom, null, {renderer: 'canvas'}); // 等价于: var chart = echarts.init(containerDom); -
SVG内存占用更低、渲染性能略高、用户使用浏览器内置的缩放功能时不会模糊。使用
Canvas渲染器和SVG渲染器绘制中等数据量的折、柱、饼图,SVG渲染器相比Canvas渲染器在移动端的总体表现更好。但是在另一些数据量较大或者有图表交互动画的场景中,目前的SVG渲染器的性能还比不过Canvas渲染器。// 使用 SVG 渲染器 var chart = echarts.init(containerDom, null, {renderer: 'svg'}); -
综上所述,选择哪种渲染器,需要根据
软硬件环境、数据量、功能需求来综合考虑决定。- 软硬件环境较好,数据量不大:不必太纠结使用哪种渲染器,二者皆宜;
- 环境较差,出现性能问题需要优化:通过试验来确定使用哪种渲染器;
- 须要创建很多
ECharts实例且浏览器易崩溃:可以使用SVG渲染器来进行改善; - 数据量很大、较多交互时:可以选用
Canvas渲染器。
- 须要创建很多
业务场景(↓) \ ECharts渲染器(→) Canvas SVG 软硬件环境较好
数据量不大√ √ 软硬件环境较差
数据量不大多ECharts实例
浏览器易崩溃× √ 数据量很大
交互较多√ × -
注意 目前的
SVG版中,富文本、材质功能尚不支持。// src/components/echarts-box/pie-charts/semiring-pie-chart/semiring-chart.vue // 渲染器使用SVG,富文本无法正确解析 // ... formatter: () => { // return `{a|${this.itemData.num}}{b|${this.showUnit ? '%' : ''}}`; return this.itemData.num + (this.showUnit ? '%' : ''); }, // ...
2. 项目分析
简要分析下公司目前的数据大屏情况:
- 除了地图模块数据量相对复杂些,其他模块展示的数据量可控;
- 项目设置了专门的展厅,页面需要长时间启用,页面时有崩溃现象发生;
- 页面投放方式为主机加载后,有场景会涉及需要使用浏览器内置的缩放功能展示。
项目的页面缩放方案参考了 百度云 页面的实现思路,按照固定的宽高比(如: 16:9)来计算出最合适的缩放比进行缩放渲染。
-
注意 使用原生表格(
table)渲染数据,如若表格行(tr)是有背景色的,使用该页面缩放方案即使表格的边框合并在一起(border-collapse: collapse;),表格边框之间的间距(border-spacing)为0,无边框(border: 0 none;),边框色透明(border-color: transparent;),单元格之间仍可见一条黑线!最终不得不借用无意义的div模拟实现表格来兼容。
<template>
<div class="scale-box" :style="{width: cw + 'px', height: ch + 'px'}">
<div class="scale-container" :style="{transform: 'scale(' + scale + ')', width: width + 'px', height: height + 'px'}">
<slot></slot>
</div>
</div>
</template>
// 容器宽高
let cw = 0;
let ch = 0;
// UI规范宽高
let width = 1920;
let height = 1080;
let scale = 1;
// 可视区宽高比例
let ww = window.innerWidth / this.width;
let wh = window.innerHeight / this.height;
// 计算实际最合适缩放比:以小者为缩放基准,内容不足处留白处理,确保内容展示的完整性。原理同背景图的background-size属性。
scale = ww < wh ? ww : wh;
// 更新容器渲染宽高
cw = this.width * scale
ch = this.height * scale
如此,UI 稿是按照 1920 × 1080 的宽高像素输出,购置的硬件规格也是一个屏幕为 1920 × 1080 像素的宽高尺寸。
- 如果一个页面在一个硬件屏幕上展示时,无需缩放,展示效果接近输出的
UI稿。 - 但实际存在九个硬件屏幕拼接成一个大屏幕来渲染一个页面的场景(此时相当于页面被二次放大了
9倍。最终,页面元素渲染模糊)。
综上所述,公司该数据大屏项目最终选择的 ECharts 渲染器为 SVG。
3. 有个疑问
关于 ECharts 元素渲染模糊问题,翻看 ECharts文档 有发现一个配置参数:devicePixelRatio(设备像素比,默认取浏览器的值 window.devicePixelRatio)。
试问,开发中是否可以保留使用 Canvas 渲染,通过设置 devicePixelRatio 来解决元素渲染模糊这个问题呢?
em...鉴于时间问题,先记录下验证思路,明天醒来后借用项目页面尝试一波~
- 使用
ECharts默认渲染器(Canvas); - 设置
devicePixelRatio为一个较大值,如:9; - 使用浏览器内置的缩放功能查看页面元素渲染结果是否模糊。如果模糊,那存在对应场景的业务代码就只能采用
SVG渲染模式;如果不模糊,那就可以继续使用Canvas渲染啦,只是加多一个devicePixelRatio参数值设置而已。
// 验证用代码
var chart = echarts.init(containerDom, null, {devicePixelRatio: 9});
4. 答疑解惑
-
默认渲染器,默认设备像素比
// 默认渲染器,默认设备像素比 var chart = echarts.init(containerDom); -
默认渲染器,设备像素比设置为较大值
// 默认渲染器,设备像素比设置为较大值 var chart = echarts.init(containerDom, null, {devicePixelRatio: 9}); -
svg渲染
// svg渲染 var chart = echarts.init(containerDom, null, {renderer: 'svg'});
测试结果如截图所示。由此说明,如若是单纯考虑浏览器内置的缩放功能的因素,使用 SVG 渲染并不是必须的。而且仔细看会发现,Canvas 渲染的效果更丰富:当前高亮模块的渐变竖线,Canvas 渲染有,而SVG 渲染没有。