1 | ## Writing plugins ##
|
2 |
|
3 | All you need to do to make a new plugin is creating an init function
|
4 | and a set of options (if needed), stuffing it into an object and
|
5 | putting it in the $.plot.plugins array. For example:
|
6 |
|
7 | ```js
|
8 | function myCoolPluginInit(plot) {
|
9 | plot.coolstring = "Hello!";
|
10 | };
|
11 |
|
12 | $.plot.plugins.push({ init: myCoolPluginInit, options: { ... } });
|
13 |
|
14 | // if $.plot is called, it will return a plot object with the
|
15 | // attribute "coolstring"
|
16 | ```
|
17 |
|
18 | Now, given that the plugin might run in many different places, it's
|
19 | a good idea to avoid leaking names. The usual trick here is wrap the
|
20 | above lines in an anonymous function which is called immediately, like
|
21 | this: (function () { inner code ... })(). To make it even more robust
|
22 | in case $ is not bound to jQuery but some other Javascript library, we
|
23 | can write it as
|
24 |
|
25 | ```js
|
26 | (function ($) {
|
27 | // plugin definition
|
28 | // ...
|
29 | })(jQuery);
|
30 | ```
|
31 |
|
32 | There's a complete example below, but you should also check out the
|
33 | plugins bundled with Flot.
|
34 |
|
35 |
|
36 | ## Complete example ##
|
37 |
|
38 | Here is a simple debug plugin which alerts each of the series in the
|
39 | plot. It has a single option that control whether it is enabled and
|
40 | how much info to output:
|
41 |
|
42 | ```js
|
43 | (function ($) {
|
44 | function init(plot) {
|
45 | var debugLevel = 1;
|
46 |
|
47 | function checkDebugEnabled(plot, options) {
|
48 | if (options.debug) {
|
49 | debugLevel = options.debug;
|
50 | plot.hooks.processDatapoints.push(alertSeries);
|
51 | }
|
52 | }
|
53 |
|
54 | function alertSeries(plot, series, datapoints) {
|
55 | var msg = "series " + series.label;
|
56 | if (debugLevel > 1) {
|
57 | msg += " with " + series.data.length + " points";
|
58 | alert(msg);
|
59 | }
|
60 | }
|
61 |
|
62 | plot.hooks.processOptions.push(checkDebugEnabled);
|
63 | }
|
64 |
|
65 | var options = { debug: 0 };
|
66 |
|
67 | $.plot.plugins.push({
|
68 | init: init,
|
69 | options: options,
|
70 | name: "simpledebug",
|
71 | version: "0.1"
|
72 | });
|
73 | })(jQuery);
|
74 | ```
|
75 |
|
76 | We also define "name" and "version". It's not used by Flot, but might
|
77 | be helpful for other plugins in resolving dependencies.
|
78 |
|
79 | Put the above in a file named "jquery.flot.debug.js", include it in an
|
80 | HTML page and then it can be used with:
|
81 |
|
82 | ```js
|
83 | $.plot($("#placeholder"), [...], { debug: 2 });
|
84 | ```
|
85 |
|
86 | This simple plugin illustrates a couple of points:
|
87 |
|
88 | - It uses the anonymous function trick to avoid name pollution.
|
89 | - It can be enabled/disabled through an option.
|
90 | - Variables in the init function can be used to store plot-specific
|
91 | state between the hooks.
|
92 |
|
93 | The two last points are important because there may be multiple plots
|
94 | on the same page, and you'd want to make sure they are not mixed up.
|
95 |
|
96 |
|
97 | ## Shutting down a plugin ##
|
98 |
|
99 | Each plot object has a shutdown hook which is run when plot.shutdown()
|
100 | is called. This usually mostly happens in case another plot is made on
|
101 | top of an existing one.
|
102 |
|
103 | The purpose of the hook is to give you a chance to unbind any event
|
104 | handlers you've registered and remove any extra DOM things you've
|
105 | inserted.
|
106 |
|
107 | The problem with event handlers is that you can have registered a
|
108 | handler which is run in some point in the future, e.g. with
|
109 | setTimeout(). Meanwhile, the plot may have been shutdown and removed,
|
110 | but because your event handler is still referencing it, it can't be
|
111 | garbage collected yet, and worse, if your handler eventually runs, it
|
112 | may overwrite stuff on a completely different plot.
|
113 |
|
114 |
|
115 | ## Some hints on the options ##
|
116 |
|
117 | Plugins should always support appropriate options to enable/disable
|
118 | them because the plugin user may have several plots on the same page
|
119 | where only one should use the plugin. In most cases it's probably a
|
120 | good idea if the plugin is turned off rather than on per default, just
|
121 | like most of the powerful features in Flot.
|
122 |
|
123 | If the plugin needs options that are specific to each series, like the
|
124 | points or lines options in core Flot, you can put them in "series" in
|
125 | the options object, e.g.
|
126 |
|
127 | ```js
|
128 | var options = {
|
129 | series: {
|
130 | downsample: {
|
131 | algorithm: null,
|
132 | maxpoints: 1000
|
133 | }
|
134 | }
|
135 | }
|
136 | ```
|
137 |
|
138 | Then they will be copied by Flot into each series, providing default
|
139 | values in case none are specified.
|
140 |
|
141 | Think hard and long about naming the options. These names are going to
|
142 | be public API, and code is going to depend on them if the plugin is
|
143 | successful.
|