代码改变世界

转载:jQuery图表插件Flot中文文档

2011-12-07 10:43  呦菜  阅读(1089)  评论(0编辑  收藏  举报

最近正在使用JQuery的flot进行画图,但是这方面的中文帮助实在是太少了,干脆把英文的document直接翻译一下吧。因为也是再学习过程当中,难免会存在翻译不准确的地方,如果文中描述的不明白的话,可以参考一下原文:http://people.iola.dk/olau/flot/API.txt

调用plot函数的方法如下:

1
var plot = $.plot(placeholder, data, options)

Data的结构:
data应该是data series的一个数组:
[ series1, series2, ... ]
一个series可以是原始数据或者是拥有属性的对象。原始数据是一个二维数组:
[ [x1, y1], [x2, y2], ... ]
为了简化flot内容的逻辑关系,x轴和y轴的数值都要使用数字(当然,如果有特殊需要的话,flot也可以支持以时间一个轴,后面会有详细的说明)。因 为大多数的情况下,我们都是从数据库中直接提取数据并转换成JSON格式,但是没有关心过数据类型的问题。如果出现了奇怪的现象的话,请先检查数据的格式 是否有问题。
如果在一个点的数据使用的是null的话,那么在绘制的过程中就会把这个点忽略。那么包含这个点的那条线就会有断开的现象。这个点之前和之后的点是无法进行连接的。

线和点是相关连的。对于bars, 可以设置第三个关联值(默认是0)。
一个单一的序列对象结构是:

1
2
3
4
5
6
7
8
9
10
11
12
13
{
    color: color or number
    data: rawdata
    label: string
    lines: specific lines options
    bars: specific bars options
    points: specific points options
    xaxis: 1 or 2
    yaxis: 1 or 2
    clickable: boolean
    hoverable: boolean
    shadowSize: number
}

除了其中的data以外,其它的属性都没有必要明确的指定,因为大多数情况下它们都是使用默认值的。通常你只指定标签和数据:

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

label是说明这一个数据序列的含义的,如果只有一个序列的话就没有必要设置这个属性。如果有多个序列,就要设置label,从而可以在图中区分出序列的含义。
如果不设置color,那么会自动生成color来进行显示。
如果你想让用户添加和删除数据序列的话,剩下的属性就非常有用了。
xaxis和yaxis选项设置使用哪个维度,默认是设置成1的,如果设置成2的话,就使用第二个维度(x轴在上面,y轴在右边)。
 
clickable和hoverable可以设置成false,当整个图表设置成可交互时,这个选项可以让这条特定的数据序列让用户无法交互。
 
没有说明的属性会在后面详细介绍,大多数情况话都是使用默认值。当你要使用自己定义的值时,就会把默认的值给覆盖。

这是一个比较复杂的数据序列定义:
[ { label: "Foo", data: [ [10, 1], [17, -14], [30, 5] ] },
    { label: "Bar", data: [ [11, 13], [19, 11], [30, -7] ] } ]

Options的含义:
所有的选项都是完全可选的。如果想要修改的话,把它当作一个对象来处理就可以了:

1
2
3
4
5
6
var options = {
    series: {
      lines: { show: true },
      points: { show: true }
    }
};

可定制说明部分的用户设置:

1
2
3
4
5
6
7
8
9
10
11
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
}

说明可以看成是一个表格,由两部分组成的:一个是所有数据序列的label,另一个是颜色。如果想让label以其它的格式显示的话,可以使用lavelFormatter这个函数:

1
2
3
4
labelFormatter: function(label, series) { 
   // series is the series object for the label 
   return '<a href="#' + label + '" mce_href="#' + label + '">' + label + '</a>'
}

noColums是要把这个说明部分划分成几列。position是要把这个说明放到图表的哪个位置(top-right, top-left, 等等)以及与其它图表之间的距离。backgroundColor和backgroundOpacity是设置背景的颜色和透明度,正常都是默认的。

如果你想把这个说明部分从图表中拿到来,并放到DOM中的一个元素中的话,就可以设置container这个属性,它可以是一个JQuery的对象或者表达式。psition和margin等等的一些属性就会被忽略,而且这个元素中的内容会被重写的。

关于轴的用户设置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
xaxis, yaxis: {
    show: null or true/false
    position: "bottom" or "top" or "left" or "right"
    mode: null or "time"
 
    color: null or color spec
    tickColor: null or color spec
     
    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: range -> 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
}

所有的都包含相同的属性。下面会详细的介绍每一个属性的含义。

show:如果不设置这个属性的话,flot会自动的来选择,比如:数据与轴有关系的话,那么就会把轴显示出来,当然更灵活的方式还是用

true或者false来设定这个属性。

position:用来定义轴文字显示的位置,是在X轴的上方还是下方,是在Y轴的左边还是右边。

mode:轴的数据类型,默认的是数值类型,当设置成time类型的话,就可以用时间做为一个轴。
color:定义轴标识文字和坐标的颜色。如果不设置的话,就与图表中网格的颜色是相同的。当然也可以自己来设置颜色,使用"tickColor"还

可以单独定义坐标的颜色。

min/max:描述轴最大值和最小值范围。如果不设置的话,flot会自动的计算并生成一个范围来进行显示。

autoscaleMargin:这个有一点难理解。flot自动计算min/max的范围的时候会加上一个值,从而防止有的点会放到图的边缘。这个属性只能

在不设置max/min的时候才可以使用。如果设置了一个margin,flot会延长轴的结束点从而构成一个完整的坐标。默认的设置是x轴没有margin,y轴有0.02的margin。默认的设置已经可以满足大多数的使用了。

"transform","inverseTransform":可以对原始的数据进行一些特殊的计算以后再进行绘制。比如:可以通过这种方法来绘制一些非线性

的曲线。例如:

1
2
3
4
xaxis: {
        transform: function (v) { return Math.log(v); },
        inverseTransform: function (v) { return Math.exp(v); }
}

同样的,想对Y轴做反转的话就可以:

1
2
3
4
yaxis: {
        transform: function (v) { return -v; },
        inverseTransform: function (v) { return -v; }
}

Flot中的数据都是单调的,也就是说原始的数据是不能出现乱序的。inverseTransform就是transform的反向函数,通过显示的数据可以得到原始数据,如果图表没有交互过程的话,这个属性可以不用设置。

 剩下的选项都是处理刻度的。如果不对刻度进行任何的设置的话,坐标生成函数会自动的计算刻度。算法会先估算刻度的个数,再计算出两个刻度之间的间隔大小, 从而可以生成完整的刻度了。你可以给算法设置刻度的个数("ticks"),算法会根据原始数据的范围返回一个最接近你设置的刻度数的一个值,也就是说如 果你设置了3,那么它返回5个坐标也是很正常的,因为算法认为5个刻度会更合适。如果不设置刻度的话,把"ticks"设置成0或者空数组就可以了。还可 以通过设置"tickSize"来定义两个刻度之间的差值,如果设置成2,那么刻度就会是2,4,6. 通过"minTickSize"可以设置两个刻度差值的最小值。对于时间刻度,我们可以设置数组来完成:[2, "month"]。

最狠的方法还是直接忽略flot自带的算法,完全使用数组自己定义的刻度:
      ticks: [0, 1.2, 2.4]
下面的方法会更加的可定制化:
      ticks: [[0, "zero"], [1.2, "one mark"], [2.4, "two marks"]]

Flot还支持更牛X的可扩展性,就是可以调用一个函数来形成各个刻度的值。在函数中需要通过最小值,最大值和自己设定的一个间隔来计算出一个数组,作为各个刻度:

1
2
3
4
5
6
7
8
9
10
function piTickGenerator(axis) {
       var res = [], i = Math.floor(axis.min / Math.PI);
       do {
           var v = i * Math.PI;
           res.push([v, i + "\u03c0"]);
           ++i;
        } while (v < axis.max);
    
       return res;
}

还可以设置"tickDecimals"来指定刻度显示的精度。

    给"tickFormatter"定义也一个函数可以灵活的格式化刻度的显示,函数有两个参数,一个是刻度的值,一个是轴上的最大值和最小值,返回值一定要是string类型:
function formatter(val, axis) {
    return val.toFixed(axis.tickDecimals);
  }

对于一个轴对象,有min和max这两个属性,还有"tickDecimals"是坐标显示的精度,"tickSize"是两个刻度之间的差值,有了这么多的属性,就可以自己定制刻度的显示内容:

1
2
3
4
5
6
7
8
function suffixFormatter(val, axis) {
    if (val > 1000000)
      return (val / 1000000).toFixed(axis.tickDecimals) + " MB";
    else if (val > 1000)
      return (val / 1000).toFixed(axis.tickDecimals) + " kB";
    else
      return val.toFixed(axis.tickDecimals) + " B";
}

"labelWidth"和"labelHeight"是定义刻度显示区域的。"reserveSpace"的意思是即使你不定义轴,flot也会 使用这个属性把轴占用的空间给预留出来。当绘制单行多轴图表时与"labelWidth"和"labelHeight"一起使用会得到很多的效果。

"tickLength"定义坐标刻度的长度,null是默认设置,也就是一个很小的刻度,如果设置成0,在轴上就不会显示刻度。

"alignTicksWithAxis":如果设置成其它轴的数字,Flot会在自动生成刻度的时候会与其它轴上的刻度对齐的。这样会更加的美观,尤其是图中有网格,并且有多具轴的时候,非常的实用。

绘制多个轴:
如果你需要绘制多个轴的话,数据序列就要按照下面的格式给出,{ data: [...], yaxis: 2 }表明这个序列要使用第二个Y轴。这时要设置轴的显示形式的话,就不能直接使用xaxis/yaxis的选项了,而是要有两个数组:
{
    xaxes: [ { position: "top" } ],
    yaxes: [ { }, { position: "right", min: 20 } ]
}
如果所有的Y轴都想设置成相同的值的话,使用yaxis: { min: 0 }就可以了。

时间类型的数据序列:

============================
时间序列比数据序列就有一点难了。因为时间序列并不是按照10进制来排列的,所以Flot需要把时间转换成数值,再进行处理。Flot是通过 javascript中的timestamps来支持时间序列的。timestamp是一个时间距1970年1月1日00:00:00的毫秒数,类似与 Unix系统中使用的timestamps,只不过javascript的单位是毫秒,unix的意单位是秒。可以通过下面的来获取浏览器的 timestamp:
alert((new Date()).getTime())
一般来说,大家都希望在网页上显示本地的时间,但是Flot只能把timestamp转换成UTC的时间来显示,所以唯一的方法就是获取本浏览当前的 timestamp,和时区,再对timestamp的值进行计算,从而得到UTC时间与当前时间相等时的UTC timestamp。再把转换后的值提供给Flot来绘图。
这时就可以用转换后的timestamp来构造原始的数据的,并把轴的类型定义成"time",Flot就可以自动的计算刻度并格式化它们。当然了,也可以自己定义刻度,但是一定要使用数值型的参数,不能是对象类型。刻度的生成和格式化也可以通过轴的选项来自定义:
  minTickSize: array
  timeformat: null or format string
  monthNames: null or array of size 12 of strings
  twelveHourClock: boolean
"timeformat":时间的显示形式:
xaxis: {
    mode: "time"
    timeformat: "%y/%m/%d"
  }
  时间刻度就会显示成"2000/12/24",具体的格式定义参考下面:
  %h: 小时
  %H: 小时 (左边补0)
  %M: 分钟 (左边补0)
  %S: 秒 (左边补0)
  %d: 日, 用 %0d 来左边补0
  %m: 月, 用 %0m 来左边补0
  %y: 年 (4位数)
  %b: 月的名字 (英文名字)
  %p: 12小时投制显示(am/pm), %h/%H
  %P: 12小时投制显示 (其中的AM/PM)

月份的名字是可以自定义的:
monthNames: ["jan", "feb", "mar", "apr", "maj", "jun", "jul", "aug", "sep", "okt", "nov", "dec"]
当"twelveHourClock"被设置成true时,时间就会用12时制来显示。

时间的格式和月份的名字是被一个flot自带的格式化函数使用的,它会使用一个数据对象,一个格式字符串,从而返回格式化后的字符串。还可以直接调 用$.plot.formatDate(date, formatstring, monthNames)或者调用自己完成的具有更强大功能的函数。

你还可以通过函数来控制刻度的显示内容。下面的例子是把December 24格式化成24/12:

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

对于时间模式的"tickSize"是有一点特别的"minTickSize",需要使用数组来定义,格式为"[value, unit]"。其中,unit只能是"second", "minute", "hour", "day", "month" and "year",所以就可以这样来设置了:
  minTickSize: [1, "month"]
这样就可以把两个刻度之间的差值设置成最小一个月了,如果tickSize是[2, "day"],那么刻度的差值就是固定了两天了。 自定义数据序列

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
series: {
    lines, points, bars: {
      show: boolean
      lineWidth: number
      fill: boolean or number
      fillColor: null or color/gradient
    }
 
    points: {
      radius: number
      symbol: "circle" or function
    }
 
    bars: {
      barWidth: number
      align: "left" or "center"
      horizontal: boolean
    }
 
    lines: {
      steps: boolean
    }
 
    shadowSize: number
}

colors: [ color1, color2, ... ]
"series: {}"的选项会拷贝到所有的数据序列中。如果想设置所有的数据序列显示属性的话,就可以在这个全局选项中设置,如果只想设置某一个数据序列的显示的话,就可以在对应的序列中进行设置。 "lines", "points"和"bars"这三个属性的设置是很重要的,因为会直接影响到点,线和柱状图的显示方式。如果所有的属性都没有设置的话,flot会有一个默认的设置。当然也可以单独的设置一个或者多个属性,flot会根据你的设置来绘制图表:

1
2
3
4
5
6
var options = {
    series: {
      lines: { show: true, fill: true, fillColor: "rgba(255, 255, 255, 0.8)" },
      points: { show: true, fill: false }
    }
};

"lineWidth"设置线的宽度,单位是pixels。你还可以把这个值设置成0,从而会把线删除,当然阴影也不会绘制。
"fill"是控制填充的,当线足够宽的话,线就变成了图形,所以就有必要确定是否要填充了。 "fillColor"确定填充的颜色,如果这个值不设置的话,flot会使用数据序列中定义的颜色来填充。第4个值是设置填充的透明度,取值从0(完全透明)到1(不透明). 对于bar类型的柱状图而言,fillColor可以是阶梯形式的,下面会有详细的介绍。"barWidth"是柱的宽度,单位就是对应轴的数据类 型。当轴是时间类型的话,那么单位就是毫秒,那么24 * 60 * 60 * 1000的宽度就是一天。"align"是柱的对齐方式,左对齐(默认)或者居中。当"horizontal"被设置以后,柱状图就会水平绘制,也就是柱 与x轴是平行的。如果之前已经绘制过与y轴平行的柱子的话,还要交换一下坐标轴。
对于线而言,"steps"用来设置两个相邻点之间是使用直线连接还是使用台阶线连接。如果使用台阶线的,flot会自动的添加一些点来实现这个功能。
对于绘制的点,可以设置点的半径和符号。目前flot只支持圆形的符号,可以使用其它的插件来使用其它的符号,也可以使用自己定义的函数:

1
2
3
4
5
6
7
function cross(ctx, x, y, radius, shadow) {
      var size = radius * Math.sqrt(Math.PI) / 2;
      ctx.moveTo(x - size, y - size);
      ctx.lineTo(x + size, y + size);
      ctx.moveTo(x - size, y + size);
      ctx.lineTo(x + size, y - size);
}

输入的参数是绘制的上下文,绘制点x和y轴的坐标,radius设置绘制点的半径,也可以设置是否显示阴影。

"shadowSize"用来设置阴影的大小,单位是pixels,设置成0的话就可以删除阴影。
"colors"数组是用来设置在绘图过程中各条线使用的颜色的默认值:
  colors: ["#d18b2c", "#dba255", "#919733"]
如果数据序列的数量比定义的颜色数量多的话,flot还会生成一些新的颜色用于绘制图表。

自定义网格

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
grid: {
    show: boolean
    aboveData: boolean
    color: color
    backgroundColor: color/gradient or null
    labelMargin: number
    axisMargin: number
    markings: array of markings or (fn: axes -> array of markings)
    borderWidth: number
    borderColor: color or null
    minBorderMargin: number or null
    clickable: boolean
    hoverable: boolean
    autoHighlight: boolean
    mouseActiveRadius: number
}

网格可以看做是轴上的刻度不断的延长而形成的。网格大多数的属性都是在轴中定义的,但是也有些属性是网格独自定义的,"color"用来定义颜 色,"backgroundColor"用来定义网格中的背景颜色。如果设置成null的话,就说明grid的背景是透明的,当然也可以设置成梯度的。

当然也把show设置成false,而不显示所有的刻度标签和网格。"aboveData"用来确定网格与数据的层次关系。

"labelMargin"是刻度标签与轴之间的像素值,"axisMargin"是两个轴之间的像素值,当有两个轴相邻的时候使用的。你可以使用CSS来定义刻度标签的显示格式,需要定义一个"tickLabel"的CSS类。

"borderWidth"是图表的边界宽度值。设置成0就没有边界。"borderColor"是定义边界的颜色,"minBorderMargin"控制边界的最小空白区域。

"markings"用来绘制图表中的简单直线和背景上的矩形区域。可以使用数组来设置要绘制的线或者区域{ xaxis: { from, to }, yaxis: { from, to } }。或者是一个可以返回这种数组的函数,参数是轴的数据作为一个对象。

还可以设置矩形区域的颜色:
  markings: [ { xaxis: { from: 0, to: 2 }, yaxis: { from: 10, to: 10 }, color: "#bb0000" }, ... ]

如果省略其中的一个值的话,那么flot就会把省略值的范围设置成对应轴的所有取值范围。{ xaxis: {
from: 0, to: 2 } }就会绘制一个x轴从0到2, Y轴全部的矩形。markings: [ { yaxis: { from: 1, to: 1 } }, ... ]就会绘制一条与x轴平行的直线。可以通过设置"lineWidth"改变线的宽度。

使用函数来设置的话可以这样来实现:

1
2
3
4
5
6
markings: function (axes) {
    var markings = [];
    for (var x = Math.floor(axes.xaxis.min); x < axes.xaxis.max; x += 2)
      markings.push({ xaxis: { from: x, to: x + 1 } });
    return markings;
}

把"clickable"设置成true, 图表就会监听鼠标的click动作,并生成"plotclick"事件,参数是点击的坐标和点击距离最近的数值,位置的坐标可以是图表中对应的值,也可以是全局页面的坐标。

同样的,如果把"hoverable"设置成true的话,图表就会监听鼠标的移动事件,并生成"plothover",参数与"plotclick"是 相同的。如果"autoHighlight"设置成true,鼠标附近的元素就会被高亮显示。当然你也可以把"autoHighlight"设置成 false,从而可以使用highlight/unhighlight函数来进行设置。

"plotclick" 和 "plothover"的处理函数可以这样完成:

1
2
3
4
5
6
7
8
9
10
11
12
$.plot($("#placeholder"), [ d ], { grid: { clickable: true } });
 
    $("#placeholder").bind("plotclick", function (event, pos, item) {
        alert("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) {
          highlight(item.series, item.datapoint);
          alert("You clicked a point!");
        }
});

其中item对象的格式是

1
2
3
4
5
6
7
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
}

如果设置的数据是这样子的:
  $.plot($("#placeholder"), [ { label: "Foo", data: [[0, 10], [7, 3]] } ], ...);
而且鼠标与(7, 3)这个节点离的非常近,"datapoint" 是 [7, 3],"dataIndex" 会是1。"series"就是一个序列的对象,包含的信息是"Foo" (series.label)和颜色(series.color),seriesIndex的值是0.

如果使用上面的方法来显示一些信息的话,那么就需要监听"mouseout"事件。"mouseActiveRadius"用来定义鼠标做用的范围。如果有多个数据点在这个范围中的话,Flot只会选择最接近的那一个。对柱状图而言,最高的那个柱子会被选中。

如果不想有交互的话,就可以"hoverable" 和 "clickable" 设置成false:{ data: [...], label: "Foo", clickable: false }。

梯度颜色的定义
===================
定义的方法: { colors: [ color1, color2, ... ] }
如果想让网格的背景从黑色到灰色的话:
  grid: {
    backgroundColor: { colors: ["#000", "#999"] }
  }

对数据序列,可以设置颜色的透明度和亮度:
  { colors: [{ opacity: 0.8 }, { brightness: 0.6, opacity: 0.8 } ] }
第一个只有透明度,第二个还包含了亮度。对于柱形图来说,下面的例子可以让柱子逐渐的消失:
  bars: {
      show: true,
      lineWidth: 0,
      fill: true,
      fillColor: { colors: [ { opacity: 0.8 }, { opacity: 0.1 } ] }
  }

Flot目前只能支持垂直方向上从上到下的渐变,因为IE只支持这个模式。

Plot方法
---------------
由plot函数生成的对象提供了可调用的方法
  - highlight(series, datapoint)
用来高亮显示一个数据点。你可以通过"plotclick"事件获取对象,或者使用highlight(1, 3)来高亮显示第2个数据序列中的第4个数据点。

  - unhighlight(series, datapoint) or unhighlight()
删除高亮显示,如果有参数的话,就是删除指定高亮的点,如果没有参数的话,plot就会删除图表中所有的高亮显示。

  - setData(data)
用来重新设置数据。但是轴的取值范围,刻度坐标,标签是不会重新绘制的,可以调用draw()让plot绘制新的曲线,但是其它部分不会改变。用这个函数可以变速的更新一个图表中的曲线,前提条件是所有值的取值范围是没有改变的。

  - setupGrid()
重新计算轴的取值范围,并设置刻度和标签。如果调用过setData的话,就可以使用这个函数重新绘制有影响的部分。
  - draw()
重新绘制图表中的显示曲线部分。
  - triggerRedrawOverlay()
在可绘制区域上更新可交互的部分,如选择区域和点的高亮。当要自己编写插件时是非常有用的。图表并不会马上重新绘制,而是可以设置一个定时器来获取多次的重给事件。
  - width()/height()
获取可绘制区域的宽度和高度。也就是网格中的区域。
  - offset()
返回网格中可绘图的区域相对于整个文档的偏移,当计算鼠标所在的位置时很重要。把event.pageX/Y减去这个偏移就是在绘图区域中的坐标。
  - pointOffset({ x: xpos, y: ypos })
(x,y)这个数据点在包含绘图div窗口中的偏移。
  - resize()
如果绘图窗口的大小发生改变,就可以调用这个函数来重新绘图。
  - shutdown()
关闭已经注册的所有事件的处理函数。

还会一些其它的函数,但是需要你了解Flot内部的代码流程。如果你修改了获取到对象中的属性的话,那么你就修改了Flot内部使用的对象,Flot无法及时的更新你修改的内容,还有可能会影响绘图功能,所以使用的时候一定要小心。具体的使用方法可以参考原版的文档。
  - getData()
  - getAxes()
  - getPlaceholder()
  - getCanvas()
  - getPlotOffset()
  - getOptions()

Hooks(钩子函数)
======================
Plot对象在绘制过程中可以添加许多的钩子函数,从而添加一些方法,在方法还可以访问Flot中的内部数据。

下面就是Flot处理流程的概要:
1. 插件的初始化,处理各个选项
2. 构造绘图区域
3. 设置各类数据:处理用户录入的数据,计算显示用的颜色,把原始数据转化成内部格式,规格化数据,查看最大最小值用来设置轴的取值范围。
4. 网格的设置:计算轴的空间,刻度,刻度的标签。
5. 绘图: 绘制网格,按照顺序绘图
6. 设置事件处理的自定义函数
7. 答复事件。
8. 关闭:一般都是发生在整个图表被重写的时候发生。

钩子函数一个简单的函数,并放在了一个特定的数组当中。你可以使用"hooks"来添加钩子函数,当绘图完成以后,钩子函数仍然是起作用的,因为它的定义已经存在于plot的对象中了。

1
2
3
4
5
6
7
8
// define a simple draw hook
  function hellohook(plot, canvascontext) { alert("hello!"); };
 
// pass it in, in an array since we might want to specify several
  var plot = $.plot(placeholder, data, { hooks: { draw: [hellohook] } });
 
// we can now find it again in plot.hooks.draw[0] unless a plugin
// has added other hooks

下面会列出所有可以设置钩子的地方。所有的钩子都会把plot对象作为第一个参数。你可以在在Flot绑定的插件中看使用的例子。
 - processOptions  [phase 1]

   function(plot, options)
当Flot处理合并完合选项后调用。当你不想仅仅简单的合并默认的选项时就可以使用。插件也可以通过这个函数来打开或者关闭与自己相关的选项。

 - processRawData  [phase 3]

   function(plot, series, data, datapoints)
在Flot复制并且格式化原始数据之前调用。如果函数中使用格式化的数据点设置了datapoints.points并把datapoints.pointsize设置成数据点的数量,那么Flot就会不会对这个数据序列进行任何的处理。

一般来说,你可能会设置datapoints.format,用来定义数据值的格式化方法和轴取值的范围。默认的格式化数组是这样子的:
     [
       { x: true, number: true, required: true },
       { y: true, number: true, required: true }
     ]
第一个对象的含义是对于第一个坐标轴,需要计算x轴的取值范围,必须是数字类型,而且是必选的。如果是空的,或者无法转换成数字类型的话,所有的点都会被 初始化成0.当然了你还可以指定"defaultValue",如果没有指定类型的话,Flot就会使用这里定义的选项值。

 - processDatapoints  [phase 3]

   function(plot, series, datapoints)
在格式化完原始数据之后,查找最大值和最小值之前。这个钩子函数是用来对数据进行转换的。"datapoints"包含了两个成员,其中 datapoints.points是格式化后的一维数组,datapoints.pointsize是所有数据点的个数。这里给出一个简单的转换,把所 有的点的y坐标都乘以2:

1
2
3
4
5
function multiply(plot, series, datapoints) {
         var points = datapoints.points, ps = datapoints.pointsize;
         for (var i = 0; i < points.length; i += ps)
             points[i + 1] *= 2;
}

一定要保证datapoints中数据的正确性,因为Flot不会再为这些数据进行检查的。

 - drawSeries  [phase 5]

   function(plot, canvascontext, series)
只用来绘制一个数据序列,在循环的绘制每一个数据序列之前调用。

 - draw  [phase 5]

   function(plot, canvascontext)
在网格绘制完成以后被调用。可以阅读原代码来学习这个方法的使用。

 - bindEvents  [phase 6]

   function(plot, eventHolder)
在Flot配置它的事件处理函数之后调用。可以给eventHolder设置需要的事件处理函数。例如:

1
2
3
4
5
function (plot, eventHolder) {
         eventHolder.mousedown(function (e) {
             alert("You pressed the mouse at " + e.pageX + " " + e.pageY);
         });
}

- drawOverlay  [phase 7]

   function (plot, canvascontext)
用来绘制可交互区域的。

 - shutdown  [phase 8]

   function (plot, eventHolder)
当plot.shutdown()时被调用,一般只有整个绘图被一个新的绘图完全覆盖时才需要。

原文转自:http://www.itivy.com/ivy/archive/2011/6/4/jquery-flot-chinese-doc.html