TEST: Added automated test proving the bugfix made.
[dygraphs.git] / plugins / README
1 dygraphs plugins
2 ----------------
3
4 A single dygraph is actually a collection of dygraphs plugins, each responsible
5 for some portion of the chart: the plot area, the axes, the legend, the labels,
6 etc.
7
8 This forces the dygraphs code to be more modular and encourages better APIs.
9
10 The "legend" plugin (plugins/legend.js) can be used as a template for new
11 plugins.
12
13 Here is a simplified version of it, with comments to explain the plugin
14 lifecycle and APIs:
15
16 ----------------
17
18 // (standard JavaScript library wrapper; prevents polluting global namespace)
19 Dygraph.Plugins.Legend = (function() {
20
21 // Plugin constructor. This is invoked once for every chart which uses the
22 // plugin. You can't actually access the Dygraph object at this point, so the
23 // initialization you do here shouldn't be chart-specific. (For that, use
24 // the activate() method).
25 var legend = function() {
26   this.div_ = null;
27 };
28
29 // Plugins are expected to implement this method for debugging purposes.
30 legend.toString = function() {
31   return "Legend";
32 };
33
34 // This is called once the dygraph is ready. The chart data may not be
35 // available yet, but the options specified in the constructor are.
36 // 
37 // Proper tasks to do here include:
38 // - Reading your own options
39 // - DOM manipulation
40 // - Registering event listeners
41 //
42 // "dygraph" is the Dygraph object for which this instance is being activated.
43 // "registerer" allows you to register event listeners.
44 legend.prototype.activate = function(dygraph, registerer) {
45   // Create the legend div and attach it to the chart DOM.
46   this.div_ = document.createElement("div");
47   dygraph.graphDiv.appendChild(this.div_);
48
49   // Add event listeners. These will be called whenever points are selected
50   // (i.e. you hover over them) or deselected (i.e. you mouse away from the
51   // chart). This is your only chance to register event listeners! Once this
52   // method returns, the gig is up.
53   registerer.addEventListener('select', legend.select);
54   registerer.addEventListener('deselect', legend.deselect);
55 };
56
57 // The functions called by event listeners all take a single parameter, an
58 // event object. This contains properties relevant to the particular event, but
59 // you can always assume that it has:
60 //
61 // 1. A "dygraph" parameter which is a reference to the chart on which the
62 //    event took place.
63 // 2. A "stopPropagation" method, which you can call to prevent the event from
64 //    being seen by any other plugins after you. This effectively cancels the
65 //    event.
66 // 3. A "preventDefault" method, which prevents dygraphs from performing the
67 //    default action associated with this event.
68 //
69 legend.select = function(e) {
70   // These are two of the properties specific to the "select" event object:
71   var xValue = e.selectedX;
72   var points = e.selectedPoints;
73
74   var html = xValue + ':';
75   for (var i = 0; i < points.length; i++) {
76     var point = points[i];
77     html += ' ' + point.name + ':' + point.yval;
78   }
79
80   // In an event listener, "this" refers to your plugin object.
81   this.div_.innerHTML = html;
82 };
83
84 // This clears out the legend when the user mouses away from the chart.
85 legend.deselect = function(e) {
86   this.div_.innerHTML = '';
87 };
88
89 return legend;
90 })();
91
92 ----------------
93
94 Plugin Events Reference:
95
96 - predraw
97 - clearChart
98 - drawChart
99 - select
100 - deselect
101
102 TODO(danvk): document all event properties for each event.
103
104
105 Special methods:
106 - (constructor)
107 - activate
108 - destroy
109
110
111 ----------------
112
113 Notes on plugin registration and event cascade ordering/behavior.