echarts tooltip-提示框轮询动画

echarts 中有 tootip 提示框组件,以浮层形式展示该点的数据信息和文字内容。默认鼠标悬停在数据项/组件上时触发。

触发类型:

  • item 数据项图形触发,主要在散点图,饼图等无类目轴的图表中使用。
  • axis 坐标轴触发,主要在柱状图,折线图等会使用类目轴的图表中使用。
  • none 什么都不触发。

1. dispatchAction api

echarts 中支持的图表行为,通过 dispatchAction 触发,比如特定位置高亮、显示提示框等。

ini 复制代码
intervalShowTooltip(chart, options) {
  var currentIndex = -1;
  this.tooltipInterval = setInterval(() => {
    var dataLen = options.series[0].data.length;
    if (dataLen > 0) {
      currentIndex = (currentIndex + 1) % dataLen;
      chart.dispatchAction({
        type: 'showTip',  // 提示框
        seriesIndex: 0,
        dataIndex: currentIndex // 该行柱子高亮
      });
    }
  }, 1500);
}
go 复制代码
dispatchAction({  
  type: 'hideTip' // 隐藏提示框
})

2. clear() 和 dispose()

(1)防止内存泄漏

在 Vue 中使用 ECharts 时,为了避免在卸载组件时出现资源泄漏(内存溢出)的问题,需要在组件销毁时手动释放ECharts实例。可以使用 clear 或 dispose 方法实现。

  • clear 方法是清空当前实例,会移除实例中所有的组件和图表,但不会释放实例占用的其他资源,比如容器DOM及绑定的事件等。
  • dispose 方法则是彻底释放ECharts实例占用的所有资源,包括DOM、事件、定时器等。

注意:在使用dispose方法时,需要先将实例置空,否则可能导致内存泄漏问题。

(2)动态更新 echarts 图表

使用场景:当 echarts 图表的数据是动态更新然后渲染图表时,哪怕使用 watch 监听数据的变化,并拿到了更新后的数据,但是图表却没有进行相应的渲染或者出现卡顿。

kotlin 复制代码
watch: {
  data: {
    handler(value) {
      ...
      // 方法1: 使用 echarts.dispose() 销毁整个实例,通过 echarts.init()重新创造新的实例
      this.chart.dispose();
      this.initChart();

      // 方法2: 使用 echarts.clear() 清空当前实例,重新 setOption()
      this.chart.clear();
      this.setOption();
    },
    immediate: true
  }
}

3. 提示框自动轮询

通过 dispatchAction 触发图表显示提示框,并根据设置的时间进行轮询,实现动画效果,同时可以选择添加阴影指示器。另外要注意在组件销毁时释放echarts实例。

kotlin 复制代码
data() {
  return {
    chart: null,
    tooltipInterval: null,
    options: {
        tooltip: {
          trigger: 'axis',
          padding: [10, 16],
          //  axisPointer: {
          //    type: 'shadow',
          //    shadowStyle: {
          //      shadowColor: '#053d48FF',
          //      opacity: 0.5
          //    }
          //  },
          backgroundColor: '#0B3A52FF',
          borderColor: '#0C3E5866',
          textStyle: {
            color: 'white',
            // fontSize: 20,
            // fontFamily: 'Source Han Sans CN-Regular, Source Han Sans CN'
          },
          formatter: params => {
            return this.formatterTip(params);
          }
        },
        ......
    }
  };
},
mounted() {
  this.iniChart();
},
beforeDestroy() {
  // 销毁ECharts实例
  this.chart && this.chart.dispose();
  this.chart = null;
  this.tooltipInterval && clearInterval(this.tooltipInterval);
  this.tooltipInterval = null;
},
methods: {
  iniChart() {
    if (!this.chart) {
      this.chart = echarts.init(this.$refs.chartRef);
    }
    this.setOption();
    this.intervalShowTooltip(this.chart, this.options);
  },
  setOption() {
    if (this.chart) {
      this.chart.setOption(this.options);
    }
  },
  
  // 自动轮询展示提示框
  intervalShowTooltip(chart, options) {
    var currentIndex = -1;
    this.tooltipInterval = setInterval(() => {
      var dataLen = options.series[0].data.length;
      if (dataLen > 0) {
        currentIndex = (currentIndex + 1) % dataLen; // 取余 循环展示
        chart.dispatchAction({
          type: 'showTip',
          seriesIndex: 0,
          dataIndex: currentIndex
        });
      }
    }, 3000);
  },
  
  // 处理提示框内容
  // 单条数据
  formatterTip(params) {
    if (params[0].data === null || params[0].data === undefined) {
      return null;
    }
    var result = '';
    // 可以手动修改标记样式 替代item.marker
    var dotHtml = '<span style="display: inline-block; margin-right: 5px; rder-radius: 10px; width: 10px; height:10px; background-color: #02FAFBFF"></span>';
    params.forEach(item => {
      result += item.axisValueLabel + '</br>' + dotHtml + item.seriesName + ': ' + item.data;
    });
    return result;
  },
  // 多条数据
  formatterTip(params) {
    // 折线图+散点图涟漪 筛选折线图数据
    const data = params.filter(item => item.seriesType === 'line');
    var tip = data.length > 0 ? data[0].axisValueLabel + '<br/>' : '';
    for (let i = 0; i < data.length; i++) {
      tip = tip + data[i].marker + data[i].seriesName + ': ' + data[i].value + '<br/>';
    }
    return tip;
  }
}
相关推荐
烛阴12 分钟前
秒懂 JSON:JavaScript JSON 方法详解,让你轻松驾驭数据交互!
前端·javascript
拉不动的猪20 分钟前
刷刷题31(vue实际项目问题)
前端·javascript·面试
zeijiershuai22 分钟前
Ajax-入门、axios请求方式、async、await、Vue生命周期
前端·javascript·ajax
恋猫de小郭24 分钟前
Flutter 小技巧之通过 MediaQuery 优化 App 性能
android·前端·flutter
只会写Bug的程序员33 分钟前
面试之《webpack从输入到输出经历了什么》
前端·面试·webpack
拉不动的猪35 分钟前
刷刷题30(vue3常规面试题)
前端·javascript·面试
狂炫一碗大米饭1 小时前
面试小题:写一个函数实现将输入的数组按指定类型过滤
前端·javascript·面试
最胖的小仙女1 小时前
通过动态获取后端数据判断输入的值打小
开发语言·前端·javascript
yzhSWJ1 小时前
Vue 3 中,将静态资源(如图片)转换为 URL
前端·javascript·vue.js
Moment1 小时前
🏞 JavaScript 提取 PDF、Word 文档图片,非常简单,别再头大了!💯💯💯
前端·javascript·react.js