在使用echart时,有时会需要在tooltip中实现点击特定数据来进行某些操作,但echart的tooltip中添加点击时只能用

<button onclick="xxx"></button>的方式实现,并且不能使用vue的指令

这样的话,点击事件的回调函数就没法访问vue组件的数据了,这就很不方便,下面就分享下我是怎么解决这个问题的

思路拆解

  • 既然在tooltip中的标签中,我们无法使用vue组件的函数,那么首先得先让这个标签的点击函数生效,于是在window上定义了一个全局的点击回调函数

    window.onClickSeries=function(series)
    {
    }
    
  • 有了这个全局回调之后,我们的点击事件已经可以正常触发了,但是如果同时创建了多个组件,那么这些组件会走到同一个点击回调函数中,并且这个回调函数还无法访问,于是我们需要增加一个用于判断当前组件的参数:

    /// chartKey是每个组件的key值
    window.onClickSeries=function(series,chartkey)
    {
    	//此时我们可以判断是来自哪个组件了,但是依然无法访问vue组件的数据,很难受
    }
    
  • 有了key值,那就key通过一个全局的map来保持key-value了,我们可以在这个value中存入我们想访问的任意值,既然如此,那就可以保存vue组件的实例,或者存放一个函数,通过这个函数访问vue实例,我这里使用的是保存函数的方式

    let globalMap = {
    
    }
    
    window.onClickSeries=function(series,chartkey)
    {
        let obj = globalMap [chartKey];
        if(obj !== undefined)
        {
        	///这里的obj是可以访问vue组件数据的
        }
    }
    
    ///组件中
    mounted()
    {
       ///保存vue实例的方式
        globalMap[this.chartKey] = this
    
        /// 保存函数的方式
        let self = this;
        globalMap[this.chartKey] = function(series){
        	///可以尽情访问vue组件的数据了
        };
    }
    
  • 结果
    在这里插入图片描述

完整代码:

<template>
	<div>
		<div>当前点击的系列是{{activeSeries}}</div>
		<div :id="chartKey" style="width:400px;height:300px;"></div>
	</div>
</template>

<script>
var echarts = require('echarts/lib/echarts');
require("echarts/lib/chart/line");
require("echarts/lib/component/grid");
require("echarts/lib/component/dataZoom");
require("echarts/lib/component/toolbox");
require("echarts/lib/component/tooltip");
require("echarts/lib/component/title");
require("echarts/lib/component/markLine");
require("echarts/lib/component/axisPointer");
require("echarts/lib/component/legendScroll");


/// 用于存放tooltip的点击回调函数的map,我们
let toolTipClickCallback = {

};

/// 真实的点击回调函数,内部实际上是调用的上面map中的函数
window.onClickSeries=function(series,chartkey)
{
	if(toolTipClickCallback[chartkey])
	{
		toolTipClickCallback[chartkey](series);
	}
}

export default {
	name:'tooltip-click',
	components:{},
	props:{
		chartKey:String,
	},
	data(){
		return {
			activeSeries:'',
		};
	},
	mounted(){
		let self = this;
		/// 这里在组件被挂在时初始化回调函数map,以当前组件key值作为key进行初始化
		/// 
		toolTipClickCallback[this.chartKey] = function(series)
		{
			console.log(series)
			self.activeSeries = series;
		}

		this.$nextTick(()=>
		{
			this.initToolTipClick();
		})
	},
	watch:{},
	methods:{
		initToolTipClick()
		{
			let self = this;
			let option = {
				xAxis: {
					type: 'category',
					data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
					axisPointer: {
								show: true,
					}
				},
				yAxis: {
					type: 'value'
				},
				series: [{
					name:'test1',
					data: [820, 932, 901, 934, 1290, 1330, 1320],
					type: 'line'
				},
				{
					name:'test2',
					data: [800, 900, 905, 935, 1005, 1307, 1320],
					type: 'line'
				}],
				tooltip:{
					enterable:true,
					trigger:'axis',
					transitionDuration: 2,
					formatter:function(param)
					{
						let ret="<div>";
						for(let i in param)
						{
							let toolTipData = param[i];
							ret += '<div style="text-align:left;" ><a href="javascript:void(0);" οnclick="onClickSeries(\''+toolTipData.seriesName+'\',\''+self.chartKey+'\')">'+ toolTipData.marker+toolTipData.seriesName +  
									'</a>:<span style="float:right;">' + toolTipData.data +'</span></div>';
						}
						ret+="</div>"
						return ret;
					}
				}
			};

			let dom = document.getElementById(this.chartKey);
			let chartInstance = echarts.init(dom);
			chartInstance.setOption(option);
		},
	},
}
</script>

小结

这个解决方案的思路就是:使用闭包访问外层作用域的数据

示例代码可以在github上找到https://github.com/luochanganz/Tick/blob/master/Web/VueDemo/src/components/echarts/ToolTipClick.vue

Logo

前往低代码交流专区

更多推荐