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