折線圖和直條圖範例
繪圖用到的檔案
製綜合圖(折線和直條圖)時,所有需要的檔案清單如下.<script type="text/javascript" src="/js/jquery-1.8.3.min.js"></script> <!--[if lte IE 8]><script language="javascript" type="text/javascript" src="/js/flot/excanvas.min.js"></script><![endif]--> <script type="text/javascript" src="/js/flot/jquery.flot.js"></script> <script type="text/javascript" src="/js/flot/jquery.flot.time.js"></script> <script type="text/javascript" src="/js/flot/jquery.flot.axislabels.js"></script> <script type="text/javascript" src="/js/flot/jquery.flot.symbol.js"></script>
建立資料
這個範例用了氣象數據當資料,有溫度、風速及大氣壓力.一開始我們先建立3個陣列變數分別代表為溫度、風速及大氣壓力,接著再插入資料,x軸我們用的是時間格式資料,我們建立了一個自訂函式gd(),用來取得timestamps,而y軸就是氣象數據資料.//temp var data1 = [ [gd(2012, 1, 1), 1], [gd(2012, 1, 2), -2], [gd(2012, 1, 3), -2], [gd(2012, 1, 4), 1], [gd(2012, 1, 5), 3], [gd(2012, 1, 6), 4], [gd(2012, 1, 7), 5], [gd(2012, 1, 8), 6], [gd(2012, 1, 9), 7], [gd(2012, 1, 10), 7], [gd(2012, 1, 11), 6], [gd(2012, 1, 12), 7], [gd(2012, 1, 13), 8], [gd(2012, 1, 14), 8], [gd(2012, 1, 15), 3], [gd(2012, 1, 16), 2], [gd(2012, 1, 17), 4], [gd(2012, 1, 18), -1], [gd(2012, 1, 19), 5], [gd(2012, 1, 20), 6], [gd(2012, 1, 21), -2], [gd(2012, 1, 22), -7], [gd(2012, 1, 23), -9], [gd(2012, 1, 24), -8], [gd(2012, 1, 25), -7], [gd(2012, 1, 26), -6], [gd(2012, 1, 27), -3], [gd(2012, 1, 28), 1], [gd(2012, 1, 29), 6], [gd(2012, 1, 30), 9], [gd(2012, 1, 31), 8] ]; //wind var data2 = [ [gd(2012, 1, 1), 11], [gd(2012, 1, 2), 9], [gd(2012, 1, 3), 7], [gd(2012, 1, 4), 13], [gd(2012, 1, 5), 11], [gd(2012, 1, 6), 11], [gd(2012, 1, 7), 9], [gd(2012, 1, 8), 10], [gd(2012, 1, 9), 7], [gd(2012, 1, 10), 11], [gd(2012, 1, 11), 7], [gd(2012, 1, 12), 6], [gd(2012, 1, 13), 4], [gd(2012, 1, 14), 5], [gd(2012, 1, 15), 11], [gd(2012, 1, 16), 8], [gd(2012, 1, 17), 9], [gd(2012, 1, 18), 16], [gd(2012, 1, 19), 11], [gd(2012, 1, 20), 18], [gd(2012, 1, 21), 8], [gd(2012, 1, 22), 17], [gd(2012, 1, 23), 11], [gd(2012, 1, 24), 13], [gd(2012, 1, 25), 11], [gd(2012, 1, 26), 11], [gd(2012, 1, 27), 9], [gd(2012, 1, 28), 8], [gd(2012, 1, 29), 7], [gd(2012, 1, 30), 8], [gd(2012, 1, 31), 20] ]; //sea level pressure var data3 = [ [gd(2012, 1, 1), 1012], [gd(2012, 1, 2), 1018], [gd(2012, 1, 3), 1020], [gd(2012, 1, 4), 1016], [gd(2012, 1, 5), 1022], [gd(2012, 1, 6), 1023], [gd(2012, 1, 7), 1029], [gd(2012, 1, 8), 1030], [gd(2012, 1, 9), 1029], [gd(2012, 1, 10), 1034], [gd(2012, 1, 11), 1034], [gd(2012, 1, 12), 1023], [gd(2012, 1, 13), 1022], [gd(2012, 1, 14), 1026], [gd(2012, 1, 15), 1027], [gd(2012, 1, 16), 1023], [gd(2012, 1, 17), 1019], [gd(2012, 1, 18), 1032], [gd(2012, 1, 19), 1029], [gd(2012, 1, 20), 1017], [gd(2012, 1, 21), 1015], [gd(2012, 1, 22), 1017], [gd(2012, 1, 23), 1023], [gd(2012, 1, 24), 1024], [gd(2012, 1, 25), 1024], [gd(2012, 1, 26), 1022], [gd(2012, 1, 27), 1031], [gd(2012, 1, 28), 1023], [gd(2012, 1, 29), 1019], [gd(2012, 1, 30), 1008], [gd(2012, 1, 31), 993] ]; function gd(year, month, day) { return new Date(year, month - 1, day).getTime(); }
另外在WindSpeed資料物件裡,因為我們要用折線圖呈現,所以設定lines.show為true,另外也設定了資料點的屬性points.symbol為"triangle",表示資料點符號為三角形,以及points.fillColor表示資料點要以什麼顏色填滿.而Temperature與Wind Speed資料物件設定是一樣的.我們還在3組資料物件裡都設定了不同的color屬性,這樣這3組資料就會以不同顏色呈現.
最後也是最重要的,因為我們要在一張圖表裡放上3組資料,所以y軸會出現3組刻度,這時就需要設定yaxis屬性,在WindSpeed資料物件裡可以看到我們設定了yaxis:2,表示WindSpeed是屬於y軸第2組的,而Temperature資料物件裡我們設定了yaxis:3,表示Temperature是屬於y軸第3組的,不過,再回頭去看Sea Level Pressure資料物件裡我們並沒有設定yaxis屬性,這是因為Sea Level Pressure是屬於y軸第1組的,若是第1組的則可以省略.yaxis屬性跟等下我們要講到的圖表選項有很大的關係,下面會提到.
完整的dataset程式碼如下.
var dataset = [ { label: "Sea Level Pressure", data: data3, color: "#756600", bars: { show: true, align: "center", barWidth: 24 * 60 * 60 * 600, lineWidth:1 } }, { label: "Wind Speed", data: data2, yaxis: 2, color: "#0062FF", points: { symbol: "triangle", fillColor: "#0062FF", show: true }, lines: {show:true} }, { label: "Temperature", data: data1, yaxis: 3, color: "#FF0000", points: { symbol: "circle", fillColor: "#FF0000", show: true }, lines: { show: true } } ];
建立圖表選項
由於我們x軸是時間格式資料,所以xaxis.mode必須設定為"time",而xaxis.tickSize: [3, "day"]是表示刻度是以每3天的間隔顯示,另外因為這範例中會出現直條圖,所以我們設定xaxis.tickLength為0,讓x軸的刻度線不要顯示,接著xaxis.axisLabel則是軸標籤的屬性,最後再設定xaxis.color為"black",讓刻度標籤以黑色顯示.xaxis: { mode: "time", tickSize: [3, "day"], tickLength: 0, axisLabel: "Date", axisLabelUseCanvas: true, axisLabelFontSizePixels: 12, axisLabelFontFamily: 'Verdana, Arial', axisLabelPadding: 10, color: "black" }
一般來說只有1組資料的圖表,只會有一個y軸刻度,如果我們要設定y軸的選項,就會用yaxis:{},而在這個範例裡,我們用了3組資料,所以會出現3個y軸刻度,如果要設定y軸的選項時就必須改用yaxes:[]來代替,而陣列中的第一個物件就代表在dataset裡yaxis:1的對應,第二個物件就代表在dataset裡yaxis:2的對應,依此類推.
預設y軸的刻度標籤都會出現在圖表的左邊,但這次我們有3個y軸的刻度標籤,都顯示在左邊會造成使用者在看圖表時的不易解讀,所以我們要把2個刻度標籤移到右邊去,要達到這樣的效果可以設定axis.position,可用的值有"left"和"right",另外我們也設定了axis.color為"black",讓刻度標籤的文字都以黑色顯示,當然我們還另外設定了軸標籤(axisLabel).
最後我們在第一個物件裡設定了max:1070,因為這物件是Sea Level Pressure的直條圖,如果沒設定最大值的話,直條圖就會和其它2個折線圖重疊,造成圖表不易解讀,所以我們設定了1070讓直條圖保持顯示在中間下方的地方,這樣圖表就會清爽多了.
y軸選項的程式碼如下.
yaxes: [ //yaxis:1 { position: "left", max: 1070, color: "black", axisLabel: "Sea Level Pressure (hPa)", axisLabelUseCanvas: true, axisLabelFontSizePixels: 12, axisLabelFontFamily: 'Verdana, Arial', axisLabelPadding: 3 }, //yaxis:2 { position: "right", clolor: "black", axisLabel: "Wind Speed (km/hr)", axisLabelUseCanvas: true, axisLabelFontSizePixels: 12, axisLabelFontFamily: 'Verdana, Arial', axisLabelPadding: 3 }, //yaxis:3 { position: "right", color: "black", axisLabel: "Temperature (°C)", axisLabelUseCanvas: true, axisLabelFontSizePixels: 12, axisLabelFontFamily: 'Verdana, Arial', axisLabelPadding: 3 } ]
網格的部份,我們設定了grid.hoverable為true,因為我們有使用提示框的功能,設定hoverable後,"plothover"事件才會被觸發,提示框才會在我們滑鼠移過資料點時顯示.而grid.borderWidth則是圖表邊框的寬度,grid.backgroundColor則是設定背景顏色.
legend: { noColumns: 1, labelBoxBorderColor: "#000000", position: "nw" } grid: { hoverable: true, borderWidth: 3, backgroundColor: { colors: ["#ffffff", "#EDF5FF"] } }
建立資料點提示框
提示框的作用是當你把滑鼠移到圖表上的資料點時,提示框會顯示該資料點的詳細資料,如x軸數值或y軸數值等,Flot的提示框必須自己實作出來.首先我們必須綁定"plothover"事件,此事件會傳入item物件,而我們所需要用到的資料都可以從這物件裡抓出來,如item.series.label可抓出該資料點的標籤名稱,而item.datapoint可抓出x及y軸的數值等等,詳細的提示框程式碼如下.
var previousPoint = null, previousLabel = null; $.fn.UseTooltip = function () { $(this).bind("plothover", function (event, pos, item) { if (item) { if ((previousLabel != item.series.label) || (previousPoint != item.dataIndex)) { previousPoint = item.dataIndex; previousLabel = item.series.label; $("#tooltip").remove(); var x = item.datapoint[0]; var y = item.datapoint[1]; var color = item.series.color; var date = "Jan " + new Date(x).getDate(); var unit = ""; if (item.series.label == "Sea Level Pressure") { unit = "hPa"; } else if (item.series.label == "Wind Speed") { unit = "km/hr"; } else if (item.series.label == "Temperature") { unit = "°C"; } showTooltip(item.pageX, item.pageY, color, "" + item.series.label + "
" + date + " : " + y + " " + unit + ""); } } else { $("#tooltip").remove(); previousPoint = null; } }); }; function showTooltip(x, y, color, contents) { $('<div id="tooltip">' + contents + '</div>').css({ position: 'absolute', display: 'none', top: y - 40, left: x - 120, border: '2px solid ' + color, padding: '3px', 'font-size': '9px', 'border-radius': '5px', 'background-color': '#fff', 'font-family': 'Verdana, Arial, Helvetica, Tahoma, sans-serif', opacity: 0.9 }).appendTo("body").fadeIn(200); }
完成繪圖
最後我們再呼叫$.plot把上面建立的dataset以及options帶入,再呼叫UseTootip()後,整個繪圖即完成.本範例完整的javascript程式碼可以在這裡下載,有興趣的可以下載回去研究看看.$(document).ready(function () { $.plot($("#flot-placeholder"), dataset, options); $("#flot-placeholder").UseTooltip(); });