hjg
2024-07-09 30304784e82d4bba24121328da8eb8490aec4f4f
提交 | 用户 | 时间
58d006 1 # Flot Reference #
A 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```.