ECharts 柱状图点击高亮

1,327 阅读2分钟

前言

最近在做一个柱状图点击高亮的需求,中途遇到一点小插曲,高亮效果始终出不来......也翻阅了不少资料,各有各的写法,跟我的始终不搭,不知道那根弦错了。故,请教导师,原来加个 v-if 配合 this.$nextTick() 就完美解决了!

由于是内部组件,不便展示!所以我自己用原生和 vue 分别写了一个柱状图的 demo 。虽然复现不了我遇到的问题,但也遇到了其他的问题。唯有自己动手试试,才有所得。

image.png

一、在原生中点击柱状图高亮

为什么想要写原生呢?因为万事万物离不开原生,任凭你千变万化,不离其宗。我非常想念曾经写原生的日子,原生让你更理解本质。

第一,我按照导师教我的方法,比较 barNameseriesName 是否相等,来切换颜色,由此展示高亮;第二,通过翻阅资料,看别人写的东西,我发现,还可以比较 selectedDepIndexdataIndex是否相等,来切换颜色,由此也可以点击高亮。

一个是比较当前点击的柱状条的名称,一个是比较当前点击的柱状条的索引。所以,没事多查查资料,也能有意外的收获呢!

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .main {
            width: 500px;
            height: 400px;
            background-color: pink;
        }
    </style>
    <script src="./echarts.js"></script>
</head>
<body>
    <div id="main" class="main"></div>
</body>
<script type="text/javascript">
    var chartDom = document.getElementById('main')
    var myChart = echarts.init(chartDom)
    var barName = ''
    var seriesName = ''
    var selectedDepIndex = 0
    var option = {
        xAxis: {
            type: 'category',
            data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
        },
        yAxis: {
            type: 'value'
        },
        series: [
            {
                data: [120, 200, 150, 80, 70, 110, 130],
                type: 'bar',
                showBackground: true,
                backgroundStyle: {
                    color: 'rgba(180, 180, 180, 0.2)'
                },
                itemStyle: {
                    normal: {
                        color: (args) => {
                            // ◆法1
                            const isHighLight =
                                barName &&
                                barName === args.name &&
                                seriesName === args.seriesName
                            // ◆法2
                            // const isHighLight = this.selectedDepIndex === args.dataIndex
                            return new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                                { offset: 0, color: isHighLight ? 'yellow' : '#83bff6' },
                                { offset: 0.5, color: isHighLight ? 'yellow' : '#188df0' },
                                { offset: 1, color: isHighLight ? 'yellow' : '#188df0' }
                            ])
                        }
                    }
                },
            }
        ]
    };
    // ◆初始渲染图表
    reFreshDepTen()
    // ◆鼠标点击显示高亮
    myChart.on('click', (data) => {
        barName = data.name
        seriesName = data.seriesName
        selectedDepIndex = data.dataIndex
        reFreshDepTen();
    })
    // ◆点击后刷新图标
    function reFreshDepTen() {
        option && myChart.setOption(option);
    }
    // ◆鼠标悬浮出现小手(补充知识点)
    myChart.getZr().on('mousemove', function (params) {
        var pointInPixel = [params.offsetX, params.offsetY]
        if (myChart.containPixel('grid', pointInPixel)) {
            myChart.getZr().setCursorStyle('pointer')
        }
    })
</script>
</html>

二、在 vue 中点击柱状图高亮

我用 vue 的方法也写了一遍,因为没有从接口获取数据,我只能模拟,虽然高亮的效果出来了,但是遇到另一个问题,控制台报错。于是我加了一个 setTimeout,就解决了,咱也不说为啥了,因为咱也不知道,跑起来就好了。嘿嘿!

虽然和实际需求中的写法不一,但也只能这样了。

<template>
  <div id="myChart" class="myChart">
  </div>
</template>
<script>
import * as echarts from 'echarts'
export default {
  data() {
    return {
      barName:'',
      seriesName:'',
      selectedDepIndex: 0,
    }
  },
  mounted () {
    setTimeout(()=>{
      this.renderMyChart()
    },500)
  },
  created () {
    setTimeout(()=>{
      this.renderMyChart()
    },500)
  },
  methods: {
    renderMyChart(){
      var myChart = echarts.init(document.getElementById("myChart"));
      var option = {
      xAxis: {
        type: 'category',
        data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
      },
      yAxis: {
        type: 'value'
      },
      series: [
        {
          data: [120, 200, 150, 80, 70, 110, 130],
          type: 'bar',
          showBackground: true,
          backgroundStyle: {
            color: 'rgba(180, 180, 180, 0.2)'
          },
          itemStyle: {
              normal: {
                  color: (args) => {
                      // 法1
                      // const isHighLight =
                      //     this.barName &&
                      //     this.barName === args.name &&
                      //     this.seriesName === args.seriesName
                      // 法2
                      const isHighLight = this.selectedDepIndex === args.dataIndex
                      return new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                          { offset: 0, color: isHighLight ? 'yellow' : '#83bff6' },
                          { offset: 0.5, color: isHighLight ? 'yellow' : '#188df0' },
                          { offset: 1, color: isHighLight ? 'yellow' : '#188df0' }
                      ])
                  }
              }
          },
        }
      ]
      };
      option && myChart.setOption(option);
      myChart.on('click',(data)=>{
        this.barName = data.name
        this.seriesName = data.seriesName
        this.selectedDepIndex = data.dataIndex
        option && myChart.setOption(option);
      })
    }
  }
}
</script>
<style scoped>
.myChart {
  width: 500px;
  height: 400px;
  background-color: pink;
}
</style>

好了,今天就到这儿吧,狗命要紧!