Commit | Line | Data |
---|---|---|
9d3fcd6a PS |
1 | /** |
2 | * @license | |
3 | * Copyright 2015 Petr Shevtsov (petr.shevtsov@gmail.com) | |
4 | * MIT-licensed (http://opensource.org/licenses/MIT) | |
5 | * | |
6 | * Rebase plugin | |
7 | * | |
8 | * On pan/zoom event, each series will rebase to a specified value (e.g. 100) at the | |
9 | * start of the displayed period. | |
10 | * | |
11 | * See http://stats.oecd.org/glossary/detail.asp?ID=2249 | |
12 | * | |
13 | * Options: | |
14 | * Value to rebase. Must be either Number or 'percent' or null. | |
15 | * | |
16 | * See tests/straw-broom.html for demo. | |
17 | */ | |
18 | ||
19 | /*global Dygraph:false */ | |
20 | ||
21 | (function() { | |
178b1e0a | 22 | |
9d3fcd6a PS |
23 | "use strict"; |
24 | ||
178b1e0a DV |
25 | // Matches DefaultHandler.parseFloat |
26 | var parseFloat = function(val) { | |
27 | if (val === null) return NaN; | |
28 | return val; | |
29 | }; | |
30 | ||
9d3fcd6a PS |
31 | Dygraph.DataHandlers.RebaseHandler = function(baseOpt) { |
32 | this.baseOpt = baseOpt; | |
33 | }; | |
34 | ||
35 | var RebaseHandler = Dygraph.DataHandlers.RebaseHandler; | |
36 | RebaseHandler.prototype = new Dygraph.DataHandlers.DefaultHandler(); | |
37 | ||
38 | RebaseHandler.rebase = function(value, initial, base) { | |
39 | if (base === "percent") { | |
40 | return (value / initial - 1) * 100; | |
41 | } | |
42 | return value * base / initial; | |
43 | }; | |
44 | ||
45 | RebaseHandler.prototype.getExtremeYValues = function(series, dateWindow, options) { | |
46 | var minY = null, maxY = null, y; | |
47 | var firstIdx = 0, lastIdx = series.length - 1; | |
48 | var initial = series[firstIdx][1]; | |
49 | ||
50 | for (var j = firstIdx; j <= lastIdx; j++) { | |
51 | if (j === firstIdx) { | |
52 | y = (this.baseOpt === "percent") ? 0 : this.baseOpt; | |
53 | } else { | |
54 | y = RebaseHandler.rebase(series[j][1], initial, this.baseOpt); | |
55 | } | |
56 | if (y === null || isNaN(y)) | |
57 | continue; | |
58 | if (maxY === null || y > maxY) { | |
59 | maxY = y; | |
60 | } | |
61 | if (minY === null || y < minY) { | |
62 | minY = y; | |
63 | } | |
64 | } | |
65 | return [ minY, maxY ]; | |
66 | }; | |
67 | ||
68 | RebaseHandler.prototype.seriesToPoints = function(series, setName, boundaryIdStart){ | |
69 | var points = []; | |
70 | var firstIdx = 0; | |
71 | var lastIdx = series.length - 1; | |
72 | var initial = series[firstIdx][1]; // TODO: check for null | |
73 | for (var i = 0; i <= lastIdx; ++i) { | |
74 | var item = series[i]; | |
75 | var yraw = item[1]; | |
178b1e0a | 76 | var yval = yraw === null ? null : parseFloat(yraw); |
9d3fcd6a PS |
77 | if (yval !== null) { |
78 | if (i === firstIdx) { | |
79 | yval = (this.baseOpt === "percent") ? 0 : this.baseOpt; | |
80 | } else { | |
81 | yval = RebaseHandler.rebase(yval, initial, this.baseOpt); | |
82 | } | |
83 | } | |
84 | var point = { | |
85 | x: NaN, | |
86 | y: NaN, | |
178b1e0a | 87 | xval: parseFloat(item[0]), |
9d3fcd6a PS |
88 | yval: yval, |
89 | name: setName, | |
90 | idx: i + boundaryIdStart | |
91 | }; | |
92 | points.push(point); | |
93 | } | |
94 | this.onPointsCreated_(series, points); | |
95 | return points; | |
96 | }; | |
97 | ||
98 | Dygraph.Plugins.Rebase = (function() { | |
99 | var rebase = function(baseOpt) { | |
100 | var isNum = function(v) { | |
101 | return !isNaN(v) && (typeof v === 'number' || {}.toString.call(v) === '[object Number]'); | |
102 | }; | |
103 | if (baseOpt === "percent" || isNum(baseOpt)) { | |
104 | this.baseOpt_ = baseOpt; | |
105 | } else { | |
106 | this.baseOpt_ = null; | |
107 | } | |
108 | }; | |
109 | ||
110 | rebase.prototype.toString = function() { | |
111 | return "Rebase Plugin"; | |
112 | }; | |
113 | ||
114 | rebase.prototype.activate = function(g) { | |
115 | if (this.baseOpt_ === null) { | |
116 | return; | |
117 | } | |
118 | return { | |
119 | predraw: this.predraw | |
120 | }; | |
121 | }; | |
122 | ||
123 | rebase.prototype.predraw = function(e) { | |
124 | var g = e.dygraph; | |
125 | ||
126 | if (this.baseOpt_ === "percent") { | |
127 | g.updateOptions({ | |
128 | axes: { | |
129 | y: { | |
130 | axisLabelFormatter: function(y) { | |
131 | return y + '%'; | |
132 | }, | |
133 | valueFormatter: function(y) { | |
134 | return Math.round(y * 100) / 100 + '%'; | |
135 | } | |
136 | } | |
137 | } | |
138 | }, true); | |
139 | } | |
140 | ||
141 | g.dataHandler_ = new Dygraph.DataHandlers.RebaseHandler(this.baseOpt_); | |
142 | }; | |
143 | ||
144 | return rebase; | |
145 | })(); | |
146 | })(); |