| | |
| | | /** |
| | | * @license Highcharts JS v3.0.6 (2013-10-04) |
| | | * |
| | | * Standalone Highcharts Framework |
| | | * |
| | | * License: MIT License |
| | | */ |
| | | |
| | | |
| | | /*global Highcharts */ |
| | | var HighchartsAdapter = (function () { |
| | | |
| | | var UNDEFINED, |
| | | doc = document, |
| | | emptyArray = [], |
| | | timers = [], |
| | | timerId, |
| | | Fx; |
| | | |
| | | Math.easeInOutSine = function (t, b, c, d) { |
| | | return -c / 2 * (Math.cos(Math.PI * t / d) - 1) + b; |
| | | }; |
| | | |
| | | |
| | | |
| | | /** |
| | | * Extend given object with custom events |
| | | */ |
| | | function augment(obj) { |
| | | function removeOneEvent(el, type, fn) { |
| | | el.removeEventListener(type, fn, false); |
| | | } |
| | | |
| | | function IERemoveOneEvent(el, type, fn) { |
| | | fn = el.HCProxiedMethods[fn.toString()]; |
| | | el.detachEvent('on' + type, fn); |
| | | } |
| | | |
| | | function removeAllEvents(el, type) { |
| | | var events = el.HCEvents, |
| | | remove, |
| | | types, |
| | | len, |
| | | n; |
| | | |
| | | if (el.removeEventListener) { |
| | | remove = removeOneEvent; |
| | | } else if (el.attachEvent) { |
| | | remove = IERemoveOneEvent; |
| | | } else { |
| | | return; // break on non-DOM events |
| | | } |
| | | |
| | | |
| | | if (type) { |
| | | types = {}; |
| | | types[type] = true; |
| | | } else { |
| | | types = events; |
| | | } |
| | | |
| | | for (n in types) { |
| | | if (events[n]) { |
| | | len = events[n].length; |
| | | while (len--) { |
| | | remove(el, n, events[n][len]); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (!obj.HCExtended) { |
| | | Highcharts.extend(obj, { |
| | | HCExtended: true, |
| | | |
| | | HCEvents: {}, |
| | | |
| | | bind: function (name, fn) { |
| | | var el = this, |
| | | events = this.HCEvents, |
| | | wrappedFn; |
| | | |
| | | // handle DOM events in modern browsers |
| | | if (el.addEventListener) { |
| | | el.addEventListener(name, fn, false); |
| | | |
| | | // handle old IE implementation |
| | | } else if (el.attachEvent) { |
| | | |
| | | wrappedFn = function (e) { |
| | | fn.call(el, e); |
| | | }; |
| | | |
| | | if (!el.HCProxiedMethods) { |
| | | el.HCProxiedMethods = {}; |
| | | } |
| | | |
| | | // link wrapped fn with original fn, so we can get this in removeEvent |
| | | el.HCProxiedMethods[fn.toString()] = wrappedFn; |
| | | |
| | | el.attachEvent('on' + name, wrappedFn); |
| | | } |
| | | |
| | | |
| | | if (events[name] === UNDEFINED) { |
| | | events[name] = []; |
| | | } |
| | | |
| | | events[name].push(fn); |
| | | }, |
| | | |
| | | unbind: function (name, fn) { |
| | | var events, |
| | | index; |
| | | |
| | | if (name) { |
| | | events = this.HCEvents[name] || []; |
| | | if (fn) { |
| | | index = HighchartsAdapter.inArray(fn, events); |
| | | if (index > -1) { |
| | | events.splice(index, 1); |
| | | this.HCEvents[name] = events; |
| | | } |
| | | if (this.removeEventListener) { |
| | | removeOneEvent(this, name, fn); |
| | | } else if (this.attachEvent) { |
| | | IERemoveOneEvent(this, name, fn); |
| | | } |
| | | } else { |
| | | removeAllEvents(this, name); |
| | | this.HCEvents[name] = []; |
| | | } |
| | | } else { |
| | | removeAllEvents(this); |
| | | this.HCEvents = {}; |
| | | } |
| | | }, |
| | | |
| | | trigger: function (name, args) { |
| | | var events = this.HCEvents[name] || [], |
| | | target = this, |
| | | len = events.length, |
| | | i, |
| | | preventDefault, |
| | | fn; |
| | | |
| | | // Attach a simple preventDefault function to skip default handler if called |
| | | preventDefault = function () { |
| | | args.defaultPrevented = true; |
| | | }; |
| | | |
| | | for (i = 0; i < len; i++) { |
| | | fn = events[i]; |
| | | |
| | | // args is never null here |
| | | if (args.stopped) { |
| | | return; |
| | | } |
| | | |
| | | args.preventDefault = preventDefault; |
| | | args.target = target; |
| | | args.type = name; // #2297 |
| | | |
| | | // If the event handler return false, prevent the default handler from executing |
| | | if (fn.call(this, args) === false) { |
| | | args.preventDefault(); |
| | | } |
| | | } |
| | | } |
| | | }); |
| | | } |
| | | |
| | | return obj; |
| | | } |
| | | |
| | | |
| | | return { |
| | | /** |
| | | * Initialize the adapter. This is run once as Highcharts is first run. |
| | | */ |
| | | init: function (pathAnim) { |
| | | |
| | | /** |
| | | * Compatibility section to add support for legacy IE. This can be removed if old IE |
| | | * support is not needed. |
| | | */ |
| | | if (!doc.defaultView) { |
| | | this._getStyle = function (el, prop) { |
| | | var val; |
| | | if (el.style[prop]) { |
| | | return el.style[prop]; |
| | | } else { |
| | | if (prop === 'opacity') { |
| | | prop = 'filter'; |
| | | } |
| | | /*jslint unparam: true*/ |
| | | val = el.currentStyle[prop.replace(/\-(\w)/g, function (a, b) { return b.toUpperCase(); })]; |
| | | if (prop === 'filter') { |
| | | val = val.replace( |
| | | /alpha\(opacity=([0-9]+)\)/, |
| | | function (a, b) { |
| | | return b / 100; |
| | | } |
| | | ); |
| | | } |
| | | /*jslint unparam: false*/ |
| | | return val === '' ? 1 : val; |
| | | } |
| | | }; |
| | | this.adapterRun = function (elem, method) { |
| | | var alias = { width: 'clientWidth', height: 'clientHeight' }[method]; |
| | | |
| | | if (alias) { |
| | | elem.style.zoom = 1; |
| | | return elem[alias] - 2 * parseInt(HighchartsAdapter._getStyle(elem, 'padding'), 10); |
| | | } |
| | | }; |
| | | } |
| | | |
| | | if (!Array.prototype.forEach) { |
| | | this.each = function (arr, fn) { // legacy |
| | | var i = 0, |
| | | len = arr.length; |
| | | for (; i < len; i++) { |
| | | if (fn.call(arr[i], arr[i], i, arr) === false) { |
| | | return i; |
| | | } |
| | | } |
| | | }; |
| | | } |
| | | |
| | | if (!Array.prototype.indexOf) { |
| | | this.inArray = function (item, arr) { |
| | | var len, |
| | | i = 0; |
| | | |
| | | if (arr) { |
| | | len = arr.length; |
| | | |
| | | for (; i < len; i++) { |
| | | if (arr[i] === item) { |
| | | return i; |
| | | } |
| | | } |
| | | } |
| | | |
| | | return -1; |
| | | }; |
| | | } |
| | | |
| | | if (!Array.prototype.filter) { |
| | | this.grep = function (elements, callback) { |
| | | var ret = [], |
| | | i = 0, |
| | | length = elements.length; |
| | | |
| | | for (; i < length; i++) { |
| | | if (!!callback(elements[i], i)) { |
| | | ret.push(elements[i]); |
| | | } |
| | | } |
| | | |
| | | return ret; |
| | | }; |
| | | } |
| | | |
| | | //--- End compatibility section --- |
| | | |
| | | |
| | | /** |
| | | * Start of animation specific code |
| | | */ |
| | | Fx = function (elem, options, prop) { |
| | | this.options = options; |
| | | this.elem = elem; |
| | | this.prop = prop; |
| | | }; |
| | | Fx.prototype = { |
| | | |
| | | update: function () { |
| | | var styles, |
| | | paths = this.paths, |
| | | elem = this.elem, |
| | | elemelem = elem.element; // if destroyed, it is null |
| | | |
| | | // Animating a path definition on SVGElement |
| | | if (paths && elemelem) { |
| | | elem.attr('d', pathAnim.step(paths[0], paths[1], this.now, this.toD)); |
| | | |
| | | // Other animations on SVGElement |
| | | } else if (elem.attr) { |
| | | if (elemelem) { |
| | | elem.attr(this.prop, this.now); |
| | | } |
| | | |
| | | // HTML styles |
| | | } else { |
| | | styles = {}; |
| | | styles[elem] = this.now + this.unit; |
| | | Highcharts.css(elem, styles); |
| | | } |
| | | |
| | | if (this.options.step) { |
| | | this.options.step.call(this.elem, this.now, this); |
| | | } |
| | | |
| | | }, |
| | | custom: function (from, to, unit) { |
| | | var self = this, |
| | | t = function (gotoEnd) { |
| | | return self.step(gotoEnd); |
| | | }, |
| | | i; |
| | | |
| | | this.startTime = +new Date(); |
| | | this.start = from; |
| | | this.end = to; |
| | | this.unit = unit; |
| | | this.now = this.start; |
| | | this.pos = this.state = 0; |
| | | |
| | | t.elem = this.elem; |
| | | |
| | | if (t() && timers.push(t) === 1) { |
| | | timerId = setInterval(function () { |
| | | |
| | | for (i = 0; i < timers.length; i++) { |
| | | if (!timers[i]()) { |
| | | timers.splice(i--, 1); |
| | | } |
| | | } |
| | | |
| | | if (!timers.length) { |
| | | clearInterval(timerId); |
| | | } |
| | | }, 13); |
| | | } |
| | | }, |
| | | |
| | | step: function (gotoEnd) { |
| | | var t = +new Date(), |
| | | ret, |
| | | done, |
| | | options = this.options, |
| | | i; |
| | | |
| | | if (this.elem.stopAnimation) { |
| | | ret = false; |
| | | |
| | | } else if (gotoEnd || t >= options.duration + this.startTime) { |
| | | this.now = this.end; |
| | | this.pos = this.state = 1; |
| | | this.update(); |
| | | |
| | | this.options.curAnim[this.prop] = true; |
| | | |
| | | done = true; |
| | | for (i in options.curAnim) { |
| | | if (options.curAnim[i] !== true) { |
| | | done = false; |
| | | } |
| | | } |
| | | |
| | | if (done) { |
| | | if (options.complete) { |
| | | options.complete.call(this.elem); |
| | | } |
| | | } |
| | | ret = false; |
| | | |
| | | } else { |
| | | var n = t - this.startTime; |
| | | this.state = n / options.duration; |
| | | this.pos = options.easing(n, 0, 1, options.duration); |
| | | this.now = this.start + ((this.end - this.start) * this.pos); |
| | | this.update(); |
| | | ret = true; |
| | | } |
| | | return ret; |
| | | } |
| | | }; |
| | | |
| | | /** |
| | | * The adapter animate method |
| | | */ |
| | | this.animate = function (el, prop, opt) { |
| | | var start, |
| | | unit = '', |
| | | end, |
| | | fx, |
| | | args, |
| | | name; |
| | | |
| | | el.stopAnimation = false; // ready for new |
| | | |
| | | if (typeof opt !== 'object' || opt === null) { |
| | | args = arguments; |
| | | opt = { |
| | | duration: args[2], |
| | | easing: args[3], |
| | | complete: args[4] |
| | | }; |
| | | } |
| | | if (typeof opt.duration !== 'number') { |
| | | opt.duration = 400; |
| | | } |
| | | opt.easing = Math[opt.easing] || Math.easeInOutSine; |
| | | opt.curAnim = Highcharts.extend({}, prop); |
| | | |
| | | for (name in prop) { |
| | | fx = new Fx(el, opt, name); |
| | | end = null; |
| | | |
| | | if (name === 'd') { |
| | | fx.paths = pathAnim.init( |
| | | el, |
| | | el.d, |
| | | prop.d |
| | | ); |
| | | fx.toD = prop.d; |
| | | start = 0; |
| | | end = 1; |
| | | } else if (el.attr) { |
| | | start = el.attr(name); |
| | | } else { |
| | | start = parseFloat(HighchartsAdapter._getStyle(el, name)) || 0; |
| | | if (name !== 'opacity') { |
| | | unit = 'px'; |
| | | } |
| | | } |
| | | |
| | | if (!end) { |
| | | end = parseFloat(prop[name]); |
| | | } |
| | | fx.custom(start, end, unit); |
| | | } |
| | | }; |
| | | }, |
| | | |
| | | /** |
| | | * Internal method to return CSS value for given element and property |
| | | */ |
| | | _getStyle: function (el, prop) { |
| | | return window.getComputedStyle(el).getPropertyValue(prop); |
| | | }, |
| | | |
| | | /** |
| | | * Downloads a script and executes a callback when done. |
| | | * @param {String} scriptLocation |
| | | * @param {Function} callback |
| | | */ |
| | | getScript: function (scriptLocation, callback) { |
| | | // We cannot assume that Assets class from mootools-more is available so instead insert a script tag to download script. |
| | | var head = doc.getElementsByTagName('head')[0], |
| | | script = doc.createElement('script'); |
| | | |
| | | script.type = 'text/javascript'; |
| | | script.src = scriptLocation; |
| | | script.onload = callback; |
| | | |
| | | head.appendChild(script); |
| | | }, |
| | | |
| | | /** |
| | | * Return the index of an item in an array, or -1 if not found |
| | | */ |
| | | inArray: function (item, arr) { |
| | | return arr.indexOf ? arr.indexOf(item) : emptyArray.indexOf.call(arr, item); |
| | | }, |
| | | |
| | | |
| | | /** |
| | | * A direct link to adapter methods |
| | | */ |
| | | adapterRun: function (elem, method) { |
| | | return parseInt(HighchartsAdapter._getStyle(elem, method), 10); |
| | | }, |
| | | |
| | | /** |
| | | * Filter an array |
| | | */ |
| | | grep: function (elements, callback) { |
| | | return emptyArray.filter.call(elements, callback); |
| | | }, |
| | | |
| | | /** |
| | | * Map an array |
| | | */ |
| | | map: function (arr, fn) { |
| | | var results = [], i = 0, len = arr.length; |
| | | |
| | | for (; i < len; i++) { |
| | | results[i] = fn.call(arr[i], arr[i], i, arr); |
| | | } |
| | | |
| | | return results; |
| | | }, |
| | | |
| | | offset: function (el) { |
| | | var left = 0, |
| | | top = 0; |
| | | |
| | | while (el) { |
| | | left += el.offsetLeft; |
| | | top += el.offsetTop; |
| | | el = el.offsetParent; |
| | | } |
| | | |
| | | return { |
| | | left: left, |
| | | top: top |
| | | }; |
| | | }, |
| | | |
| | | /** |
| | | * Add an event listener |
| | | */ |
| | | addEvent: function (el, type, fn) { |
| | | augment(el).bind(type, fn); |
| | | }, |
| | | |
| | | /** |
| | | * Remove event added with addEvent |
| | | */ |
| | | removeEvent: function (el, type, fn) { |
| | | augment(el).unbind(type, fn); |
| | | }, |
| | | |
| | | /** |
| | | * Fire an event on a custom object |
| | | */ |
| | | fireEvent: function (el, type, eventArguments, defaultFunction) { |
| | | var e; |
| | | |
| | | if (doc.createEvent && (el.dispatchEvent || el.fireEvent)) { |
| | | e = doc.createEvent('Events'); |
| | | e.initEvent(type, true, true); |
| | | e.target = el; |
| | | |
| | | Highcharts.extend(e, eventArguments); |
| | | |
| | | if (el.dispatchEvent) { |
| | | el.dispatchEvent(e); |
| | | } else { |
| | | el.fireEvent(type, e); |
| | | } |
| | | |
| | | } else if (el.HCExtended === true) { |
| | | eventArguments = eventArguments || {}; |
| | | el.trigger(type, eventArguments); |
| | | } |
| | | |
| | | if (eventArguments && eventArguments.defaultPrevented) { |
| | | defaultFunction = null; |
| | | } |
| | | |
| | | if (defaultFunction) { |
| | | defaultFunction(eventArguments); |
| | | } |
| | | }, |
| | | |
| | | washMouseEvent: function (e) { |
| | | return e; |
| | | }, |
| | | |
| | | |
| | | /** |
| | | * Stop running animation |
| | | */ |
| | | stop: function (el) { |
| | | el.stopAnimation = true; |
| | | }, |
| | | |
| | | /** |
| | | * Utility for iterating over an array. Parameters are reversed compared to jQuery. |
| | | * @param {Array} arr |
| | | * @param {Function} fn |
| | | */ |
| | | each: function (arr, fn) { // modern browsers |
| | | return Array.prototype.forEach.call(arr, fn); |
| | | } |
| | | }; |
| | | }()); |
| | | /**
|
| | | * @license Highcharts JS v3.0.6 (2013-10-04)
|
| | | *
|
| | | * Standalone Highcharts Framework
|
| | | *
|
| | | * License: MIT License
|
| | | */
|
| | |
|
| | |
|
| | | /*global Highcharts */
|
| | | var HighchartsAdapter = (function () {
|
| | |
|
| | | var UNDEFINED,
|
| | | doc = document,
|
| | | emptyArray = [],
|
| | | timers = [],
|
| | | timerId,
|
| | | Fx;
|
| | |
|
| | | Math.easeInOutSine = function (t, b, c, d) {
|
| | | return -c / 2 * (Math.cos(Math.PI * t / d) - 1) + b;
|
| | | };
|
| | |
|
| | |
|
| | |
|
| | | /**
|
| | | * Extend given object with custom events
|
| | | */
|
| | | function augment(obj) {
|
| | | function removeOneEvent(el, type, fn) {
|
| | | el.removeEventListener(type, fn, false);
|
| | | }
|
| | |
|
| | | function IERemoveOneEvent(el, type, fn) {
|
| | | fn = el.HCProxiedMethods[fn.toString()];
|
| | | el.detachEvent('on' + type, fn);
|
| | | }
|
| | |
|
| | | function removeAllEvents(el, type) {
|
| | | var events = el.HCEvents,
|
| | | remove,
|
| | | types,
|
| | | len,
|
| | | n;
|
| | |
|
| | | if (el.removeEventListener) {
|
| | | remove = removeOneEvent;
|
| | | } else if (el.attachEvent) {
|
| | | remove = IERemoveOneEvent;
|
| | | } else {
|
| | | return; // break on non-DOM events
|
| | | }
|
| | |
|
| | |
|
| | | if (type) {
|
| | | types = {};
|
| | | types[type] = true;
|
| | | } else {
|
| | | types = events;
|
| | | }
|
| | |
|
| | | for (n in types) {
|
| | | if (events[n]) {
|
| | | len = events[n].length;
|
| | | while (len--) {
|
| | | remove(el, n, events[n][len]);
|
| | | }
|
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | | if (!obj.HCExtended) {
|
| | | Highcharts.extend(obj, {
|
| | | HCExtended: true,
|
| | |
|
| | | HCEvents: {},
|
| | |
|
| | | bind: function (name, fn) {
|
| | | var el = this,
|
| | | events = this.HCEvents,
|
| | | wrappedFn;
|
| | |
|
| | | // handle DOM events in modern browsers
|
| | | if (el.addEventListener) {
|
| | | el.addEventListener(name, fn, false);
|
| | |
|
| | | // handle old IE implementation
|
| | | } else if (el.attachEvent) {
|
| | | |
| | | wrappedFn = function (e) {
|
| | | fn.call(el, e);
|
| | | };
|
| | |
|
| | | if (!el.HCProxiedMethods) {
|
| | | el.HCProxiedMethods = {};
|
| | | }
|
| | |
|
| | | // link wrapped fn with original fn, so we can get this in removeEvent
|
| | | el.HCProxiedMethods[fn.toString()] = wrappedFn;
|
| | |
|
| | | el.attachEvent('on' + name, wrappedFn);
|
| | | }
|
| | |
|
| | |
|
| | | if (events[name] === UNDEFINED) {
|
| | | events[name] = [];
|
| | | }
|
| | |
|
| | | events[name].push(fn);
|
| | | },
|
| | |
|
| | | unbind: function (name, fn) {
|
| | | var events,
|
| | | index;
|
| | |
|
| | | if (name) {
|
| | | events = this.HCEvents[name] || [];
|
| | | if (fn) {
|
| | | index = HighchartsAdapter.inArray(fn, events);
|
| | | if (index > -1) {
|
| | | events.splice(index, 1);
|
| | | this.HCEvents[name] = events;
|
| | | }
|
| | | if (this.removeEventListener) {
|
| | | removeOneEvent(this, name, fn);
|
| | | } else if (this.attachEvent) {
|
| | | IERemoveOneEvent(this, name, fn);
|
| | | }
|
| | | } else {
|
| | | removeAllEvents(this, name);
|
| | | this.HCEvents[name] = [];
|
| | | }
|
| | | } else {
|
| | | removeAllEvents(this);
|
| | | this.HCEvents = {};
|
| | | }
|
| | | },
|
| | |
|
| | | trigger: function (name, args) {
|
| | | var events = this.HCEvents[name] || [],
|
| | | target = this,
|
| | | len = events.length,
|
| | | i,
|
| | | preventDefault,
|
| | | fn;
|
| | |
|
| | | // Attach a simple preventDefault function to skip default handler if called
|
| | | preventDefault = function () {
|
| | | args.defaultPrevented = true;
|
| | | };
|
| | | |
| | | for (i = 0; i < len; i++) {
|
| | | fn = events[i];
|
| | |
|
| | | // args is never null here
|
| | | if (args.stopped) {
|
| | | return;
|
| | | }
|
| | |
|
| | | args.preventDefault = preventDefault;
|
| | | args.target = target;
|
| | | args.type = name; // #2297 |
| | | |
| | | // If the event handler return false, prevent the default handler from executing
|
| | | if (fn.call(this, args) === false) {
|
| | | args.preventDefault();
|
| | | }
|
| | | }
|
| | | }
|
| | | });
|
| | | }
|
| | |
|
| | | return obj;
|
| | | }
|
| | |
|
| | |
|
| | | return {
|
| | | /**
|
| | | * Initialize the adapter. This is run once as Highcharts is first run.
|
| | | */
|
| | | init: function (pathAnim) {
|
| | |
|
| | | /**
|
| | | * Compatibility section to add support for legacy IE. This can be removed if old IE |
| | | * support is not needed.
|
| | | */
|
| | | if (!doc.defaultView) {
|
| | | this._getStyle = function (el, prop) {
|
| | | var val;
|
| | | if (el.style[prop]) {
|
| | | return el.style[prop];
|
| | | } else {
|
| | | if (prop === 'opacity') {
|
| | | prop = 'filter';
|
| | | }
|
| | | /*jslint unparam: true*/
|
| | | val = el.currentStyle[prop.replace(/\-(\w)/g, function (a, b) { return b.toUpperCase(); })];
|
| | | if (prop === 'filter') {
|
| | | val = val.replace(
|
| | | /alpha\(opacity=([0-9]+)\)/, |
| | | function (a, b) { |
| | | return b / 100; |
| | | }
|
| | | );
|
| | | }
|
| | | /*jslint unparam: false*/
|
| | | return val === '' ? 1 : val;
|
| | | } |
| | | };
|
| | | this.adapterRun = function (elem, method) {
|
| | | var alias = { width: 'clientWidth', height: 'clientHeight' }[method];
|
| | |
|
| | | if (alias) {
|
| | | elem.style.zoom = 1;
|
| | | return elem[alias] - 2 * parseInt(HighchartsAdapter._getStyle(elem, 'padding'), 10);
|
| | | }
|
| | | };
|
| | | }
|
| | |
|
| | | if (!Array.prototype.forEach) {
|
| | | this.each = function (arr, fn) { // legacy
|
| | | var i = 0, |
| | | len = arr.length;
|
| | | for (; i < len; i++) {
|
| | | if (fn.call(arr[i], arr[i], i, arr) === false) {
|
| | | return i;
|
| | | }
|
| | | }
|
| | | };
|
| | | }
|
| | |
|
| | | if (!Array.prototype.indexOf) {
|
| | | this.inArray = function (item, arr) {
|
| | | var len, |
| | | i = 0;
|
| | |
|
| | | if (arr) {
|
| | | len = arr.length;
|
| | | |
| | | for (; i < len; i++) {
|
| | | if (arr[i] === item) {
|
| | | return i;
|
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | | return -1;
|
| | | };
|
| | | }
|
| | |
|
| | | if (!Array.prototype.filter) {
|
| | | this.grep = function (elements, callback) {
|
| | | var ret = [],
|
| | | i = 0,
|
| | | length = elements.length;
|
| | |
|
| | | for (; i < length; i++) {
|
| | | if (!!callback(elements[i], i)) {
|
| | | ret.push(elements[i]);
|
| | | }
|
| | | }
|
| | |
|
| | | return ret;
|
| | | };
|
| | | }
|
| | |
|
| | | //--- End compatibility section ---
|
| | |
|
| | |
|
| | | /**
|
| | | * Start of animation specific code
|
| | | */
|
| | | Fx = function (elem, options, prop) {
|
| | | this.options = options;
|
| | | this.elem = elem;
|
| | | this.prop = prop;
|
| | | };
|
| | | Fx.prototype = {
|
| | | |
| | | update: function () {
|
| | | var styles,
|
| | | paths = this.paths,
|
| | | elem = this.elem,
|
| | | elemelem = elem.element; // if destroyed, it is null
|
| | |
|
| | | // Animating a path definition on SVGElement
|
| | | if (paths && elemelem) {
|
| | | elem.attr('d', pathAnim.step(paths[0], paths[1], this.now, this.toD));
|
| | | |
| | | // Other animations on SVGElement
|
| | | } else if (elem.attr) {
|
| | | if (elemelem) {
|
| | | elem.attr(this.prop, this.now);
|
| | | }
|
| | |
|
| | | // HTML styles
|
| | | } else {
|
| | | styles = {};
|
| | | styles[elem] = this.now + this.unit;
|
| | | Highcharts.css(elem, styles);
|
| | | }
|
| | | |
| | | if (this.options.step) {
|
| | | this.options.step.call(this.elem, this.now, this);
|
| | | }
|
| | |
|
| | | },
|
| | | custom: function (from, to, unit) {
|
| | | var self = this,
|
| | | t = function (gotoEnd) {
|
| | | return self.step(gotoEnd);
|
| | | },
|
| | | i;
|
| | |
|
| | | this.startTime = +new Date();
|
| | | this.start = from;
|
| | | this.end = to;
|
| | | this.unit = unit;
|
| | | this.now = this.start;
|
| | | this.pos = this.state = 0;
|
| | |
|
| | | t.elem = this.elem;
|
| | |
|
| | | if (t() && timers.push(t) === 1) {
|
| | | timerId = setInterval(function () {
|
| | | |
| | | for (i = 0; i < timers.length; i++) {
|
| | | if (!timers[i]()) {
|
| | | timers.splice(i--, 1);
|
| | | }
|
| | | }
|
| | |
|
| | | if (!timers.length) {
|
| | | clearInterval(timerId);
|
| | | }
|
| | | }, 13);
|
| | | }
|
| | | },
|
| | | |
| | | step: function (gotoEnd) {
|
| | | var t = +new Date(),
|
| | | ret,
|
| | | done,
|
| | | options = this.options,
|
| | | i;
|
| | |
|
| | | if (this.elem.stopAnimation) {
|
| | | ret = false;
|
| | |
|
| | | } else if (gotoEnd || t >= options.duration + this.startTime) {
|
| | | this.now = this.end;
|
| | | this.pos = this.state = 1;
|
| | | this.update();
|
| | |
|
| | | this.options.curAnim[this.prop] = true;
|
| | |
|
| | | done = true;
|
| | | for (i in options.curAnim) {
|
| | | if (options.curAnim[i] !== true) {
|
| | | done = false;
|
| | | }
|
| | | }
|
| | |
|
| | | if (done) {
|
| | | if (options.complete) {
|
| | | options.complete.call(this.elem);
|
| | | }
|
| | | }
|
| | | ret = false;
|
| | |
|
| | | } else {
|
| | | var n = t - this.startTime;
|
| | | this.state = n / options.duration;
|
| | | this.pos = options.easing(n, 0, 1, options.duration);
|
| | | this.now = this.start + ((this.end - this.start) * this.pos);
|
| | | this.update();
|
| | | ret = true;
|
| | | }
|
| | | return ret;
|
| | | }
|
| | | };
|
| | |
|
| | | /**
|
| | | * The adapter animate method
|
| | | */
|
| | | this.animate = function (el, prop, opt) {
|
| | | var start,
|
| | | unit = '',
|
| | | end,
|
| | | fx,
|
| | | args,
|
| | | name;
|
| | |
|
| | | el.stopAnimation = false; // ready for new
|
| | |
|
| | | if (typeof opt !== 'object' || opt === null) {
|
| | | args = arguments;
|
| | | opt = {
|
| | | duration: args[2],
|
| | | easing: args[3],
|
| | | complete: args[4]
|
| | | };
|
| | | }
|
| | | if (typeof opt.duration !== 'number') {
|
| | | opt.duration = 400;
|
| | | }
|
| | | opt.easing = Math[opt.easing] || Math.easeInOutSine;
|
| | | opt.curAnim = Highcharts.extend({}, prop);
|
| | | |
| | | for (name in prop) {
|
| | | fx = new Fx(el, opt, name);
|
| | | end = null;
|
| | | |
| | | if (name === 'd') {
|
| | | fx.paths = pathAnim.init(
|
| | | el,
|
| | | el.d,
|
| | | prop.d
|
| | | );
|
| | | fx.toD = prop.d;
|
| | | start = 0;
|
| | | end = 1;
|
| | | } else if (el.attr) {
|
| | | start = el.attr(name);
|
| | | } else {
|
| | | start = parseFloat(HighchartsAdapter._getStyle(el, name)) || 0;
|
| | | if (name !== 'opacity') {
|
| | | unit = 'px';
|
| | | }
|
| | | }
|
| | | |
| | | if (!end) {
|
| | | end = parseFloat(prop[name]);
|
| | | }
|
| | | fx.custom(start, end, unit);
|
| | | } |
| | | };
|
| | | },
|
| | |
|
| | | /**
|
| | | * Internal method to return CSS value for given element and property
|
| | | */
|
| | | _getStyle: function (el, prop) {
|
| | | return window.getComputedStyle(el).getPropertyValue(prop);
|
| | | },
|
| | |
|
| | | /**
|
| | | * Downloads a script and executes a callback when done.
|
| | | * @param {String} scriptLocation
|
| | | * @param {Function} callback
|
| | | */
|
| | | getScript: function (scriptLocation, callback) {
|
| | | // We cannot assume that Assets class from mootools-more is available so instead insert a script tag to download script.
|
| | | var head = doc.getElementsByTagName('head')[0],
|
| | | script = doc.createElement('script');
|
| | |
|
| | | script.type = 'text/javascript';
|
| | | script.src = scriptLocation;
|
| | | script.onload = callback;
|
| | |
|
| | | head.appendChild(script);
|
| | | },
|
| | |
|
| | | /**
|
| | | * Return the index of an item in an array, or -1 if not found
|
| | | */
|
| | | inArray: function (item, arr) {
|
| | | return arr.indexOf ? arr.indexOf(item) : emptyArray.indexOf.call(arr, item);
|
| | | },
|
| | |
|
| | |
|
| | | /**
|
| | | * A direct link to adapter methods
|
| | | */
|
| | | adapterRun: function (elem, method) {
|
| | | return parseInt(HighchartsAdapter._getStyle(elem, method), 10);
|
| | | },
|
| | |
|
| | | /**
|
| | | * Filter an array
|
| | | */
|
| | | grep: function (elements, callback) {
|
| | | return emptyArray.filter.call(elements, callback);
|
| | | },
|
| | |
|
| | | /**
|
| | | * Map an array
|
| | | */
|
| | | map: function (arr, fn) {
|
| | | var results = [], i = 0, len = arr.length;
|
| | |
|
| | | for (; i < len; i++) {
|
| | | results[i] = fn.call(arr[i], arr[i], i, arr);
|
| | | }
|
| | |
|
| | | return results;
|
| | | },
|
| | |
|
| | | offset: function (el) {
|
| | | var left = 0,
|
| | | top = 0;
|
| | |
|
| | | while (el) {
|
| | | left += el.offsetLeft;
|
| | | top += el.offsetTop;
|
| | | el = el.offsetParent;
|
| | | }
|
| | |
|
| | | return {
|
| | | left: left,
|
| | | top: top
|
| | | };
|
| | | },
|
| | |
|
| | | /**
|
| | | * Add an event listener
|
| | | */
|
| | | addEvent: function (el, type, fn) {
|
| | | augment(el).bind(type, fn);
|
| | | },
|
| | |
|
| | | /**
|
| | | * Remove event added with addEvent
|
| | | */
|
| | | removeEvent: function (el, type, fn) {
|
| | | augment(el).unbind(type, fn);
|
| | | },
|
| | |
|
| | | /**
|
| | | * Fire an event on a custom object
|
| | | */
|
| | | fireEvent: function (el, type, eventArguments, defaultFunction) {
|
| | | var e;
|
| | |
|
| | | if (doc.createEvent && (el.dispatchEvent || el.fireEvent)) {
|
| | | e = doc.createEvent('Events');
|
| | | e.initEvent(type, true, true);
|
| | | e.target = el;
|
| | |
|
| | | Highcharts.extend(e, eventArguments);
|
| | |
|
| | | if (el.dispatchEvent) {
|
| | | el.dispatchEvent(e);
|
| | | } else {
|
| | | el.fireEvent(type, e);
|
| | | }
|
| | |
|
| | | } else if (el.HCExtended === true) {
|
| | | eventArguments = eventArguments || {};
|
| | | el.trigger(type, eventArguments);
|
| | | }
|
| | |
|
| | | if (eventArguments && eventArguments.defaultPrevented) {
|
| | | defaultFunction = null;
|
| | | }
|
| | |
|
| | | if (defaultFunction) {
|
| | | defaultFunction(eventArguments);
|
| | | }
|
| | | },
|
| | |
|
| | | washMouseEvent: function (e) {
|
| | | return e;
|
| | | },
|
| | |
|
| | |
|
| | | /**
|
| | | * Stop running animation
|
| | | */
|
| | | stop: function (el) {
|
| | | el.stopAnimation = true;
|
| | | },
|
| | |
|
| | | /**
|
| | | * Utility for iterating over an array. Parameters are reversed compared to jQuery.
|
| | | * @param {Array} arr
|
| | | * @param {Function} fn
|
| | | */
|
| | | each: function (arr, fn) { // modern browsers
|
| | | return Array.prototype.forEach.call(arr, fn);
|
| | | }
|
| | | };
|
| | | }());
|