在以前的學習中,咱們已經能夠繪製各類類型的圖表,也能夠給圖表添加不一樣的組件,如標題、圖例等等。但這些圖表只能用於展現數據,一旦但願對圖表有所操做——好比查看數據明細——就顯得一籌莫展了。其實jqPlot是提供了圖表事件交互功能的,且實現起來,也至關的簡單。接下來咱們要作的就是,學習若是監聽圖表事件,並對事件進行處理。javascript
在jqPlot的源碼中,咱們可以看到這樣的代碼片斷:
css
** * Class: jqPlot * Plot object returned by call to $.jqplot. Handles parsing user options, * creating sub objects (Axes, legend, title, series) and rendering the plot. */ function jqPlot() { ...其它代碼 // 方法:draw // 繪製全部的塊節點到圖表容器中,繪製以前不會清空容器 this.draw = function(){ ...其它代碼 // 給註冊的事件綁定事件處理器 this.bindCustomEvents(); ...其它代碼 } ...其它代碼 this.bindCustomEvents = function() { // 給圖表容器(指chart1這個div)綁定點擊事件處理函數,其它相似 this.eventCanvas._elem.bind('click', {plot:this}, this.onClick); this.eventCanvas._elem.bind('dblclick', {plot:this}, this.onDblClick); this.eventCanvas._elem.bind('mousedown', {plot:this}, this.onMouseDown); this.eventCanvas._elem.bind('mousemove', {plot:this}, this.onMouseMove); this.eventCanvas._elem.bind('mouseenter', {plot:this}, this.onMouseEnter); this.eventCanvas._elem.bind('mouseleave', {plot:this}, this.onMouseLeave); if (this.captureRightClick) { this.eventCanvas._elem.bind('mouseup', {plot:this}, this.onRightClick); this.eventCanvas._elem.get(0).oncontextmenu = function() { return false; }; } else { this.eventCanvas._elem.bind('mouseup', {plot:this}, this.onMouseUp); } }; // 點擊事件處理函數,另有其它如onDblClick、onMouseDown、onMouseMove等 this.onClick = function(ev) { // 傳入標準化的Event對象,會攜帶一些數據屬性 // 傳出非標準化Event對象 var positions = getEventPosition(ev); var p = ev.data.plot; var neighbor = checkIntersection(positions.gridPos, p); // 獲取jqplotClick事件 var evt = $.Event('jqplotClick'); evt.pageX = ev.pageX; evt.pageY = ev.pageY; // 關鍵代碼,觸發jqplotClick事件,並傳遞一些數據 $(this).trigger(evt, [positions.gridPos, positions.dataPos, neighbor, p]); }; ...其它代碼 }
能夠看出,咱們不能直接給畫布綁定一些諸如click、mouseover之類的常規事件。若是要處理這些事件,咱們要作的應該是綁定jqplotClick事件,當咱們觸發點擊事件時,圖表會自動幫咱們觸發畫布的jqplotClick事件。所以,要處理圖表點擊事件,咱們只須要添加以下代碼便可:
html
$('#chart1').on('jqplotClick', function(){ // 事件處理代碼 });
咱們先來繪製一個簡單的線形圖表,在此圖表上添加相關的交互事件:
java
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>圖表事件交互</title> <link rel="stylesheet" type="text/css" href="js/jqPlot/1.0.4/jquery.jqplot.min.css"/> <!--[if lt IE 9]> <script language="javascript" type="text/javascript" src="js/jqPlot/1.0.4/excanvas.js"></script> <![endif]--> <script src="http://libs.baidu.com/jquery/1.8.2/jquery.min.js"></script> <script src="js/jqPlot/1.0.4/jquery.jqplot.min.js" type="text/javascript"></script> <script type="text/javascript" charset="utf-8"> $(function(){ $.jqplot('chart1', [[75, 69, 71, 77, 76, 81, 73]]); // 如前所述,添加事件處理 $('#chart1').on('jqplotClick', function(){ alert('圖表點擊事件被觸發...'); }); }); </script> </head> <body> <div id="chart1" style="width: 800px;height: 400px;"> <!-- 描述:圖表展現區域 --> </div> </body> </html>
在此圖表上,咱們點擊任何位置,均可以看到以下結果:
jquery
雖然前面的代碼已經能夠處理圖表的一些事件,但對於一個應用程序來講,沒有數據是沒有多大意義的。上面的事件處理,咱們沒法從事件中取得任何數據,所以事件觸發時所能作的也就有限。可是若是仔細觀察前面this.onClick函數,咱們不難發現,在觸發jqplotClick事件時,實際上是有數據傳遞給事件的:
canvas
$(this).trigger(evt, [positions.gridPos, positions.dataPos, neighbor, p]);
在這行代碼的前面,咱們能夠知道這些傳遞的數據到底是什麼意思。其中,position.gridPos是指鼠標點擊位置相對於整個Grid對象的座標位置,它是一個點對象,包含x和y兩個屬性;position.dataPos表示鼠標點擊位置在數據區域所對應各個軸的取值,它也是一個對象,不過包含的屬性則爲xaxis、x2axis、yaxis、y2axis、y3axis、y4axis、y5axis、y6axis、y7axis、y8axis、y9axis以及yMidAxis;neighbor則爲事件源數據,這裏爲空;參數p則爲觸發事件的圖表對象。
數組
有了這些數據,咱們就能夠在事件處理函數中使用它們。使用方法也很簡單,只須要給四個參數到事件處理函數,這些數據就會自動注入到各個參數中。以下:
函數
// 第一個參數是Event對象,其他四個參數分別對應position.gridPos、position.dataPos、neighbor和p $('#chart1').on('jqplotClick', function(ev, gridpos, datapos, neighbor, plot){ plot.replot({ seriesDefaults:{ color:'#ff0000' } }); });
如上,當咱們再去點擊圖表時,圖表中的數據線段就會變成紅色,以下圖效果:
學習
假設咱們的頁面中有若干個圖表,咱們可使用這種方式,去模擬圖表選中效果。固然,合理的應用事件傳遞的數據,還能作出其餘更多更好的效果。this
在大多數狀況下,當咱們真的有需求要處理圖表的點擊事件時,一般咱們但願可以處理被點的數據點而非整個圖表。同時在處理點擊數據點的事件時,咱們確定也但願可以從點擊事件中知道,當前點擊的究竟是哪一個數據點,這個數據點的取值是什麼。先來看一張圖表:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>圖表事件交互</title> <link rel="stylesheet" type="text/css" href="js/jqPlot/1.0.4/jquery.jqplot.min.css"/> <!--[if lt IE 9]> <script language="javascript" type="text/javascript" src="js/jqPlot/1.0.4/excanvas.js"></script> <![endif]--> <script src="http://libs.baidu.com/jquery/1.8.2/jquery.min.js"></script> <script src="js/jqPlot/1.0.4/jquery.jqplot.min.js" type="text/javascript"></script> <script src="js/jqPlot/1.0.4/plugins/jqplot.pointLabels.min.js" type="text/javascript"></script> <script type="text/javascript" charset="utf-8"> $(function(){ var chart = $.jqplot('chart1', [[75, 69, 71, 77, 76, 81, 73]], { title:'《jqPlot圖表插件使用說明》日閱讀數趨勢圖', axes:{ // 具體座標軸屬性 xaxis:{ label:'日期', ticks:[[0,'06/22'], [1,'06/23'], [2,'06/24'], [3,'06/25'], [4,'06/26'], [5,'06/27'], [6,'06/28'], [7,'06/29'], [8,'06/30'] ] }, yaxis: { label: '閱讀數' } }, seriesDefaults:{ pointLabels: { // 顯示數據點,依賴於jqplot.pointLabels.min.js文件 show: true } } }); $('#chart1').on('jqplotDataClick', function(ev, gridpos, datapos, neighbor, plot){ // 事件處理代碼 }); }); </script> </head> <body> <div id="chart1" style="width: 800px;height: 400px;"> <!-- 描述:圖表展現區域 --> </div> </body> </html>
效果圖:
在這張圖表中,數據表示的是博客《jqPlot圖表插件使用說明》的每日閱讀數趨勢。能夠看出,6月23日閱讀人數是75次,6月24日是69次等等。在實際業務需求中,更大多是在點擊75這個點的時候,咱們要展現這75個讀者的詳細列表,查看他們究竟是哪些讀者。這個時候,咱們就得在事件處理中,判斷點擊的是哪個點,這個點對應的日期是哪天。顯然,若是隻是給圖表綁定點擊事件,這種數據是沒法取到的。
這個時候就要關注更爲精細的交互了。除了圖表總體的交互事件,jqPlot還能夠在數據序列上註冊事件。與圖表事件不一樣的是,只有鼠標點擊在數據節點上時,事件纔會被觸發。另外,與圖表事件相比,數據序列上的事件名稱會也不一樣,一般以「jqplotData」開頭,後接事件類型。如jqplotDataClick、jqplotDataMouseover等等;數據序列中事件處理函數接收到的參數含義也有區別,第一個參數gridPos是指被點擊的數據點在當前網格中的下標。單條線的圖表取值都是0,只有當同時存在多條線時,才能分辯出來。dataPos是指被點擊的數據點在全部數據點中的位置下標,好比途中點擊第一個點75時,dataPos就是0,點擊69時,dataPos就是1,依此類推。neighbor則保存着被點的數據點的數據信息,它是一個數組,其中第一個元素是ticks的下標,第二個元素是該點對應的值,好比第一個點的值是75。最後一個參數plot仍表明當前點擊圖表對象,但在點擊序列點時,貌似沒有傳入這個參數,因此會是undefined。
如上代碼中是監聽數據序列的點擊事件,稍做修改以下:
$('#chart1').on('jqplotDataClick', function(ev, gridpos, datapos, neighbor, plot){ // 獲取標籤下標 var tickIndex = neighbor[0]; // 獲取標籤值(日期) var date = chart.axes.xaxis.ticks[tickIndex][1]; // 拼接查詢url var url = 'getReaders.action?date=' + encodeURIComponent(date); // 跳轉url window.location.href = url; });
這樣,咱們就只須要根據傳遞的日期,在getReader.action中處理請求,展現數據便可: