大屏图表,ECharts 从“熟练”到入门
本文为稀土掘金技术社区首发签约文章,14天内禁止转载,14天后未获授权禁止转载,侵权必究!
??阅读本文,你将了解配置驱动的思想理解Echarts基本概念了解graphic和动画基本玩法。了解Echarts基底组件的封装的思路一、不是标题党!Echarts,简历上人均 “熟练”?公司最近在招外包,而因为目前大屏的需求比较多,所以我就稍微关注了一下候选人们简历上对于Echarts的熟悉程度。
不看不知道,一看下一跳,Echarts属实已经是业内人均 “熟练” 的基本技能了。
以上是短短几篇简历中摘选的自我描述,可以看出,Echarts在大众研发的心中,已经是和Antd、ElementUI、Bootstrap相当的常用第三方库了。
所以,我就开始在面试中加入了关于Echarts使用的相关问题,想看看熟练到底是什么意思。
但是一轮问题问下来,大家好像又对它很陌生。
难道,所谓熟练,就是能在社区里找到Demo,然后把配置项Copy到项目之中?
问:“现在你找到Demo了,但是Demo没有显示图例(也就是那些彩色小方块小圆圈,表示各类数据颜色的东西),你应该查文档的什么关键词?”
答:“一时说不出来,但我肯定能试出来...”
问:“我想把UI出的一张图片放在饼图的背面,作为背景,应该怎么弄?”
答:“先去社区找找Demo吧...”
问:“这种Demo可能不太好找吧...而且有些场景,Demo涉及的也不多,比如需要在某个特定位置放一些字,做一些动画,应该怎么办?”
答:……
虽然我的习惯和大家是一样的,遇到需求,先去社区里找一个相似度最高的Demo再说,但是开发大屏,怎么可能不遇到“特异化、定制化”的诉求呢?
当Demo帮不了你的时候,你是否可以熟练地通过文档,找到合适的解决之道呢?
如果找DEMO就是熟练,那我建议咱还是先忘记“万事求DEMO”的这种熟练方式,重头捋一捋Echarts这个框架,先力求入门。
这就是标题所谓的,从熟练到入门的意思。
二、大屏图表,为什么我选Echarts?在问出这个问题之前,我觉得还是先问一问:为什么不选Echarts呢?
大屏的本质是什么?是讲故事,是给客户量身定做的讲故事!因此,大屏需求,更多的情况就是做项目,而不是做产品。
做项目,什么最重要?
六个字:成本低、效率高。
老板:你说复用、优雅?我都觉得好笑。
成本低
软件项目最大的成本,就是人的成本,现在哪怕是培训班刚出来的小萌新,哪怕他压根不知道g2plot是什么,但简历上大概率会写上 **熟练使用Echarts**。如果招到那种五六年的前端老兵,那Echarts的API熟练度只会更高。
花更低的钱,能招来直接做项目的人,这就是成本低。
效率高
为什么Echarts效率更高,因为它的社区实在太成熟,各种样式风格Demo的沉淀实在太多。 比如:早期的Echarts gallery(已被关闭)、又比如:http://www.isqqw.com/
在这些社区里,你可以快速找到各类你想要的风格和实现,从而低成本改造成UI想要的样子。
Echarts通常被拿来和AntV进行横向对比,关于孰优孰劣,某乎上的争论也比较大,但大家似乎都能达成一种共识:
社区方面,Echarts完胜。
社区完胜,效率就完胜,这是很容易推导的结果;毕竟,大多数时候,大家的开发模式就是社区找相似度高的DEMO。
另外,Echarts早已经是Apache基金会在托管了,没有面向KPI的压力。(你懂我的意思吧?)
三、认识Echarts一个基于 JavaScript 的开源可视化图表库。 ——官网
一个看似什么都说了,却什么都没说的客观发言。
但是作为开发者,我们却需要通过阅读文档,自行去摸索一些更为核心的内容,以了解:“Echarts能做什么?Echarts擅长做什么?Echarts有哪些特性? ”
它能开发图表、地图、做图形渲染它擅长做图表开发至于特性?
我虽然也只是Echarts入门使用者,我冒昧而经验地认为它的三个核心特性是:
1、配置驱动2、事件驱动3、图形能力理解以上三点,我认为大概就能做到“入门Echarts”这个常用前端工具了。但本文还是会把重点放在配置驱动这个最为核心的能力讲解上。
3.1 什么是配置驱动什么是配置驱动?
这其实是很好理解的一个定义:
我只需要修改配置,就能让它显示的画面完成更新。
在使用Echarts的过程中,最重要的API一定是Echarts.setOption。
伪代码如下:
//让图表显示状态A
chart.setOption(optionA)
//让图表更新状态到B
chart.setOption(optionB)
对,这就是配置驱动。
稍微改动官方示例:
template
divclass="chart"ref="chartEl"/div
/template
scriptsetup
constchartEl=ref(null);
letchart=null
constcategories=['老包','老南','老君']
constgenDataArr=()={
returncategories.map(t={
returnMath.ceil(Math.random()*100)
})
}
onMounted(()={
//指定图表的配置项和数据
constchart=echarts.init(chartEl.value);
constoption={
tooltip:{},
legend:{
data:['黑子程度']
},
xAxis:{
data:categories
},
yAxis:{},
series:[
{
name:'销量',
type:'bar',
data:genDataArr()
}
]
chart.setOption(option)
setInterval(()={
chart.setOption({series:[
{
data:genDataArr()
}
]})
},1000)
})
/script
通过修改配置项中某一项的值,我们可以清晰看到呈现出的动态变化:
代码片段
如果你无法看到上述码上掘金内容的变化,那有可能是因为网络原因,无妨,其gif效果如下:
配置驱动就是这么直观,且易于理解。
它最大的优点就在于:
当我们希望图表从"状态A"进化到"状态B"时,我们其实无需关注当前的状态到底是什么样,我们只需要组装好"状态B"的配置,并将它交付给Echarts即可。
基本上,你可以利用配置项完成绝大多数工作上你遇到的各种需求。鲜明而无状态的API设计,也是它如此受到大家喜爱的根本原因。
本文,我们先专注于配置驱动封装一个能应对前端90%业务开发场景的基础Vue3基底组件。
3.2 配置项基本概念配置项固然简单,但你首先需要知道 “我要实现某个能力实,应该去寻找什么样的配置” 。
对此,最快去了解各种概念的办法是看官方文档的常用组件说明。
如果你觉得看文档不如看图片,我也单独整理了一份简图:
通过图中相关对照,我们可以在官方文档的配置项手册中快速浏览相关内容的支持选项及用法。
3.3 轻度自定义的神器:graphic以上配置项中,大多数能力都是“Echarts预设好,我们直接拿来用”模式的,但难免会遇到产品经理或者UI同学突发奇想,增加一些特殊的文本或者图案,比如:
这种就属于,乍一眼看上去很容易,然后一琢磨:不对啊,DEMO里找不到可以直接拿来用的类型了。
怎么办?
'graphic' 可能是个不错的选择。
graphic配置提供了以下节点能力的渲染配置:
图片文本元素组(可包含子节点,对子节点进行整体缩放、旋转等)以及其他各种图形,例如(圆形、扇形、环形、多边形、折线、矩形、直线、贝塞尔曲线、圆弧)其中,我认为最常用的两种:
图片文本让我们先通过一个例子认识图片及文本的用法,核心代码如下:
option={
...//省略其他,
graphic:[
{
type:'image',
style:{
image:'https://pic.zhangshichun.top/pic/circle.png',
width:150,
height:150
},
top:'middle',
left:'center',
},
{
type:'text',
style:{
x:100,
y:150,
text:`鸡你太美`,
fill:'#fff',
stroke:'#fff',
textAlign:'center',
fontSize:14
}
},
{
type:'text',
style:{
x:100,
y:180,
text:`唱跳rap`,
fill:'#fff',
stroke:'#fff',
textAlign:'center',
fontSize:14
}
},
]
}
码上掘金相关片段,赶紧亲自试试:代码片段
效果图:
3.4 配置化与动画细心的同学想必已经发现了,我并没有声明和动画相关的东西,但我上面的示例里已经有了最基本的补间动画,这是因为echarts内置了一部分默认动画逻辑。
但实际上,你也拥有配置动画的能力
关键帧效果,以及循环动画
尝试在type: 'image'的元素上添加以下代码:
{
//...其他配置暂且省略
transition:'rotation',
originX:75,
originY:75,
keyframeAnimation:{
duration:3000,
loop:true,
keyframes:[{
percent:0.5,
easing:'linear',
rotation:Math.PI
},{
percent:1,
easing:'linear',
rotation:Math.PI*2
}]
}
}
而你会看到如下效果:鸡哥的篮球背景的圆环永远地滚动了起来。
代码片段
这个效果正是借助了Echarts提供的关键帧动画能力,指定时长、以及不同进度上元素应该表现的配置状态,驱使它完成了页面的渲染。
进入/离开/更新动画
关键帧动画更倾向于按照编码者指定的方式进行运转,而 “进入/离开/更新动画” 则适用于更新数据状态时,自动获取动画的能力。
看代码:
//移除上面keyframeAnimation这一段代码
//增加以下代码:
setInterval(()={
constrotation=Math.random()*2*Math.PI
chart.setOption({
graphic:[
{
rotation
}
]
})
},500)
效果如下:鸡哥的篮球背景的圆环rap起来了。
代码片段
学会以上动画能力,也基本算可以称得上在Echarts使用上入门了,可以应对大多数UI和产品的奇思妙想了。
四、 基底组件的能力?我对基底组件的期望,其实很简单:
它能自适应容器的宽高,并让自身的图表自适应容器宽高的变化这当然是痛点了,我不止一次,不止在一个项目里,发现大屏进行布局调整、或者是浏览器页面大小调整后,图表的大小变得不适宜。依靠研发在紧张工期下,依然保持严谨的防御性代码编写习惯,是一种奢望。
它能具备基础的主题能力大屏通常有自己的主题色,自带 “主题色” 的Echarts组件,可以让研发节省大量时间。
当数据为空时,它能智能的显示 “空值缺省”试想,哪个客户希望对着一个空空如也的折线图猜测用意呢?此时,一句简简单单的暂无数据是多么的贴心。
它应该给我最大限度的自定义的能力永远不要失去能力,封装的意义在于增强,而不是阉割。
基于以上诉求,我们可以开始设计自己的Echarts 基底组件的API。
src/components/BaseECharts/index.vue
//提供props属性empty,让组件稳定感知当前是否是空数据
defineProps({
empty:{
type:Boolean,
default:false
}
})
//向外弹射事件'resize'
constemits=defineEmits(['resize'])
defineExpose(
{
//向父组件暴露方法:获得ECharts实例
getChart:()={
},
//向父组件暴露方法:更新ECharts配置
setOption:(v)={
}
}
)
五、如何实现动态适配容器宽高先了解一个API:ResizeObserver。 (MDN相关参考)
通过ResizeObserver,我们可以从容地监听某个元素的尺寸变化。
既然这个API这么优秀,那我们直接用它?你们可以随便用,但本老年vue-coder选择逻辑完备的Hooks:useElementSize,一行代码解决元素尺寸监听的问题:
constel=ref(null)
const{width,height}=useElementSize(el)//width和height都是响应式的`ref`对象
然后再监听相关变化,适时地调用chart.resize()方法即可:
watchEffect(()={
if(width.valueheight.value){
emits('resize',{width:width.value,height:height.value})
chartRef.value?.resize();
}
})
这样,当视窗大小变化后,相关的图表也会重新根据新视窗的大小调整尺寸。
而在@resize事件里,用户因为得到了{width, height},对于一些依赖绝对尺寸的场景,也可以从容更新option,保证resize后尺寸不会出现问题。
比如,在父组件中,我们可以这样写:
template
BaseECharts @resize="size = onResize(size)" ref="chartRef"/BaseECharts
/template
script setup
import BaseECharts from '@/components/BaseECharts'
const chartRef = ref(null)
const genOption = ({ width, height }) = {
const minSideLength = Math.min(width, height)
return {
series: [
// ...其他选项省略
{
radius: [0.3 * minSideLength, 0.4 * minSideLength],
center: [minSideLength / 2, minSideLength / 2],
type: 'pie',
}
]
}
}
const onResize = (size) = {
const option = genOption(size)
chartRef.value.setOption(option)
}
/script
从而实现 “像素级” 的尺寸操控(当然,能用百分比解决的就用百分比,但某些场景不支持百分比,那就必须上像素了);
六、如何具备内置的主题色?首先,ECharts是支持自定义主题的,访问:https://echarts.apache.org/zh/theme-builder.html
可以通过左侧的操作栏,让UI同学快速定制一套适合你们系统的主题色,然后导出主题json配置文件,并将它存在 '@/theme/echarts-dark.json' 文件中。
在src/main.js中写如下带代码:
import*asEChartsfrom"echarts";
importthemefrom'@/theme/echarts-dark.json'
ECharts.registerTheme('dark',theme)
完成对主题的注册,(写在main.js是为了避免重复注册),当然,如果要充分组件化的话,此处应该有vue-plugin。
然后,在基底组件中如此写:
onMounted(()={
constchart=Echarts.init(chartEl.value,'dark');
})
完成对主题的初始化。
七、空值缺省这一步,其实不太涉及到Echarts本身的内容,只需要通过判断empty属性,通过v-show切换展示内容。
为什么用v-show不用v-if? 为了降低echarts实例周期管理的复杂度。
src/components/BaseECharts/index.vue
template
div class="chart"
div v-show="!empty" class="chart__el" ref="chartEl"/div
NoData v-show="empty" class="chart__empty"/NoData
/div
/template
八、总结通过:
学习配置驱动的思想理解Echarts基本概念学习graphic和动画基本玩法。完成基底组件的封装你已经可以胜任简单大屏项目图表的快速开发和迭代了,此时,如果在简历上写上入门Echarts使用,应该就不会再出现尴尬的场景了吧。
面对面试官高深场景的问题,也可以理直气壮地回答一句:
我就入门水平,你还想怎样?
阅读原文
网站开发网络凭借多年的网站建设经验,坚持以“帮助中小企业实现网络营销化”为宗旨,累计为4000多家客户提供品质建站服务,得到了客户的一致好评。如果您有网站建设、网站改版、域名注册、主机空间、手机网站建设、网站备案等方面的需求...
请立即点击咨询我们或拨打咨询热线:13245491521 13245491521 ,我们会详细为你一一解答你心中的疑难。 项目经理在线