因为公司主要做前端数据可视化项目的,因此有些项目需要有大屏展示的效果,所以一般公司的项目,设计那边给出的设计稿都是 1920*1080 的。
数据可视化,肯定是离不开数据图表的展示,所以有些图表,我们在技术选型上就用了开源的 echarts。
如果只是单纯的做固定尺寸的大屏页面的话,做起来肯定是很简单的,直接照着设计稿的尺寸无脑的还原就行了。
但是实际情况下,用户的需求是复杂多变的,比如最近做的这个项目,主要是三维的模型展示+二维的图表展示。但是客户的需求是,必须要适配移动端和pc端不同尺寸的设备。这个需求咋一听很无脑,细想一下,确实很无脑。
但是客户的需求,我们肯定是要解决的对不对,于是就寻找解决的方案。
首先对于 3d 拓扑图展示区域,适配起来很简单,因为我们用的是浏览器中的 webgl 技术,我们的场景的就是绘制在那块 canvas 上面的,虽然根据尺寸不同的设备,我们的 canvas 大小势必要发生变化,但是没关系,我们监听一下窗口的 resize 事件,然后动态的获取 canvas 元素尺寸,而一般的 webgl 三维框架,都会对这种尺寸变化作出适配。
比如比较有名的 webgl 框架 three.js,就是采用下面这种方式,针对 canvas 尺寸变化的时候,作出适配:
function resizeRendererToDisplaySize(renderer) {
const canvas = renderer.domElement;
const width = canvas.clientWidth;
const height = canvas.clientHeight;
const needResize = canvas.width !== width || canvas.height !== height;
if (needResize) {
renderer.setSize(width, height, false);
}
return needResize;
}
如果对这方面有兴趣,请参考这篇文章:
https://threejsfundamentals.org/threejs/lessons/threejs-responsive.html
当然,一个页面,除了有三维场景,有图表展示区域以外,肯定会有一些标题区域,一些按钮区域的。
我先在这儿偷偷的截一张我们项目中大屏页面实际运行的时候的效果图吧,无图我相信不会火的。
对于那些按钮、标题等区域,研究了各种方案以后,最终我们选用了 vw、vh 适配方案,也就是根据设计稿的尺寸,换算出对应的按钮标题等的 vw 或者 vh 尺寸设置进去,当我们屏幕大小发生变化的时候,就会根据屏幕的尺寸去自适应。
至于为什么不用百分比,这个方案我们之前也尝试过,但是发现效果还是没有 vw、vh 来的好,因为百分比都是根据父容器的尺寸来变化的,实际使用的过程中,在不同尺寸的页面中显示的效果并不太好。
而 echarts,对于自适应,做起来就很麻烦了。
首先,我了解到,官方确实给出了移动端适配的方案:
https://www.echartsjs.com/tutorial.html#%E7%A7%BB%E5%8A%A8%E7%AB%AF%E8%87%AA%E9%80%82%E5%BA%94
也有几个简单易懂的示例:
从官方的建议和示例中可以看出来,这是一种类似于媒体查询的方案,当我满心欢喜的以为找到了一种一劳永逸的方案的时候,但是用起来,却发现啪啪啪的打脸了,并不像想象中那么容易使用,还是有些坑在里面的。
1. media 配置里面需要有默认配置
比如我想根据不同的屏幕寸尺,写几套不同的样式,使图表能够适应这些不同的屏幕。
但是起先用起来发现没有效果,后来发现,是我使用的方式存在错误。
比如官方示例配置是这么写的:
option = {
baseOption: { // 这里是基本的『原子option』。
title: {...},
legend: {...},
series: [{...}, {...}, ...],
...
},
media: [ // 这里定义了 media query 的逐条规则。
{
query: {...}, // 这里写规则。
option: { // 这里写此规则满足下的option。
legend: {...},
...
}
},
{
query: {...}, // 第二个规则。
option: { // 第二个规则对应的option。
legend: {...},
...
}
},
{ // 这条里没有写规则,表示『默认』,
option: { // 即所有规则都不满足时,采纳这个option。
legend: {...},
...
}
}
]
};
我想当然的自动过滤掉了,media 里面的默认配置规则,后来发现,怎么尝试都有问题,原来是因为原子 option 里面都会被 media 里面的规则覆盖掉,如果不给个默认的,原来的规则也没了。
因此 media 里面的默认是千万不可省略的。
2. 有些配置其实不用嵌套在内部
还有个坑点是,我用了 gauge 类型的图表,如果没用过这个类型,请参考文档:https://echarts.baidu.com/option.html#series-gauge
这个类型可以配置 detail 属性,用以显示仪表盘详情数据,我想根据不同的尺寸,设置不同大小的字体。
因为刚开始我是直接在官方示例上魔改的:https://gallery.echartsjs.com/editor.html?c=gauge-car
因此有些配置是直接从官方配置里面 copy 过来的,但是后来才发现可能是版本不兼容,因为有些配置 demo 中是这样写的:
detail: {
textStyle: { // 其余属性默认使用全局文本样式,详见TEXTSTYLE
fontWeight: 'bolder'
}
},
但是官方配置里面确实这样的:<br />可以看到 detail 对象里面,并没有 textStyle 属性,但是你这样配起来,却是可以正常运行的,没研究过源码,因此不明白这地方 echarts 内部是怎么处理的,但是我动态的改 textStyle 里面的属性,却发现不生效,后来才明白要根据这个配置项里面的属性来,才有效果。
3. 字体用百分比,可以自动适配
字体其实在 echarts 里面适配起来很麻烦,毕竟从 pc 到 移动端,屏幕大小的变化太大了.现在标准的宽屏一般都是 1920*1080,而如果用户浏览器不开全屏,其实页面是达不到这个尺寸的,因此肯定是会被压缩的。
所以如果根据宽高来设置字体,是很麻烦的,当然这种方法和我们的方法一一样,具有普适性,肯定是能够适用的。
但是如果没有太过特殊的要求,先尝试下试用百分比,说不定会有出其不意的功效。
以上几个方案,就是我尝试过 echarts pc && 移动端适配的方案的总结,如果你也碰到了这个问题,并且刚好通过我提供的方案解决了问题,不妨给我点个赞吧!