echart图表组件封装(vue3)

组件封装:

javascript 复制代码
<template>
  <div class="echart-container">
    <div class="chart" ref="chartRef"></div>
  </div>
</template>

<script lang="ts" setup>
  import { ref, nextTick, onMounted, watch, defineProps, defineExpose, computed } from 'vue'
  import * as echarts from 'echarts'
  import lodash from 'lodash'
  const props = defineProps({
    data: {
      type: Object,
      default() {
        return {
          title: '',
          series: [],
          xAxis: []
        }
      },
    },
  })
  const chartData = ref(props.data)
  let chartRef = ref(null)
  let myChart = null
  let defTitle = {
    text: '',
    textStyle: {
      fontSize: 16,
      fontWeight: 'none',
      color: '#999999',
    },
    left: 10,
    top: 10,
  }
  let defYA = {
    type: 'value',
    splitLine: {
      show: true,
    },
    axisTick: {
      show: true,
    },
    axisLine: {
      show: true,
    },
    axisLabel: {
      color: '#999999',
    },
    nameTextStyle: {
      color: '#999999',
    },
    minInterval: 1,
  }
  let defYAxis = [
    defYA,
    lodash.defaultsDeep(
      {
        position: 'right',
        nameTextStyle: {
          padding: [0, 0, 20, 0],
          align: 'left',
        },
        axisLabel: {
          align: 'right',
          margin: 30,
        },
      },
      defYA,
    ),
  ]
  let yAxis = computed(() => {
    let val = props.data.yAxis
    let value = [defYAxis[0]]
    let arr = []
    if (Array.isArray(val) && val.length) {
      val.forEach((ele, index) => {
        let defObj = defYAxis[index] || value
        let obj = lodash.defaultsDeep(ele, defObj)
        arr.push(obj)
      })
      value = arr
    }
    return value
  })
  let defXAxis = {
    type: 'category',
    data: [],
    axisTick: {
      show: true,
    },
    splitLine: {
      show: false,
    },
    axisLine: {
      show: true,
    },
    axisLabel: {
      color: '#999999',
    },
  }
  let xAxis = computed(() => {
    let val = props.data.xAxis
    let value = defXAxis
    if (Array.isArray(val)) {
      value.data = val
    } else {
      value = lodash.defaultsDeep(val, value)
    }
    return value
  })
  let title = computed(() => {
    let val = defTitle
    let tit = props.data.title
    if (typeof tit === 'string') {
      val.text = tit
    } else {
      val = lodash.defaultsDeep(tit, val)
    }
    return val
  })
  const formatNumber = (num) => {
    return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',')
  }
  let option = ref({
    title: title.value,
    legend: {},
    tooltip: lodash.defaultsDeep(props.data.tooltip, {
      trigger: 'axis',
      formatter: (params) => {
        let html = params[0].name
        let data = props.data
        for (let i = 0, l = params.length; i < l; i++) {
          let unit = data.series[i].unit || data.unit || ''
          let color = data.series[i].color
          html += `<div style="margin-top:5px;">
            <span style="float:left;">${params[i].marker}${params[i].seriesName}</span>
            <span style="float:right;margin-left:20px;">
            <span style="margin-right:1px;">${formatNumber(params[i].value)}</span>${unit}</span>
            <div style="clear:both;"></div>
          <div>`
        }
        return html
      },
    }),
    grid: {
      left: '2%',
      right: '2%',
      bottom: '4%',
      containLabel: true,
    },
    toolbox: {},
    xAxis: xAxis.value,
    yAxis: yAxis.value,
    series: [],
  })
  const init = () => {
    myChart = echarts.init(chartRef.value)
    myChart.setOption(option.value)
  }
  const setData = () => {
    nextTick(() => {
      var data = chartData.value
      let xAxis = data.xAxis
      if (Array.isArray(xAxis)) {
        option.value.xAxis.data = xAxis
      } else {
        option.value.xAxis = xAxis
      }
      option.value.series = data.series
      myChart.setOption(option.value)
    })
  }
  const resize = lodash.debounce(() => {
    myChart.resize()
  }, 200)
  onMounted(() => {
    init()
    window.onresize = function () {
      resize()
    }
  })
  watch(
    () => props.data,
    (val) => {
      chartData.value = val
      setData()
    },
    {
      immediate: true,
      deep: true,
    },
  )
  defineExpose({
    chartRef,
  })
</script>
<style lang="scss" scoped>
  .echart-container {
    width: 100%;
    min-height: 200px;
    height: 100%;
    padding: 0 10px;
    box-sizing: border-box;
    .chart {
      height: 100%;
      width: 100%;
    }
  }
</style>

组件调用:

javascript 复制代码
<template>
    <my-chart :data="chartData"></my-chart>
</template>
<script lang="ts" setup>
  import myChart from '@/components/MyChart/index.vue'
  const chartData = ref({
    title:'标题',
    unit: '单位',
    series: [
      {
        name: '折线图',
        type: 'line',
        data: [],
        smooth: true,
        color: '#1B5CFF',
      },
    ],
    xAxis: []
  })
</script>
相关推荐
LJ小番茄6 分钟前
Vue 常见的几种通信方式(总结)
前端·javascript·vue.js·html
黑狼传说10 分钟前
前端项目优化:极致最优 vs 相对最优 —— 深入探索与实践
前端·性能优化
장숙혜16 分钟前
前端-CDN的理解及CDN一些使用平台
前端
m0_6312704021 分钟前
高级c语言(五)
c语言·开发语言
2401_8582861127 分钟前
53.【C语言】 字符函数和字符串函数(strcmp函数)
c语言·开发语言
程序猿练习生1 小时前
C++速通LeetCode中等第5题-无重复字符的最长字串
开发语言·c++·leetcode
2401_858120261 小时前
MATLAB中的无线通信系统部署和优化工具有哪些
开发语言·matlab
MATLAB滤波1 小时前
【PSINS】基于PSINS工具箱的EKF+UKF对比程序|三维定位|组合导航|MATLAB
开发语言·matlab
2401_858120531 小时前
MATLAB在嵌入式系统设计中的最佳实践
开发语言·matlab
蓝裕安1 小时前
伪工厂模式制造敌人
开发语言·unity·游戏引擎