ECharts 弹窗无法手动关闭?造一个!

333 阅读1分钟

一、手写一个 MyTooltip 弹窗组件

前面我写了关于 如何使用 formatter 回调函数实现 ECharts 弹窗,相信可以满足大部分的业务需求。但往往也有愁人的时候,比如:这个弹窗咋不能多停留会儿呢?能不能做到用户手动关闭呢?咱还想复制里面的东西嘞,咱还想点击跳转到另一个页面嘞......它都不给咱机会,生怕咱吃了它。怎么办捏,手写一个呗。

@/components/MyTooltip.vue

<template>
  <div class="myTooltip">
    <div class="tip_mask" @click="closeTip"></div>
    <div class="tip_main">
      <div class="tip-header">
        <div :class="['riskColor', getColor(tipData.value)]"></div>
        <div class="riskRank">{{ getRiskRank(tipData.value) }}风险</div>
      </div>
      <div class="tip-body">{{ tipData.name }}:{{ tipData.value }}</div>
    </div>
  </div>
</template>
<script>
export default {
  name: 'MyTooltip',
  props: {
    tipData: {
      type: Object,
      default: () => {}
    }
  },
  mounted () {},
  methods: {
    // 获取风险等级颜色
    getColor (value) {
      let color = ''
      if (value > 300) {
        color = 'bgGreen'
      } else if (value > 200) {
        color = 'bgYellow'
      } else {
        color = 'bgRed'
      }
      return color
    },
    // 获取风险等级
    getRiskRank (value) {
      let risk = '无'
      if (value > 300) {
        risk = '低'
      } else if (value > 200) {
        risk = '中'
      } else {
        risk = '高'
      }
      return risk
    },
    // 点击蒙层
    closeTip () {
      this.$emit('closeTip')
    }
  }
}
</script>
<style lang="less" scoped>
.myTooltip {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  width: 400px;
  height: 300px;
  .tip_mask {
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
    background-color: rgba(0, 0, 0, 0.2);
    z-index: 988;
  }
  .tip_main {
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
    margin: auto;
    width: 100px;
    height: 50px;
    background-color: rgba(255,220,115,0.2);
    border: 1px solid #ffdc73;
    color: black;
    padding: 10px;
    border-radius: 10px;
    z-index: 999;
    .tip-header {
      display: flex;
      align-items: center;
      .riskColor {
        width: 20px;
        height: 20px;
        border-radius: 50%;
        margin-right: 5px;
        &.bgGreen {
          background-color: green;
        }
        &.bgYellow {
          background-color: yellow;
        }
        &.bgRed {
          background-color: red;
        }
      }
    }
    .tip-body {
      margin-top: 10px;
    }
  }
}
</style>

二、页面引人并使用 MyTooltip 弹窗组件

注意了,既然我们使用自己写的弹窗组件,那么 ECharts 内置的 tooltip 就要关闭啦!那怎么让这个弹窗出来呢?别忘了,ECharts 本身也有原生的事件哦:单击、双击、悬浮等,应有尽有!下面我们就用 chart-click 事件啦!

组件写好了,我们需要在父组件使用它,下面需要做三件事:

  1. 点击出来弹窗
  2. 点击的柱条显示高亮
  3. 关闭弹窗不显示高亮

另,关于 MyChart 组件,是我之前写的 基于 ECharts 的 二次封装,我就直接使用啦,不懂的可以先去看看那篇文章。

App.vue

<template>
  <div class="echartBar">
    <MyChart :op="op" :height="'100%'" @chart-click="chartClick" v-if="showBar"></MyChart>
    <MyTooltip :tipData="tipData" v-if="showTooltip" @closeTip="closeTip"></MyTooltip>
  </div>
</template>
<script>
import MyChart from '@/components/MyChart.vue'
import MyTooltip from '@/components/MyTooltip.vue'
export default {
  components: {
    MyChart,
    MyTooltip
  },
  data () {
    return {
      tipData: {},
      showBar: true,
      showTooltip: false,
      isHighLight: false,
      selectedIndex: ''
    }
  },
  computed: {
    op () {
      return {
        // 内置弹窗必须设置为 false
        tooltip: {
          show: false
        },
        grid: {
          left: '3%',
          right: '4%',
          bottom: '3%',
          containLabel: true
        },
        xAxis: [
          {
            type: 'category',
            data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
            axisTick: {
              alignWithLabel: true
            }
          }
        ],
        yAxis: [
          {
            type: 'value'
          }
        ],
        series: [
          {
            name: 'Direct',
            type: 'bar',
            barWidth: '60%',
            data: [10, 52, 200, 334, 390, 330, 220],
            itemStyle: {
              normal: {
                color: (args) => {
                  // 判断当前点击的柱条是否高亮
                  const isHighLight = this.selectedIndex === args.dataIndex
                  return isHighLight ? this.getClickBarColor(args.value) : '#5470c6'
                }
              }
            }
          }
        ]
      }
    }
  },
  methods: {
    chartClick (params) {
      // 1.获取当前点击的柱条的索引
      this.selectedIndex = params.dataIndex
      // 2.传递弹窗数据给子组件 MyTooltip
      this.tipData = { name: params.name, value: params.value }
      // 3.打开弹窗
      this.showTooltip = true
      // 4.重新渲染柱状图
      this.showBar = false
      this.$nextTick(() => {
        this.showBar = true
      })
    },
    // 获取柱条高亮的颜色(为风险等级对应的颜色)
    getClickBarColor (value) {
      let color = ''
      if (value > 300) {
        color = 'green'
      } else if (value > 200) {
        color = 'yellow'
      } else {
        color = 'red'
      }
      return color
    },
    // 点击蒙层
    closeTip () {
      // 1.关闭弹窗
      this.showTooltip = false
      // 2.不展示高亮
      this.isHighLight = false
      // 3. 高亮的索引置空
      this.selectedIndex = ''
      // 4.重新渲染柱状图
      this.showBar = false
      this.$nextTick(() => {
        this.showBar = true
      })
    }
  }
}
</script>
<style lang="less" scoped>
.echartBar {
  position: relative;
  width: 400px;
  height: 300px;
}
</style>

三、MyTooltip 弹窗的页面效果

点击咱们的任意一个柱条,就能出来对应的弹窗啦,还有高亮效果!点击蒙层就可以关闭弹窗,高亮随之消失!当然,你也可以在弹窗里面加一个关闭的按钮,这不就更 nice 啦!这个弹窗真的很好看耶!

image.png