1. 程式人生 > >jquery.flot圖表外掛使用

jquery.flot圖表外掛使用

Flot是純Javascript實現的基於jQuery的圖表外掛,主要支援線狀圖和柱狀圖的繪製(通過外掛也可以支援餅狀圖)。它的特點是使用簡單、圖形美觀,支援滑鼠跟蹤及縮放功能。Flot是基於canvas進行圖表的繪製,可以在IE6+/Firefox2+/Safari3+/Opera9.5+/Chrome等主流瀏覽器上執行;其中IE9以下瀏覽器不支援canvas標記,需要額外引用excanvas庫(VML)來實現。

基本使用

1.首先,在頁面頭部引用指令碼:

<!--[if lte IE 8]><script src="js/excanvas.min.js"></script><![endif]-->
<script src="js/jquery.min.js"></script> <script src="js/jquery.flot.min.js"></script>

2.在頁面中建立一個html標記,如div,然後通過樣式來指定圖表的大小:

<div id="placeholder" style="width:600px;height:300px;"></div>

3.最後,在DOM Ready事件中呼叫Flot的繪製方法$.plot:

$(function () {
    $.plot($("#placeholder"
), [[[0, 0], [1, 2]]]); });

4.做完上面的步驟就繪製完成了一條線

資料格式

flot的資料格式是陣列,陣列中包含多個系列的資料,每個系列的資料對應一條線:

[ series1, series2, ... ]

每一個系列的資料可以是一個數組或者物件。
陣列格式的資料,每一個點都是一個數組(分x/y軸):

[ [x1, y1], [x2, y2], ... ]

如下定義了三個點:

[ [1, 3], [2, 14.01], [3.5, 3.14] ]

繪製圖表的時候,會把這三個點連線起來;假如中間有個點使用了空值即null,這個點的兩邊則不會連線起來:

[ [1, 3], [2, 14.01], null, [3.5, 3.14], [5, 8] ]

需要注意的是,每個點的資料必須是數字,如果是字串,可能會得到奇怪的錯誤。
物件格式的資料,如下:

{
    color: color or number  //顏色,如果不設定會自動生成
    data: rawdata //資料
    label: string //用於圖例說明
    lines: specific lines options
    bars: specific bars options
    points: specific points options
    xaxis: number
    yaxis: number
    clickable: boolean
    hoverable: boolean
    shadowSize: number
    highlightColor: color or number
}

通常不需要關心其他選項,只需要指定label和data:

{
    label: "y = 3",
    data: [[0, 3], [10, 3]]
}

物件格式的資料提供更大的靈活性,也更有利於程式碼的可讀性,如下定義了兩個系列即兩條線:

[ 
  { label: "Foo", data: [ [10, 1], [17, -14], [30, 5] ] },
  { label: "Bar", data: [ [11, 13], [19, 11], [30, -7] ] }
]

選項設定

所有的選項都是可選的,改變某個屬性,只需要指定特定的屬性名稱:

{
  // 自定義資料系列
  series: {
    //共有屬性:點、線、柱狀圖的顯示方式
    lines, points, bars: {
          // 是否顯示
          show: boolean
          // 線寬度
          lineWidth: number
          // 是否填充
          fill: boolean or number
          // 填充色,如rgba(255, 255, 255, 0.8)
          fillColor: null or color/gradient
      }
      // 只針對點的屬性
      points: {
          //點的半徑
          radius: number
          // 繪製點的方法,預設為內建的圓形,可以通過自定義函式來定義其他形狀
          symbol: "circle" or function
      }
      // 只針對柱狀圖的屬性
      bars: {
          barWidth: number
          align: "left", "right" or "center"
          horizontal: boolean
      }
      // 只針對線的屬性
      lines: {
          // 指定兩個點之間是用水平線還是垂直線連線
          steps: boolean
      }
      // 設定陰影的大小,0消除陰影
      shadowSize: number
      // 滑鼠懸停時的顏色
      highlightColor: color or number
  }
  // 設定各個對應的資料序列,即線的顏色
  colors: [ color1, color2, ... ]
  // 網格設定
  grid: {
      // 是否顯示格子
      show: boolean
      // 資料的線是否繪製在網格線下
      aboveData: boolean
      // 網格線顏色
      color: color
      // 網格背景顏色
      backgroundColor: color/gradient or null
      margin: number or margin object({top,left,bottom,right})
      // 刻度與網格間距
      labelMargin: number
      axisMargin: number
      markings: array of markings or (fn: axes -> array of markings)
      // 邊框寬度
      borderWidth: number
      // 邊框顏色
      borderColor: color or null
      minBorderMargin: number or null
      // 監聽滑鼠點選,會生成plotclick事件
      clickable: boolean
      // 監聽滑鼠移動,會生成plothover事件
      hoverable: boolean
      // 滑鼠附近元素高亮顯示
      autoHighlight: boolean
      mouseActiveRadius: number
  }

  interaction: {
      // 最大重繪延遲
      redrawOverlayInterval: number or -1
  }
  // x,y軸的設定
  xaxis, yaxis: {
      show: null or true/false
      // 刻度文字顯示的位置
      position: "bottom" or "top" or "left" or "right"
      // 設定成time型別時可以用時間作為資料
      mode: null or "time" ("time" requires jquery.flot.time.js plugin)
      // 時區,僅用於time模式
      timezone: null, "browser" or timezone (only makes sense for mode: "time")
      // 軸文字和刻度文字顏色
      color: null or color spec
      // 單獨定義刻度文字顏色
      tickColor: null or color spec
      font: null or font spec object
      // 最大最小隻範圍,不設定則自動計算
      min: null or number
      max: null or number
      autoscaleMargin: null or number
      // 對資料進行計算後再繪製
      transform: null or fn: number -> number
      inverseTransform: null or fn: number -> number
      // 用於自定義刻度顯示
      ticks: null or number or ticks array or (fn: axis -> ticks array)
      tickSize: number or array
      minTickSize: number or array
      // 格式化刻度顯示
      tickFormatter: (fn: number, object -> string) or string
      // 刻度顯示精確度,即小數位數
      tickDecimals: null or number
      // 刻度區域大小
      labelWidth: null or number
      labelHeight: null or number
      reserveSpace: null or true

      tickLength: null or number

      alignTicksWithAxis: null or number
  }
  // 定義多個座標軸
  xaxes: []
  yaxes: []
  // 圖例
  legend: {
      show: boolean
      // 格式化圖例的顯示
      labelFormatter: null or (fn: string, series object -> string)
      labelBoxBorderColor: color
      noColumns: number
      position: "ne" or "nw" or "se" or "sw"
      margin: number of pixels or [x margin, y margin]
      backgroundColor: null or color
      backgroundOpacity: number between 0 and 1
       //圖例的容器,用於從圖表中分離
      container: null or jQuery object/DOM element/jQuery expression
      sorted: null/false, true, "ascending", "descending" or a comparator
  }

格式化圖例的顯示

通過legend引數的labelFormatter引數來格式化圖例的顯示,其中series為一個物件(屬性參考物件格式的資料):

labelFormatter: function (label, series) {
  // series is the series object for the label 
  return '<a href="#' + label + '" title="' + series.label + '">' + label + '</a>';
}

軸的設定

自定義刻度的顯示,可以通過ticks引數來設定,如下定義X軸:

xaxis: {
  ticks: [0, 2, 4, 8, 10, 15]
}

這樣軸上只會顯示以上定義的刻度。當有時候資料超出這個範圍時,部分刻度會被隱藏,這時候就需要手動指定min/max引數,如下:

$.plot($("#placeholder"), 
  [{ label: "Foo", data: [[10, 1], [17, -14], [30, 5]] },
    { label: "Bar", data: [[11, 13], [19, 11], [30, -7]] }
  ],
  {
    xaxis: {
      ticks: [0, 2, 4, 8, 10, 15],
      min: 0,
      max: 30
    }
  }
  );

ticks引數還可以定製刻度顯示的文字:

ticks: [[0, "零"], [2, "二"], [4, "四"], [8, "八"], [10, "十"], [15, "十五"]]

最強大的還是通過自定義函式,通過tickFormatter引數:

tickFormatter: function(axis) {
  return "數字" + axis.toString();
}

繪製多個刻度軸

如下,繪製兩個y軸,同時需要在資料中指定屬於哪個軸:

$.plot($("#placeholder"), 
  [ { label: "Foo", data: [[10, 1], [17, -14], [30, 5]] },
    { label: "Bar", data: [[11, 13], [19, 11], [30, -7]] },
    { label: "Three", data: [[2, 6], [5, 8], [18, 15]], yaxis: 2 },
  ],
  {
    xaxes: [{ position: "bottom" }],
    yaxes: [{ position: "left" }, { position: "right", min: 2 }]
  }
  );

時間格式的資料

使用時間格式的資料需要引用jquery.flot.time.js,它支援以下格式的時間格式化:

%a: weekday name (customizable)
%b: month name (customizable)
%d: day of month, zero-padded (01-31)
%e: day of month, space-padded ( 1-31)
%H: hours, 24-hour time, zero-padded (00-23)
%I: hours, 12-hour time, zero-padded (01-12)
%m: month, zero-padded (01-12)
%M: minutes, zero-padded (00-59)
%S: seconds, zero-padded (00-59)
%y: year (two digits)
%Y: year (four digits)
%p: am/pm
%P: AM/PM (uppercase version of %p)
%w: weekday as number (0-6, 0 being Sunday)

還支援自定義月份、一週中每一天的名稱:

monthNames: ["jan", "feb", "mar", "apr", "maj", "jun", "jul", "aug", "sep", "okt", "nov", "dec"]
dayNames: ["dim", "lun", "mar", "mer", "jeu", "ven", "sam"]

使用如下:

$.plot($("#placeholder"),
   [{ label: "Foo", data: [[new Date(2010, 1, 1), 1], [new Date(2010, 5, 1), -14], [new Date(2010, 10, 1), 5]] },
     { label: "Bar", data: [[new Date(2010, 2, 1), 13], [new Date(2010, 6, 1), 11], [new Date(2010, 12, 1), -7]] }
   ],
   {
     xaxis: {
       mode: "time",
       timeformat: "%y/%m/%d"
     }
   }
   );

當然,如果不使用timeformat的話,也可以用tickFormatter來格式化顯示:

tickFormatter: function (val, axis) {
  var d = new Date(val);
  console.log(val)
  return (d.getUTCMonth() + 1) + "/" + d.getUTCDate() + "/" + d.getFullYear();
}

特殊的顯示需求

可能需要在同一個點上進行時間的對比,比如x軸:

$.plot($("#placeholder"),
   [ { label: "Foo", data: [[1, new Date(2010, 1, 1)], [2, new Date(2010, 5, 1)], [3, new Date(2010, 10, 1)]] },
     { label: "Bar", data: [[1, new Date(2010, 2, 1)], [2, new Date(2010, 6, 1)], [3, new Date(2010, 12, 1)]] }
   ],
   {
     yaxis: {
       mode: "time",
       timeformat: "%y/%m/%d"
     },
     xaxis: {
       ticks: [[1, "一"], [2, "二"], [3, "三"]]
     }
   }
   );

在以上方法中,把x軸和x軸刻度的值一一對應,當然也可以換成y軸。

控制線和點的顯示

通過series引數,可以控制線的填充、點的顯示(點預設是不顯示的):

series: {
  lines: { show: true, fill:true },
  points: { show: true, fill: false }
}

顏色的控制

flot有多個引數都用到了顏色,均可以通過定義單個、或多個顏色來控制每個資料呈現的顏色:

colors: ["#d18b2c", "#dba255", "#919733"]

再比如網格的背景色:

grid: {
    backgroundColor: { colors: ["#000", "#999"] }
}

顏色還有更加詳細的選項來定義:

{ colors: [{ opacity: 0.8 }, { brightness: 0.6, opacity: 0.8 } ] }

跟蹤滑鼠事件

主要有滑鼠移動和點選事件,需要先開啟相應開關:

grid: {
  clickable: true,
  hoverable: true
}

然後再繫結相應的事件,如點選事件:

$("#placeholder").bind("plotclick", function (event, pos, item) {
  console.log("You clicked at " + pos.x + ", " + pos.y);
  // axis coordinates for other axes, if present, are in pos.x2, pos.x3, ...
  // if you need global screen coordinates, they are pos.pageX, pos.pageY

  if (item) {
    console.log(item.series, item.datapoint);
    console.log("You clicked a point!");
  }
});

plothover事件的的繫結也一樣。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
}

內建方法

highlight(series, datapoint):高亮顯示point
unhighlight(series, datapoint) or unhighlight():取消高亮point,沒有引數則取消高亮當前的point
setData(data):重新設定資料,需要呼叫draw()方法來重繪
setupGrid():重新計算座標、軸,需要呼叫draw()方法來重繪
draw():重繪圖表
triggerRedrawOverlay():更新可互動的區域,如point
width()/height():獲取寬高
offset():獲取偏移
pointOffset({ x: xpos, y: ypos }):獲取某個點相對於placeholderdiv的偏移
resize():調整圖表的大小
shutdown():清理即取消繫結所有事件處理函式

還有一些其他函式,但需要你比較瞭解flot內部運作,否則可能產生不好的結果:

getData():獲取資料,即在$.plot方法中定義的資料
getAxes():獲取座標軸
getPlaceholder():獲取placeholder元素
getCanvas():獲取canvas物件
getPlotOffset():獲取偏移
getOptions():獲取設定的選項

如highlight方法,就可以在click事件中使用:

var pl = $.plot($("#placeholder"), data, options);

 $("#placeholder").bind("plotclick", function (event, pos, item) {
   if (item) {
     pl.highlight(item.series, item.datapoint);
   }
 });

flot還提供了一些函式,用於在繪圖各個流程步驟中進行一些額外的處理,這裡不再列出。

相關資源

外掛主頁:http://code.google.com/p/flot/   (API文件:http://people.iola.dk/olau/flot/API.txt)

最新版本:https://github.com/flot/flot  (API文件:https://github.com/flot/flot/blob/master/API.md)

線上DEMO:http://people.iola.dk/olau/flot/examples/

Flot的外掛:http://code.google.com/p/flot/wiki/Plugins (實現更多型別的圖表)