Merge pull request #207 from kberg/master
[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
56 // This function draws bars for a single series. See
57 // multiColumnBarPlotter below for a plotter which can draw multi-series
58 // bar charts.
59 function barChartPlotter(e) {
60 var ctx = e.drawingContext;
61 var points = e.points;
62 var y_bottom = e.dygraph.toDomYCoord(0);
63
64 // The RGBColorParser class is provided by rgbcolor.js, which is
65 // packed in with dygraphs.
66 var color = new RGBColorParser(e.color);
67 color.r = Math.floor((255 + color.r) / 2);
68 color.g = Math.floor((255 + color.g) / 2);
69 color.b = Math.floor((255 + color.b) / 2);
70 ctx.fillStyle = color.toRGB();
71
72 // Find the minimum separation between x-values.
73 // This determines the bar width.
74 var min_sep = Infinity;
75 for (var i = 1; i < points.length; i++) {
76 var sep = points[i].canvasx - points[i - 1].canvasx;
77 if (sep < min_sep) min_sep = sep;
78 }
79 var bar_width = Math.floor(2.0 / 3 * min_sep);
80
81 // Do the actual plotting.
82 for (var i = 0; i < points.length; i++) {
83 var p = points[i];
84 var center_x = p.canvasx;
85
86 ctx.fillRect(center_x - bar_width / 2, p.canvasy,
87 bar_width, y_bottom - p.canvasy);
88
89 ctx.strokeRect(center_x - bar_width / 2, p.canvasy,
90 bar_width, y_bottom - p.canvasy);
91 }
92 }
93
94 g = new Dygraph(
95 document.getElementById("demodiv"),
96 "Date,Widgets Sold\n" +
97 "2012/07/21,10\n" +
98 "2012/07/22,12\n" +
99 "2012/07/23,9\n" +
100 "2012/07/24,16\n" +
101 "2012/07/25,10\n",
102 {
103 legend: 'always',
104 title: 'Daily Widget Sales',
105 includeZero: true,
106 dateWindow: [ Date.parse("2012/07/20"), Date.parse("2012/07/26") ],
107 animatedZooms: true,
108 drawXGrid: false,
109 plotter: barChartPlotter
110 }
111 );
112
113 // The Candle chart plotter is adapted from code written by
114 // Zhenlei Cai (jpenguin@gmail.com)
115 // https://github.com/danvk/dygraphs/pull/141/files
116
117 var BAR_WIDTH = 8;
118 function candlePlotter(e) {
119 // This is the officially endorsed way to plot all the series at once.
120 if (e.seriesIndex !== 0) return;
121
122 var setCount = e.seriesCount;
123 if (setCount != 4) {
124 throw "Exactly 4 prices each point must be provided for candle chart (open close high low)";
125 }
126
127 var prices = [];
128 var price;
129 var sets = e.allSeriesPoints;
130 for (var p = 0 ; p < sets[0].length; p++) {
131 price = {
132 open : sets[0][p].yval,
133 close : sets[1][p].yval,
134 high : sets[2][p].yval,
135 low : sets[3][p].yval,
136 openY : sets[0][p].y,
137 closeY : sets[1][p].y,
138 highY : sets[2][p].y,
139 lowY : sets[3][p].y
140 };
141 prices.push(price);
142 }
143
144 var area = e.plotArea;
145 var ctx = e.drawingContext;
146 ctx.strokeStyle = '#202020';
147 ctx.lineWidth = 0.6;
148
149 for (p = 0 ; p < prices.length; p++) {
150 ctx.beginPath();
151
152 price = prices[p];
153 var topY = area.h * price.highY + area.y;
154 var bottomY = area.h * price.lowY + area.y;
155 var centerX = area.x + sets[0][p].x * area.w;
156 ctx.moveTo(centerX, topY);
157 ctx.lineTo(centerX, bottomY);
158 ctx.closePath();
159 ctx.stroke();
160 var bodyY;
161 if (price.open > price.close) {
162 ctx.fillStyle ='rgba(244,44,44,1.0)';
163 bodyY = area.h * price.openY + area.y;
164 }
165 else {
166 ctx.fillStyle ='rgba(44,244,44,1.0)';
167 bodyY = area.h * price.closeY + area.y;
168 }
169 var bodyHeight = area.h * Math.abs(price.openY - price.closeY);
170 ctx.fillRect(centerX - BAR_WIDTH / 2, bodyY, BAR_WIDTH, bodyHeight);
171 }
172
173 }
174
175 var candleData = "Date,Open,Close,High,Low\n" +
176 "2011-12-06,392.54,390.95,394.63,389.38\n" +
177 "2011-12-07,389.93,389.09,390.94,386.76\n" +
178 "2011-12-08,391.45,390.66,395.50,390.23\n" +
179 "2011-12-09,392.85,393.62,394.04,391.03\n" +
180 "2011-12-12,391.68,391.84,393.90,389.45\n" +
181 "2011-12-13,393.00,388.81,395.40,387.10\n" +
182 "2011-12-14,386.70,380.19,387.38,377.68\n" +
183 "2011-12-15,383.33,378.94,383.74,378.31\n" +
184 "2011-12-16,380.36,381.02,384.15,379.57\n" +
185 "2011-12-19,382.47,382.21,384.85,380.48\n" +
186 "2011-12-20,387.76,395.95,396.10,387.26\n" +
187 "2011-12-21,396.69,396.45,397.30,392.01\n" +
188 "2011-12-22,397.00,398.55,399.13,396.10\n" +
189 "2011-12-23,399.69,403.33,403.59,399.49\n" +
190 "2011-12-27,403.10,406.53,409.09,403.02\n" +
191 "2011-12-28,406.89,402.64,408.25,401.34\n" +
192 "2011-12-29,403.40,405.12,405.65,400.51\n" +
193 "2011-12-30,403.51,405.00,406.28,403.49\n" +
194 "2012-01-03,409.50,411.23,412.50,409.00\n" +
195 "2012-01-04,410.21,413.44,414.68,409.28\n" +
196 "2012-01-05,414.95,418.03,418.55,412.67\n" +
197 "2012-01-06,419.77,422.40,422.75,419.22\n" +
198 "2012-01-09,425.52,421.73,427.75,421.35\n" +
199 "2012-01-10,425.91,423.24,426.00,421.50\n" +
200 "2012-01-11,422.59,422.55,422.85,419.31\n" +
201 "2012-01-12,422.41,421.39,422.90,418.75\n" +
202 "2012-01-13,419.53,419.81,420.45,418.66\n" +
203 "2012-01-17,424.20,424.70,425.99,422.96\n" +
204 "2012-01-18,426.87,429.11,429.47,426.30\n" +
205 "2012-01-19,430.03,427.75,431.37,426.51\n" +
206 "2012-01-20,427.49,420.30,427.50,419.75\n" +
207 "2012-01-23,422.67,427.41,428.45,422.30\n" +
208 "2012-01-24,425.10,420.41,425.10,419.55\n" +
209 "2012-01-25,454.26,446.66,454.45,443.73\n" +
210 "2012-01-26,448.45,444.63,448.79,443.14\n" +
211 "2012-01-27,444.37,447.28,448.48,443.77\n" +
212 "2012-01-30,445.71,453.01,453.90,445.39\n" +
213 "2012-01-31,455.85,456.48,458.24,453.07\n" +
214 "2012-02-01,458.49,456.19,458.99,455.55\n" +
215 "2012-02-02,455.90,455.12,457.17,453.98\n" +
216 "2012-02-03,457.30,459.68,460.00,455.56\n" +
217 "2012-02-06,458.38,463.97,464.98,458.20\n" +
218 "2012-02-07,465.25,468.83,469.75,464.58\n" +
219 "2012-02-08,470.50,476.68,476.79,469.70\n" +
220 "2012-02-09,480.95,493.17,496.75,480.56\n" +
221 "2012-02-10,491.17,493.42,497.62,488.55\n" +
222 "2012-02-13,499.74,502.60,503.83,497.09\n" +
223 "2012-02-14,504.70,509.46,509.56,502.00\n" ;
224
225 g2 = new Dygraph(
226 document.getElementById("candlechart"),
227 candleData,
228 {
229 plotter: candlePlotter
230 });
231
232
233 // Bar and Line chart
234 var short_data = data_nolabel();
235 short_data = short_data.split('\n').slice(0, 20).join('\n');
236
237 g3 = new Dygraph(
238 document.getElementById("barlinechart"),
239 short_data,
240 {
241 labels: ['Date', 'A', 'B'],
242 includeZero: true,
243 "A": {
244 strokeWidth: 2
245 },
246 "B": {
247 plotter: barChartPlotter
248 }
249 });
250
251
252 // Multiple column bar chart
253 function multiColumnBarPlotter(e) {
254 // We need to handle all the series simultaneously.
255 if (e.seriesIndex !== 0) return;
256
257 var g = e.dygraph;
258 var ctx = e.drawingContext;
259 var sets = e.allSeriesPoints;
260 var y_bottom = e.dygraph.toDomYCoord(0);
261
262 // Find the minimum separation between x-values.
263 // This determines the bar width.
264 var min_sep = Infinity;
265 for (var j = 0; j < sets.length; j++) {
266 var points = sets[j];
267 for (var i = 1; i < points.length; i++) {
268 var sep = points[i].canvasx - points[i - 1].canvasx;
269 if (sep < min_sep) min_sep = sep;
270 }
271 }
272 var bar_width = Math.floor(2.0 / 3 * min_sep);
273
274 var fillColors = [];
275 var strokeColors = g.getColors();
276 for (var i = 0; i < strokeColors.length; i++) {
277 var color = new RGBColorParser(strokeColors[i]);
278 color.r = Math.floor((255 + color.r) / 2);
279 color.g = Math.floor((255 + color.g) / 2);
280 color.b = Math.floor((255 + color.b) / 2);
281 fillColors.push(color.toRGB());
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 'A': {
316 plotter: Dygraph.Plotters.errorPlotter
317 },
318 'B': {
319 plotter: Dygraph.Plotters.linePlotter,
320 strokePattern: Dygraph.DASHED_LINE
321 }
322 });
323
324 </script>
325 </body>
326 </html>