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