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;
}
}