需求背景:點擊Echarts區域跳轉頁面,跳轉的區域不包括grid的坐標及標簽,翻看了Echarts官網,實現觸發事件之的on方法,但是此方法只能在鼠標點擊某個圖形上會觸發,這樣並不能實現需求。通過百度和查看github issue后多用Echarts實例的getZr()方法監聽到整個畫布的 click 事件。
使用echartsInstance.getZr().on('click' , params => {})監聽畫布,配合echartsInstance.containPixel('grid', pointInPixel) 方法判斷點擊位置是否在坐標系里面,從而解決需求問題。
但是getZr()官方文檔並沒解釋。所以下面將分享兩個點擊事件的場景,一:點擊某個圖形觸發點擊事件,二:點擊任意位置觸發點擊事件並且知道自己點擊的位置,處理折線不易點擊的情況。
一. 場景一 : 點擊圖形觸發點擊事件
1.echartsInstance.on()
鼠標點擊某個圖形上會觸發點擊事件使用on方法
圖形為折線上的折點,柱狀圖的柱子等等。折線,坐標軸的標簽,坐標軸內的空白位置是不會觸發點擊事件。

可選參數有:
參數一:事件名稱 eventName
eventName: string,//事件名稱,全小寫,例如'click','mousemove', 'legendselected'
參數二:過濾條件 query
query: string|Object,//可選的過濾條件,能夠只在指定的組件或者元素上進行響應。可為 string 或者 Object。
如果為 string 表示組件類型。格式可以是 'mainType' 或者 'mainType.subType'。例如:
chart.on('click', 'series', function () {...});
chart.on('click', 'series.line', function () {...});
chart.on('click', 'dataZoom', function () {...});
chart.on('click', 'xAxis.category', function () {...});
如果為 Object,可以包含以下一個或多個屬性,每個屬性都是可選的:
{
<mainType>Index: number // 組件 index
<mainType>Name: string // 組件 name
<mainType>Id: string // 組件 id
dataIndex: number // 數據項 index
name: string // 數據項 name
dataType: string // 數據項 type,如關系圖中的 'node', 'edge'
element: string // 自定義系列中的 el 的 name
}
例如:更多案例移步官網
chart.setOption({
// ...
series: [{
name: 'uuu'
// ...
}]
});
chart.on('mouseover', {seriesName: 'uuu'}, function () {
// series name 為 'uuu' 的系列中的圖形元素被 'mouseover' 時,此方法被回調。
});
參數三:事件處理函數 handler
handler: Function,//(params)=>{}
參數四: context
可選。回調函數內部的context,即this的指向。
2.鼠標事件參數:
通過參數獲取點擊位置的數據
鼠標事件的事件參數是 事件對象的數據 的各個屬性,通過參數獲取點擊位置的數據,對於圖表的點擊事件,基本參數如下,其它圖表諸如餅圖可能會有部分附加參數。例如餅圖會有percent屬性表示百分比,具體見各個圖表類型的 label formatter 回調函數的 params。
{
// 當前點擊的圖形元素所屬的組件名稱,
// 其值如 'series'、'markLine'、'markPoint'、'timeLine' 等。
componentType: string,
// 系列類型。值可能為:'line'、'bar'、'pie' 等。當 componentType 為 'series' 時有意義。
seriesType: string,
// 系列在傳入的 option.series 中的 index。當 componentType 為 'series' 時有意義。
seriesIndex: number,
// 系列名稱。當 componentType 為 'series' 時有意義。
seriesName: string,
// 數據名,類目名
name: string,
// 數據在傳入的 data 數組中的 index
dataIndex: number,
// 傳入的原始數據項
data: Object,
// sankey、graph 等圖表同時含有 nodeData 和 edgeData 兩種 data,
// dataType 的值會是 'node' 或者 'edge',表示當前點擊在 node 還是 edge 上。
// 其他大部分圖表中只有一種 data,dataType 無意義。
dataType: string,
// 傳入的數據值
value: number|Array,
// 數據圖形的顏色。當 componentType 為 'series' 時有意義。
color: string,
// 用戶自定義的數據。只在 graphic component 和自定義系列(custom series)
// 中生效,如果節點定義上設置了如:{type: 'circle', info: {some: 123}}。
info: *
}
場景二 . 任意位置觸發點擊事件:
echartsInstance.getZr().on('click' , params => {})監聽整個畫布的點擊事件。
參數params如下:
注意,不同版本的echarts參數不一樣,本次使用的是echarts@4.2.1

1.使用參數,知道點擊位置
- 通過參數對象中的target屬性和topTarget屬性進行定位位置
- 當點擊某個圖形元素:target對象中有dataIndex,seriesIndex屬性,即可知道點擊那個圖形元素。
- 當點擊grid內的空白位置:target對象為undefined,topTarget不為undefined。
- 當點擊坐標軸標簽:topTarget對象的anid值為"label_xx", xx為坐標值。
- 當點擊坐標軸外的空白位置:target對象和topTarget多為undefined。
因為官方並沒對getZr()方法進行解釋,所以只能觀察參數的差異去實現點擊的位置的獲取。
2.getZr()配合containPixel()方法判斷給定點的位置
echartsInstance.containPixel() 判斷給定的點是否在指定的坐標系或者系列上。
語法如下:
(
// finder 用於指示『在哪個坐標系或者系列上判斷』。
// 通常地,可以使用 index 或者 id 或者 name 來定位。
finder: {
seriesIndex?: number,
seriesId?: string,
seriesName?: string,
geoIndex?: number,
geoId?: string,
geoName?: string,
xAxisIndex?: number,
xAxisId?: string,
xAxisName?: string,
yAxisIndex?: number,
yAxisId?: string,
yAxisName?: string,
gridIndex?: number,
gridId?: string
gridName?: string
},
// 要被判斷的點,為像素坐標值,以 echarts 實例的 dom 節點的左上角為坐標 [0, 0] 點。
value: Array
) => boolean
目前支持在這些坐標系和系列上進行判斷:grid, polar, geo, series-map, series-graph, series-pie。
例:
// 判斷 [23, 44] 點是否在 geoIndex 為 0 的 geo 坐標系上。
chart.containPixel('geo', [23, 44]); // 'geo' 等同於 {geoIndex: 0}
// 判斷 [23, 44] 點是否在 gridId 為 'z' 的 grid 上。
chart.containPixel({gridId: 'z'}, [23, 44]);
// 判斷 [23, 44] 點是否在 index 為 1,4,5 的系列上。
chart.containPixel({seriesIndex: [1, 4, 5]}, [23, 44]);
// 判斷 [23, 44] 點是否在 index 為 1,4,5 的系列或者 gridName 為 'a' 的 grid 上。
chart.containPixel({seriesIndex: [1, 4, 5], gridName: 'a'}, [23, 44]);
getZr()配合containPixel()例子:
判斷點擊位置是否在grid中:(this.line為echartsInstance)
this.line.getZr().on('click', params => {
let pointInPixel = [params.offsetX, params.offsetY]
console.log(this.line.containPixel('grid', pointInPixel))
})
3.處理折線不易點擊的情況:
折現圖設置點擊事件時,只能點擊折點,有時並不容易點擊,可以配合axisPointer的shadow指示器方便點擊。

this.line.getZr().on('click', params => {
const pointInPixel = [params.offsetX, params.offsetY]
// 使用 convertFromPixel方法 轉換像素坐標值到邏輯坐標系上的點。獲取點擊位置對應的x軸數據的索引 值,借助於索引值的獲取到其它的信息
let pointInGrid = this.line.convertFromPixel({ seriesIndex: 0 }, pointInPixel)
// x軸數據的索引值
let xIndex = pointInGrid[0]
// 使用getOption() 獲取圖表的option
let op = this.line.getOption()
// 獲取當前點擊位置要的數據
var xData = op.series[0].data[xIndex]
})
注:
echartsInstance.convertFromPixel()方法:鏈接。
echartsInstance.getOption()方法:鏈接。
