shop.balmet.com

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

API.md (53886B)


      1 # Flot Reference #
      2 
      3 Consider a call to the plot function:
      4 
      5 ```js
      6 var plot = $.plot(placeholder, data, options)
      7 ```
      8 
      9 The placeholder is a jQuery object or DOM element or jQuery expression
     10 that the plot will be put into. This placeholder needs to have its
     11 width and height set as explained in the [README](README.md) (go read that now if
     12 you haven't, it's short). The plot will modify some properties of the
     13 placeholder so it's recommended you simply pass in a div that you
     14 don't use for anything else. Make sure you check any fancy styling
     15 you apply to the div, e.g. background images have been reported to be a
     16 problem on IE 7.
     17 
     18 The plot function can also be used as a jQuery chainable property.  This form
     19 naturally can't return the plot object directly, but you can still access it
     20 via the 'plot' data key, like this:
     21 
     22 ```js
     23 var plot = $("#placeholder").plot(data, options).data("plot");
     24 ```
     25 
     26 The format of the data is documented below, as is the available
     27 options. The plot object returned from the call has some methods you
     28 can call. These are documented separately below.
     29 
     30 Note that in general Flot gives no guarantees if you change any of the
     31 objects you pass in to the plot function or get out of it since
     32 they're not necessarily deep-copied.
     33 
     34 
     35 ## Data Format ##
     36 
     37 The data is an array of data series:
     38 
     39 ```js
     40 [ series1, series2, ... ]
     41 ```
     42 
     43 A series can either be raw data or an object with properties. The raw
     44 data format is an array of points:
     45 
     46 ```js
     47 [ [x1, y1], [x2, y2], ... ]
     48 ```
     49 
     50 E.g.
     51 
     52 ```js
     53 [ [1, 3], [2, 14.01], [3.5, 3.14] ]
     54 ```
     55 
     56 Note that to simplify the internal logic in Flot both the x and y
     57 values must be numbers (even if specifying time series, see below for
     58 how to do this). This is a common problem because you might retrieve
     59 data from the database and serialize them directly to JSON without
     60 noticing the wrong type. If you're getting mysterious errors, double
     61 check that you're inputting numbers and not strings.
     62 
     63 If a null is specified as a point or if one of the coordinates is null
     64 or couldn't be converted to a number, the point is ignored when
     65 drawing. As a special case, a null value for lines is interpreted as a
     66 line segment end, i.e. the points before and after the null value are
     67 not connected.
     68 
     69 Lines and points take two coordinates. For filled lines and bars, you
     70 can specify a third coordinate which is the bottom of the filled
     71 area/bar (defaults to 0).
     72 
     73 The format of a single series object is as follows:
     74 
     75 ```js
     76 {
     77     color: color or number
     78     data: rawdata
     79     label: string
     80     lines: specific lines options
     81     bars: specific bars options
     82     points: specific points options
     83     xaxis: number
     84     yaxis: number
     85     clickable: boolean
     86     hoverable: boolean
     87     shadowSize: number
     88     highlightColor: color or number
     89 }
     90 ```
     91 
     92 You don't have to specify any of them except the data, the rest are
     93 options that will get default values. Typically you'd only specify
     94 label and data, like this:
     95 
     96 ```js
     97 {
     98     label: "y = 3",
     99     data: [[0, 3], [10, 3]]
    100 }
    101 ```
    102 
    103 The label is used for the legend, if you don't specify one, the series
    104 will not show up in the legend.
    105 
    106 If you don't specify color, the series will get a color from the
    107 auto-generated colors. The color is either a CSS color specification
    108 (like "rgb(255, 100, 123)") or an integer that specifies which of
    109 auto-generated colors to select, e.g. 0 will get color no. 0, etc.
    110 
    111 The latter is mostly useful if you let the user add and remove series,
    112 in which case you can hard-code the color index to prevent the colors
    113 from jumping around between the series.
    114 
    115 The "xaxis" and "yaxis" options specify which axis to use. The axes
    116 are numbered from 1 (default), so { yaxis: 2} means that the series
    117 should be plotted against the second y axis.
    118 
    119 "clickable" and "hoverable" can be set to false to disable
    120 interactivity for specific series if interactivity is turned on in
    121 the plot, see below.
    122 
    123 The rest of the options are all documented below as they are the same
    124 as the default options passed in via the options parameter in the plot
    125 commmand. When you specify them for a specific data series, they will
    126 override the default options for the plot for that data series.
    127 
    128 Here's a complete example of a simple data specification:
    129 
    130 ```js
    131 [ { label: "Foo", data: [ [10, 1], [17, -14], [30, 5] ] },
    132   { label: "Bar", data: [ [11, 13], [19, 11], [30, -7] ] }
    133 ]
    134 ```
    135 
    136 
    137 ## Plot Options ##
    138 
    139 All options are completely optional. They are documented individually
    140 below, to change them you just specify them in an object, e.g.
    141 
    142 ```js
    143 var options = {
    144     series: {
    145         lines: { show: true },
    146         points: { show: true }
    147     }
    148 };
    149 	
    150 $.plot(placeholder, data, options);
    151 ```
    152 
    153 
    154 ## Customizing the legend ##
    155 
    156 ```js
    157 legend: {
    158     show: boolean
    159     labelFormatter: null or (fn: string, series object -> string)
    160     labelBoxBorderColor: color
    161     noColumns: number
    162     position: "ne" or "nw" or "se" or "sw"
    163     margin: number of pixels or [x margin, y margin]
    164     backgroundColor: null or color
    165     backgroundOpacity: number between 0 and 1
    166     container: null or jQuery object/DOM element/jQuery expression
    167     sorted: null/false, true, "ascending", "descending", "reverse", or a comparator
    168 }
    169 ```
    170 
    171 The legend is generated as a table with the data series labels and
    172 small label boxes with the color of the series. If you want to format
    173 the labels in some way, e.g. make them to links, you can pass in a
    174 function for "labelFormatter". Here's an example that makes them
    175 clickable:
    176 
    177 ```js
    178 labelFormatter: function(label, series) {
    179     // series is the series object for the label
    180     return '<a href="#' + label + '">' + label + '</a>';
    181 }
    182 ```
    183 
    184 To prevent a series from showing up in the legend, simply have the function
    185 return null.
    186 
    187 "noColumns" is the number of columns to divide the legend table into.
    188 "position" specifies the overall placement of the legend within the
    189 plot (top-right, top-left, etc.) and margin the distance to the plot
    190 edge (this can be either a number or an array of two numbers like [x,
    191 y]). "backgroundColor" and "backgroundOpacity" specifies the
    192 background. The default is a partly transparent auto-detected
    193 background.
    194 
    195 If you want the legend to appear somewhere else in the DOM, you can
    196 specify "container" as a jQuery object/expression to put the legend
    197 table into. The "position" and "margin" etc. options will then be
    198 ignored. Note that Flot will overwrite the contents of the container.
    199 
    200 Legend entries appear in the same order as their series by default. If "sorted"
    201 is "reverse" then they appear in the opposite order from their series. To sort
    202 them alphabetically, you can specify true, "ascending" or "descending", where
    203 true and "ascending" are equivalent.
    204 
    205 You can also provide your own comparator function that accepts two
    206 objects with "label" and "color" properties, and returns zero if they
    207 are equal, a positive value if the first is greater than the second,
    208 and a negative value if the first is less than the second.
    209 
    210 ```js
    211 sorted: function(a, b) {
    212     // sort alphabetically in ascending order
    213     return a.label == b.label ? 0 : (
    214         a.label > b.label ? 1 : -1
    215     )
    216 }
    217 ```
    218 
    219 
    220 ## Customizing the axes ##
    221 
    222 ```js
    223 xaxis, yaxis: {
    224     show: null or true/false
    225     position: "bottom" or "top" or "left" or "right"
    226     mode: null or "time" ("time" requires jquery.flot.time.js plugin)
    227     timezone: null, "browser" or timezone (only makes sense for mode: "time")
    228 
    229     color: null or color spec
    230     tickColor: null or color spec
    231     font: null or font spec object
    232 
    233     min: null or number
    234     max: null or number
    235     autoscaleMargin: null or number
    236     
    237     transform: null or fn: number -> number
    238     inverseTransform: null or fn: number -> number
    239     
    240     ticks: null or number or ticks array or (fn: axis -> ticks array)
    241     tickSize: number or array
    242     minTickSize: number or array
    243     tickFormatter: (fn: number, object -> string) or string
    244     tickDecimals: null or number
    245 
    246     labelWidth: null or number
    247     labelHeight: null or number
    248     reserveSpace: null or true
    249     
    250     tickLength: null or number
    251 
    252     alignTicksWithAxis: null or number
    253 }
    254 ```
    255 
    256 All axes have the same kind of options. The following describes how to
    257 configure one axis, see below for what to do if you've got more than
    258 one x axis or y axis.
    259 
    260 If you don't set the "show" option (i.e. it is null), visibility is
    261 auto-detected, i.e. the axis will show up if there's data associated
    262 with it. You can override this by setting the "show" option to true or
    263 false.
    264 
    265 The "position" option specifies where the axis is placed, bottom or
    266 top for x axes, left or right for y axes. The "mode" option determines
    267 how the data is interpreted, the default of null means as decimal
    268 numbers. Use "time" for time series data; see the time series data
    269 section. The time plugin (jquery.flot.time.js) is required for time
    270 series support.
    271 
    272 The "color" option determines the color of the line and ticks for the axis, and
    273 defaults to the grid color with transparency. For more fine-grained control you
    274 can also set the color of the ticks separately with "tickColor".
    275 
    276 You can customize the font and color used to draw the axis tick labels with CSS
    277 or directly via the "font" option. When "font" is null - the default - each
    278 tick label is given the 'flot-tick-label' class. For compatibility with Flot
    279 0.7 and earlier the labels are also given the 'tickLabel' class, but this is
    280 deprecated and scheduled to be removed with the release of version 1.0.0.
    281 
    282 To enable more granular control over styles, labels are divided between a set
    283 of text containers, with each holding the labels for one axis. These containers
    284 are given the classes 'flot-[x|y]-axis', and 'flot-[x|y]#-axis', where '#' is
    285 the number of the axis when there are multiple axes.  For example, the x-axis
    286 labels for a simple plot with only a single x-axis might look like this:
    287 
    288 ```html
    289 <div class='flot-x-axis flot-x1-axis'>
    290     <div class='flot-tick-label'>January 2013</div>
    291     ...
    292 </div>
    293 ```
    294 
    295 For direct control over label styles you can also provide "font" as an object
    296 with this format:
    297 
    298 ```js
    299 {
    300     size: 11,
    301     lineHeight: 13,
    302     style: "italic",
    303     weight: "bold",
    304     family: "sans-serif",
    305     variant: "small-caps",
    306     color: "#545454"
    307 }
    308 ```
    309 
    310 The size and lineHeight must be expressed in pixels; CSS units such as 'em'
    311 or 'smaller' are not allowed.
    312 
    313 The options "min"/"max" are the precise minimum/maximum value on the
    314 scale. If you don't specify either of them, a value will automatically
    315 be chosen based on the minimum/maximum data values. Note that Flot
    316 always examines all the data values you feed to it, even if a
    317 restriction on another axis may make some of them invisible (this
    318 makes interactive use more stable).
    319 
    320 The "autoscaleMargin" is a bit esoteric: it's the fraction of margin
    321 that the scaling algorithm will add to avoid that the outermost points
    322 ends up on the grid border. Note that this margin is only applied when
    323 a min or max value is not explicitly set. If a margin is specified,
    324 the plot will furthermore extend the axis end-point to the nearest
    325 whole tick. The default value is "null" for the x axes and 0.02 for y
    326 axes which seems appropriate for most cases.
    327 
    328 "transform" and "inverseTransform" are callbacks you can put in to
    329 change the way the data is drawn. You can design a function to
    330 compress or expand certain parts of the axis non-linearly, e.g.
    331 suppress weekends or compress far away points with a logarithm or some
    332 other means. When Flot draws the plot, each value is first put through
    333 the transform function. Here's an example, the x axis can be turned
    334 into a natural logarithm axis with the following code:
    335 
    336 ```js
    337 xaxis: {
    338     transform: function (v) { return Math.log(v); },
    339     inverseTransform: function (v) { return Math.exp(v); }
    340 }
    341 ```
    342 
    343 Similarly, for reversing the y axis so the values appear in inverse
    344 order:
    345 
    346 ```js
    347 yaxis: {
    348     transform: function (v) { return -v; },
    349     inverseTransform: function (v) { return -v; }
    350 }
    351 ```
    352 
    353 Note that for finding extrema, Flot assumes that the transform
    354 function does not reorder values (it should be monotone).
    355 
    356 The inverseTransform is simply the inverse of the transform function
    357 (so v == inverseTransform(transform(v)) for all relevant v). It is
    358 required for converting from canvas coordinates to data coordinates,
    359 e.g. for a mouse interaction where a certain pixel is clicked. If you
    360 don't use any interactive features of Flot, you may not need it.
    361 
    362 
    363 The rest of the options deal with the ticks.
    364 
    365 If you don't specify any ticks, a tick generator algorithm will make
    366 some for you. The algorithm has two passes. It first estimates how
    367 many ticks would be reasonable and uses this number to compute a nice
    368 round tick interval size. Then it generates the ticks.
    369 
    370 You can specify how many ticks the algorithm aims for by setting
    371 "ticks" to a number. The algorithm always tries to generate reasonably
    372 round tick values so even if you ask for three ticks, you might get
    373 five if that fits better with the rounding. If you don't want any
    374 ticks at all, set "ticks" to 0 or an empty array.
    375 
    376 Another option is to skip the rounding part and directly set the tick
    377 interval size with "tickSize". If you set it to 2, you'll get ticks at
    378 2, 4, 6, etc. Alternatively, you can specify that you just don't want
    379 ticks at a size less than a specific tick size with "minTickSize".
    380 Note that for time series, the format is an array like [2, "month"],
    381 see the next section.
    382 
    383 If you want to completely override the tick algorithm, you can specify
    384 an array for "ticks", either like this:
    385 
    386 ```js
    387 ticks: [0, 1.2, 2.4]
    388 ```
    389 
    390 Or like this where the labels are also customized:
    391 
    392 ```js
    393 ticks: [[0, "zero"], [1.2, "one mark"], [2.4, "two marks"]]
    394 ```
    395 
    396 You can mix the two if you like.
    397   
    398 For extra flexibility you can specify a function as the "ticks"
    399 parameter. The function will be called with an object with the axis
    400 min and max and should return a ticks array. Here's a simplistic tick
    401 generator that spits out intervals of pi, suitable for use on the x
    402 axis for trigonometric functions:
    403 
    404 ```js
    405 function piTickGenerator(axis) {
    406     var res = [], i = Math.floor(axis.min / Math.PI);
    407     do {
    408         var v = i * Math.PI;
    409         res.push([v, i + "\u03c0"]);
    410         ++i;
    411     } while (v < axis.max);
    412     return res;
    413 }
    414 ```
    415 
    416 You can control how the ticks look like with "tickDecimals", the
    417 number of decimals to display (default is auto-detected).
    418 
    419 Alternatively, for ultimate control over how ticks are formatted you can
    420 provide a function to "tickFormatter". The function is passed two
    421 parameters, the tick value and an axis object with information, and
    422 should return a string. The default formatter looks like this:
    423 
    424 ```js
    425 function formatter(val, axis) {
    426     return val.toFixed(axis.tickDecimals);
    427 }
    428 ```
    429 
    430 The axis object has "min" and "max" with the range of the axis,
    431 "tickDecimals" with the number of decimals to round the value to and
    432 "tickSize" with the size of the interval between ticks as calculated
    433 by the automatic axis scaling algorithm (or specified by you). Here's
    434 an example of a custom formatter:
    435 
    436 ```js
    437 function suffixFormatter(val, axis) {
    438     if (val > 1000000)
    439         return (val / 1000000).toFixed(axis.tickDecimals) + " MB";
    440     else if (val > 1000)
    441         return (val / 1000).toFixed(axis.tickDecimals) + " kB";
    442     else
    443         return val.toFixed(axis.tickDecimals) + " B";
    444 }
    445 ```
    446 
    447 "labelWidth" and "labelHeight" specifies a fixed size of the tick
    448 labels in pixels. They're useful in case you need to align several
    449 plots. "reserveSpace" means that even if an axis isn't shown, Flot
    450 should reserve space for it - it is useful in combination with
    451 labelWidth and labelHeight for aligning multi-axis charts.
    452 
    453 "tickLength" is the length of the tick lines in pixels. By default, the
    454 innermost axes will have ticks that extend all across the plot, while
    455 any extra axes use small ticks. A value of null means use the default,
    456 while a number means small ticks of that length - set it to 0 to hide
    457 the lines completely.
    458 
    459 If you set "alignTicksWithAxis" to the number of another axis, e.g.
    460 alignTicksWithAxis: 1, Flot will ensure that the autogenerated ticks
    461 of this axis are aligned with the ticks of the other axis. This may
    462 improve the looks, e.g. if you have one y axis to the left and one to
    463 the right, because the grid lines will then match the ticks in both
    464 ends. The trade-off is that the forced ticks won't necessarily be at
    465 natural places.
    466 
    467 
    468 ## Multiple axes ##
    469 
    470 If you need more than one x axis or y axis, you need to specify for
    471 each data series which axis they are to use, as described under the
    472 format of the data series, e.g. { data: [...], yaxis: 2 } specifies
    473 that a series should be plotted against the second y axis.
    474 
    475 To actually configure that axis, you can't use the xaxis/yaxis options
    476 directly - instead there are two arrays in the options:
    477 
    478 ```js
    479 xaxes: []
    480 yaxes: []
    481 ```
    482 
    483 Here's an example of configuring a single x axis and two y axes (we
    484 can leave options of the first y axis empty as the defaults are fine):
    485 
    486 ```js
    487 {
    488     xaxes: [ { position: "top" } ],
    489     yaxes: [ { }, { position: "right", min: 20 } ]
    490 }
    491 ```
    492 
    493 The arrays get their default values from the xaxis/yaxis settings, so
    494 say you want to have all y axes start at zero, you can simply specify
    495 yaxis: { min: 0 } instead of adding a min parameter to all the axes.
    496 
    497 Generally, the various interfaces in Flot dealing with data points
    498 either accept an xaxis/yaxis parameter to specify which axis number to
    499 use (starting from 1), or lets you specify the coordinate directly as
    500 x2/x3/... or x2axis/x3axis/... instead of "x" or "xaxis".
    501 
    502 
    503 ## Time series data ##
    504 
    505 Please note that it is now required to include the time plugin,
    506 jquery.flot.time.js, for time series support.
    507 
    508 Time series are a bit more difficult than scalar data because
    509 calendars don't follow a simple base 10 system. For many cases, Flot
    510 abstracts most of this away, but it can still be a bit difficult to
    511 get the data into Flot. So we'll first discuss the data format.
    512 
    513 The time series support in Flot is based on Javascript timestamps,
    514 i.e. everywhere a time value is expected or handed over, a Javascript
    515 timestamp number is used. This is a number, not a Date object. A
    516 Javascript timestamp is the number of milliseconds since January 1,
    517 1970 00:00:00 UTC. This is almost the same as Unix timestamps, except it's
    518 in milliseconds, so remember to multiply by 1000!
    519 
    520 You can see a timestamp like this
    521 
    522 ```js
    523 alert((new Date()).getTime())
    524 ```
    525 
    526 There are different schools of thought when it comes to diplay of
    527 timestamps. Many will want the timestamps to be displayed according to
    528 a certain time zone, usually the time zone in which the data has been
    529 produced. Some want the localized experience, where the timestamps are
    530 displayed according to the local time of the visitor. Flot supports
    531 both. Optionally you can include a third-party library to get
    532 additional timezone support.
    533 
    534 Default behavior is that Flot always displays timestamps according to
    535 UTC. The reason being that the core Javascript Date object does not
    536 support other fixed time zones. Often your data is at another time
    537 zone, so it may take a little bit of tweaking to work around this
    538 limitation.
    539 
    540 The easiest way to think about it is to pretend that the data
    541 production time zone is UTC, even if it isn't. So if you have a
    542 datapoint at 2002-02-20 08:00, you can generate a timestamp for eight
    543 o'clock UTC even if it really happened eight o'clock UTC+0200.
    544 
    545 In PHP you can get an appropriate timestamp with:
    546 
    547 ```php
    548 strtotime("2002-02-20 UTC") * 1000
    549 ```
    550 
    551 In Python you can get it with something like:
    552 
    553 ```python
    554 calendar.timegm(datetime_object.timetuple()) * 1000
    555 ```
    556 
    557 In .NET you can get it with something like:
    558 
    559 ```aspx
    560 public static int GetJavascriptTimestamp(System.DateTime input)
    561 {
    562     System.TimeSpan span = new System.TimeSpan(System.DateTime.Parse("1/1/1970").Ticks);
    563     System.DateTime time = input.Subtract(span);
    564     return (long)(time.Ticks / 10000);
    565 }
    566 ```
    567 
    568 Javascript also has some support for parsing date strings, so it is
    569 possible to generate the timestamps manually client-side.
    570 
    571 If you've already got the real UTC timestamp, it's too late to use the
    572 pretend trick described above. But you can fix up the timestamps by
    573 adding the time zone offset, e.g. for UTC+0200 you would add 2 hours
    574 to the UTC timestamp you got. Then it'll look right on the plot. Most
    575 programming environments have some means of getting the timezone
    576 offset for a specific date (note that you need to get the offset for
    577 each individual timestamp to account for daylight savings).
    578 
    579 The alternative with core Javascript is to interpret the timestamps
    580 according to the time zone that the visitor is in, which means that
    581 the ticks will shift with the time zone and daylight savings of each
    582 visitor. This behavior is enabled by setting the axis option
    583 "timezone" to the value "browser".
    584 
    585 If you need more time zone functionality than this, there is still
    586 another option. If you include the "timezone-js" library
    587 <https://github.com/mde/timezone-js> in the page and set axis.timezone
    588 to a value recognized by said library, Flot will use timezone-js to
    589 interpret the timestamps according to that time zone.
    590 
    591 Once you've gotten the timestamps into the data and specified "time"
    592 as the axis mode, Flot will automatically generate relevant ticks and
    593 format them. As always, you can tweak the ticks via the "ticks" option
    594 - just remember that the values should be timestamps (numbers), not
    595 Date objects.
    596 
    597 Tick generation and formatting can also be controlled separately
    598 through the following axis options:
    599 
    600 ```js
    601 minTickSize: array
    602 timeformat: null or format string
    603 monthNames: null or array of size 12 of strings
    604 dayNames: null or array of size 7 of strings
    605 twelveHourClock: boolean
    606 ```
    607 
    608 Here "timeformat" is a format string to use. You might use it like
    609 this:
    610 
    611 ```js
    612 xaxis: {
    613     mode: "time",
    614     timeformat: "%Y/%m/%d"
    615 }
    616 ```
    617 
    618 This will result in tick labels like "2000/12/24". A subset of the
    619 standard strftime specifiers are supported (plus the nonstandard %q):
    620 
    621 ```js
    622 %a: weekday name (customizable)
    623 %b: month name (customizable)
    624 %d: day of month, zero-padded (01-31)
    625 %e: day of month, space-padded ( 1-31)
    626 %H: hours, 24-hour time, zero-padded (00-23)
    627 %I: hours, 12-hour time, zero-padded (01-12)
    628 %m: month, zero-padded (01-12)
    629 %M: minutes, zero-padded (00-59)
    630 %q: quarter (1-4)
    631 %S: seconds, zero-padded (00-59)
    632 %y: year (two digits)
    633 %Y: year (four digits)
    634 %p: am/pm
    635 %P: AM/PM (uppercase version of %p)
    636 %w: weekday as number (0-6, 0 being Sunday)
    637 ```
    638 
    639 Flot 0.8 switched from %h to the standard %H hours specifier. The %h specifier
    640 is still available, for backwards-compatibility, but is deprecated and
    641 scheduled to be removed permanently with the release of version 1.0.
    642 
    643 You can customize the month names with the "monthNames" option. For
    644 instance, for Danish you might specify:
    645 
    646 ```js
    647 monthNames: ["jan", "feb", "mar", "apr", "maj", "jun", "jul", "aug", "sep", "okt", "nov", "dec"]
    648 ```
    649 
    650 Similarly you can customize the weekday names with the "dayNames"
    651 option. An example in French:
    652 
    653 ```js
    654 dayNames: ["dim", "lun", "mar", "mer", "jeu", "ven", "sam"]
    655 ```
    656 
    657 If you set "twelveHourClock" to true, the autogenerated timestamps
    658 will use 12 hour AM/PM timestamps instead of 24 hour. This only
    659 applies if you have not set "timeformat". Use the "%I" and "%p" or
    660 "%P" options if you want to build your own format string with 12-hour
    661 times.
    662 
    663 If the Date object has a strftime property (and it is a function), it
    664 will be used instead of the built-in formatter. Thus you can include
    665 a strftime library such as http://hacks.bluesmoon.info/strftime/ for
    666 more powerful date/time formatting.
    667 
    668 If everything else fails, you can control the formatting by specifying
    669 a custom tick formatter function as usual. Here's a simple example
    670 which will format December 24 as 24/12:
    671 
    672 ```js
    673 tickFormatter: function (val, axis) {
    674     var d = new Date(val);
    675     return d.getUTCDate() + "/" + (d.getUTCMonth() + 1);
    676 }
    677 ```
    678 
    679 Note that for the time mode "tickSize" and "minTickSize" are a bit
    680 special in that they are arrays on the form "[value, unit]" where unit
    681 is one of "second", "minute", "hour", "day", "month" and "year". So
    682 you can specify
    683 
    684 ```js
    685 minTickSize: [1, "month"]
    686 ```
    687 
    688 to get a tick interval size of at least 1 month and correspondingly,
    689 if axis.tickSize is [2, "day"] in the tick formatter, the ticks have
    690 been produced with two days in-between.
    691 
    692 
    693 ## Customizing the data series ##
    694 
    695 ```js
    696 series: {
    697     lines, points, bars: {
    698         show: boolean
    699         lineWidth: number
    700         fill: boolean or number
    701         fillColor: null or color/gradient
    702     }
    703 
    704     lines, bars: {
    705         zero: boolean
    706     }
    707 
    708     points: {
    709         radius: number
    710         symbol: "circle" or function
    711     }
    712 
    713     bars: {
    714         barWidth: number
    715         align: "left", "right" or "center"
    716         horizontal: boolean
    717     }
    718 
    719     lines: {
    720         steps: boolean
    721     }
    722 
    723     shadowSize: number
    724     highlightColor: color or number
    725 }
    726 
    727 colors: [ color1, color2, ... ]
    728 ```
    729 
    730 The options inside "series: {}" are copied to each of the series. So
    731 you can specify that all series should have bars by putting it in the
    732 global options, or override it for individual series by specifying
    733 bars in a particular the series object in the array of data.
    734   
    735 The most important options are "lines", "points" and "bars" that
    736 specify whether and how lines, points and bars should be shown for
    737 each data series. In case you don't specify anything at all, Flot will
    738 default to showing lines (you can turn this off with
    739 lines: { show: false }). You can specify the various types
    740 independently of each other, and Flot will happily draw each of them
    741 in turn (this is probably only useful for lines and points), e.g.
    742 
    743 ```js
    744 var options = {
    745     series: {
    746         lines: { show: true, fill: true, fillColor: "rgba(255, 255, 255, 0.8)" },
    747         points: { show: true, fill: false }
    748     }
    749 };
    750 ```
    751 
    752 "lineWidth" is the thickness of the line or outline in pixels. You can
    753 set it to 0 to prevent a line or outline from being drawn; this will
    754 also hide the shadow.
    755 
    756 "fill" is whether the shape should be filled. For lines, this produces
    757 area graphs. You can use "fillColor" to specify the color of the fill.
    758 If "fillColor" evaluates to false (default for everything except
    759 points which are filled with white), the fill color is auto-set to the
    760 color of the data series. You can adjust the opacity of the fill by
    761 setting fill to a number between 0 (fully transparent) and 1 (fully
    762 opaque).
    763 
    764 For bars, fillColor can be a gradient, see the gradient documentation
    765 below. "barWidth" is the width of the bars in units of the x axis (or
    766 the y axis if "horizontal" is true), contrary to most other measures
    767 that are specified in pixels. For instance, for time series the unit
    768 is milliseconds so 24 * 60 * 60 * 1000 produces bars with the width of
    769 a day. "align" specifies whether a bar should be left-aligned
    770 (default), right-aligned or centered on top of the value it represents. 
    771 When "horizontal" is on, the bars are drawn horizontally, i.e. from the 
    772 y axis instead of the x axis; note that the bar end points are still
    773 defined in the same way so you'll probably want to swap the
    774 coordinates if you've been plotting vertical bars first.
    775 
    776 Area and bar charts normally start from zero, regardless of the data's range.
    777 This is because they convey information through size, and starting from a
    778 different value would distort their meaning. In cases where the fill is purely
    779 for decorative purposes, however, "zero" allows you to override this behavior.
    780 It defaults to true for filled lines and bars; setting it to false tells the
    781 series to use the same automatic scaling as an un-filled line.
    782 
    783 For lines, "steps" specifies whether two adjacent data points are
    784 connected with a straight (possibly diagonal) line or with first a
    785 horizontal and then a vertical line. Note that this transforms the
    786 data by adding extra points.
    787 
    788 For points, you can specify the radius and the symbol. The only
    789 built-in symbol type is circles, for other types you can use a plugin
    790 or define them yourself by specifying a callback:
    791 
    792 ```js
    793 function cross(ctx, x, y, radius, shadow) {
    794     var size = radius * Math.sqrt(Math.PI) / 2;
    795     ctx.moveTo(x - size, y - size);
    796     ctx.lineTo(x + size, y + size);
    797     ctx.moveTo(x - size, y + size);
    798     ctx.lineTo(x + size, y - size);
    799 }
    800 ```
    801 
    802 The parameters are the drawing context, x and y coordinates of the
    803 center of the point, a radius which corresponds to what the circle
    804 would have used and whether the call is to draw a shadow (due to
    805 limited canvas support, shadows are currently faked through extra
    806 draws). It's good practice to ensure that the area covered by the
    807 symbol is the same as for the circle with the given radius, this
    808 ensures that all symbols have approximately the same visual weight.
    809 
    810 "shadowSize" is the default size of shadows in pixels. Set it to 0 to
    811 remove shadows.
    812 
    813 "highlightColor" is the default color of the translucent overlay used
    814 to highlight the series when the mouse hovers over it.
    815 
    816 The "colors" array specifies a default color theme to get colors for
    817 the data series from. You can specify as many colors as you like, like
    818 this:
    819 
    820 ```js
    821 colors: ["#d18b2c", "#dba255", "#919733"]
    822 ```
    823 
    824 If there are more data series than colors, Flot will try to generate
    825 extra colors by lightening and darkening colors in the theme.
    826 
    827 
    828 ## Customizing the grid ##
    829 
    830 ```js
    831 grid: {
    832     show: boolean
    833     aboveData: boolean
    834     color: color
    835     backgroundColor: color/gradient or null
    836     margin: number or margin object
    837     labelMargin: number
    838     axisMargin: number
    839     markings: array of markings or (fn: axes -> array of markings)
    840     borderWidth: number or object with "top", "right", "bottom" and "left" properties with different widths
    841     borderColor: color or null or object with "top", "right", "bottom" and "left" properties with different colors
    842     minBorderMargin: number or null
    843     clickable: boolean
    844     hoverable: boolean
    845     autoHighlight: boolean
    846     mouseActiveRadius: number
    847 }
    848 
    849 interaction: {
    850     redrawOverlayInterval: number or -1
    851 }
    852 ```
    853 
    854 The grid is the thing with the axes and a number of ticks. Many of the
    855 things in the grid are configured under the individual axes, but not
    856 all. "color" is the color of the grid itself whereas "backgroundColor"
    857 specifies the background color inside the grid area, here null means
    858 that the background is transparent. You can also set a gradient, see
    859 the gradient documentation below.
    860 
    861 You can turn off the whole grid including tick labels by setting
    862 "show" to false. "aboveData" determines whether the grid is drawn
    863 above the data or below (below is default).
    864 
    865 "margin" is the space in pixels between the canvas edge and the grid,
    866 which can be either a number or an object with individual margins for
    867 each side, in the form:
    868 
    869 ```js
    870 margin: {
    871     top: top margin in pixels
    872     left: left margin in pixels
    873     bottom: bottom margin in pixels
    874     right: right margin in pixels
    875 }
    876 ```
    877 
    878 "labelMargin" is the space in pixels between tick labels and axis
    879 line, and "axisMargin" is the space in pixels between axes when there
    880 are two next to each other.
    881 
    882 "borderWidth" is the width of the border around the plot. Set it to 0
    883 to disable the border. Set it to an object with "top", "right",
    884 "bottom" and "left" properties to use different widths. You can
    885 also set "borderColor" if you want the border to have a different color
    886 than the grid lines. Set it to an object with "top", "right", "bottom"
    887 and "left" properties to use different colors. "minBorderMargin" controls
    888 the default minimum margin around the border - it's used to make sure
    889 that points aren't accidentally clipped by the canvas edge so by default
    890 the value is computed from the point radius.
    891 
    892 "markings" is used to draw simple lines and rectangular areas in the
    893 background of the plot. You can either specify an array of ranges on
    894 the form { xaxis: { from, to }, yaxis: { from, to } } (with multiple
    895 axes, you can specify coordinates for other axes instead, e.g. as
    896 x2axis/x3axis/...) or with a function that returns such an array given
    897 the axes for the plot in an object as the first parameter.
    898 
    899 You can set the color of markings by specifying "color" in the ranges
    900 object. Here's an example array:
    901 
    902 ```js
    903 markings: [ { xaxis: { from: 0, to: 2 }, yaxis: { from: 10, to: 10 }, color: "#bb0000" }, ... ]
    904 ```
    905 
    906 If you leave out one of the values, that value is assumed to go to the
    907 border of the plot. So for example if you only specify { xaxis: {
    908 from: 0, to: 2 } } it means an area that extends from the top to the
    909 bottom of the plot in the x range 0-2.
    910 
    911 A line is drawn if from and to are the same, e.g.
    912 
    913 ```js
    914 markings: [ { yaxis: { from: 1, to: 1 } }, ... ]
    915 ```
    916 
    917 would draw a line parallel to the x axis at y = 1. You can control the
    918 line width with "lineWidth" in the range object.
    919 
    920 An example function that makes vertical stripes might look like this:
    921 
    922 ```js
    923 markings: function (axes) {
    924     var markings = [];
    925     for (var x = Math.floor(axes.xaxis.min); x < axes.xaxis.max; x += 2)
    926         markings.push({ xaxis: { from: x, to: x + 1 } });
    927     return markings;
    928 }
    929 ```
    930 
    931 If you set "clickable" to true, the plot will listen for click events
    932 on the plot area and fire a "plotclick" event on the placeholder with
    933 a position and a nearby data item object as parameters. The coordinates
    934 are available both in the unit of the axes (not in pixels) and in
    935 global screen coordinates.
    936 
    937 Likewise, if you set "hoverable" to true, the plot will listen for
    938 mouse move events on the plot area and fire a "plothover" event with
    939 the same parameters as the "plotclick" event. If "autoHighlight" is
    940 true (the default), nearby data items are highlighted automatically.
    941 If needed, you can disable highlighting and control it yourself with
    942 the highlight/unhighlight plot methods described elsewhere.
    943 
    944 You can use "plotclick" and "plothover" events like this:
    945 
    946 ```js
    947 $.plot($("#placeholder"), [ d ], { grid: { clickable: true } });
    948 
    949 $("#placeholder").bind("plotclick", function (event, pos, item) {
    950     alert("You clicked at " + pos.x + ", " + pos.y);
    951     // axis coordinates for other axes, if present, are in pos.x2, pos.x3, ...
    952     // if you need global screen coordinates, they are pos.pageX, pos.pageY
    953 
    954     if (item) {
    955         highlight(item.series, item.datapoint);
    956         alert("You clicked a point!");
    957     }
    958 });
    959 ```
    960 
    961 The item object in this example is either null or a nearby object on the form:
    962 
    963 ```js
    964 item: {
    965     datapoint: the point, e.g. [0, 2]
    966     dataIndex: the index of the point in the data array
    967     series: the series object
    968     seriesIndex: the index of the series
    969     pageX, pageY: the global screen coordinates of the point
    970 }
    971 ```
    972 
    973 For instance, if you have specified the data like this 
    974 
    975 ```js
    976 $.plot($("#placeholder"), [ { label: "Foo", data: [[0, 10], [7, 3]] } ], ...);
    977 ```
    978 
    979 and the mouse is near the point (7, 3), "datapoint" is [7, 3],
    980 "dataIndex" will be 1, "series" is a normalized series object with
    981 among other things the "Foo" label in series.label and the color in
    982 series.color, and "seriesIndex" is 0. Note that plugins and options
    983 that transform the data can shift the indexes from what you specified
    984 in the original data array.
    985 
    986 If you use the above events to update some other information and want
    987 to clear out that info in case the mouse goes away, you'll probably
    988 also need to listen to "mouseout" events on the placeholder div.
    989 
    990 "mouseActiveRadius" specifies how far the mouse can be from an item
    991 and still activate it. If there are two or more points within this
    992 radius, Flot chooses the closest item. For bars, the top-most bar
    993 (from the latest specified data series) is chosen.
    994 
    995 If you want to disable interactivity for a specific data series, you
    996 can set "hoverable" and "clickable" to false in the options for that
    997 series, like this:
    998 
    999 ```js
   1000 { data: [...], label: "Foo", clickable: false }
   1001 ```
   1002 
   1003 "redrawOverlayInterval" specifies the maximum time to delay a redraw
   1004 of interactive things (this works as a rate limiting device). The
   1005 default is capped to 60 frames per second. You can set it to -1 to
   1006 disable the rate limiting.
   1007 
   1008 
   1009 ## Specifying gradients ##
   1010 
   1011 A gradient is specified like this:
   1012 
   1013 ```js
   1014 { colors: [ color1, color2, ... ] }
   1015 ```
   1016 
   1017 For instance, you might specify a background on the grid going from
   1018 black to gray like this:
   1019 
   1020 ```js
   1021 grid: {
   1022     backgroundColor: { colors: ["#000", "#999"] }
   1023 }
   1024 ```
   1025 
   1026 For the series you can specify the gradient as an object that
   1027 specifies the scaling of the brightness and the opacity of the series
   1028 color, e.g.
   1029 
   1030 ```js
   1031 { colors: [{ opacity: 0.8 }, { brightness: 0.6, opacity: 0.8 } ] }
   1032 ```
   1033 
   1034 where the first color simply has its alpha scaled, whereas the second
   1035 is also darkened. For instance, for bars the following makes the bars
   1036 gradually disappear, without outline:
   1037 
   1038 ```js
   1039 bars: {
   1040     show: true,
   1041     lineWidth: 0,
   1042     fill: true,
   1043     fillColor: { colors: [ { opacity: 0.8 }, { opacity: 0.1 } ] }
   1044 }
   1045 ```
   1046 
   1047 Flot currently only supports vertical gradients drawn from top to
   1048 bottom because that's what works with IE.
   1049 
   1050 
   1051 ## Plot Methods ##
   1052 
   1053 The Plot object returned from the plot function has some methods you
   1054 can call:
   1055 
   1056  - highlight(series, datapoint)
   1057 
   1058     Highlight a specific datapoint in the data series. You can either
   1059     specify the actual objects, e.g. if you got them from a
   1060     "plotclick" event, or you can specify the indices, e.g.
   1061     highlight(1, 3) to highlight the fourth point in the second series
   1062     (remember, zero-based indexing).
   1063 
   1064  - unhighlight(series, datapoint) or unhighlight()
   1065 
   1066     Remove the highlighting of the point, same parameters as
   1067     highlight.
   1068 
   1069     If you call unhighlight with no parameters, e.g. as
   1070     plot.unhighlight(), all current highlights are removed.
   1071 
   1072  - setData(data)
   1073 
   1074     You can use this to reset the data used. Note that axis scaling,
   1075     ticks, legend etc. will not be recomputed (use setupGrid() to do
   1076     that). You'll probably want to call draw() afterwards.
   1077 
   1078     You can use this function to speed up redrawing a small plot if
   1079     you know that the axes won't change. Put in the new data with
   1080     setData(newdata), call draw(), and you're good to go. Note that
   1081     for large datasets, almost all the time is consumed in draw()
   1082     plotting the data so in this case don't bother.
   1083 
   1084  - setupGrid()
   1085 
   1086     Recalculate and set axis scaling, ticks, legend etc.
   1087 
   1088     Note that because of the drawing model of the canvas, this
   1089     function will immediately redraw (actually reinsert in the DOM)
   1090     the labels and the legend, but not the actual tick lines because
   1091     they're drawn on the canvas. You need to call draw() to get the
   1092     canvas redrawn.
   1093 
   1094  - draw()
   1095 
   1096     Redraws the plot canvas.
   1097 
   1098  - triggerRedrawOverlay()
   1099 
   1100     Schedules an update of an overlay canvas used for drawing
   1101     interactive things like a selection and point highlights. This
   1102     is mostly useful for writing plugins. The redraw doesn't happen
   1103     immediately, instead a timer is set to catch multiple successive
   1104     redraws (e.g. from a mousemove). You can get to the overlay by
   1105     setting up a drawOverlay hook.
   1106 
   1107  - width()/height()
   1108 
   1109     Gets the width and height of the plotting area inside the grid.
   1110     This is smaller than the canvas or placeholder dimensions as some
   1111     extra space is needed (e.g. for labels).
   1112 
   1113  - offset()
   1114 
   1115     Returns the offset of the plotting area inside the grid relative
   1116     to the document, useful for instance for calculating mouse
   1117     positions (event.pageX/Y minus this offset is the pixel position
   1118     inside the plot).
   1119 
   1120  - pointOffset({ x: xpos, y: ypos })
   1121 
   1122     Returns the calculated offset of the data point at (x, y) in data
   1123     space within the placeholder div. If you are working with multiple
   1124     axes, you can specify the x and y axis references, e.g. 
   1125 
   1126     ```js
   1127       o = pointOffset({ x: xpos, y: ypos, xaxis: 2, yaxis: 3 })
   1128       // o.left and o.top now contains the offset within the div
   1129     ````
   1130 
   1131  - resize()
   1132 
   1133     Tells Flot to resize the drawing canvas to the size of the
   1134     placeholder. You need to run setupGrid() and draw() afterwards as
   1135     canvas resizing is a destructive operation. This is used
   1136     internally by the resize plugin.
   1137 
   1138  - shutdown()
   1139 
   1140     Cleans up any event handlers Flot has currently registered. This
   1141     is used internally.
   1142 
   1143 There are also some members that let you peek inside the internal
   1144 workings of Flot which is useful in some cases. Note that if you change
   1145 something in the objects returned, you're changing the objects used by
   1146 Flot to keep track of its state, so be careful.
   1147 
   1148   - getData()
   1149 
   1150     Returns an array of the data series currently used in normalized
   1151     form with missing settings filled in according to the global
   1152     options. So for instance to find out what color Flot has assigned
   1153     to the data series, you could do this:
   1154 
   1155     ```js
   1156     var series = plot.getData();
   1157     for (var i = 0; i < series.length; ++i)
   1158         alert(series[i].color);
   1159     ```
   1160 
   1161     A notable other interesting field besides color is datapoints
   1162     which has a field "points" with the normalized data points in a
   1163     flat array (the field "pointsize" is the increment in the flat
   1164     array to get to the next point so for a dataset consisting only of
   1165     (x,y) pairs it would be 2).
   1166 
   1167   - getAxes()
   1168 
   1169     Gets an object with the axes. The axes are returned as the
   1170     attributes of the object, so for instance getAxes().xaxis is the
   1171     x axis.
   1172 
   1173     Various things are stuffed inside an axis object, e.g. you could
   1174     use getAxes().xaxis.ticks to find out what the ticks are for the
   1175     xaxis. Two other useful attributes are p2c and c2p, functions for
   1176     transforming from data point space to the canvas plot space and
   1177     back. Both returns values that are offset with the plot offset.
   1178     Check the Flot source code for the complete set of attributes (or
   1179     output an axis with console.log() and inspect it).
   1180 
   1181     With multiple axes, the extra axes are returned as x2axis, x3axis,
   1182     etc., e.g. getAxes().y2axis is the second y axis. You can check
   1183     y2axis.used to see whether the axis is associated with any data
   1184     points and y2axis.show to see if it is currently shown. 
   1185  
   1186   - getPlaceholder()
   1187 
   1188     Returns placeholder that the plot was put into. This can be useful
   1189     for plugins for adding DOM elements or firing events.
   1190 
   1191   - getCanvas()
   1192 
   1193     Returns the canvas used for drawing in case you need to hack on it
   1194     yourself. You'll probably need to get the plot offset too.
   1195   
   1196   - getPlotOffset()
   1197 
   1198     Gets the offset that the grid has within the canvas as an object
   1199     with distances from the canvas edges as "left", "right", "top",
   1200     "bottom". I.e., if you draw a circle on the canvas with the center
   1201     placed at (left, top), its center will be at the top-most, left
   1202     corner of the grid.
   1203 
   1204   - getOptions()
   1205 
   1206     Gets the options for the plot, normalized, with default values
   1207     filled in. You get a reference to actual values used by Flot, so
   1208     if you modify the values in here, Flot will use the new values.
   1209     If you change something, you probably have to call draw() or
   1210     setupGrid() or triggerRedrawOverlay() to see the change.
   1211     
   1212 
   1213 ## Hooks ##
   1214 
   1215 In addition to the public methods, the Plot object also has some hooks
   1216 that can be used to modify the plotting process. You can install a
   1217 callback function at various points in the process, the function then
   1218 gets access to the internal data structures in Flot.
   1219 
   1220 Here's an overview of the phases Flot goes through:
   1221 
   1222   1. Plugin initialization, parsing options
   1223   
   1224   2. Constructing the canvases used for drawing
   1225 
   1226   3. Set data: parsing data specification, calculating colors,
   1227      copying raw data points into internal format,
   1228      normalizing them, finding max/min for axis auto-scaling
   1229 
   1230   4. Grid setup: calculating axis spacing, ticks, inserting tick
   1231      labels, the legend
   1232 
   1233   5. Draw: drawing the grid, drawing each of the series in turn
   1234 
   1235   6. Setting up event handling for interactive features
   1236 
   1237   7. Responding to events, if any
   1238 
   1239   8. Shutdown: this mostly happens in case a plot is overwritten 
   1240 
   1241 Each hook is simply a function which is put in the appropriate array.
   1242 You can add them through the "hooks" option, and they are also available
   1243 after the plot is constructed as the "hooks" attribute on the returned
   1244 plot object, e.g.
   1245 
   1246 ```js
   1247   // define a simple draw hook
   1248   function hellohook(plot, canvascontext) { alert("hello!"); };
   1249 
   1250   // pass it in, in an array since we might want to specify several
   1251   var plot = $.plot(placeholder, data, { hooks: { draw: [hellohook] } });
   1252 
   1253   // we can now find it again in plot.hooks.draw[0] unless a plugin
   1254   // has added other hooks
   1255 ```
   1256 
   1257 The available hooks are described below. All hook callbacks get the
   1258 plot object as first parameter. You can find some examples of defined
   1259 hooks in the plugins bundled with Flot.
   1260 
   1261  - processOptions  [phase 1]
   1262 
   1263     ```function(plot, options)```
   1264    
   1265     Called after Flot has parsed and merged options. Useful in the
   1266     instance where customizations beyond simple merging of default
   1267     values is needed. A plugin might use it to detect that it has been
   1268     enabled and then turn on or off other options.
   1269 
   1270  
   1271  - processRawData  [phase 3]
   1272 
   1273     ```function(plot, series, data, datapoints)```
   1274  
   1275     Called before Flot copies and normalizes the raw data for the given
   1276     series. If the function fills in datapoints.points with normalized
   1277     points and sets datapoints.pointsize to the size of the points,
   1278     Flot will skip the copying/normalization step for this series.
   1279    
   1280     In any case, you might be interested in setting datapoints.format,
   1281     an array of objects for specifying how a point is normalized and
   1282     how it interferes with axis scaling. It accepts the following options:
   1283 
   1284     ```js
   1285     {
   1286         x, y: boolean,
   1287         number: boolean,
   1288         required: boolean,
   1289         defaultValue: value,
   1290         autoscale: boolean
   1291     }
   1292     ```
   1293 
   1294     "x" and "y" specify whether the value is plotted against the x or y axis,
   1295     and is currently used only to calculate axis min-max ranges. The default
   1296     format array, for example, looks like this:
   1297 
   1298     ```js
   1299     [
   1300         { x: true, number: true, required: true },
   1301         { y: true, number: true, required: true }
   1302     ]
   1303     ```
   1304 
   1305     This indicates that a point, i.e. [0, 25], consists of two values, with the
   1306     first being plotted on the x axis and the second on the y axis.
   1307 
   1308     If "number" is true, then the value must be numeric, and is set to null if
   1309     it cannot be converted to a number.
   1310 
   1311     "defaultValue" provides a fallback in case the original value is null. This
   1312     is for instance handy for bars, where one can omit the third coordinate
   1313     (the bottom of the bar), which then defaults to zero.
   1314 
   1315     If "required" is true, then the value must exist (be non-null) for the
   1316     point as a whole to be valid. If no value is provided, then the entire
   1317     point is cleared out with nulls, turning it into a gap in the series.
   1318 
   1319     "autoscale" determines whether the value is considered when calculating an
   1320     automatic min-max range for the axes that the value is plotted against.
   1321 
   1322  - processDatapoints  [phase 3]
   1323 
   1324     ```function(plot, series, datapoints)```
   1325 
   1326     Called after normalization of the given series but before finding
   1327     min/max of the data points. This hook is useful for implementing data
   1328     transformations. "datapoints" contains the normalized data points in
   1329     a flat array as datapoints.points with the size of a single point
   1330     given in datapoints.pointsize. Here's a simple transform that
   1331     multiplies all y coordinates by 2:
   1332 
   1333     ```js
   1334     function multiply(plot, series, datapoints) {
   1335         var points = datapoints.points, ps = datapoints.pointsize;
   1336         for (var i = 0; i < points.length; i += ps)
   1337             points[i + 1] *= 2;
   1338     }
   1339     ```
   1340 
   1341     Note that you must leave datapoints in a good condition as Flot
   1342     doesn't check it or do any normalization on it afterwards.
   1343 
   1344  - processOffset  [phase 4]
   1345 
   1346     ```function(plot, offset)```
   1347 
   1348     Called after Flot has initialized the plot's offset, but before it
   1349     draws any axes or plot elements. This hook is useful for customizing
   1350     the margins between the grid and the edge of the canvas. "offset" is
   1351     an object with attributes "top", "bottom", "left" and "right",
   1352     corresponding to the margins on the four sides of the plot.
   1353 
   1354  - drawBackground [phase 5]
   1355 
   1356     ```function(plot, canvascontext)```
   1357 
   1358     Called before all other drawing operations. Used to draw backgrounds
   1359     or other custom elements before the plot or axes have been drawn.
   1360 
   1361  - drawSeries  [phase 5]
   1362 
   1363     ```function(plot, canvascontext, series)```
   1364 
   1365     Hook for custom drawing of a single series. Called just before the
   1366     standard drawing routine has been called in the loop that draws
   1367     each series.
   1368 
   1369  - draw  [phase 5]
   1370 
   1371     ```function(plot, canvascontext)```
   1372 
   1373     Hook for drawing on the canvas. Called after the grid is drawn
   1374     (unless it's disabled or grid.aboveData is set) and the series have
   1375     been plotted (in case any points, lines or bars have been turned
   1376     on). For examples of how to draw things, look at the source code.
   1377 
   1378  - bindEvents  [phase 6]
   1379 
   1380     ```function(plot, eventHolder)```
   1381 
   1382     Called after Flot has setup its event handlers. Should set any
   1383     necessary event handlers on eventHolder, a jQuery object with the
   1384     canvas, e.g.
   1385 
   1386     ```js
   1387     function (plot, eventHolder) {
   1388         eventHolder.mousedown(function (e) {
   1389             alert("You pressed the mouse at " + e.pageX + " " + e.pageY);
   1390         });
   1391     }
   1392     ```
   1393 
   1394     Interesting events include click, mousemove, mouseup/down. You can
   1395     use all jQuery events. Usually, the event handlers will update the
   1396     state by drawing something (add a drawOverlay hook and call
   1397     triggerRedrawOverlay) or firing an externally visible event for
   1398     user code. See the crosshair plugin for an example.
   1399      
   1400     Currently, eventHolder actually contains both the static canvas
   1401     used for the plot itself and the overlay canvas used for
   1402     interactive features because some versions of IE get the stacking
   1403     order wrong. The hook only gets one event, though (either for the
   1404     overlay or for the static canvas).
   1405 
   1406     Note that custom plot events generated by Flot are not generated on
   1407     eventHolder, but on the div placeholder supplied as the first
   1408     argument to the plot call. You can get that with
   1409     plot.getPlaceholder() - that's probably also the one you should use
   1410     if you need to fire a custom event.
   1411 
   1412  - drawOverlay  [phase 7]
   1413 
   1414     ```function (plot, canvascontext)```
   1415 
   1416     The drawOverlay hook is used for interactive things that need a
   1417     canvas to draw on. The model currently used by Flot works the way
   1418     that an extra overlay canvas is positioned on top of the static
   1419     canvas. This overlay is cleared and then completely redrawn
   1420     whenever something interesting happens. This hook is called when
   1421     the overlay canvas is to be redrawn.
   1422 
   1423     "canvascontext" is the 2D context of the overlay canvas. You can
   1424     use this to draw things. You'll most likely need some of the
   1425     metrics computed by Flot, e.g. plot.width()/plot.height(). See the
   1426     crosshair plugin for an example.
   1427 
   1428  - shutdown  [phase 8]
   1429 
   1430     ```function (plot, eventHolder)```
   1431 
   1432     Run when plot.shutdown() is called, which usually only happens in
   1433     case a plot is overwritten by a new plot. If you're writing a
   1434     plugin that adds extra DOM elements or event handlers, you should
   1435     add a callback to clean up after you. Take a look at the section in
   1436     PLUGINS.txt for more info.
   1437 
   1438    
   1439 ## Plugins ##
   1440 
   1441 Plugins extend the functionality of Flot. To use a plugin, simply
   1442 include its Javascript file after Flot in the HTML page.
   1443 
   1444 If you're worried about download size/latency, you can concatenate all
   1445 the plugins you use, and Flot itself for that matter, into one big file
   1446 (make sure you get the order right), then optionally run it through a
   1447 Javascript minifier such as YUI Compressor.
   1448 
   1449 Here's a brief explanation of how the plugin plumbings work:
   1450 
   1451 Each plugin registers itself in the global array $.plot.plugins. When
   1452 you make a new plot object with $.plot, Flot goes through this array
   1453 calling the "init" function of each plugin and merging default options
   1454 from the "option" attribute of the plugin. The init function gets a
   1455 reference to the plot object created and uses this to register hooks
   1456 and add new public methods if needed.
   1457 
   1458 See the PLUGINS.txt file for details on how to write a plugin. As the
   1459 above description hints, it's actually pretty easy.
   1460 
   1461 
   1462 ## Version number ##
   1463 
   1464 The version number of Flot is available in ```$.plot.version```.