本文为稀土技能社区首发签约文章,14天内禁止转载,14天后未获授权禁止转载,侵权必究!

阅览本文,你将

  1. 了解 装备驱动 的思维
  2. 了解 Echarts 基本概念
  3. 了解 graphic动画基本玩法
  4. 了解 Echarts 基底组件的封装的思路

一、不是标题党!Echarts,简历上人均 “娴熟”?

公司最近在招外包,而由于目前大屏的需求比较多,所以我就略微关注了一下候选人们简历上关于 Echarts 的了解程度。

不看不知道,一看下一跳,Echarts 事完成已是业内人均 “娴熟” 的基本技能了。

大屏图表,ECharts 从“娴熟”到入门

以上是短短几篇简历中摘选的自我描述,能够看出,Echarts 在群众研制的心中,现已是和 AntdElementUIBootstrap 适当的常用第三方库了。

所以,我就开端在面试中加入了关于 Echarts 运用的相关问题,想看看 娴熟 到底是什么意思。

可是一轮问题问下来,咱们好像又对它很陌生。

难道,所谓 娴熟,便是能在社区里找到 Demo,然后把装备项 Copy 到项目之中?

问:“现在你找到 Demo 了,可是 Demo 没有显现图例(也便是那些彩色小方块小圆圈,表示各类数据颜色的东西),你应该查文档的什么关键词?”

答:“一时说不出来,但我肯定能试出来…”

问:“我想把UI出的一张图片放在饼图的背面,作为背景,应该怎么弄?”

答:“先去社区找找 Demo 吧…”

问:“这种 Demo 或许不太好找吧…并且有些场景,Demo 触及的也不多,比方需要在某个特定位置放一些字,做一些动画,应该怎么办?”

答:……

尽管我的习气和咱们是相同的,遇到需求,先去社区里找一个相似度最高的 Demo 再说,可是开发大屏,怎么或许不遇到 “特异化、定制化” 的诉求呢?

Demo 帮不了你的时分,你是否能够娴熟地经过文档,找到合适的解决之道呢?

假如 找DEMO 便是 娴熟,那我建议咱仍是先忘记 “万事求DEMO” 的这种娴熟办法,重头捋一捋 Echarts 这个框架,先力求 入门

这便是标题所谓的,从 娴熟入门 的意思。

二、大屏图表,为什么我选 Echarts?

在问出这个问题之前,我觉得仍是先问一问:为什么不选Echarts 呢?

大屏的实质是什么?是讲故事,是给客户 量身定做 的讲故事!因此,大屏需求,更多的情况便是 做项目,而不是 做产品

做项目,什么最重要?

六个字:本钱低、功率高

老板:你说复用、高雅?我都觉得好笑。

  • 本钱低
    软件项目最大的本钱,便是人的本钱,现在哪怕是培训班刚出来的小萌新,哪怕他压根不知道 g2plot 是什么,但简历上大概率会写上 娴熟运用 Echarts。假如招到那种五六年的前端老兵,那 EchartsAPI 娴熟度只会更高。

    花更低的钱,能招来直接做项目的人,这便是本钱低。

  • 功率高
    为什么 Echarts 功率更高,由于它的社区实在太老练,各种样式风格 Demo 的沉淀实在太多。 比方:前期的 Echarts gallery (已被关闭)、又比方: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>
  <div class="chart" ref="chartEl"></div>
</template>
<script setup>
const chartEl = ref(null);
let chart = null
const categories = ['老包', '老南', '老君']
const genDataArr = () => {
  return categories.map(t => {
    return Math.ceil(Math.random() * 100)
  })
}
onMounted(() => {
  // 指定图表的装备项和数据
  const chart = echarts.init(chartEl.value);
  const option = {
    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 作用如下:

大屏图表,ECharts 从“娴熟”到入门

装备驱动 便是这么直观,且易于了解。

它最大的优点就在于:

当咱们期望图表从”状况A”进化到”状况B”时,咱们其实无需关注当时的状况到底是什么样,咱们只需要组装好”状况B”的装备,并将它交付给 Echarts 即可。

基本上,你能够利用 装备项 完结绝大多数工作上你遇到的各种需求。鲜明而无状况的 API 规划,也是它如此受到咱们喜爱的根本原因。

本文,咱们先专注于 装备驱动 封装一个能应对前端 90% 业务开发场景的根底 Vue3 基底组件。

3.2 装备项基本概念

装备项固然简略,但你首要需要知道 “我要完结某个才能实,应该去寻找什么样的装备” 。

对此,最快去了解各种概念的办法是看官方文档的 常用组件说明。

假如你觉得看文档不如看图片,我也单独整理了一份简图:

大屏图表,ECharts 从“娴熟”到入门

经过图中相关对照,咱们能够在官方文档的装备项手册 中快速浏览相关内容的支持选项及用法。

3.3 轻度自界说的神器:graphic

以上装备项中,大多数才能都是 Echarts 预设好,咱们直接拿来用” 形式的,但难免会遇到产品经理或者 UI 同学突发奇想,增加一些特别的文本或者图画,比方:

大屏图表,ECharts 从“娴熟”到入门

这种就属于,乍一眼看上去很简略,然后一揣摩:不对啊,DEMO 里找不到能够直接拿来用 的类型了。

怎么办?

‘graphic’ 或许是个不错的挑选。

graphic 装备供给了以下节点才能的烘托装备:

  • 图片
  • 文本
  • 元素组(可包括子节点,对子节点进行全体缩放、旋转等)
  • 以及 其他各种图形,例如(圆形、扇形、环形、多边形、折线、矩形、直线、贝塞尔曲线、圆弧)

其间,我以为最常用的两种:

  • 图片
  • 文本

让咱们先经过一个比如知道 图片文本 的用法,中心代码如下:

option = {
  ...// 省略其他,
  graphic: [
      {
        type: 'image',
        style: {
          image: 'https://www.6hu.cc/wp-content/uploads/2022/12/1669965209-883a6d886a4f284.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
        }
      },
  ]
}

码上相关片段,赶紧亲自试试:

作用图:

大屏图表,ECharts 从“娴熟”到入门

3.4 装备化与动画

细心的同学想必现已发现了,我并没有声明和动画相关的东西,但我上面的示例里现已有了最基本的 补间动画,这是由于 echarts 内置了一部分默许动画逻辑。

但实际上,你也拥有装备动画的才能

  1. 关键帧作用,以及循环动画

    尝试在 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 从“娴熟”到入门
    鸡哥的篮球 背景的圆环永久地滚动了起来。

    这个作用正是借助了 Echarts 供给的关键帧动画才能,指定时长、以及不同进展上元素应该体现的装备状况,驱使它完结了页面的烘托。

  2. 进入/脱离/更新动画

    关键帧动画更倾向于按照 编码者指定的办法 进行工作,而 “进入/脱离/更新动画” 则适用于 更新数据状况时,主动获取动画 的才能。
    看代码:

    // 移除上面 keyframeAnimation 这一段代码
    // 增加以下代码:
    setInterval(() => {
      const rotation = Math.random() * 2 * Math.PI
      chart.setOption({
        graphic: [
          {
            rotation
          }
        ]
      })
    }, 500)
    

    作用如下:

    大屏图表,ECharts 从“娴熟”到入门
    鸡哥的篮球 背景的圆环 rap 起来了。

学会以上动画才能,也基本算能够称得上在 Echarts 运用上入门了,能够应对大多数 UI 和产品的奇思妙想了。

四、 基底组件的才能?

我对 基底组件 的期望,其实很简略:

  • 它能自适应容器的宽高,并让自身的图表自适应容器宽高的改变

    这当然是痛点了,我不止一次,不止在一个项目里,发现大屏进行布局调整、或者是浏览器页面巨细调整后,图表的巨细变得不适宜。依靠研制在紧张工期下,仍然坚持严谨的防御性代码编写习气,是一种奢求。

  • 它能具备根底的主题才能

    大屏一般有自己的主题色,自带 “主题色” 的 Echarts 组件,能够让研制节省很多时间。

  • 当数据为空时,它能智能的显现 “空值缺省”

    试想,哪个客户期望对着一个空空如也的折线图猜测意图呢?此刻,一句简简略单的 暂无数据 是多么的贴心。

  • 它应该给我最大极限的 自界说 的才能

    永久不要失掉才能,封装的意义在于 增强,而不是 阉割

基于以上诉求,咱们能够开端规划自己的 Echarts 基底组件 的API。

src/components/BaseECharts/index.vue

// 供给 props 特点 empty,让组件稳定感知当时是否是空数据
defineProps({
  empty: {
    type: Boolean,
    default: false
  }
})
// 向外弹射事情 'resize'
const emits = defineEmits(['resize'])
defineExpose(
  {
    // 向父组件暴露办法:获得ECharts实例
    getChart: () => {
    },
    // 向父组件暴露办法:更新ECharts装备
    setOption: (v) => {
    }
  }
)

五、怎么完结动态适配容器宽高

先了解一个 API: ResizeObserver。 (MDN相关参考)

经过 ResizeObserver,咱们能够沉着地监听某个元素的尺度改变。

既然这个 API 这么优秀,那咱们直接用它?你们能够随便用,但本晚年 vue-coder 挑选逻辑完备的 Hooks: useElementSize,一行代码解决元素尺度监听的问题:

const el = ref(null)
const { width, height } = useElementSize(el) // width和 height 都是呼应式的 `ref` 对象

然后再监听相关改变,适时地调用 chart.resize() 办法即可:


watchEffect(() => {
  if (width.value && height.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 是支持自界说主题的,拜访: echarts.apache.org/zh/theme-bu…

能够经过左边的操作栏,让 UI同学快速定制一套合适你们体系的主题色,然后导出主题 json 装备文件,并将它存在 ‘@/theme/echarts-dark.json’ 文件中。

src/main.js 中写如下带代码:

import * as ECharts from "echarts";
import theme from '@/theme/echarts-dark.json'
ECharts.registerTheme('dark', theme)

完结对主题的注册,(写在 main.js 是为了避免重复注册),当然,假如要充沛组件化的话,此处应该有 vue-plugin

然后,在基底组件中如此写:

onMounted(() => {
  const chart = 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 运用,应该就不会再呈现为难的场景了吧。

面对面试官高深场景的问题,也能够理直气壮地答复一句:

我就入门水平,你还想怎样?