Vue3中我是这样玩Echart的

前言

最近接到个业务需求,类似于数据大屏展示图表的功能,需要具备一键换肤和表格转换成为图表的功能,对于我这种老Echarter来说已经是很轻车熟路的操作了,但是由于团队使用的是Vue3+TS还是遇到了些坑点的。

Vue3中我是这样玩Echart的

Echart的基本操作

vue3中,通过npm install echarts可获取到对应的echart资源,在项目文件中建立对应的utils作为引用echart资源的工具库。

@/utils/utils

import * as echarts from "echarts/core"

import { BarChart, LineChart, PieChart, MapChart, PictorialBarChart, RadarChart } from "echarts/charts"

import {
  TitleComponent,
  TooltipComponent,
  GridComponent,
  PolarComponent,
  AriaComponent,
  ParallelComponent,
  LegendComponent,
  RadarComponent,
  ToolboxComponent,
  DataZoomComponent,
  VisualMapComponent,
  TimelineComponent,
  CalendarComponent,
  GraphicComponent
} from "echarts/components"

import { CanvasRenderer } from "echarts/renderers"

echarts.use([
  LegendComponent,
  TitleComponent,
  TooltipComponent,
  GridComponent,
  PolarComponent,
  AriaComponent,
  ParallelComponent,
  BarChart,
  LineChart,
  PieChart,
  MapChart,
  RadarChart,
  CanvasRenderer,
  PictorialBarChart,
  RadarComponent,
  ToolboxComponent,
  DataZoomComponent,
  VisualMapComponent,
  TimelineComponent,
  CalendarComponent,
  GraphicComponent
])

export default echarts

然后再建立个Echart.vue文件

<template>
  <div ref="echartsRef" style="height: 400px; width: 500px">gamePlay</div>
</template>
<script setup lang="ts">
import { ref, onMounted } from "vue"
import echarts from "@/utils/echarts"
const echartsRef = ref()
onMounted(() => {
  const myChart = echarts.init(echartsRef.value)
  // 指定图表的配置项和数据
  const option = {
    title: {
      text: "ECharts 入门示例"
    },
    tooltip: {},
    legend: {
      data: ["销量"]
    },
    xAxis: {
      data: ["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"]
    },
    yAxis: {},
    series: [
      {
        name: "销量",
        type: "bar",
        data: [5, 20, 36, 10, 10, 20]
      }
    ]
  }

  // 使用刚指定的配置项和数据显示图表。
  myChart.setOption(option)
})
</script>

Vue3中我是这样玩Echart的
就这么简单就可以渲染出一个echart图表了。

封装useEchartHook渲染图表

虽然我们已经能渲染出图表了,但是这个操作并不是最优解,因为我们的实际业务中是存在很多不同类型的图表,不可能每个都实例化Echart然后再手动调用setOptions方法,这显的很蠢。那么这个时候就需要引入useHookEchart的做法了。

import { Ref, shallowRef, onMounted, onDeactivated, onBeforeUnmount } from "vue"
import echarts from "@/utils/echarts"
export type EChartsCoreOption = echarts.EChartsCoreOption
const useEcharts = (elRef: Ref<HTMLDivElement>, options: EChartsCoreOption) => {
  const charts = shallowRef<echarts.ECharts>()

  const initCharts = () => {
    charts.value = echarts.init(elRef.value)
    setOptions(options)
  }
  const setOptions = (options: EChartsCoreOption) => {
    charts.value && charts.value.setOption(options)
  }
  const echartsResize = () => {
    charts.value && charts.value.resize()
  }
  onMounted(() => {
    window.addEventListener("resize", echartsResize)
  })
  // 防止 echarts 页面 keepAlive 时,还在继续监听页面
  onDeactivated(() => {
    window.removeEventListener("resize", echartsResize)
  })

  onBeforeUnmount(() => {
    window.removeEventListener("resize", echartsResize)
  })
  return {
    initCharts,
    setOptions,
    echartsResize
  }
}
export { useEcharts }

然后再echart.vue中引入

<template>
  <div style="width: 100%; height: 100%" ref="elEcharts" />
</template>
<script setup lang="ts">
import { shallowRef, onMounted, watch } from "vue"
import { useEcharts, type EChartsCoreOption } from "@/hooks/useEcharts"

interface Props {
  options: EChartsCoreOption
}
const props = defineProps<Props>()
const themeStore = useThemeStore()
const elEcharts = shallowRef()
const currentOptions = shallowRef(props.options)
const { setOptions, initCharts } = useEcharts(elEcharts, currentOptions.value)

watch(
  () => props.options,
  (nVal) => {
    let targetOptions: EChartsCoreOption = {}
    if (themeStore.currentColorArray && themeStore.currentColorArray.length > 0) {
      targetOptions = { ...nVal }
      targetOptions.color = themeStore.currentColorArray
    } else {
      targetOptions = { ...nVal }
    }
    setOptions(targetOptions)
  }
)

onMounted(() => {
  initCharts()
})
</script>

业务中使用

<template>
    <BaseEcharts :options="options2" />
</template>
import BaseEcharts from "@/components/baseEcharts/index.vue"
const options2: EChartsCoreOption = {
  tooltip: {
    trigger: "axis"
  },

  grid: {
    left: "3%",
    right: "4%",
    bottom: "0%",
    top: "5%",
    containLabel: true
  },
  xAxis: {
    type: "category",
    boundaryGap: false,
    data: ["3-1", "3-2", "3-3", "3-4", "3-5", "3-6", "3-7"]
  },
  yAxis: {
    axisLabel: {
      formatter: function (val: number) {
        return val
      }
    }
  },
  series: [
    {
      name: "QQ",
      type: "line",
      stack: "Total",
      data: [200,201,202,203,204,205,206]
    },
    {
      name: "微信",
      type: "line",
      stack: "Total",
      data: [200,201,202,203,204,205,206]
    }
  ]
}

Vue3中我是这样玩Echart的

关于Echart主题换肤

由于产品希望图表的主题是可以自由变换的,也就是图表换肤。那好说,因为在echart中可以通过options上的color字段进行自由换主题。这个时候需要改造useEcharts中的initCharts方法

...
 const initCharts = (themeColor?: Array<string>) => {
    charts.value = echarts.init(elRef.value)
    if (themeColor) {
      options.color = themeColor
    }

    setOptions(options)
  }
...

然后再建立themeStore(由于是全局操作,这里使用的pinia)
@/store/themeStore中建立updateCurrentColorByArray方法

import { defineStore } from "pinia"
import { ref } from "vue"
export const useThemeStore = defineStore("themeStore", () => {
 const currentColorArray = ref<string[]>()
  // 根据颜色组更新当前颜色组
  const updateCurrentColorByArray = (color: string[]) => {
    currentColorArray.value = color
  }



  return {
    updateCurrentColorByArray,
    currentColorArray
  }
})

在echartsTheme.ts中预设以下几种主题

在setting.vue中引入themeStore和echartTheme.ts

在echarts.vue中监听currentColorArray变化,重新去设置图表主题即可

Vue3中我是这样玩Echart的

Vue3中我是这样玩Echart的

自定义颜色跟新图表主题

当我准备提交代码,关机下班的时候。产品突然说,用户再增加个根据颜色来生成图表的主题,而不是预设的主题。这个时候,我心里真的有1W只草泥马在奔腾。你一个图表目的不就是为了看数据展示吗?搞这么多花里胡哨的干嘛捏?

Vue3中我是这样玩Echart的

吐槽归吐槽,班还是要上的,先做个基础布局吧。

Vue3中我是这样玩Echart的

tvision-color

根据某个色阶来生成主题,我们可以通过 tvision-color进行操作。
在utils/color.ts

getColorArray方法会返回根据这个色阶返回一系列的相关颜色的数据,其中brandColorIndex为这个色阶的主色。
在themeStore中添加

在业务中customColor.vue中调用

Vue3中我是这样玩Echart的

Vue3中我是这样玩Echart的

总结

在这过程中,我们使用了Vue3和TS中使用Echart实现一键换肤和根据颜色生成图表主题的功能。通过封装useEchartHook来渲染图表,并使用tvision-color库根据色阶生成颜色组来更新主题。最终实现了用户可以根据自定义颜色来展示图表数据的需求。

原文链接:https://juejin.cn/post/7344567580643000335 作者:迷途小羔羊

(0)
上一篇 2024年3月11日 下午4:16
下一篇 2024年3月11日 下午4:27

相关推荐

发表回复

登录后才能评论