在使用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/blowingBreeze/Tick/blob/master/Web/demo/src/components/echarts/ToolTipClick.vue