highcharts-rails 0.1.1 → 2.1.9

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,284 +1,331 @@
1
- /**
2
- * @license Highcharts JS v2.1.6 (2011-07-08)
3
- * Prototype adapter
4
- *
5
- * @author Michael Nelson, Torstein Hønsi.
6
- *
7
- * Feel free to use and modify this script.
8
- * Highcharts license: www.highcharts.com/license.
9
- */
10
-
11
- /*
12
- * Known issues:
13
- * - Some grid lines land in wrong position - http://jsfiddle.net/highcharts/jaRhY/28
14
- */
15
-
16
- // JSLint options:
17
- /*jslint forin: true */
18
- /*global Effect, Class, Highcharts, Event, $, $A */
19
-
20
- // Adapter interface between prototype and the Highcarts charting library
21
- var HighchartsAdapter = (function() {
22
-
23
- var hasEffect = typeof Effect != 'undefined';
24
-
25
- return {
26
-
27
- init: function() {
28
-
29
- if (hasEffect) {
30
- /**
31
- * Animation for Highcharts SVG element wrappers only
32
- * @param {Object} element
33
- * @param {Object} attribute
34
- * @param {Object} to
35
- * @param {Object} options
36
- */
37
- Effect.HighchartsTransition = Class.create(Effect.Base, {
38
- initialize: function(element, attr, to, options){
39
- var from,
40
- opts;
41
-
42
- this.element = element;
43
-
44
- from = element.attr(attr);
45
-
46
- // special treatment for paths
47
- if (attr == 'd') {
48
- this.paths = Highcharts.pathAnim.init(
49
- element,
50
- element.d,
51
- to
52
- );
53
- this.toD = to;
54
-
55
-
56
- // fake values in order to read relative position as a float in update
57
- from = 0;
58
- to = 1;
59
- }
60
-
61
- opts = Object.extend((options || {}), {
62
- from: from,
63
- to: to,
64
- attribute: attr
65
- });
66
- this.start(opts);
67
- },
68
- setup: function(){
69
- HighchartsAdapter._extend(this.element);
70
- this.element._highchart_animation = this;
71
- },
72
- update: function(position) {
73
- var paths = this.paths;
74
-
75
- if (paths) {
76
- position = Highcharts.pathAnim.step(paths[0], paths[1], position, this.toD);
77
- }
78
-
79
- this.element.attr(this.options.attribute, position);
80
- },
81
- finish: function(){
82
- this.element._highchart_animation = null;
83
- }
84
- });
85
- }
86
- },
87
-
88
- // el needs an event to be attached. el is not necessarily a dom element
89
- addEvent: function(el, event, fn) {
90
- if (el.addEventListener || el.attachEvent) {
91
- Event.observe($(el), event, fn);
92
-
93
- } else {
94
- HighchartsAdapter._extend(el);
95
- el._highcharts_observe(event, fn);
96
- }
97
- },
98
-
99
- // motion makes things pretty. use it if effects is loaded, if not... still get to the end result.
100
- animate: function(el, params, options) {
101
- var key,
102
- fx;
103
-
104
- // default options
105
- options = options || {};
106
- options.delay = 0;
107
- options.duration = (options.duration || 500) / 1000;
108
-
109
- // animate wrappers and DOM elements
110
- if (hasEffect) {
111
- for (key in params) {
112
- fx = new Effect.HighchartsTransition($(el), key, params[key], options);
113
- }
114
- } else {
115
- for (key in params) {
116
- el.attr(key, params[key]);
117
- }
118
- }
119
-
120
- if (!el.attr) {
121
- throw 'Todo: implement animate DOM objects';
122
- }
123
- },
124
-
125
- // this only occurs in higcharts 2.0+
126
- stop: function(el){
127
- if (el._highcharts_extended && el._highchart_animation) {
128
- el._highchart_animation.cancel();
129
- }
130
- },
131
-
132
- // um.. each
133
- each: function(arr, fn){
134
- $A(arr).each(fn);
135
- },
136
-
137
- // fire an event based on an event name (event) and an object (el).
138
- // again, el may not be a dom element
139
- fireEvent: function(el, event, eventArguments, defaultFunction){
140
- if (event.preventDefault) {
141
- defaultFunction = null;
142
- }
143
-
144
- if (el.fire) {
145
- el.fire(event, eventArguments);
146
- } else if (el._highcharts_extended) {
147
- el._highcharts_fire(event, eventArguments);
148
- }
149
-
150
- if (defaultFunction) {
151
- defaultFunction(eventArguments);
152
- }
153
- },
154
-
155
- removeEvent: function(el, event, handler){
156
- if ($(el).stopObserving) {
157
- $(el).stopObserving(event, handler);
158
- } else {
159
- HighchartsAdapter._extend(el);
160
- el._highcharts_stop_observing(event, handler);
161
- }
162
- },
163
-
164
- // um, grep
165
- grep: function(arr, fn){
166
- return arr.findAll(fn);
167
- },
168
-
169
- // um, map
170
- map: function(arr, fn){
171
- return arr.map(fn);
172
- },
173
-
174
- // deep merge. merge({a : 'a', b : {b1 : 'b1', b2 : 'b2'}}, {b : {b2 : 'b2_prime'}, c : 'c'}) => {a : 'a', b : {b1 : 'b1', b2 : 'b2_prime'}, c : 'c'}
175
- /*merge: function(){
176
- function doCopy(copy, original) {
177
- var value,
178
- key,
179
- undef,
180
- nil,
181
- same,
182
- obj,
183
- arr,
184
- node;
185
-
186
- for (key in original) {
187
- value = original[key];
188
- undef = typeof(value) === 'undefined';
189
- nil = value === null;
190
- same = original === copy[key];
191
-
192
- if (undef || nil || same) {
193
- continue;
194
- }
195
-
196
- obj = typeof(value) === 'object';
197
- arr = value && obj && value.constructor == Array;
198
- node = !!value.nodeType;
199
-
200
- if (obj && !arr && !node) {
201
- copy[key] = doCopy(typeof copy[key] == 'object' ? copy[key] : {}, value);
202
- }
203
- else {
204
- copy[key] = original[key];
205
- }
206
- }
207
- return copy;
208
- }
209
-
210
- var args = arguments, retVal = {};
211
-
212
- for (var i = 0; i < args.length; i++) {
213
- retVal = doCopy(retVal, args[i]);
214
- }
215
-
216
- return retVal;
217
- },*/
218
- merge: function() { // the built-in prototype merge function doesn't do deep copy
219
- function doCopy(copy, original) {
220
- var value;
221
-
222
- for (var key in original) {
223
- value = original[key];
224
- if (value && typeof value == 'object' && value.constructor != Array &&
225
- typeof value.nodeType !== 'number') {
226
- copy[key] = doCopy(copy[key] || {}, value); // copy
227
-
228
- } else {
229
- copy[key] = original[key];
230
- }
231
- }
232
- return copy;
233
- }
234
-
235
- function merge() {
236
- var args = arguments,
237
- retVal = {};
238
-
239
- for (var i = 0; i < args.length; i++) {
240
- retVal = doCopy(retVal, args[i])
241
-
242
- }
243
- return retVal;
244
- }
245
-
246
- return merge.apply(this, arguments);
247
- },
248
-
249
- // extend an object to handle highchart events (highchart objects, not svg elements).
250
- // this is a very simple way of handling events but whatever, it works (i think)
251
- _extend: function(object){
252
- if (!object._highcharts_extended) {
253
- Object.extend(object, {
254
- _highchart_events: {},
255
- _highchart_animation: null,
256
- _highcharts_extended: true,
257
- _highcharts_observe: function(name, fn){
258
- this._highchart_events[name] = [this._highchart_events[name], fn].compact().flatten();
259
- },
260
- _highcharts_stop_observing: function(name, fn){
261
- if (name) {
262
- if (fn) {
263
- this._highchart_events[name] = [this._highchart_events[name]].compact().flatten().without(fn);
264
- } else {
265
- delete this._highchart_events[name];
266
- }
267
- } else {
268
- this._highchart_events = {};
269
- }
270
- },
271
- _highcharts_fire: function(name, args){
272
- (this._highchart_events[name] || []).each(function(fn){
273
- if (args && args.stopped) {
274
- return; // "throw $break" wasn't working. i think because of the scope of 'this'.
275
- }
276
- fn.bind(this)(args);
277
- }
278
- .bind(this));
279
- }
280
- });
281
- }
282
- }
283
- };
284
- })();
1
+ /**
2
+ * @license Highcharts JS v2.1.9 (2011-11-11)
3
+ * Prototype adapter
4
+ *
5
+ * @author Michael Nelson, Torstein Hønsi.
6
+ *
7
+ * Feel free to use and modify this script.
8
+ * Highcharts license: www.highcharts.com/license.
9
+ */
10
+
11
+ /*
12
+ * Known issues:
13
+ * - Some grid lines land in wrong position - http://jsfiddle.net/highcharts/jaRhY/28
14
+ */
15
+
16
+ // JSLint options:
17
+ /*global Effect, Class, Event, $, $A */
18
+
19
+ // Adapter interface between prototype and the Highcharts charting library
20
+ var HighchartsAdapter = (function () {
21
+
22
+ var hasEffect = typeof Effect !== 'undefined';
23
+
24
+ return {
25
+
26
+ /**
27
+ * Initialize the adapter. This is run once as Highcharts is first run.
28
+ * @param {Object} pathAnim The helper object to do animations across adapters.
29
+ */
30
+ init: function (pathAnim) {
31
+ if (hasEffect) {
32
+ /**
33
+ * Animation for Highcharts SVG element wrappers only
34
+ * @param {Object} element
35
+ * @param {Object} attribute
36
+ * @param {Object} to
37
+ * @param {Object} options
38
+ */
39
+ Effect.HighchartsTransition = Class.create(Effect.Base, {
40
+ initialize: function (element, attr, to, options) {
41
+ var from,
42
+ opts;
43
+
44
+ this.element = element;
45
+ this.key = attr;
46
+ from = element.attr(attr);
47
+
48
+ // special treatment for paths
49
+ if (attr === 'd') {
50
+ this.paths = pathAnim.init(
51
+ element,
52
+ element.d,
53
+ to
54
+ );
55
+ this.toD = to;
56
+
57
+
58
+ // fake values in order to read relative position as a float in update
59
+ from = 0;
60
+ to = 1;
61
+ }
62
+
63
+ opts = Object.extend((options || {}), {
64
+ from: from,
65
+ to: to,
66
+ attribute: attr
67
+ });
68
+ this.start(opts);
69
+ },
70
+ setup: function () {
71
+ HighchartsAdapter._extend(this.element);
72
+ // If this is the first animation on this object, create the _highcharts_animation helper that
73
+ // contain pointers to the animation objects.
74
+ if (!this.element._highchart_animation) {
75
+ this.element._highchart_animation = {};
76
+ }
77
+
78
+ // Store a reference to this animation instance.
79
+ this.element._highchart_animation[this.key] = this;
80
+ },
81
+ update: function (position) {
82
+ var paths = this.paths;
83
+
84
+ if (paths) {
85
+ position = pathAnim.step(paths[0], paths[1], position, this.toD);
86
+ }
87
+
88
+ this.element.attr(this.options.attribute, position);
89
+ },
90
+ finish: function () {
91
+ // Delete the property that holds this animation now that it is finished.
92
+ // Both canceled animations and complete ones gets a 'finish' call.
93
+ delete this.element._highchart_animation[this.key];
94
+ }
95
+ });
96
+ }
97
+ },
98
+
99
+ /**
100
+ * Custom events in prototype needs to be namespaced. This method adds a namespace 'h:' in front of
101
+ * events that are not recognized as native.
102
+ */
103
+ addNS: function (eventName) {
104
+ var HTMLEvents = /^(?:load|unload|abort|error|select|change|submit|reset|focus|blur|resize|scroll)$/,
105
+ MouseEvents = /^(?:click|mouse(?:down|up|over|move|out))$/;
106
+ return (HTMLEvents.test(eventName) || MouseEvents.test(eventName)) ?
107
+ eventName :
108
+ 'h:' + eventName;
109
+ },
110
+
111
+ // el needs an event to be attached. el is not necessarily a dom element
112
+ addEvent: function (el, event, fn) {
113
+ if (el.addEventListener || el.attachEvent) {
114
+ Event.observe($(el), HighchartsAdapter.addNS(event), fn);
115
+
116
+ } else {
117
+ HighchartsAdapter._extend(el);
118
+ el._highcharts_observe(event, fn);
119
+ }
120
+ },
121
+
122
+ // motion makes things pretty. use it if effects is loaded, if not... still get to the end result.
123
+ animate: function (el, params, options) {
124
+ var key,
125
+ fx;
126
+
127
+ // default options
128
+ options = options || {};
129
+ options.delay = 0;
130
+ options.duration = (options.duration || 500) / 1000;
131
+
132
+ // animate wrappers and DOM elements
133
+ if (hasEffect) {
134
+ for (key in params) {
135
+ // The fx variable is seemingly thrown away here, but the Effect.setup will add itself to the _highcharts_animation object
136
+ // on the element itself so its not really lost.
137
+ fx = new Effect.HighchartsTransition($(el), key, params[key], options);
138
+ }
139
+ } else {
140
+ for (key in params) {
141
+ el.attr(key, params[key]);
142
+ }
143
+ }
144
+
145
+ if (!el.attr) {
146
+ throw 'Todo: implement animate DOM objects';
147
+ }
148
+ },
149
+
150
+ // this only occurs in higcharts 2.0+
151
+ stop: function (el) {
152
+ var key;
153
+ if (el._highcharts_extended && el._highchart_animation) {
154
+ for (key in el._highchart_animation) {
155
+ // Cancel the animation
156
+ // The 'finish' function in the Effect object will remove the reference
157
+ el._highchart_animation[key].cancel();
158
+ }
159
+ }
160
+ },
161
+
162
+ // um.. each
163
+ each: function (arr, fn) {
164
+ $A(arr).each(fn);
165
+ },
166
+
167
+ // fire an event based on an event name (event) and an object (el).
168
+ // again, el may not be a dom element
169
+ fireEvent: function (el, event, eventArguments, defaultFunction) {
170
+ if (el.fire) {
171
+ el.fire(HighchartsAdapter.addNS(event), eventArguments);
172
+ } else if (el._highcharts_extended) {
173
+ eventArguments = eventArguments || {};
174
+ el._highcharts_fire(event, eventArguments);
175
+ }
176
+
177
+ if (eventArguments && eventArguments.defaultPrevented) {
178
+ defaultFunction = null;
179
+ }
180
+
181
+ if (defaultFunction) {
182
+ defaultFunction(eventArguments);
183
+ }
184
+ },
185
+
186
+ removeEvent: function (el, event, handler) {
187
+ if ($(el).stopObserving) {
188
+ if (event) {
189
+ event = HighchartsAdapter.addNS(event);
190
+ }
191
+ $(el).stopObserving(event, handler);
192
+ } if (window === el) {
193
+ Event.stopObserving(el, event, handler);
194
+ } else {
195
+ HighchartsAdapter._extend(el);
196
+ el._highcharts_stop_observing(event, handler);
197
+ }
198
+ },
199
+
200
+ // um, grep
201
+ grep: function (arr, fn) {
202
+ return arr.findAll(fn);
203
+ },
204
+
205
+ // um, map
206
+ map: function (arr, fn) {
207
+ return arr.map(fn);
208
+ },
209
+
210
+ // deep merge. merge({a : 'a', b : {b1 : 'b1', b2 : 'b2'}}, {b : {b2 : 'b2_prime'}, c : 'c'}) => {a : 'a', b : {b1 : 'b1', b2 : 'b2_prime'}, c : 'c'}
211
+ /*merge: function(){
212
+ function doCopy(copy, original) {
213
+ var value,
214
+ key,
215
+ undef,
216
+ nil,
217
+ same,
218
+ obj,
219
+ arr,
220
+ node;
221
+
222
+ for (key in original) {
223
+ value = original[key];
224
+ undef = typeof(value) === 'undefined';
225
+ nil = value === null;
226
+ same = original === copy[key];
227
+
228
+ if (undef || nil || same) {
229
+ continue;
230
+ }
231
+
232
+ obj = typeof(value) === 'object';
233
+ arr = value && obj && value.constructor == Array;
234
+ node = !!value.nodeType;
235
+
236
+ if (obj && !arr && !node) {
237
+ copy[key] = doCopy(typeof copy[key] == 'object' ? copy[key] : {}, value);
238
+ }
239
+ else {
240
+ copy[key] = original[key];
241
+ }
242
+ }
243
+ return copy;
244
+ }
245
+
246
+ var args = arguments, retVal = {};
247
+
248
+ for (var i = 0; i < args.length; i++) {
249
+ retVal = doCopy(retVal, args[i]);
250
+ }
251
+
252
+ return retVal;
253
+ },*/
254
+ merge: function () { // the built-in prototype merge function doesn't do deep copy
255
+ function doCopy(copy, original) {
256
+ var value, key;
257
+
258
+ for (key in original) {
259
+ value = original[key];
260
+ if (value && typeof value === 'object' && value.constructor !== Array &&
261
+ typeof value.nodeType !== 'number') {
262
+ copy[key] = doCopy(copy[key] || {}, value); // copy
263
+
264
+ } else {
265
+ copy[key] = original[key];
266
+ }
267
+ }
268
+ return copy;
269
+ }
270
+
271
+ function merge() {
272
+ var args = arguments,
273
+ i,
274
+ retVal = {};
275
+
276
+ for (i = 0; i < args.length; i++) {
277
+ retVal = doCopy(retVal, args[i]);
278
+
279
+ }
280
+ return retVal;
281
+ }
282
+
283
+ return merge.apply(this, arguments);
284
+ },
285
+
286
+ // extend an object to handle highchart events (highchart objects, not svg elements).
287
+ // this is a very simple way of handling events but whatever, it works (i think)
288
+ _extend: function (object) {
289
+ if (!object._highcharts_extended) {
290
+ Object.extend(object, {
291
+ _highchart_events: {},
292
+ _highchart_animation: null,
293
+ _highcharts_extended: true,
294
+ _highcharts_observe: function (name, fn) {
295
+ this._highchart_events[name] = [this._highchart_events[name], fn].compact().flatten();
296
+ },
297
+ _highcharts_stop_observing: function (name, fn) {
298
+ if (name) {
299
+ if (fn) {
300
+ this._highchart_events[name] = [this._highchart_events[name]].compact().flatten().without(fn);
301
+ } else {
302
+ delete this._highchart_events[name];
303
+ }
304
+ } else {
305
+ this._highchart_events = {};
306
+ }
307
+ },
308
+ _highcharts_fire: function (name, args) {
309
+ (this._highchart_events[name] || []).each(function (fn) {
310
+ // args is never null here
311
+ if (args.stopped) {
312
+ return; // "throw $break" wasn't working. i think because of the scope of 'this'.
313
+ }
314
+
315
+ // Attach a simple preventDefault function to skip default handler if called
316
+ args.preventDefault = function () {
317
+ args.defaultPrevented = true;
318
+ };
319
+
320
+ // If the event handler return false, prevent the default handler from executing
321
+ if (fn.bind(this)(args) === false) {
322
+ args.preventDefault();
323
+ }
324
+ }
325
+ .bind(this));
326
+ }
327
+ });
328
+ }
329
+ }
330
+ };
331
+ }());