Use "legend" option with "follow" value. Hide legend on deselect.
[dygraphs.git] / tests / plotters.html
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7; IE=EmulateIE9">
5 <title>Plotters demo</title>
6 <!--[if IE]>
7 <script type="text/javascript" src="../excanvas.js"></script>
8 <![endif]-->
9 <script type="text/javascript" src="../dygraph-dev.js"></script>
10
11 <script type="text/javascript" src="data.js"></script>
12 <style type="text/css">
13 body {
14 max-width: 750px;
15 }
16 div.chart {
17 width: 640px;
18 height: 320px;
19 }
20 </style>
21 </head>
22 <body>
23 <p>This page demonstrates how to build custom plotters with dygraphs.
24 The <a href="http://dygraphs.com/options.html#plotter">plotter</a> option
25 allows you to write your own drawing logic. This can be used to achieve
26 powerful customization. View source to see how the examples work.</p>
27
28 <h2>Bar Chart</h2>
29 <p>Here a specialized <a
30 href="http://dygraphs.com/options.html#plotter">plotter</a> is used to draw
31 a bar plot rather than a line plot:</p>
32 <div id="demodiv" class=chart></div>
33
34 <h2>Candle Chart</h2>
35 <p>Here a specialized <a
36 href="http://dygraphs.com/options.html#plotter">plotter</a> is used to
37 combined four series into a unified "Candle" plot:</p>
38 <div id="candlechart" class=chart></div>
39
40 <h2>Bar &amp; Line Chart</h2>
41 <p>The <a href="http://dygraphs.com/options.html#plotter">plotter</a>
42 option may be set on a per-series basis to create mixed charts:</p>
43 <div id="barlinechart" class="chart"></div>
44
45 <h2>Multi-column Bar Chart</h2>
46 <div id="multibar" class="chart"></div>
47
48 <h2>Mixed Error Bars and Lines</h2>
49 <p>You can tweak the standard plotters list to achieve effects which would
50 be difficult otherwise, e.g. drawing series with only confidence intervals
51 and showing error bars only for some series.</p>
52 <div id="mixed-error" class="chart"></div>
53
54 <script type="text/javascript">
55 // Darken a color
56 function darkenColor(colorStr) {
57 // Defined in dygraph-utils.js
58 var color = Dygraph.toRGB_(colorStr);
59 color.r = Math.floor((255 + color.r) / 2);
60 color.g = Math.floor((255 + color.g) / 2);
61 color.b = Math.floor((255 + color.b) / 2);
62 return 'rgb(' + color.r + ',' + color.g + ',' + color.b + ')';
63 }
64
65 // This function draws bars for a single series. See
66 // multiColumnBarPlotter below for a plotter which can draw multi-series
67 // bar charts.
68 function barChartPlotter(e) {
69 var ctx = e.drawingContext;
70 var points = e.points;
71 var y_bottom = e.dygraph.toDomYCoord(0);
72
73 ctx.fillStyle = darkenColor(e.color);
74
75 // Find the minimum separation between x-values.
76 // This determines the bar width.
77 var min_sep = Infinity;
78 for (var i = 1; i < points.length; i++) {
79 var sep = points[i].canvasx - points[i - 1].canvasx;
80 if (sep < min_sep) min_sep = sep;
81 }
82 var bar_width = Math.floor(2.0 / 3 * min_sep);
83
84 // Do the actual plotting.
85 for (var i = 0; i < points.length; i++) {
86 var p = points[i];
87 var center_x = p.canvasx;
88
89 ctx.fillRect(center_x - bar_width / 2, p.canvasy,
90 bar_width, y_bottom - p.canvasy);
91
92 ctx.strokeRect(center_x - bar_width / 2, p.canvasy,
93 bar_width, y_bottom - p.canvasy);
94 }
95 }
96
97 g = new Dygraph(
98 document.getElementById("demodiv"),
99 "Date,Widgets Sold\n" +
100 "2012/07/21,10\n" +
101 "2012/07/22,12\n" +
102 "2012/07/23,9\n" +
103 "2012/07/24,16\n" +
104 "2012/07/25,10\n",
105 {
106 legend: 'always',
107 title: 'Daily Widget Sales',
108 includeZero: true,
109 dateWindow: [ Date.parse("2012/07/20"), Date.parse("2012/07/26") ],
110 animatedZooms: true,
111 drawXGrid: false,
112 plotter: barChartPlotter
113 }
114 );
115
116 // The Candle chart plotter is adapted from code written by
117 // Zhenlei Cai (jpenguin@gmail.com)
118 // https://github.com/danvk/dygraphs/pull/141/files
119
120 var BAR_WIDTH = 8;
121 function candlePlotter(e) {
122 // This is the officially endorsed way to plot all the series at once.
123 if (e.seriesIndex !== 0) return;
124
125 var setCount = e.seriesCount;
126 if (setCount != 4) {
127 throw "Exactly 4 prices each point must be provided for candle chart (open close high low)";
128 }
129
130 var prices = [];
131 var price;
132 var sets = e.allSeriesPoints;
133 for (var p = 0 ; p < sets[0].length; p++) {
134 price = {
135 open : sets[0][p].yval,
136 close : sets[1][p].yval,
137 high : sets[2][p].yval,
138 low : sets[3][p].yval,
139 openY : sets[0][p].y,
140 closeY : sets[1][p].y,
141 highY : sets[2][p].y,
142 lowY : sets[3][p].y
143 };
144 prices.push(price);
145 }
146
147 var area = e.plotArea;
148 var ctx = e.drawingContext;
149 ctx.strokeStyle = '#202020';
150 ctx.lineWidth = 0.6;
151
152 for (p = 0 ; p < prices.length; p++) {
153 ctx.beginPath();
154
155 price = prices[p];
156 var topY = area.h * price.highY + area.y;
157 var bottomY = area.h * price.lowY + area.y;
158 var centerX = area.x + sets[0][p].x * area.w;
159 ctx.moveTo(centerX, topY);
160 ctx.lineTo(centerX, bottomY);
161 ctx.closePath();
162 ctx.stroke();
163 var bodyY;
164 if (price.open > price.close) {
165 ctx.fillStyle ='rgba(244,44,44,1.0)';
166 bodyY = area.h * price.openY + area.y;
167 }
168 else {
169 ctx.fillStyle ='rgba(44,244,44,1.0)';
170 bodyY = area.h * price.closeY + area.y;
171 }
172 var bodyHeight = area.h * Math.abs(price.openY - price.closeY);
173 ctx.fillRect(centerX - BAR_WIDTH / 2, bodyY, BAR_WIDTH, bodyHeight);
174 }
175
176 }
177
178 var candleData = "Date,Open,Close,High,Low\n" +
179 "2011-12-06,392.54,390.95,394.63,389.38\n" +
180 "2011-12-07,389.93,389.09,390.94,386.76\n" +
181 "2011-12-08,391.45,390.66,395.50,390.23\n" +
182 "2011-12-09,392.85,393.62,394.04,391.03\n" +
183 "2011-12-12,391.68,391.84,393.90,389.45\n" +
184 "2011-12-13,393.00,388.81,395.40,387.10\n" +
185 "2011-12-14,386.70,380.19,387.38,377.68\n" +
186 "2011-12-15,383.33,378.94,383.74,378.31\n" +
187 "2011-12-16,380.36,381.02,384.15,379.57\n" +
188 "2011-12-19,382.47,382.21,384.85,380.48\n" +
189 "2011-12-20,387.76,395.95,396.10,387.26\n" +
190 "2011-12-21,396.69,396.45,397.30,392.01\n" +
191 "2011-12-22,397.00,398.55,399.13,396.10\n" +
192 "2011-12-23,399.69,403.33,403.59,399.49\n" +
193 "2011-12-27,403.10,406.53,409.09,403.02\n" +
194 "2011-12-28,406.89,402.64,408.25,401.34\n" +
195 "2011-12-29,403.40,405.12,405.65,400.51\n" +
196 "2011-12-30,403.51,405.00,406.28,403.49\n" +
197 "2012-01-03,409.50,411.23,412.50,409.00\n" +
198 "2012-01-04,410.21,413.44,414.68,409.28\n" +
199 "2012-01-05,414.95,418.03,418.55,412.67\n" +
200 "2012-01-06,419.77,422.40,422.75,419.22\n" +
201 "2012-01-09,425.52,421.73,427.75,421.35\n" +
202 "2012-01-10,425.91,423.24,426.00,421.50\n" +
203 "2012-01-11,422.59,422.55,422.85,419.31\n" +
204 "2012-01-12,422.41,421.39,422.90,418.75\n" +
205 "2012-01-13,419.53,419.81,420.45,418.66\n" +
206 "2012-01-17,424.20,424.70,425.99,422.96\n" +
207 "2012-01-18,426.87,429.11,429.47,426.30\n" +
208 "2012-01-19,430.03,427.75,431.37,426.51\n" +
209 "2012-01-20,427.49,420.30,427.50,419.75\n" +
210 "2012-01-23,422.67,427.41,428.45,422.30\n" +
211 "2012-01-24,425.10,420.41,425.10,419.55\n" +
212 "2012-01-25,454.26,446.66,454.45,443.73\n" +
213 "2012-01-26,448.45,444.63,448.79,443.14\n" +
214 "2012-01-27,444.37,447.28,448.48,443.77\n" +
215 "2012-01-30,445.71,453.01,453.90,445.39\n" +
216 "2012-01-31,455.85,456.48,458.24,453.07\n" +
217 "2012-02-01,458.49,456.19,458.99,455.55\n" +
218 "2012-02-02,455.90,455.12,457.17,453.98\n" +
219 "2012-02-03,457.30,459.68,460.00,455.56\n" +
220 "2012-02-06,458.38,463.97,464.98,458.20\n" +
221 "2012-02-07,465.25,468.83,469.75,464.58\n" +
222 "2012-02-08,470.50,476.68,476.79,469.70\n" +
223 "2012-02-09,480.95,493.17,496.75,480.56\n" +
224 "2012-02-10,491.17,493.42,497.62,488.55\n" +
225 "2012-02-13,499.74,502.60,503.83,497.09\n" +
226 "2012-02-14,504.70,509.46,509.56,502.00\n" ;
227
228 g2 = new Dygraph(
229 document.getElementById("candlechart"),
230 candleData,
231 {
232 plotter: candlePlotter
233 });
234
235
236 // Bar and Line chart
237 var short_data = data_nolabel();
238 short_data = short_data.split('\n').slice(0, 20).join('\n');
239
240 g3 = new Dygraph(
241 document.getElementById("barlinechart"),
242 short_data,
243 {
244 labels: ['Date', 'A', 'B'],
245 includeZero: true,
246 "A": {
247 strokeWidth: 2
248 },
249 "B": {
250 plotter: barChartPlotter
251 }
252 });
253
254
255 // Multiple column bar chart
256 function multiColumnBarPlotter(e) {
257 // We need to handle all the series simultaneously.
258 if (e.seriesIndex !== 0) return;
259
260 var g = e.dygraph;
261 var ctx = e.drawingContext;
262 var sets = e.allSeriesPoints;
263 var y_bottom = e.dygraph.toDomYCoord(0);
264
265 // Find the minimum separation between x-values.
266 // This determines the bar width.
267 var min_sep = Infinity;
268 for (var j = 0; j < sets.length; j++) {
269 var points = sets[j];
270 for (var i = 1; i < points.length; i++) {
271 var sep = points[i].canvasx - points[i - 1].canvasx;
272 if (sep < min_sep) min_sep = sep;
273 }
274 }
275 var bar_width = Math.floor(2.0 / 3 * min_sep);
276
277 var fillColors = [];
278 var strokeColors = g.getColors();
279 for (var i = 0; i < strokeColors.length; i++) {
280 fillColors.push(darkenColor(strokeColors[i]));
281 }
282
283 for (var j = 0; j < sets.length; j++) {
284 ctx.fillStyle = fillColors[j];
285 ctx.strokeStyle = strokeColors[j];
286 for (var i = 0; i < sets[j].length; i++) {
287 var p = sets[j][i];
288 var center_x = p.canvasx;
289 var x_left = center_x - (bar_width / 2) * (1 - j/(sets.length-1));
290
291 ctx.fillRect(x_left, p.canvasy,
292 bar_width/sets.length, y_bottom - p.canvasy);
293
294 ctx.strokeRect(x_left, p.canvasy,
295 bar_width/sets.length, y_bottom - p.canvasy);
296 }
297 }
298 }
299
300 g4 = new Dygraph(
301 document.getElementById("multibar"),
302 short_data,
303 {
304 includeZero: true,
305 plotter: multiColumnBarPlotter
306 });
307
308 // Mixed Error Bars and Lines
309 g5 = new Dygraph(
310 document.getElementById("mixed-error"),
311 NoisyData(),
312 {
313 errorBars: true,
314 'A': {
315 plotter: Dygraph.Plotters.errorPlotter
316 },
317 'B': {
318 plotter: Dygraph.Plotters.linePlotter,
319 strokePattern: Dygraph.DASHED_LINE
320 }
321 });
322
323 </script>
324 </body>
325 </html>