懒羊羊
2023-08-30 1ac2bc1590406d9babec036e154d8d08f34a6aa1
提交 | 用户 | 时间
1ac2bc 1 /**
2  * @license Highcharts JS v3.0.6 (2013-10-04)
3  * MooTools adapter
4  *
5  * (c) 2010-2013 Torstein Hønsi
6  *
7  * License: www.highcharts.com/license
8  */
9
10 // JSLint options:
11 /*global Fx, $, $extend, $each, $merge, Events, Event, DOMEvent */
12
13 (function () {
14
15 var win = window,
16     doc = document,
17     mooVersion = win.MooTools.version.substring(0, 3), // Get the first three characters of the version number
18     legacy = mooVersion === '1.2' || mooVersion === '1.1', // 1.1 && 1.2 considered legacy, 1.3 is not.
19     legacyEvent = legacy || mooVersion === '1.3', // In versions 1.1 - 1.3 the event class is named Event, in newer versions it is named DOMEvent.
20     $extend = win.$extend || function () {
21         return Object.append.apply(Object, arguments);
22     };
23
24 win.HighchartsAdapter = {
25     /**
26      * Initialize the adapter. This is run once as Highcharts is first run.
27      * @param {Object} pathAnim The helper object to do animations across adapters.
28      */
29     init: function (pathAnim) {
30         var fxProto = Fx.prototype,
31             fxStart = fxProto.start,
32             morphProto = Fx.Morph.prototype,
33             morphCompute = morphProto.compute;
34
35         // override Fx.start to allow animation of SVG element wrappers
36         /*jslint unparam: true*//* allow unused parameters in fx functions */
37         fxProto.start = function (from, to) {
38             var fx = this,
39                 elem = fx.element;
40
41             // special for animating paths
42             if (from.d) {
43                 //this.fromD = this.element.d.split(' ');
44                 fx.paths = pathAnim.init(
45                     elem,
46                     elem.d,
47                     fx.toD
48                 );
49             }
50             fxStart.apply(fx, arguments);
51
52             return this; // chainable
53         };
54
55         // override Fx.step to allow animation of SVG element wrappers
56         morphProto.compute = function (from, to, delta) {
57             var fx = this,
58                 paths = fx.paths;
59
60             if (paths) {
61                 fx.element.attr(
62                     'd',
63                     pathAnim.step(paths[0], paths[1], delta, fx.toD)
64                 );
65             } else {
66                 return morphCompute.apply(fx, arguments);
67             }
68         };
69         /*jslint unparam: false*/
70     },
71     
72     /**
73      * Run a general method on the framework, following jQuery syntax
74      * @param {Object} el The HTML element
75      * @param {String} method Which method to run on the wrapped element
76      */
77     adapterRun: function (el, method) {
78         
79         // This currently works for getting inner width and height. If adding
80         // more methods later, we need a conditional implementation for each.
81         if (method === 'width' || method === 'height') {
82             return parseInt($(el).getStyle(method), 10);
83         }
84     },
85
86     /**
87      * Downloads a script and executes a callback when done.
88      * @param {String} scriptLocation
89      * @param {Function} callback
90      */
91     getScript: function (scriptLocation, callback) {
92         // We cannot assume that Assets class from mootools-more is available so instead insert a script tag to download script.
93         var head = doc.getElementsByTagName('head')[0];
94         var script = doc.createElement('script');
95
96         script.type = 'text/javascript';
97         script.src = scriptLocation;
98         script.onload = callback;
99
100         head.appendChild(script);
101     },
102
103     /**
104      * Animate a HTML element or SVG element wrapper
105      * @param {Object} el
106      * @param {Object} params
107      * @param {Object} options jQuery-like animation options: duration, easing, callback
108      */
109     animate: function (el, params, options) {
110         var isSVGElement = el.attr,
111             effect,
112             complete = options && options.complete;
113
114         if (isSVGElement && !el.setStyle) {
115             // add setStyle and getStyle methods for internal use in Moo
116             el.getStyle = el.attr;
117             el.setStyle = function () { // property value is given as array in Moo - break it down
118                 var args = arguments;
119                 this.attr.call(this, args[0], args[1][0]);
120             };
121             // dirty hack to trick Moo into handling el as an element wrapper
122             el.$family = function () { return true; };
123         }
124
125         // stop running animations
126         win.HighchartsAdapter.stop(el);
127
128         // define and run the effect
129         effect = new Fx.Morph(
130             isSVGElement ? el : $(el),
131             $extend({
132                 transition: Fx.Transitions.Quad.easeInOut
133             }, options)
134         );
135
136         // Make sure that the element reference is set when animating svg elements
137         if (isSVGElement) {
138             effect.element = el;
139         }
140
141         // special treatment for paths
142         if (params.d) {
143             effect.toD = params.d;
144         }
145
146         // jQuery-like events
147         if (complete) {
148             effect.addEvent('complete', complete);
149         }
150
151         // run
152         effect.start(params);
153
154         // record for use in stop method
155         el.fx = effect;
156     },
157
158     /**
159      * MooTool's each function
160      *
161      */
162     each: function (arr, fn) {
163         return legacy ?
164             $each(arr, fn) :
165             Array.each(arr, fn);
166     },
167
168     /**
169      * Map an array
170      * @param {Array} arr
171      * @param {Function} fn
172      */
173     map: function (arr, fn) {
174         return arr.map(fn);
175     },
176
177     /**
178      * Grep or filter an array
179      * @param {Array} arr
180      * @param {Function} fn
181      */
182     grep: function (arr, fn) {
183         return arr.filter(fn);
184     },
185     
186     /**
187      * Return the index of an item in an array, or -1 if not matched
188      */
189     inArray: function (item, arr, from) {
190         return arr ? arr.indexOf(item, from) : -1;
191     },
192
193     /**
194      * Get the offset of an element relative to the top left corner of the web page
195      */
196     offset: function (el) {
197         var offsets = el.getPosition(); // #1496
198         return {
199             left: offsets.x,
200             top: offsets.y
201         };
202     },
203
204     /**
205      * Extends an object with Events, if its not done
206      */
207     extendWithEvents: function (el) {
208         // if the addEvent method is not defined, el is a custom Highcharts object
209         // like series or point
210         if (!el.addEvent) {
211             if (el.nodeName) {
212                 el = $(el); // a dynamically generated node
213             } else {
214                 $extend(el, new Events()); // a custom object
215             }
216         }
217     },
218
219     /**
220      * Add an event listener
221      * @param {Object} el HTML element or custom object
222      * @param {String} type Event type
223      * @param {Function} fn Event handler
224      */
225     addEvent: function (el, type, fn) {
226         if (typeof type === 'string') { // chart broke due to el being string, type function
227
228             if (type === 'unload') { // Moo self destructs before custom unload events
229                 type = 'beforeunload';
230             }
231
232             win.HighchartsAdapter.extendWithEvents(el);
233
234             el.addEvent(type, fn);
235         }
236     },
237
238     removeEvent: function (el, type, fn) {
239         if (typeof el === 'string') {
240             // el.removeEvents below apperantly calls this method again. Do not quite understand why, so for now just bail out.
241             return;
242         }
243         
244         if (el.addEvent) { // If el doesn't have an addEvent method, there are no events to remove
245             if (type) {
246                 if (type === 'unload') { // Moo self destructs before custom unload events
247                     type = 'beforeunload';
248                 }
249     
250                 if (fn) {
251                     el.removeEvent(type, fn);
252                 } else if (el.removeEvents) { // #958
253                     el.removeEvents(type);
254                 }
255             } else {
256                 el.removeEvents();
257             }
258         }
259     },
260
261     fireEvent: function (el, event, eventArguments, defaultFunction) {
262         var eventArgs = {
263             type: event,
264             target: el
265         };
266         // create an event object that keeps all functions
267         event = legacyEvent ? new Event(eventArgs) : new DOMEvent(eventArgs);
268         event = $extend(event, eventArguments);
269
270         // When running an event on the Chart.prototype, MooTools nests the target in event.event
271         if (!event.target && event.event) {
272             event.target = event.event.target;
273         }
274
275         // override the preventDefault function to be able to use
276         // this for custom events
277         event.preventDefault = function () {
278             defaultFunction = null;
279         };
280         // if fireEvent is not available on the object, there hasn't been added
281         // any events to it above
282         if (el.fireEvent) {
283             el.fireEvent(event.type, event);
284         }
285
286         // fire the default if it is passed and it is not prevented above
287         if (defaultFunction) {
288             defaultFunction(event);
289         }
290     },
291     
292     /**
293      * Set back e.pageX and e.pageY that MooTools has abstracted away. #1165, #1346.
294      */
295     washMouseEvent: function (e) {
296         if (e.page) {
297             e.pageX = e.page.x;
298             e.pageY = e.page.y;
299         }
300         return e;
301     },
302
303     /**
304      * Stop running animations on the object
305      */
306     stop: function (el) {
307         if (el.fx) {
308             el.fx.cancel();
309         }
310     }
311 };
312
313 }());