在最近的BS新項目中須要用到繪圖數據顯示的功能。在進行充足的選擇以後決定纔去開源的Flot。Flot是一個jQuery繪圖庫。主要用於簡單的繪製圖表功能。具備吸引人的渲染外觀和互操做的特性。其在Internet Explorer 6+, Chrome, Firefox 2+, Safari 3+ and Opera 9.5+瀏覽器下工做正常。目前的版本是Version0.8.3. 如下是相關連接。在官網的example中展現出了flot能夠繪製的樣例,而且我想這些樣例的源代碼也許是你們如何學習flot的最快的方法吧。嘿嘿。這裏有一點要注意的地方: 在文檔中都用plot來代替Flot,做者給出了回答瞬間無語。javascript
First: it's pronounced with a short o, like "plot". Not like "flawed".css
So "Flot" rhymes with "plot".html
And if you look up "flot" in a Danish-to-English dictionary, some of the words that come up are "good-looking", "attractive", "stylish", "smart", "impressive", "extravagant". One of the main goals with Flot is pretty looks.java
官網jquery
GitHubgit
和其餘jquery庫同樣,咱們只須要在html文檔的末尾的jquery庫的後面引入便可。這裏要注意的是咱們的瀏覽器必須支持HTML5 canvas標籤。爲了兼容IE9。咱們可使用canvas模擬庫Excanvas來實現。咱們在官網的demo中也能夠發現以下的引入方式。 github
1 <!--[if lte IE 8]><script language="javascript" type="text/javascript" src="excanvas.min.js"></script><![endif]--> 算法
在這裏要說明IE6是不被支持的。Excanvas實現仿真繪圖的原理是依賴VML矢量標記語言。另外咱們也能夠嘗試着使用Flashcanvas庫來經過Flash實現仿真。儘管Flash對比VML加載起來會顯得慢一點,可是當在繪製不少點的圖時,Flash版本在總體的加載上會更加的快。在jquery庫的要求上至少是須要jquery1.2.6。數據庫
建立一個佔位div來放置繪出來的圖:express
1 <div id="placeholder"></div>
在這裏咱們只須要簡單的設置div的id,plot將會修改不少屬性來呈現繪製的圖像。咱們無需本身設置該div的樣式,好比在IE7下若是設置該div的背景圖就會引起問題。
而後咱們須要設置placeholder的高度和寬度,由於plot庫不知道如何繪製圖的大小。這裏咱們採起直接在html中定義css:
1 <div id="placeholder" style="width:600px;height:300px"></div>
同時你也能夠在外部的stylesheet中定義大小,確保該div placeholder沒有被display:none來標記,這樣可能會致使混亂的結果。
而後在js中運行以下方法:
1 var plot = $.plot(placeholder, data, options)
咱們來看看這三個參數和plot對象
這裏是一個簡單的例子:
1 $.plot($("#placeholder"), [ [[0, 0], [1, 1]] ], { yaxis: { max: 1 } });
[series1, series2, ...]
這一系列的數據便可是原始的二維座標點數組(內部x和y值必須爲數字--咱們在從數據庫檢索出數據序列化爲JSON提交至前臺時要注意數據格式,若是發生一些神祕錯誤請確保你的輸入數據爲數字類型而不是字符串類型),也能夠是一個對象的屬性。
當輸入進去的座標值爲空或者不能轉換成爲數字,那麼該數據點就不予以繪製出。存在一個特殊的例子即若是繪製一條線時遇到座標爲空的點則該點將成爲這條繪製線的截至點。後面的點將不能和前面的點相連。咱們能夠指定第三個座標值來設置繪製線或者柵欄下方填充的面積值(默認是0);
1 var d1 = []; 2 for (var i = 0; i < 14; i += 0.5) { 3 d1.push([i, Math.sin(i)]); 4 } 5 6 var d2 = [[0, 3], [4, 8], [8, 5], [9, 13]]; 7 8 // A null signifies separate line segments 9 10 var d3 = [[0, 12], [7, 12], null, [7, 2.5], [12, 2.5]]; 11 12 $.plot("#placeholder", [ d1, d2, d3 ]);
獲得的效果是這樣的
紅線處存在斷截。
對於數據爲對象類型時應當知足以下格式內容:
1 { 2 color: color or number 3 data: rawdata 4 label: string 5 lines: specific lines options 6 bars: specific bars options 7 points: specific points options 8 xaxis: number 9 yaxis: number 10 clickable: boolean 11 hoverable: boolean 12 shadowSize: number 13 highlightColor: color or number 14 }
下面我來一一介紹以上的屬性:
color: 繪製出來的圖中線條或者柱狀的顏色,若是不指定將自動生成格式爲CSS color規則的顏色值。
data: 爲繪製的座標點的值。
label: 用來指示圖中該段數據對應的名字,如「Line1」。
lines: 設置若是繪圖爲折線圖時的相關屬性,如show, fill, fillColor等
bars: 設置如何繪圖爲柱狀圖時的相關屬性, 如show, fill, fillColor等
points: 設置繪圖中的每一個點的相關屬性,如形狀(默認爲circle)還有半徑大小
xaxis, yaxis: 這兩屬性的意思是對應的該條折線或者柱子所採用的座標軸,默認爲一,若是不設定則全部的數據都採用相同一個座標軸,若是設置其餘值(2~n)則採用圖像上顯示的第n個座標軸顯示。以下圖所示:
(d2採用的座標軸爲外圍的座標軸)
clickable, hoverable: 用來設置互操做的屬性,取值爲bool類型。相似事件機制。false則靜止該點的互操做功能。
shadowSize: 該段線條的陰影大小。爲阿拉伯數字
highlightColor: 選擇高亮的顏色。
每一個字段都存在一個默認值。若是咱們對其須要的屬性進行再賦值則覆蓋掉默認值如:
1 [ { label: "Foo", data: [ [10, 1], [17, -14], [30, 5] ] }, { label: "Bar", data: [ [11, 13], [19, 11], [30, -7] ] } ]
以下是數據爲對象時的例子:(options設置爲空)
1 ar d1 = []; 2 for (var i = 0; i < 14; i += 0.5) { 3 d1.push([i, Math.sin(i)]); 4 } 5 6 var d2 = [[0, 3], [4, 8], [8, 5], [9, 13]]; 7 8 var d3 = []; 9 for (var i = 0; i < 14; i += 0.5) { 10 d3.push([i, Math.cos(i)]); 11 } 12 13 var d4 = []; 14 for (var i = 0; i < 14; i += 0.1) { 15 d4.push([i, Math.sqrt(i * 10)]); 16 } 17 18 var d5 = []; 19 for (var i = 0; i < 14; i += 0.5) { 20 d5.push([i, Math.sqrt(i)]); 21 } 22 23 var d6 = []; 24 for (var i = 0; i < 14; i += 0.5 + Math.random()) { 25 d6.push([i, Math.sqrt(2*i + Math.sin(i) + 5)]); 26 } 27 28 $.plot("#placeholder", [{ 29 data: d1, 30 lines: { show: true, fill: true } 31 }, { 32 data: d2, 33 bars: { show: true } 34 }, { 35 data: d3, 36 points: { show: true } 37 }, { 38 data: d4, 39 lines: { show: true } 40 }, { 41 data: d5, 42 lines: { show: true }, 43 points: { show: true } 44 }, { 45 data: d6, 46 lines: { show: true, steps: true } 47 }]);
注意:咱們便可以在每一個data集合中單獨的設置以上的屬性來實現每一個折線或者條形柱的不一樣之處,同時也能夠在option的統一設置中來集體設置以上相關屬性。
全部的選項都是徹底可選擇的,咱們能夠單獨的在文檔中定義option對象,而後在$.plot方法中傳入option值:
1 var options = { 2 series: { 3 lines: { show: true }, 4 points: { show: true } 5 } 6 }; 7 8 $.plot(placeholder, data, options);
在options內部有不少屬性。如下咱們一一來講明:
legend屬性是來定義折線圖的label標籤信息屬性
1 legend: { 2 show: boolean 3 labelFormatter: null or (fn: string, series object -> string) 4 labelBoxBorderColor: color 5 noColumns: number 6 position: "ne" or "nw" or "se" or "sw" 7 margin: number of pixels or [x margin, y margin] 8 backgroundColor: null or color 9 backgroundOpacity: number between 0 and 1 10 container: null or jQuery object/DOM element/jQuery expression 11 sorted: null/false, true, "ascending", "descending", "reverse", or a comparator 12 }
show:設置是否顯示該label,
labelFormatter: 設置點擊該label對應的事件。舉例以下:
labelFormatter: function(label, series){ //alert(label); return '<a href="#' + label + '">' + label + '</a>'; }
labelBoxBorderColor: 設置label的邊框顏色。
noColumns: 設定圖中的label組排成多少列,默認爲1.則代表每行只排列一個label.設置爲n則每行排列n個label. 以下是noColumns:2的狀況。
Position: 有4個選項"ne", "nw", "se", "sw"分別表示將label組顯示在 ↗, ↖, ↘, ↙。
margin: 設置其與繪圖div邊緣的距離,能夠像素值表示,也可用[x margin, y margin]表示。 如[50,50]
backgroundColor與backgroundOpacity:設置label塊的背景顏色顏色值。默認是透明色。
container:
sorted: 容許設置爲null/false/true/"ascending"/"descending"/"reverse"/function(). 默認label的排序是經過默認的series數組內部的序列號來排序的。如上d2的data在d1的data前push進數組,因此d2顯示在前面。"reverse":顛倒默認的排序。 "descending": 按照label名字降序排列。true&"ascending":按照label的名字的升序排列。 false&null: 按照默認排列。同時咱們還能自定義排序內部比較方法經過傳遞兩個data對象來對比其label或者color.以下是一個例子:看過排序算法的應該理解很少說了。
1 sorted: function(a, b) { 2 // sort alphabetically in ascending order 3 return a.label == b.label ? 0 : ( 4 a.label > b.label ? 1 : -1 5 ) 6 }
1 xaxis, yaxis: { 2 show: null or true/false 3 position: "bottom" or "top" or "left" or "right" 4 mode: null or "time" ("time" requires jquery.flot.time.js plugin) 5 timezone: null, "browser" or timezone (only makes sense for mode: "time") 6 7 color: null or color spec 8 tickColor: null or color spec 9 font: null or font spec object 10 11 min: null or number 12 max: null or number 13 autoscaleMargin: null or number 14 15 transform: null or fn: number -> number 16 inverseTransform: null or fn: number -> number 17 18 ticks: null or number or ticks array or (fn: axis -> ticks array) 19 tickSize: number or array 20 minTickSize: number or array 21 tickFormatter: (fn: number, object -> string) or string 22 tickDecimals: null or number 23 24 labelWidth: null or number 25 labelHeight: null or number 26 reserveSpace: null or true 27 28 tickLength: null or number 29 30 alignTicksWithAxis: null or number 31 }
以上的屬性是用來設置座標軸相關。x軸和Y軸通用。我來一一解釋:
show: 取值爲bool 是否顯示座標軸。默認值爲true.
position: 設置座標軸所處圖的位置。x軸取值"top" / "bottom", y軸取值"left" / "right"。
mode: 設置對應的數值應該如何解析。默認值或者null值則認爲對應的數值用小數來解析, 設置"time" 來解析時間戳類型的數值(須要引入jquery.flot.time.js插件來支持時間戳轉換)
timezone: 設置時區。取值有null、"browser",或者具體的時區設置。
color: 設置座標線的顏色
tickColor:設置座標線的顏色。貌似和上者同樣。官網說能夠獲得更加有細密紋路的控制。
font:設置座標軸上的值的字體樣式,以下所示:
1 { 2 size: 11, 3 lineHeight: 13, 4 style: "italic", 5 weight: "bold", 6 family: "sans-serif", 7 variant: "small-caps", 8 color: "#545454" 9 }
在這裏size和lineHeight屬性必須用像素值定義。
min && max: 設定座標軸的最大值和最小值。若是未設定則選擇繪圖數據源中的最大值和最小值。
autoscaleMargin:此屬性用在未指定座標軸最大值和最小值的時候來指定該座標軸最大的延伸值(感受就是在壓縮或者放大圖)。x軸的默認值爲null,y軸的默認值爲0.02這樣可以適應大部分用例的正常大小。
transform & inverseTransForm: 設置更改你繪圖出來的數值。例如原始值須要作一些壓縮或者擴張(eg.須要對小數值轉換爲百分數的時候)。接受的值爲function.其大體運行過程是當Flot開始繪圖時,每個data源首先經過該轉換函數。以下例子:x 座標軸的值轉換成爲天然對數:
1 xaxis: { 2 transform: function (v) { return Math.log(v); }, 3 inverseTransform: function (v) { return Math.exp(v); } 4 }
inverseTransform是transform方法的反方法。 v == inverseTransform(transform(v))。這個方法在轉換canvas座標爲數據原始座標是須要用到的。前提是你若是想使用互操做功能的話。假如你點擊一個點想獲得該點的原始數據。你就須要該轉換方法來還原canvas座標爲原始座標。
ticks: 在英語中爲十字叉的意思。在這裏咱們能夠理解爲網格線的起點座標。前面咱們能夠設置ticks的顏色。這裏是設置ticks的具體屬性。爲什麼咱們不設置時繪製出來的圖可以恰如其分的生成適當數量的座標線來美化圖呢。這是由於tick 生成器算法來完成的,這個算法有兩個步驟,首先算法根據數據的max和min來估算須要多少條ticks而後根據這個數量計算出一個可以很好的均分ticks的間隔大小。而後再生成ticks. 以下兩張圖前者是沒有設置tick時系統自動生成(0.0~15.0)均等分割的7條tick。然後者是經過設置ticks: [[0, "zero"], [5, "one mark"], [10, "two marks"]]來顯示3條ticks.
這裏須要注意的是ticks可接受的值以下:
ticks: [[0, "zero"], [5, "one mark"], [10, "two marks"]]
1 function piTickGenerator(axis) { 2 var res = [], i = Math.floor(axis.min / Math.PI); 3 do { 4 var v = i * Math.PI; 5 res.push([v, i + "\u03c0"]); 6 ++i; 7 } while (v < axis.max); 8 return res; 9 }
tickSize: 若是你但願跳過算法自動計算的間隔來手動設置tick的間隔大小。你能夠設置該屬性。如上圖的算法設置的間隔爲2.5,我在此處設置tickSize: 5, 則獲得以下圖
minTickSize: 若是你想設置一個不肯定的tick的大小的話,能夠設置這個屬性。
tickFormatter: 設置tick的格式。可接受function或者string。function(val, axis)接受兩個參數爲tick值和axis座標對象(該對象中保存着從數據源收集來的最大值和最小值等),返回string類型。默認的格式化器爲:
function formatter(val, axis) { return val.toFixed(axis.tickDecimals); }
這裏有一個定製化的格式化器:
1 function suffixFormatter(val, axis) { 2 if (val > 1000000) 3 return (val / 1000000).toFixed(axis.tickDecimals) + " MB"; 4 else if (val > 1000) 5 return (val / 1000).toFixed(axis.tickDecimals) + " kB"; 6 else 7 return val.toFixed(axis.tickDecimals) + " B"; 8 }
tickDecimals: 設置tick的數值的小數點位數。爲number。
labelWidth & labelHeight: 設置tick中label的大小
reserveSpace:
tickLength: 設置tick線的長度。默認ticks長度延伸到整個plot, 設置0爲則徹底的隱藏線條。
alignTicksWithAxis: 當設置折線圖相同軸的座標軸不止一條時,設置該屬性能夠美化數據對應的外觀,設置爲1,當你存在一條Y軸在左邊另一條在右邊時,網格線能夠自動的匹配他們對應的數值。
若是你須要不止一條x軸或者y軸來顯示數據(如在data屬性中設置yaxis: 2),你須要指定圖中每條data對應使用的座標軸。在這裏咱們經過xaxes:[] & yaxes: []來設置。
1 grid: { 2 show: boolean 3 aboveData: boolean 4 color: color 5 backgroundColor: color/gradient or null 6 margin: number or margin object 7 labelMargin: number 8 axisMargin: number 9 markings: array of markings or (fn: axes -> array of markings) 10 borderWidth: number or object with "top", "right", "bottom" and "left" properties with different widths 11 borderColor: color or null or object with "top", "right", "bottom" and "left" properties with different colors 12 minBorderMargin: number or null 13 clickable: boolean 14 hoverable: boolean 15 autoHighlight: boolean 16 mouseActiveRadius: number 17 } 18 19 interaction: { 20 redrawOverlayInterval: number or -1 21 }
網格是圖的基本架構,咱們能夠在grid屬性中設置更多的參數。
show: boolean. 設置爲false時繪製的圖不顯示網格,ticks也不顯示。
aboveData: 若是設置爲true, 則網格線處於圖的上方。
color: 設置網格的顏色。
backgroundColor: 設置網格的背景色。
margin: {top: pixels, bottom:pixels, left: pixels, right: pixels}設置圖對於placeholder的外邊距值。
labelMargin: 設置tick的label和座標線的空間,取值爲pixels.
axisMargin: 當咱們設置兩條同軸的座標軸在同一邊時設置其之間的邊距。
markings: 數組值或者方法。用來在plot的背景中繪畫出簡單的線條或者矩形,你能夠指定數組來規定x軸和y軸的範圍{xaxis: {from, to}, yaxis{from, to}, color: ##}或者用一個方法來返回如上格式的數組。
若是你想要着重渲染某一塊區域的或者某一條座標線,可使用from a to a
markings: [ { xaxis: { from: 0, to: 2 }, yaxis: { from: 0, to: 0.5 }, color: "#bb0000" }, ... ]
1 markings: function (axes) { 2 var markings = []; 3 for (var x = Math.floor(axes.xaxis.min); x < axes.xaxis.max; x += 2) 4 markings.push({ xaxis: { from: x, to: x + 1 } }); 5 return markings; 6 }
borderWidth & borderColor: 用來設置網格邊框的顏色和寬度。
minBorderMargin: 設置默認最小的網格的外邊距。
clickable & hoverable: 設置該屬性爲true, plot會監聽鼠標在plot區域發生的事件並執行"plotclick"和「plothover」事件。該兩個事件的參數爲function(position, dataItem)。以下是plotclick和plothover事件的用例:
1 $.plot($("#placeholder"), [ d ], { grid: { clickable: true } }); 2 3 $("#placeholder").bind("plotclick", function (event, pos, item) { 4 alert("You clicked at " + pos.x + ", " + pos.y); 5 // axis coordinates for other axes, if present, are in pos.x2, pos.x3, ... 6 // if you need global screen coordinates, they are pos.pageX, pos.pageY 7 8 if (item) {10 alert("You clicked a point!"); 11 } 12 });
當咱們點擊plot區域的point時,item對象不爲空,其內部屬性爲:
item: { datapoint: the point, e.g. [0, 2] dataIndex: the index of the point in the data array series: the series object seriesIndex: the index of the series pageX, pageY: the global screen coordinates of the point }
pageX & PageY: 爲該點在整個屏幕中的座標值。
autoHighlight: boolean.若是設置爲true,則點會自動被highlight。
mouseActiveRadius: 設置鼠標觸及該點多遠的距離仍然能夠觸發事件,在兩個點相隔很近的時候,plot默認傳入最近的那個點的數據。對於柱狀圖,兩個柱子相隔很近的時候鼠標觸擊默認自動選擇最高的柱子。
keep updating!