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