亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

ECharts 事件系統

當我們的圖表變得越來越龐大之后,我們加入的組件也會越來越多,所以我們之后做的不單單只有 “看”這一個動作,還要有其他的動作,對應的就是一個個事件的處理,用戶操作觸發事件,我們則可以通過監聽事件并處理來完成一系列的事件操作,所以這一節我們就來從事件三要素,事件綁定,事件解綁這幾個方面去了解一下 ECharts 的事件系統。

1. 簡介

官方解釋:

在 ECharts 的圖表中用戶的操作將會觸發相應的事件。開發者可以監聽這些事件,然后通過回調函數做相應的處理,比如跳轉到一個地址,或者彈出對話框,或者做數據下鉆等等。更多細節可參考 官網

慕課解釋

ECharts 開放了兩套 API 體系,一是 ECharts 類接口實例的接口,例如常用的 echarts.init 方法、echartInstance.setOption();二是圍繞事件展開的動態交互接口,包括用于監聽事件的 echartInstance.on 函數和用于觸發行為的 echartInstance.dispatchAction 函數。

本文討論使用 echartInstance.on 接口實現的事件監聽功能。

2. 事件三要素

Dom Event 規范 類似,ECharts 通過事件名稱、事件源、事件參數三個要素精確描述何處執行了何種操作。在展開示例討論前,有必要簡單討論下 ECharts 事件三要素的含義。

2.1 事件名稱

ECharts 中存在兩種類型的事件,第一種是鼠標在圖形示例上的行為所觸發的鼠標事件,包括:

上述事件除 globalout 外,均與 DOM Event 規范 定義的同名事件有相同的語義、觸發條件。globalout 在鼠標移出圖表示例范圍時觸發。

第二種稱為行為事件,在組件、圖表狀態發生某種業務狀態遷移時觸發,包括:

事件名 適用組件 觸發時機
legendselectchanged legend 切換圖例選中狀態后的事件
legendselected legend 圖例選中后的事件
legendunselected legend 圖例取消選中后的事件
legendscroll legend 圖例滾動事件
datazoom datazoom 數據區域縮放后的事件
datarangeselected visualMap 視覺映射組件中,range 值改變后觸發的事件
timelinechanged timeline 時間軸中的時間點改變后的事件
timelineplaychanged timeline 時間軸中播放狀態的切換事件
dataviewchanged toolbox 工具欄中數據視圖的修改事件
magictypechanged toolbox 工具欄中動態類型切換的切換事件
brush brush 選框添加事件
globalcursortaken brush brush 組件捕獲鼠標 cursor 時觸發
brushselected brush 選框內容變更事件
geoselectchanged geo geo 中地圖區域切換選中狀態的事件
geoselected geo geo 中地圖區域選中后的事件
geounselected geo geo 中地圖區域取消選中后的事件
axisareaselected 平行坐標軸 平行坐標軸范圍選取事件
pieselectchanged 餅圖 餅圖扇形切換選中狀態的事件
pieselected 餅圖 餅圖扇形選中后的事件
pieunselected 餅圖 餅圖扇形取消選中后的事件
mapselectchanged 地圖 地圖區域切換選中狀態的事件
mapselected 地圖 地圖區域選中后的事件
mapunselected 地圖 地圖區域取消選中后的事件
focusnodeadjacency 連接圖 graph 圖鄰接節點高亮事件
unfocusnodeadjacency 連接圖 graph 的鄰接節點取消高亮事件
restore ECharts 實例 重置 option 事件
rendered ECharts 實例 渲染完成事件
finished ECharts 實例 同樣是渲染完成事件,當動畫或漸進渲染結束時觸發

上表只摘錄行為事件的關鍵部分,更詳細的介紹請參考 官網文檔。

行為事件的發生代表著組件實體內部狀態發生了某些變更,有兩種原因可能觸發行為事件:

  1. 用戶交互行為,例如圖例組件中,用戶通過鼠標點擊切換圖例開關時,ECharts 除觸發鼠標 click 事件外,還會觸發 legendselectchanged 行為事件;
  2. 接口調用,例如圖例組件中,調用 echartInstance.dispatchAction({ type: 'legendToggleSelect' }) 后也依然會觸發 legendselectchanged 行為事件。

2.2 事件源

事件源描述了觸發事件的主體,對于鼠標事件,事件源通常是行為發生時鼠標焦點所在圖形區域對應的圖表。所有類型的圖表都支持鼠標事件;部分組件支持觸發鼠標事件,但默認是關閉的,需要通過設置 triggerEvent: true 來啟動。組件對鼠標事件的支持情況如下:

  • 支持:titlexAxis ,yAxisradiusAxis ,angleAxisradar ,parallelAxis, singleAxis ,timeline,calendar;
  • 不支持: polar ,legend, grid ,datazoomvisualMap, tooltip, axisPointer, toolboxbrushgeo ,parallelgraphic

Tips:

graphic 是原生圖形組件,不支持echartInstance.on 接口,但可直接調用 element.onclick 等接口實現事件監聽。

行為事件由特定的組件、圖表觸發,例如 legendselectchanged 的事件源只能是 legend 組件,更多信息請參考 事件名稱 一節。

2.3 事件參數

事件參數描述事件發生時的上下文信息,ECharts中不同事件的參數信息相差極大,甚至同種事件在不同組件觸發時,回調參數也有差異。

2.3.1 鼠標事件參數

ECharts 鼠標事件,雖然名稱上與 DOM Event 規范 一致,但回調中傳遞的參數比標準相差很大。以 click 為例,DOM 的 click 事件參數是一個 MouseEvent 對象,主要屬性有:

{
	isTrusted: boolean,
	screenX: number,
	screenY: number,
	clientX: number,
	clientY: number,
	ctrlKey: boolean,
	shiftKey: boolean,
	altKey: boolean,
	metaKey: boolean,
	relatedTarget: object,
	pageX: number,
	pageY: number,
	x: number,
	y: number,
	offsetX: number,
  offsetY: number,
  ...
}

可以看出 DOM 的 click 事件參數詳細描述了點擊行為發生的位置、事件源的 dom、是否帶有快捷鍵、捕獲的階段等。而 ECharts 在 series 上發生的 click 事件帶有如下參數:

{
	// 當前點擊的圖形元素所屬的組件名稱,
	// 其值如 'series'、'markLine'、'markPoint'、'timeLine' 等。
	componentType: string,
	// 圖形元素所屬二級組件類型
	// 如 `bar`、`line`、`pie` 等
	componentSubType: string,
	componentIndex: number,
	// 系列類型。值可能為:'line'、'bar'、'pie' 等
	seriesType: string,
	// 系列在傳入的 option.series 中的 index
	seriesIndex: number,
	// 系列ID
	seriesId: string,
	// 系列名稱
	seriesName: string,
	// 數據名,類目名
	name: string,
	// 觸發事件的數據在data數組中的index
	dataIndex: number,
	// 觸發事件的數據所傳入的原始data值
	data: number,
	// sankey、graph 等圖表同時含有 nodeData 和 edgeData 兩種 data,
	// dataType 的值會是 'node' 或者 'edge',表示當前點擊在 node 還是 edge 上。
	// 其他大部分圖表中只有一種 data,dataType 無意義。
	dataType: string,
	// 傳入的數據值
	value: number | Array,
	// 數據圖形的顏色
	color: string,
	// 數據圖形的邊框色
	borderColor: undefined,
	// 數據圖形的維度信息
	dimensionNames: object,
	encode: object,
	// 標記信息的html內容
	marker: string,
	$vars: object,
	// 原始click事件參數
	event: object,
	// 事件名稱,本例中為 `click`
	type: string,
}

可以看出,ECharts 傳遞的 click 事件參數側重于描述發生點擊行為的圖形所對應的組件信息、狀態、配置,比如上例中的 componentType、componentSubType 指明單擊的組件類別、子類別;seriesType、seriesIndex、data 等指明單擊組件所對應的數據配置值;marker、encode 則指明單擊發生時,組件內部狀態信息。大多數情況下這些信息是足夠使用的,必要時也可以通過 event 屬性讀取原始 dom 事件參數。

需要注意的第二點是,即使是同種事件,不同組件所暴露的參數也是不一樣的,以 click 為例,在 series.bar 上觸發時有如下屬性:

componentTypecomponentSubType、componentIndex、seriesType、seriesIndex、seriesId、seriesName、name、dataIndex、data、dataType、value、color、borderColordimensionNames、encode、marker$vars、event、type

yAxis 則有:

componentTypecomponentIndex、yAxisIndextargetType、valueevent、type

title 上則是:

componentTypecomponentIndex、event、type

Tips
遺憾的是,官網并未就此給出詳細、完整的列表,建議開發時通過 console.logdebugger 等手段獲取各種組件所傳遞的事件參數。

2.3.2 行為事件參數

與鼠標事件參數一樣,行為事件也沒有提供一致的參數模型,不過官網提供了 明細說明,開發時建議前往查閱。

3. 監聽事件

ECharts 中可通過 echartInstance.on 函數綁定事件處理函數,on 函數簽名:

(eventName: string, query?: string|Object, handler: Function, context?: Object)

各參數說明:

參數名 類型 必選 說明
eventName string 指定監聽的事件名稱
query string|object 指定在特定的組件或者元素上響應 ,僅在鼠標事件中有效
handler function 事件回調函數
context object 回調函數執行時的 this 對象,默認為觸發事件的 ECharts 實例對象

3.1 全局監聽

若未提供 query 參數,ECharts 將不對事件源做任何過濾,相當于注冊了一個全局事件回調。例如:

實例演示
預覽 復制
復制成功!
<!DOCTYPE html>
<html lang="zh-CN">
	<head>
		<meta charset="utf-8" />
		<meta http-equiv="X-UA-Compatible" content="IE=edge" />
		<meta name="viewport" content="width=device-width,initial-scale=1.0" />
		<title>Echarts Example</title>
	</head>
	<body>
		<div id="main" style="width: 600px;height: 400px"></div>

		<script src="//cdn.bootcss.com/echarts/4.5.0/echarts.common.js"></script>
		<script type="text/javascript">
			const myChart = echarts.init(document.getElementById('main'));

			const option = {
				title: {
					text: 'test',
					// 通過 triggerEvent 顯式聲明
					// 該組件將觸發事件回調
					triggerEvent: true,
				},
				xAxis: {
					type: 'category',
					data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
					triggerEvent: true,
				},
				yAxis: {
					type: 'value',
					triggerEvent: true,
				},
				series: [
					{
						data: [820, 932, 901, 934, 1290, 1330, 1320],
						type: 'bar',
					},
				],
			};
			myChart.setOption(option);

			// 注冊 `click` 事件回調
			myChart.on('click', function (e) {
				console.log(`click invoke at ${e.componentType}`);
			});
		</script>
	</body>
</html>
運行案例 點擊 "運行案例" 可查看在線運行效果

示例效果:

圖片描述

Tips
需要注意,所謂的全局監聽并不是所有組件的交互行為都可以被監聽,對于鼠標事件,需要滿足如下條件:

  1. 組件本身支持鼠標交互事件,詳情可參考 2.2 事件源 一節。
  2. 組件啟用了鼠標事件功能,所有圖表默認啟用;其他組件則需要設置 triggerEvent: true 顯式聲明,如上例的 title、yAxisxAxis 組件。

在回調函數中,可以通過回調參數的 componentType、componentSubType 等屬性事件發生的具體位置,詳情可參考 2.3 事件參數 一節。

3.2 帶過濾條件的監聽

若提供了 query 參數,則 ECharts 在執行回調前,會先判斷事件源是否滿足過濾條件。 query 參數支持 string、object 兩種形式,當使用字符串時,內容格式可以是 mainType、mainType.subType 兩種形式,例如:

實例演示
預覽 復制
復制成功!
<!DOCTYPE html>
<html lang="zh-CN">
	<head>
		<meta charset="utf-8" />
		<meta http-equiv="X-UA-Compatible" content="IE=edge" />
		<meta name="viewport" content="width=device-width,initial-scale=1.0" />
		<title>Echarts Example</title>
	</head>
	<body>
		<div id="main" style="width: 600px;height: 400px"></div>
		<script src="//cdn.bootcss.com/echarts/4.5.0/echarts.common.js"></script>
		<script type="text/javascript">
			const myChart = echarts.init(document.getElementById('main'));
			const option = {
				xAxis: { type: 'category', data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] },
				yAxis: { type: 'value', min: 800 },
				series: [
					{ data: [820, 932, 901, 934, 1290, 1330, 1320], type: 'bar' },
					{ data: [920, 1032, 1001, 1034, 1390, 1430, 1420], type: 'line' },
				],
			};

			myChart.setOption(option);

			// 在所有 series 上都觸發
			myChart.on('click', 'series', function (e) {
				console.log(`series listener: click invoke at ${e.componentType}.${e.componentSubType}`);
			});

			// 只在 line 圖表上觸發
			myChart.on('click', 'series.line', function (e) {
				console.log(`line listener: click invoke at ${e.componentType}.${e.componentSubType}`);
			});
		</script>
	</body>
</html>
運行案例 點擊 "運行案例" 可查看在線運行效果

示例有兩個 click 回調,第一個指定過濾參數為 series,將在所有圖表發生單擊事件時執行回調;第二個指定過濾參數為 series.line,則只在折線圖發生單擊事件時觸發。示例效果:

圖片描述

query 還可以以對象方式傳入,對象可以包含如下屬性:

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

其中 mainType 為組件類型,如 seriesIndex、xAxisIndex 等。示例:

const option = {
	...
	series: [
		{ data: [820, 932, 901, 934, 1290, 1330, 1320], type: 'bar', name: 'series1' },
		{ data: [920, 1032, 1001, 1034, 1390, 1430, 1420], type: 'line', name: 'series2' },
	],
};

myChart.on(
	'click',
	// 在 series1 上觸發
	{seriesName:'series1'},
	function(e) {
	}
);

字符串與對象形式過濾的功能不同,字符串形式只能根據組件類型、子類型過濾;對象形式則精確到組件、數據項維度。繼續看看示例:

實例演示
預覽 復制
復制成功!
<!DOCTYPE html>
<html lang="zh-CN">
	<head>
		<meta charset="utf-8" />
		<meta http-equiv="X-UA-Compatible" content="IE=edge" />
		<meta name="viewport" content="width=device-width,initial-scale=1.0" />
		<title>Echarts Example</title>
	</head>
	<body>
		<div id="main" style="width: 600px;height: 400px"></div>

		<script src="//cdn.bootcss.com/echarts/4.5.0/echarts.js"></script>
		<script type="text/javascript">
			const myChart = echarts.init(document.getElementById('main'));

			const option = {
				grid: { triggerEvent: true },
				xAxis: {
					type: 'category',
					data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
				},
				yAxis: {
					type: 'value',
				},
				series: [
					{
						data: [820, 932, 901, 934, 1290, 1330, 1320],
						type: 'bar',
					},
				],
				title: { text: 'test' },
			};
			myChart.setOption(option);

			myChart.on('click', { dataIndex: 1 }, (e) => {
				console.log(`click invoke with data index: ${e.dataIndex}`);
			});
		</script>
	</body>
</html>
運行案例 點擊 "運行案例" 可查看在線運行效果

示例聲明過濾參數為 { dataIndex: 1 },則只會在數據項 1 上觸發,效果:

圖片描述

4. 解綁事件監聽

可通過 echartInstance.off 接觸事件綁定,函數簽名:

(eventName: string, handler?: Function)

handler 參數可選,若未提供該參數則解除所有 eventName 的事件監聽。

5. 個人經驗

ECharts 的事件系統設計的比較隱晦,有很多隱藏邏輯并沒有表現在官方文檔上,本文嘗試對事件系統做個全局的介紹,總結重點如下:

  1. ECharts 事件包括鼠標事件、交互事件兩種類型;
  2. 所有圖表組件都支持鼠標事件;部分組件支持鼠標事件,但需要設置 triggerEvent: true 顯式聲明啟動鼠標組件支持;
  3. 監聽函數 on 默認監聽實例上所有的組件,可通過 query 過濾事件源,不過 query 參數只對鼠標事件有效;
  4. 對于鼠標事件,種類型的事件在不同組件觸發時,事件參數不同,且目前官方未提供詳盡的說明文檔,只能又開發者自行摸索;
  5. 同一組件的所有鼠標事件的事件參數相同。

6. 小結

圖片描述
本節完整地介紹 Echarts 中事件系統的設計理念與用法,包括事件名稱、事件源、事件參數三類要素的意義;綁定、解綁事件的接口;官方事件,以及如何自定義事件等。