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