ECharts柱状图动画组件

136 阅读2分钟

一、示例

image.png

二、使用案例

image.png

image.png

三、封装组件完整代码

<template>
  <div class="EChartsBar"
    :ref="chartRef"
    @mouseover="clearTimer"
    @mouseout="setTimer">
  </div>
</template>

<script>
export default {
  name: "EChartsBar",
  props: {
    // 图表ref标识
    chartRef: {
      type: String,
      default: "chartRef"
    },
    // 边距
    grid: {
      type: Object,
      default: () => {
        return {}
      }
    },
    // Y轴单位名称
    yAxisName: {
      type: String,
      default: "辆"
    },
    // x轴单位名称
    xAxisName: {
      type: String,
      default: ""
    },
    // 颜色值
    color: {
      type: Array,
      default: () => {
        return ["rgba(255, 179, 0, 1)", "rgba(4, 245, 255, 1)", "rgba(1, 156, 255, 1)"]
      }
    },
    // x轴数据
    xAxisData: {
      type: Array,
      default: () => {
        return ["暂无数据"]
      }
    },
    // 图表数据
    series: {
      type: Array,
      default: () => {
        return [{ data: [0] }]
      },
    },
    // 图例展示
    legendShow: {
      type: Boolean,
      default: false
    },
    // x轴刻度标签对齐方式
    xAxisLabelAlign: {
      type: String,
      default: ""
    },
    // 是否开启动画
    isAnimate: {
      type: Boolean,
      default: true
    }
  },
  data() {
    return {
      // EChartsBar: null,
      EChartsBarTimer: null,
      option: {}
    }
  },
  mounted() {
    this.$nextTick(() => {
      this.initECharts()
    })
  },
  beforeDestroy() {
    clearInterval(this.EChartsBarTimer)
  },
  watch: {
    series: {
      handler() {
        this.updateECharts()
      },
      deep: true
    },
    xAxisData() {
      this.updateECharts()
    }
  },
  methods: {
    updateECharts() {
      let seriesArray = []
      this.series.forEach((item) => {
        seriesArray.push({
          type: "bar",
          barWidth: "30%",
          ...item
        })
      })
      this.EChartsBar.setOption({
        xAxis: { data: this.xAxisData },
        series: seriesArray
      })
      clearInterval(this.EChartsBarTimer)
      this.setTimer()
    },
    // 清除轮播定时器
    clearTimer() {
      clearInterval(this.EChartsBarTimer)
    },
    // 设置轮播定时器
    setTimer() {
      this.isAnimate && this.animateECharts(this.EChartsBar, this.xAxisData)
    },
    // 初始化图表
    initECharts() {
      this.EChartsBar = this.$echarts.init(this.$refs[this.chartRef])
      let seriesArray = []
      this.series.forEach((item) => {
        seriesArray.push({
          type: "bar",
          barWidth: "30%",
          ...item
        })
      })
      this.option = {
        backgroundColor: "#00000000",
        color: this.color,
        tooltip: {
          trigger: "axis",
          axisPointer: {
            type: "shadow"
          },
          textStyle: {
            color: "#ffffff",
            align: "left",
            fontSize: 16
          },
          backgroundColor: "rgba(0, 0, 0,.6)",
          borderColor: "rgba(186, 186, 186, .4)",
          formatter: '{a}: {c}'
        },
        grid: {
          top: this.legendShow ? "15%" : '8%',
          left: "2%",
          right: "6%",
          bottom: "10%",
          containLabel: true,
          ...this.grid
        },
        xAxis: {
          type: "category",
          name: this.xAxisName,
          nameTextStyle: {
            color: "#ffffff",
            fontSize: 12,
            verticalAlign: 'top',
            align: 'left',
          },
          data: [...this.xAxisData],
          // 轴线设置
          axisLine: {
            show: true,
            lineStyle: { color: "#FFFFFF80", type: "solid", width: 1 }
          },
          // 坐标轴刻度
          axisTick: {
            show: true
          },
          // 坐标轴标签
          axisLabel: {
            show: true,
            fontSize: 12,
            interval: 0,
            color: "#ffffff",
            align: this.xAxisLabelAlign,
            lineHeight: 30,
            // formatter: function (params) {
            //   return params.length > 8 ? params.slice(0, 8) + "..." : params
            // },
          },
        },
        yAxis: {
          type: "value",
          name: this.yAxisName,
          nameTextStyle: {
            color: "#ffffff",
            fontSize: 12,
            align: "left",
            lineHeight: 0
          },
          minInterval: 1,
          splitNumber: 4,
          splitLine: {
            show: true,
            lineStyle: {
              color: "#ffffff20",
              type: "dashed",
              width: 2
            }
          },
          axisLine: {
            show: false
          },
          axisLabel: {
            color: "#ffffff",
            fontSize: 12,
            // margin: 0,
            verticalAlign: 'top',
            lineHeight: 20,
          },
          axisTick: {
            show: false
          }
        },
        legend: {
          show: this.legendShow,
          left: '2%',
          top: "2%",
          icon: "rect",
          itemWidth: 14,
          itemHeight: 10,
          textStyle: {
            color: "#ffffff",
            fontSize: 14
          }
        },
        series: seriesArray
      }
      //渲染数据
      this.EChartsBar.setOption(this.option, true)
      this.isAnimate && this.animateECharts(this.EChartsBar, this.xAxisData)
    },
    // 动画设置
    animateECharts(myChart, array) {
      // mychart:当前图形实例
      // option:当前图形渲染参数
      let currentIndex = -1
      this.EChartsBarTimer = setInterval(() => {
        var dataLen = array.length
        // 取消之前高亮的图形
        myChart.dispatchAction({
          type: "downplay",
          seriesIndex: 0,
          dataIndex: currentIndex
        })
        currentIndex = (currentIndex + 1) % dataLen
        // 高亮当前图形
        myChart.dispatchAction({
          type: "highlight",
          seriesIndex: 0,
          dataIndex: currentIndex
        })
        // 显示 tooltip
        myChart.dispatchAction({
          type: "showTip",
          seriesIndex: 0,
          dataIndex: currentIndex
        })
      }, 3000)
    }
  }
}
</script>

<style lang="scss" scoped>
.EChartsBar {
  width: 100%;
  height: 100%;
}
</style>