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>
相关推荐
燃先生._.29 分钟前
Day-03 Vue(生命周期、生命周期钩子八个函数、工程化开发和脚手架、组件化开发、根组件、局部注册和全局注册的步骤)
前端·javascript·vue.js
Dream_Snowar30 分钟前
速通Python 第三节
开发语言·python
高山我梦口香糖1 小时前
[react]searchParams转普通对象
开发语言·前端·javascript
m0_748235241 小时前
前端实现获取后端返回的文件流并下载
前端·状态模式
信号处理学渣2 小时前
matlab画图,选择性显示legend标签
开发语言·matlab
红龙创客2 小时前
某狐畅游24校招-C++开发岗笔试(单选题)
开发语言·c++
jasmine s2 小时前
Pandas
开发语言·python
biomooc2 小时前
R 语言 | 绘图的文字格式(绘制上标、下标、斜体、文字标注等)
开发语言·r语言
骇客野人2 小时前
【JAVA】JAVA接口公共返回体ResponseData封装
java·开发语言