app/assets/javascripts/highcharts.js in highcharts-rails-4.1.10 vs app/assets/javascripts/highcharts.js in highcharts-rails-4.2.0
- old
+ new
@@ -1,30 +1,27 @@
// ==ClosureCompiler==
// @compilation_level SIMPLE_OPTIMIZATIONS
/**
- * @license Highcharts JS v4.1.10 (2015-12-07)
+ * @license Highcharts JS v4.2.0 (2105-12-15)
*
* (c) 2009-2014 Torstein Honsi
*
* License: www.highcharts.com/license
*/
(function (root, factory) {
if (typeof module === 'object' && module.exports) {
- module.exports = root.document ?
- factory(root) :
- function (w) {
- return factory(w);
- };
+ module.exports = root.document ?
+ factory(root) :
+ factory;
} else {
- root.Highcharts = factory();
+ root.Highcharts = factory(root);
}
-}(typeof window !== 'undefined' ? window : this, function (w) {
+}(typeof window !== 'undefined' ? window : this, function (win) { // eslint-disable-line no-undef
// encapsulated variables
var UNDEFINED,
- win = w || window,
doc = win.document,
math = Math,
mathRound = math.round,
mathFloor = math.floor,
mathCeil = math.ceil,
@@ -36,21 +33,21 @@
mathPI = math.PI,
deg2rad = mathPI * 2 / 360,
// some variables
- userAgent = navigator.userAgent,
+ userAgent = (win.navigator && win.navigator.userAgent) || '',
isOpera = win.opera,
isMS = /(msie|trident|edge)/i.test(userAgent) && !isOpera,
- docMode8 = doc.documentMode === 8,
+ docMode8 = doc && doc.documentMode === 8,
isWebKit = !isMS && /AppleWebKit/.test(userAgent),
isFirefox = /Firefox/.test(userAgent),
isTouchDevice = /(Mobile|Android|Windows Phone)/.test(userAgent),
SVG_NS = 'http://www.w3.org/2000/svg',
- hasSVG = !!doc.createElementNS && !!doc.createElementNS(SVG_NS, 'svg').createSVGRect,
+ hasSVG = doc && doc.createElementNS && !!doc.createElementNS(SVG_NS, 'svg').createSVGRect,
hasBidiBug = isFirefox && parseInt(userAgent.split('Firefox/')[1], 10) < 4, // issue #38
- useCanVG = !hasSVG && !isMS && !!doc.createElement('canvas').getContext,
+ useCanVG = doc && !hasSVG && !isMS && !!doc.createElement('canvas').getContext,
Renderer,
hasTouch,
symbolSizes = {},
idCounter = 0,
garbageBin,
@@ -60,11 +57,11 @@
timeUnits,
noop = function () {},
charts = [],
chartCount = 0,
PRODUCT = 'Highcharts',
- VERSION = '4.1.10',
+ VERSION = '4.2.0',
// some constants for frequently used strings
DIV = 'div',
ABSOLUTE = 'absolute',
RELATIVE = 'relative',
@@ -124,18 +121,254 @@
console.log(msg); // eslint-disable-line no-console
}
}
// The Highcharts namespace
- Highcharts = win.Highcharts ? error(16, true) : function (adapter) {
- Highcharts.loadAdapter(adapter);
- return Highcharts;
- };
+ Highcharts = win.Highcharts ? error(16, true) : { win: win };
Highcharts.seriesTypes = seriesTypes;
+ var timers = [],
+ getStyle,
+ // Previous adapter functions
+ inArray,
+ each,
+ grep,
+ offset,
+ map,
+ addEvent,
+ removeEvent,
+ fireEvent,
+ animate,
+ stop;
+
/**
+ * An animator object. One instance applies to one property (attribute or style prop)
+ * on one element.
+ *
+ * @param {object} elem The element to animate. May be a DOM element or a Highcharts SVGElement wrapper.
+ * @param {object} options Animation options, including duration, easing, step and complete.
+ * @param {object} prop The property to animate.
+ */
+ function Fx(elem, options, prop) {
+ this.options = options;
+ this.elem = elem;
+ this.prop = prop;
+ }
+ Fx.prototype = {
+
+ /**
+ * Animating a path definition on SVGElement
+ * @returns {undefined}
+ */
+ dSetter: function () {
+ var start = this.paths[0],
+ end = this.paths[1],
+ ret = [],
+ now = this.now,
+ i = start.length,
+ startVal;
+
+ if (now === 1) { // land on the final path without adjustment points appended in the ends
+ ret = this.toD;
+
+ } else if (i === end.length && now < 1) {
+ while (i--) {
+ startVal = parseFloat(start[i]);
+ ret[i] =
+ isNaN(startVal) ? // a letter instruction like M or L
+ start[i] :
+ now * (parseFloat(end[i] - startVal)) + startVal;
+
+ }
+ } else { // if animation is finished or length not matching, land on right value
+ ret = end;
+ }
+ this.elem.attr('d', ret);
+ },
+
+ /**
+ * Update the element with the current animation step
+ * @returns {undefined}
+ */
+ update: function () {
+ var elem = this.elem,
+ prop = this.prop, // if destroyed, it is null
+ now = this.now,
+ step = this.options.step;
+
+ // Animation setter defined from outside
+ if (this[prop + 'Setter']) {
+ this[prop + 'Setter']();
+
+ // Other animations on SVGElement
+ } else if (elem.attr) {
+ if (elem.element) {
+ elem.attr(prop, now);
+ }
+
+ // HTML styles, raw HTML content like container size
+ } else {
+ elem.style[prop] = now + this.unit;
+ }
+
+ if (step) {
+ step.call(elem, now, this);
+ }
+
+ },
+
+ /**
+ * Run an animation
+ */
+ run: function (from, to, unit) {
+ var self = this,
+ timer = function (gotoEnd) {
+ return timer.stopped ? false : self.step(gotoEnd);
+ },
+ i;
+
+ this.startTime = +new Date();
+ this.start = from;
+ this.end = to;
+ this.unit = unit;
+ this.now = this.start;
+ this.pos = 0;
+
+ timer.elem = this.elem;
+
+ if (timer() && timers.push(timer) === 1) {
+ timer.timerId = setInterval(function () {
+
+ for (i = 0; i < timers.length; i++) {
+ if (!timers[i]()) {
+ timers.splice(i--, 1);
+ }
+ }
+
+ if (!timers.length) {
+ clearInterval(timer.timerId);
+ }
+ }, 13);
+ }
+ },
+
+ /**
+ * Run a single step in the animation
+ * @param {Boolean} gotoEnd Whether to go to then endpoint of the animation after abort
+ * @returns {Boolean} True if animation continues
+ */
+ step: function (gotoEnd) {
+ var t = +new Date(),
+ ret,
+ done,
+ options = this.options,
+ elem = this.elem,
+ complete = options.complete,
+ duration = options.duration,
+ curAnim = options.curAnim,
+ i;
+
+ if (elem.attr && !elem.element) { // #2616, element including flag is destroyed
+ ret = false;
+
+ } else if (gotoEnd || t >= duration + this.startTime) {
+ this.now = this.end;
+ this.pos = 1;
+ this.update();
+
+ curAnim[this.prop] = true;
+
+ done = true;
+ for (i in curAnim) {
+ if (curAnim[i] !== true) {
+ done = false;
+ }
+ }
+
+ if (done && complete) {
+ complete.call(elem);
+ }
+ ret = false;
+
+ } else {
+ this.pos = options.easing((t - this.startTime) / duration);
+ this.now = this.start + ((this.end - this.start) * this.pos);
+ this.update();
+ ret = true;
+ }
+ return ret;
+ },
+
+ /**
+ * Prepare start and end values so that the path can be animated one to one
+ */
+ initPath: function (elem, fromD, toD) {
+ fromD = fromD || '';
+ var shift = elem.shift,
+ bezier = fromD.indexOf('C') > -1,
+ numParams = bezier ? 7 : 3,
+ endLength,
+ slice,
+ i,
+ start = fromD.split(' '),
+ end = [].concat(toD), // copy
+ startBaseLine,
+ endBaseLine,
+ sixify = function (arr) { // in splines make move points have six parameters like bezier curves
+ i = arr.length;
+ while (i--) {
+ if (arr[i] === M) {
+ arr.splice(i + 1, 0, arr[i + 1], arr[i + 2], arr[i + 1], arr[i + 2]);
+ }
+ }
+ };
+
+ if (bezier) {
+ sixify(start);
+ sixify(end);
+ }
+
+ // pull out the base lines before padding
+ if (elem.isArea) {
+ startBaseLine = start.splice(start.length - 6, 6);
+ endBaseLine = end.splice(end.length - 6, 6);
+ }
+
+ // if shifting points, prepend a dummy point to the end path
+ if (shift <= end.length / numParams && start.length === end.length) {
+ while (shift--) {
+ end = [].concat(end).splice(0, numParams).concat(end);
+ }
+ }
+ elem.shift = 0; // reset for following animations
+
+ // copy and append last point until the length matches the end length
+ if (start.length) {
+ endLength = end.length;
+ while (start.length < endLength) {
+
+ //bezier && sixify(start);
+ slice = [].concat(start).splice(start.length - numParams, numParams);
+ if (bezier) { // disable first control point
+ slice[numParams - 6] = slice[numParams - 2];
+ slice[numParams - 5] = slice[numParams - 1];
+ }
+ start = start.concat(slice);
+ }
+ }
+
+ if (startBaseLine) { // append the base lines for areas
+ start = start.concat(startBaseLine);
+ end = end.concat(endBaseLine);
+ }
+ return [start, end];
+ }
+ }; // End of Fx prototype
+
+
+ /**
* Extend an object with the members of another
* @param {Object} a The object to be extended
* @param {Object} b The object to add to the first one
*/
var extend = Highcharts.extend = function (a, b) {
@@ -265,11 +498,11 @@
}
//return arr;
}
/**
- * Returns true if the object is not null or undefined. Like MooTools' $.defined.
+ * Returns true if the object is not null or undefined.
* @param {Object} obj
*/
function defined(obj) {
return obj !== UNDEFINED && obj !== null;
}
@@ -304,12 +537,11 @@
}
}
return ret;
}
/**
- * Check if an element is an array, and if not, make it into an array. Like
- * MooTools' $.splat.
+ * Check if an element is an array, and if not, make it into an array.
*/
function splat(obj) {
return isArray(obj) ? obj : [obj];
}
@@ -327,11 +559,11 @@
fn.call(0, context);
}
/**
- * Return the first value that is defined. Like MooTools' $.pick.
+ * Return the first value that is defined.
*/
var pick = Highcharts.pick = function () {
var args = arguments,
i,
arg,
@@ -786,512 +1018,447 @@
j = i.length > 3 ? i.length % 3 : 0;
return (s + (j ? i.substr(0, j) + t : '') + i.substr(j).replace(/(\d{3})(?=\d)/g, '$1' + t) +
(c ? d + mathAbs(n - i).toFixed(c).slice(2) : ''));
};
+
/**
- * Path interpolation algorithm used across adapters
+ * Easing definition
+ * @param {Number} pos Current position, ranging from 0 to 1
*/
- pathAnim = {
- /**
- * Prepare start and end values so that the path can be animated one to one
- */
- init: function (elem, fromD, toD) {
- fromD = fromD || '';
- var shift = elem.shift,
- bezier = fromD.indexOf('C') > -1,
- numParams = bezier ? 7 : 3,
- endLength,
- slice,
- i,
- start = fromD.split(' '),
- end = [].concat(toD), // copy
- startBaseLine,
- endBaseLine,
- sixify = function (arr) { // in splines make move points have six parameters like bezier curves
- i = arr.length;
- while (i--) {
- if (arr[i] === M) {
- arr.splice(i + 1, 0, arr[i + 1], arr[i + 2], arr[i + 1], arr[i + 2]);
- }
- }
- };
+ Math.easeInOutSine = function (pos) {
+ return -0.5 * (Math.cos(Math.PI * pos) - 1);
+ };
- if (bezier) {
- sixify(start);
- sixify(end);
- }
+ /**
+ * Internal method to return CSS value for given element and property
+ */
+ getStyle = function (el, prop) {
+ var style = win.getComputedStyle(el, undefined);
+ return style && pInt(style.getPropertyValue(prop));
+ };
- // pull out the base lines before padding
- if (elem.isArea) {
- startBaseLine = start.splice(start.length - 6, 6);
- endBaseLine = end.splice(end.length - 6, 6);
- }
+ /**
+ * Return the index of an item in an array, or -1 if not found
+ */
+ inArray = function (item, arr) {
+ return arr.indexOf ? arr.indexOf(item) : [].indexOf.call(arr, item);
+ };
- // if shifting points, prepend a dummy point to the end path
- if (shift <= end.length / numParams && start.length === end.length) {
- while (shift--) {
- end = [].concat(end).splice(0, numParams).concat(end);
- }
- }
- elem.shift = 0; // reset for following animations
+ /**
+ * Filter an array
+ */
+ grep = function (elements, callback) {
+ return [].filter.call(elements, callback);
+ };
- // copy and append last point until the length matches the end length
- if (start.length) {
- endLength = end.length;
- while (start.length < endLength) {
+ /**
+ * Map an array
+ */
+ map = function (arr, fn) {
+ var results = [], i = 0, len = arr.length;
- //bezier && sixify(start);
- slice = [].concat(start).splice(start.length - numParams, numParams);
- if (bezier) { // disable first control point
- slice[numParams - 6] = slice[numParams - 2];
- slice[numParams - 5] = slice[numParams - 1];
- }
- start = start.concat(slice);
- }
- }
+ for (; i < len; i++) {
+ results[i] = fn.call(arr[i], arr[i], i, arr);
+ }
- if (startBaseLine) { // append the base lines for areas
- start = start.concat(startBaseLine);
- end = end.concat(endBaseLine);
- }
- return [start, end];
- },
+ return results;
+ };
- /**
- * Interpolate each value of the path and return the array
- */
- step: function (start, end, pos, complete) {
- var ret = [],
- i = start.length,
- startVal;
+ /**
+ * Get the element's offset position, corrected by overflow:auto.
+ */
+ offset = function (el) {
+ var docElem = doc.documentElement,
+ box = el.getBoundingClientRect();
- if (pos === 1) { // land on the final path without adjustment points appended in the ends
- ret = complete;
+ return {
+ top: box.top + (win.pageYOffset || docElem.scrollTop) - (docElem.clientTop || 0),
+ left: box.left + (win.pageXOffset || docElem.scrollLeft) - (docElem.clientLeft || 0)
+ };
+ };
- } else if (i === end.length && pos < 1) {
- while (i--) {
- startVal = parseFloat(start[i]);
- ret[i] =
- isNaN(startVal) ? // a letter instruction like M or L
- start[i] :
- pos * (parseFloat(end[i] - startVal)) + startVal;
+ /**
+ * Stop running animation.
+ * A possible extension to this would be to stop a single property, when
+ * we want to continue animating others. Then assign the prop to the timer
+ * in the Fx.run method, and check for the prop here. This would be an improvement
+ * in all cases where we stop the animation from .attr. Instead of stopping
+ * everything, we can just stop the actual attributes we're setting.
+ */
+ stop = function (el) {
- }
- } else { // if animation is finished or length not matching, land on right value
- ret = end;
+ var i = timers.length;
+
+ // Remove timers related to this element (#4519)
+ while (i--) {
+ if (timers[i].elem === el) {
+ timers[i].stopped = true; // #4667
}
- return ret;
}
};
- function loadJQueryAdapter($) {
- /**
- * The default HighchartsAdapter for jQuery
- */
- return {
+ /**
+ * Utility for iterating over an array.
+ * @param {Array} arr
+ * @param {Function} fn
+ */
+ each = function (arr, fn) { // modern browsers
+ return Array.prototype.forEach.call(arr, fn);
+ };
- /**
- * Initialize the adapter by applying some extensions to jQuery
- */
- init: function (pathAnim) {
+ /**
+ * Add an event listener
+ */
+ addEvent = function (el, type, fn) {
+
+ var events = el.hcEvents = el.hcEvents || {};
- // extend the animate function to allow SVG animations
- var Fx = $.fx;
+ function wrappedFn(e) {
+ e.target = e.srcElement || win; // #2820
+ fn.call(el, e);
+ }
- $.extend($.easing, {
- easeOutQuad: function (x, t, b, c, d) {
- return -c * (t /= d) * (t - 2) + b;
- }
- });
+ // Handle DOM events in modern browsers
+ if (el.addEventListener) {
+ el.addEventListener(type, fn, false);
- // extend some methods to check for elem.attr, which means it is a Highcharts SVG object
- $.each(['cur', '_default', 'width', 'height', 'opacity'], function (i, fn) {
- var obj = Fx.step,
- base;
+ // Handle old IE implementation
+ } else if (el.attachEvent) {
- // Handle different parent objects
- if (fn === 'cur') {
- obj = Fx.prototype; // 'cur', the getter, relates to Fx.prototype
+ if (!el.hcEventsIE) {
+ el.hcEventsIE = {};
+ }
- } else if (fn === '_default' && $.Tween) { // jQuery 1.8 model
- obj = $.Tween.propHooks[fn];
- fn = 'set';
- }
+ // Link wrapped fn with original fn, so we can get this in removeEvent
+ el.hcEventsIE[fn.toString()] = wrappedFn;
- // Overwrite the method
- base = obj[fn];
- if (base) { // step.width and step.height don't exist in jQuery < 1.7
+ el.attachEvent('on' + type, wrappedFn);
+ }
- // create the extended function replacement
- obj[fn] = function (effects) {
+ if (!events[type]) {
+ events[type] = [];
+ }
- var elem, fx;
+ events[type].push(fn);
+ };
- // Fx.prototype.cur does not use fx argument
- fx = i ? effects : this;
+ /**
+ * Remove event added with addEvent
+ */
+ removeEvent = function (el, type, fn) {
+
+ var events,
+ hcEvents = el.hcEvents,
+ index;
- // Don't run animations on textual properties like align (#1821)
- if (fx.prop === 'align') {
- return;
- }
+ function removeOneEvent(type, fn) {
+ if (el.removeEventListener) {
+ el.removeEventListener(type, fn, false);
+ } else if (el.attachEvent) {
+ fn = el.hcEventsIE[fn.toString()];
+ el.detachEvent('on' + type, fn);
+ }
+ }
- // shortcut
- elem = fx.elem;
+ function removeAllEvents() {
+ var types,
+ len,
+ n;
- // Fx.prototype.cur returns the current value. The other ones are setters
- // and returning a value has no effect.
- if (elem.attr) { // is SVG element wrapper
- return elem.attr(
- fx.prop.replace('strokeWidth', 'stroke-width'), // #4721
- fn === 'cur' ? undefined : fx.now
- );
- }
+ if (!el.nodeName) {
+ return; // break on non-DOM events
+ }
- return base.apply(this, arguments); // use jQuery's built-in method
- };
+ if (type) {
+ types = {};
+ types[type] = true;
+ } else {
+ types = hcEvents;
+ }
+
+ for (n in types) {
+ if (hcEvents[n]) {
+ len = hcEvents[n].length;
+ while (len--) {
+ removeOneEvent(n, hcEvents[n][len]);
}
- });
+ }
+ }
+ }
- // Extend the opacity getter, needed for fading opacity with IE9 and jQuery 1.10+
- wrap($.cssHooks.opacity, 'get', function (proceed, elem, computed) {
- return elem.attr ? (elem.opacity || 0) : proceed.call(this, elem, computed);
- });
-
- // Define the setter function for d (path definitions)
- this.addAnimSetter('d', function (fx) {
- var elem = fx.elem,
- ends;
-
- // Normally start and end should be set in state == 0, but sometimes,
- // for reasons unknown, this doesn't happen. Perhaps state == 0 is skipped
- // in these cases
- if (!fx.started) {
- ends = pathAnim.init(elem, elem.d, elem.toD);
- fx.start = ends[0];
- fx.end = ends[1];
- fx.started = true;
+ if (hcEvents) {
+ if (type) {
+ events = hcEvents[type] || [];
+ if (fn) {
+ index = inArray(fn, events);
+ if (index > -1) {
+ events.splice(index, 1);
+ hcEvents[type] = events;
}
+ removeOneEvent(type, fn);
- // Interpolate each value of the path
- elem.attr('d', pathAnim.step(fx.start, fx.end, fx.pos, elem.toD));
- });
+ } else {
+ removeAllEvents();
+ hcEvents[type] = [];
+ }
+ } else {
+ removeAllEvents();
+ el.hcEvents = {};
+ }
+ }
+ };
- /**
- * Utility for iterating over an array. Parameters are reversed compared to jQuery.
- * @param {Array} arr
- * @param {Function} fn
- */
- this.each = Array.prototype.forEach ?
- function each(arr, fn) { // modern browsers
- return Array.prototype.forEach.call(arr, fn);
+ /**
+ * Fire an event on a custom object
+ */
+ fireEvent = function (el, type, eventArguments, defaultFunction) {
+ var e,
+ hcEvents = el.hcEvents,
+ events,
+ len,
+ i,
+ preventDefault,
+ fn;
- } :
- function each(arr, fn) { // legacy
- var i,
- len = arr.length;
- for (i = 0; i < len; i++) {
- if (fn.call(arr[i], arr[i], i, arr) === false) {
- return i;
- }
- }
- };
+ eventArguments = eventArguments || {};
- /**
- * Register Highcharts as a plugin in the respective framework
- */
- $.fn.highcharts = function () {
- var constr = 'Chart', // default constructor
- args = arguments,
- options,
- ret;
+ if (doc.createEvent && (el.dispatchEvent || el.fireEvent)) {
+ e = doc.createEvent('Events');
+ e.initEvent(type, true, true);
+ e.target = el;
- if (this[0]) {
+ extend(e, eventArguments);
- if (isString(args[0])) {
- constr = args[0];
- args = Array.prototype.slice.call(args, 1);
- }
- options = args[0];
+ if (el.dispatchEvent) {
+ el.dispatchEvent(e);
+ } else {
+ el.fireEvent(type, e);
+ }
- // Create the chart
- if (options !== UNDEFINED) {
- options.chart = options.chart || {};
- options.chart.renderTo = this[0];
- ret = new Highcharts[constr](options, args[1]);
- ret = this;
- }
+ } else if (hcEvents) {
+
+ events = hcEvents[type] || [];
+ len = events.length;
- // When called without parameters or with the return argument, get a predefined chart
- if (options === UNDEFINED) {
- ret = charts[attr(this[0], 'data-highcharts-chart')];
- }
- }
+ // Attach a simple preventDefault function to skip default handler if called
+ preventDefault = function () {
+ eventArguments.defaultPrevented = true;
+ };
+
+ for (i = 0; i < len; i++) {
+ fn = events[i];
- return ret;
- };
+ // eventArguments is never null here
+ if (eventArguments.stopped) {
+ return;
+ }
- },
+ eventArguments.preventDefault = preventDefault;
+ eventArguments.target = el;
- /**
- * Add an animation setter for a specific property
- */
- addAnimSetter: function (prop, setter) {
- // jQuery 1.8 style
- if ($.Tween) {
- $.Tween.propHooks[prop] = {
- set: setter
- };
- // pre 1.8
- } else {
- $.fx.step[prop] = setter;
+ // If the type is not set, we're running a custom event (#2297). If it is set,
+ // we're running a browser event, and setting it will cause en error in
+ // IE8 (#2465).
+ if (!eventArguments.type) {
+ eventArguments.type = type;
}
- },
+
+ // If the event handler return false, prevent the default handler from executing
+ if (fn.call(el, eventArguments) === false) {
+ eventArguments.preventDefault();
+ }
+ }
+ }
- /**
- * Downloads a script and executes a callback when done.
- * @param {String} scriptLocation
- * @param {Function} callback
- */
- getScript: $.getScript,
+ // Run the default if not prevented
+ if (defaultFunction && !eventArguments.defaultPrevented) {
+ defaultFunction(eventArguments);
+ }
+ };
- /**
- * Return the index of an item in an array, or -1 if not found
- */
- inArray: $.inArray,
+ /**
+ * The global animate method, which uses Fx to create individual animators.
+ */
+ animate = function (el, params, opt) {
+ var start,
+ unit = '',
+ end,
+ fx,
+ args,
+ prop;
- /**
- * A direct link to jQuery methods. MooTools and Prototype adapters must be implemented for each case of method.
- * @param {Object} elem The HTML element
- * @param {String} method Which method to run on the wrapped element
- */
- adapterRun: function (elem, method) {
- return $(elem)[method]();
- },
+ if (!isObject(opt)) { // Number or undefined/null
+ args = arguments;
+ opt = {
+ duration: args[2],
+ easing: args[3],
+ complete: args[4]
+ };
+ }
+ if (!isNumber(opt.duration)) {
+ opt.duration = 400;
+ }
+ opt.easing = Math[opt.easing] || Math.easeInOutSine;
+ opt.curAnim = merge(params);
- /**
- * Filter an array
- */
- grep: $.grep,
+ for (prop in params) {
+ fx = new Fx(el, opt, prop);
+ end = null;
- /**
- * Map an array
- * @param {Array} arr
- * @param {Function} fn
- */
- map: function (arr, fn) {
- //return jQuery.map(arr, fn);
- var results = [],
- i,
- len = arr.length;
- for (i = 0; i < len; i++) {
- results[i] = fn.call(arr[i], arr[i], i, arr);
+ if (prop === 'd') {
+ fx.paths = fx.initPath(
+ el,
+ el.d,
+ params.d
+ );
+ fx.toD = params.d;
+ start = 0;
+ end = 1;
+ } else if (el.attr) {
+ start = el.attr(prop);
+ } else {
+ start = parseFloat(getStyle(el, prop)) || 0;
+ if (prop !== 'opacity') {
+ unit = 'px';
}
- return results;
+ }
- },
+ if (!end) {
+ end = params[prop];
+ }
+ if (end.match && end.match('px')) {
+ end = end.replace(/px/g, ''); // #4351
+ }
+ fx.run(start, end, unit);
+ }
+ };
- /**
- * Get the position of an element relative to the top left of the page
- */
- offset: function (el) {
- return $(el).offset();
- },
+ /**
+ * Register Highcharts as a plugin in jQuery
+ */
+ if (win.jQuery) {
+ win.jQuery.fn.highcharts = function () {
+ var args = [].slice.call(arguments);
- /**
- * Add an event listener
- * @param {Object} el A HTML element or custom object
- * @param {String} event The event type
- * @param {Function} fn The event handler
- */
- addEvent: function (el, event, fn) {
- $(el).bind(event, fn);
- },
+ if (this[0]) { // this[0] is the renderTo div
- /**
- * Remove event added with addEvent
- * @param {Object} el The object
- * @param {String} eventType The event type. Leave blank to remove all events.
- * @param {Function} handler The function to remove
- */
- removeEvent: function (el, eventType, handler) {
- // workaround for jQuery issue with unbinding custom events:
- // http://forum.jQuery.com/topic/javascript-error-when-unbinding-a-custom-event-using-jQuery-1-4-2
- var func = doc.removeEventListener ? 'removeEventListener' : 'detachEvent';
- if (doc[func] && el && !el[func]) {
- el[func] = function () {};
+ // Create the chart
+ if (args[0]) {
+ new Highcharts[ // eslint-disable-line no-new
+ isString(args[0]) ? args.shift() : 'Chart' // Constructor defaults to Chart
+ ](this[0], args[0], args[1]);
+ return this;
}
- $(el).unbind(eventType, handler);
- },
+ // When called without parameters or with the return argument, return an existing chart
+ return charts[attr(this[0], 'data-highcharts-chart')];
+ }
+ };
+ }
- /**
- * Fire an event on a custom object
- * @param {Object} el
- * @param {String} type
- * @param {Object} eventArguments
- * @param {Function} defaultFunction
- */
- fireEvent: function (el, type, eventArguments, defaultFunction) {
- var event = $.Event(type),
- detachedType = 'detached' + type,
- defaultPrevented;
- // Remove warnings in Chrome when accessing returnValue (#2790), layerX and layerY. Although Highcharts
- // never uses these properties, Chrome includes them in the default click event and
- // raises the warning when they are copied over in the extend statement below.
- //
- // To avoid problems in IE (see #1010) where we cannot delete the properties and avoid
- // testing if they are there (warning in chrome) the only option is to test if running IE.
- if (!isMS && eventArguments) {
- delete eventArguments.layerX;
- delete eventArguments.layerY;
- delete eventArguments.returnValue;
- }
+ /**
+ * Compatibility section to add support for legacy IE. This can be removed if old IE
+ * support is not needed.
+ */
+ if (doc && !doc.defaultView) {
+ getStyle = function (el, prop) {
+ var val,
+ alias = { width: 'clientWidth', height: 'clientHeight' }[prop];
+
+ if (el.style[prop]) {
+ return pInt(el.style[prop]);
+ }
+ if (prop === 'opacity') {
+ prop = 'filter';
+ }
- extend(event, eventArguments);
+ // Getting the rendered width and height
+ if (alias) {
+ el.style.zoom = 1;
+ return el[alias] - 2 * getStyle(el, 'padding');
+ }
+
+ 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;
+ }
+ );
+ }
+
+ return val === '' ? 1 : pInt(val);
+ };
+ }
- // Prevent jQuery from triggering the object method that is named the
- // same as the event. For example, if the event is 'select', jQuery
- // attempts calling el.select and it goes into a loop.
- if (el[type]) {
- el[detachedType] = el[type];
- el[type] = null;
+ if (!Array.prototype.forEach) {
+ 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;
}
+ }
+ };
+ }
- // Wrap preventDefault and stopPropagation in try/catch blocks in
- // order to prevent JS errors when cancelling events on non-DOM
- // objects. #615.
- $.each(['preventDefault', 'stopPropagation'], function (i, fn) {
- var base = event[fn];
- event[fn] = function () {
- try {
- base.call(event);
- } catch (e) {
- if (fn === 'preventDefault') {
- defaultPrevented = true;
- }
- }
- };
- });
+ if (!Array.prototype.indexOf) {
+ inArray = function (item, arr) {
+ var len,
+ i = 0;
- // trigger it
- $(el).trigger(event);
-
- // attach the method
- if (el[detachedType]) {
- el[type] = el[detachedType];
- el[detachedType] = null;
+ if (arr) {
+ len = arr.length;
+
+ for (; i < len; i++) {
+ if (arr[i] === item) {
+ return i;
+ }
}
+ }
- if (defaultFunction && !event.isDefaultPrevented() && !defaultPrevented) {
- defaultFunction(event);
- }
- },
+ return -1;
+ };
+ }
- /**
- * Extension method needed for MooTools
- */
- washMouseEvent: function (e) {
- var ret = e.originalEvent || e;
+ if (!Array.prototype.filter) {
+ grep = function (elements, fn) {
+ var ret = [],
+ i = 0,
+ length = elements.length;
- // computed by jQuery, needed by IE8
- if (ret.pageX === UNDEFINED) { // #1236
- ret.pageX = e.pageX;
- ret.pageY = e.pageY;
+ for (; i < length; i++) {
+ if (fn(elements[i], i)) {
+ ret.push(elements[i]);
}
-
- return ret;
- },
-
- /**
- * Animate a HTML element or SVG element wrapper
- * @param {Object} el
- * @param {Object} params
- * @param {Object} options jQuery-like animation options: duration, easing, callback
- */
- animate: function (el, params, options) {
- var $el = $(el);
- if (!el.style) {
- el.style = {}; // #1881
- }
- if (params.d) {
- el.toD = params.d; // keep the array form for paths, used in $.fx.step.d
- params.d = 1; // because in jQuery, animating to an array has a different meaning
- }
-
- $el.stop();
- if (params.opacity !== UNDEFINED && el.attr) {
- params.opacity += 'px'; // force jQuery to use same logic as width and height (#2161)
- }
- el.hasAnim = 1; // #3342
- $el.animate(params, options);
-
- },
- /**
- * Stop running animation
- */
- stop: function (el) {
- if (el.hasAnim) { // #3342, memory leak on calling $(el) from destroy
- $(el).stop();
- }
}
+
+ return ret;
};
}
- // Utility functions. If the HighchartsAdapter is not defined, adapter is an empty object
- // and all the utility functions will be null. In that case they are populated by the
- // default adapters below.
- var adapterRun,
- inArray,
- each,
- grep,
- offset,
- map,
- addEvent,
- removeEvent,
- fireEvent,
- washMouseEvent,
- animate,
- stop;
- /**
- * Helper function to load and extend Highcharts with adapter functionality.
- * @param {object|function} adapter - HighchartsAdapter or jQuery
- */
- Highcharts.loadAdapter = function (adapter) {
-
- if (adapter) {
- // If jQuery, then load our default jQueryAdapter
- if (adapter.fn && adapter.fn.jquery) {
- adapter = loadJQueryAdapter(adapter);
- }
- // Initialize the adapter.
- if (adapter.init) {
- adapter.init(pathAnim);
- delete adapter.init; // Avoid copying to Highcharts object
- }
- // Extend Highcharts with adapter functionality.
- Highcharts.extend(Highcharts, adapter);
+ //--- End compatibility section ---
- // Assign values to local functions.
- adapterRun = Highcharts.adapterRun;
- inArray = Highcharts.inArray;
- each = Highcharts.each;
- grep = Highcharts.grep;
- offset = Highcharts.offset;
- map = Highcharts.map;
- addEvent = Highcharts.addEvent;
- removeEvent = Highcharts.removeEvent;
- fireEvent = Highcharts.fireEvent;
- washMouseEvent = Highcharts.washMouseEvent;
- animate = Highcharts.animate;
- stop = Highcharts.stop;
- }
- };
+ // Expose utilities
+ Highcharts.Fx = Fx;
+ Highcharts.inArray = inArray;
+ Highcharts.each = each;
+ Highcharts.grep = grep;
+ Highcharts.offset = offset;
+ Highcharts.map = map;
+ Highcharts.addEvent = addEvent;
+ Highcharts.removeEvent = removeEvent;
+ Highcharts.fireEvent = fireEvent;
+ Highcharts.animate = animate;
+ Highcharts.stop = stop;
- // Load adapter if HighchartsAdapter or jQuery is set on the window.
- Highcharts.loadAdapter(win.HighchartsAdapter || win.jQuery);
/* ****************************************************************************
* Handle the options *
*****************************************************************************/
defaultOptions = {
colors: ['#7cb5ec', '#434348', '#90ed7d', '#f7a35c',
@@ -1312,11 +1479,11 @@
},
global: {
useUTC: true,
//timezoneOffset: 0,
canvasToolsURL: 'http://code.highcharts.com/modules/canvas-tools.js',
- VMLRadialGradientURL: 'http://code.highcharts.com/4.1.10/gfx/vml-radial-gradient.png'
+ VMLRadialGradientURL: 'http://code.highcharts.com/4.2.0/gfx/vml-radial-gradient.png'
},
chart: {
//animation: true,
//alignTicks: false,
//reflow: true,
@@ -1637,11 +1804,11 @@
useUTC = globalOptions.useUTC,
GET = useUTC ? 'getUTC' : 'get',
SET = useUTC ? 'setUTC' : 'set';
- Date = globalOptions.Date || window.Date;
+ Date = globalOptions.Date || win.Date;
timezoneOffset = useUTC && globalOptions.timezoneOffset;
getTimezoneOffset = useUTC && globalOptions.getTimezoneOffset;
makeTime = function (year, month, date, hours, minutes, seconds) {
var d;
if (useUTC) {
@@ -1876,11 +2043,11 @@
},
/**
* Animate a given attribute
* @param {Object} params
- * @param {Number} options The same options as in jQuery animation
+ * @param {Number} options Options include duration, easing, step and complete
* @param {Function} complete Function to perform at the end of animation
*/
animate: function (params, options, complete) {
var animOptions = pick(options, this.renderer.globalAnimation, true);
stop(this); // stop regardless of animation actually running, or reverting to .attr (#607)
@@ -3075,11 +3242,10 @@
* @param {Number} height
* @param {Boolean} forExport
*/
init: function (container, width, height, style, forExport, allowHTML) {
var renderer = this,
- loc = location,
boxWrapper,
element,
desc;
boxWrapper = renderer.createElement('svg')
@@ -3101,11 +3267,11 @@
renderer.boxWrapper = boxWrapper;
renderer.alignedObjects = [];
// Page url used for internal references. #24, #672, #1070
renderer.url = (isFirefox || isWebKit) && doc.getElementsByTagName('base').length ?
- loc.href
+ win.location.href
.replace(/#.*?$/, '') // remove the hash
.replace(/([\('\)])/g, '\\$1') // escape parantheses and quotes
.replace(/ /g, '%20') : // replace spaces (needed for Safari only)
'';
@@ -3913,11 +4079,11 @@
if (this.width === 0) {
css(this, {
position: ABSOLUTE,
top: '-999em'
});
- document.body.appendChild(this);
+ doc.body.appendChild(this);
}
// Center the image
centerImage(obj, symbolSizes[imageSrc] = [this.width, this.height]);
@@ -5224,21 +5390,29 @@
} else if (nodeName !== 'IMG') { // #1336
element.filled = value !== NONE;
this.setAttr('fillcolor', this.renderer.color(value, element, key, this));
}
},
+ 'fill-opacitySetter': function (value, key, element) {
+ createElement(
+ this.renderer.prepVML(['<', key.split('-')[0], ' opacity="', value, '"/>']),
+ null,
+ null,
+ element
+ );
+ },
opacitySetter: noop, // Don't bother - animation is too slow and filters introduce artifacts
rotationSetter: function (value, key, element) {
var style = element.style;
this[key] = style[key] = value; // style is for #1873
// Correction for the 1x1 size of the shape container. Used in gauge needles.
style.left = -mathRound(mathSin(value * deg2rad) + 1) + PX;
style.top = mathRound(mathCos(value * deg2rad)) + PX;
},
strokeSetter: function (value, key, element) {
- this.setAttr('strokecolor', this.renderer.color(value, element, key));
+ this.setAttr('strokecolor', this.renderer.color(value, element, key, this));
},
'stroke-widthSetter': function (value, key, element) {
element.stroked = !!value; // VML "stroked" attribute
this[key] = value; // used in getter, issue #113
if (isNumber(value)) {
@@ -5300,10 +5474,12 @@
},
zIndexSetter: function (value, key, element) {
element.style[key] = value;
}
};
+ VMLElement['stroke-opacitySetter'] = VMLElement['fill-opacitySetter'];
+
Highcharts.VMLElement = VMLElement = extendClass(SVGElement, VMLElement);
// Some shared setters
VMLElement.prototype.ySetter =
VMLElement.prototype.widthSetter =
@@ -5590,18 +5766,17 @@
// Gradients are not supported for VML stroke, return the first color. #722.
} else {
ret = stopColor;
}
- // if the color is an rgba color, split it and add a fill node
+ // If the color is an rgba color, split it and add a fill node
// to hold the opacity component
} else if (regexRgba.test(color) && elem.tagName !== 'IMG') {
colorObject = Color(color);
- markup = ['<', prop, ' opacity="', colorObject.get('a'), '"/>'];
- createElement(this.prepVML(markup), null, null, elem);
+ wrapper[prop + '-opacitySetter'](colorObject.get('a'), prop, elem);
ret = colorObject.get('rgb');
} else {
@@ -5897,10 +6072,26 @@
* *
*****************************************************************************/
var CanVGRenderer,
CanVGController;
+ /**
+ * Downloads a script and executes a callback when done.
+ * @param {String} scriptLocation
+ * @param {Function} callback
+ */
+ function getScript(scriptLocation, callback) {
+ var head = doc.getElementsByTagName('head')[0],
+ script = doc.createElement('script');
+
+ script.type = 'text/javascript';
+ script.src = scriptLocation;
+ script.onload = callback;
+
+ head.appendChild(script);
+ }
+
if (useCanVG) {
/**
* The CanVGRenderer is empty from start to keep the source footprint small.
* When requested, the CanVGController downloads the rest of the source packaged
* together with the canvg library.
@@ -5940,11 +6131,11 @@
return {
push: function (func, scriptLocation) {
// Only get the script once
if (deferredRenderCalls.length === 0) {
- Highcharts.getScript(scriptLocation, drawDeferred);
+ getScript(scriptLocation, drawDeferred);
}
// Register render call
deferredRenderCalls.push(func);
}
};
@@ -9683,11 +9874,11 @@
};
var hoverChartIndex;
// Global flag for touch support
- hasTouch = doc.documentElement.ontouchstart !== UNDEFINED;
+ hasTouch = doc && doc.documentElement.ontouchstart !== UNDEFINED;
/**
* The mouse tracker object. All methods starting with "on" are primary DOM event handlers.
* Subsequent methods should be named differently from what they are doing.
* @param {Object} chart The Chart instance
@@ -9742,17 +9933,12 @@
normalize: function (e, chartPosition) {
var chartX,
chartY,
ePos;
- // common IE normalizing
- e = e || window.event;
-
- // Framework specific normalizing (#1165)
- e = washMouseEvent(e);
-
- // More IE normalizing, needs to go after washMouseEvent
+ // IE normalizing
+ e = e || win.event;
if (!e.target) {
e.target = e.srcElement;
}
// iOS (#2757)
@@ -10142,12 +10328,11 @@
hasPinched = this.hasPinched;
if (this.selectionMarker) {
var selectionData = {
xAxis: [],
- yAxis: [],
- originalEvent: e.originalEvent || e
+ yAxis: []
},
selectionBox = this.selectionMarker,
selectionLeft = selectionBox.attr ? selectionBox.attr('x') : selectionBox.x,
selectionTop = selectionBox.attr ? selectionBox.attr('y') : selectionBox.y,
selectionWidth = selectionBox.attr ? selectionBox.attr('width') : selectionBox.width,
@@ -10303,11 +10488,10 @@
hoverPoint = chart.hoverPoint,
plotLeft = chart.plotLeft,
plotTop = chart.plotTop;
e = this.normalize(e);
- e.originalEvent = e; // #3913
if (!chart.cancelClick) {
// On tracker click, fire the series and point events. #783, #1583
if (hoverPoint && this.inClass(e.target, PREFIX + 'tracker')) {
@@ -10643,11 +10827,10 @@
}
return fake;
},
translateMSPointer = function (e, method, wktype, func) {
var p;
- e = e.originalEvent || e;
if ((e.pointerType === 'touch' || e.pointerType === e.MSPOINTER_TYPE_TOUCH) && charts[hoverChartIndex]) {
func(e);
p = charts[hoverChartIndex].pointer;
p[method]({
type: wktype,
@@ -10875,20 +11058,21 @@
* Position the checkboxes after the width is determined
*/
positionCheckboxes: function (scrollOffset) {
var alignAttr = this.group.alignAttr,
translateY,
- clipHeight = this.clipHeight || this.legendHeight;
+ clipHeight = this.clipHeight || this.legendHeight,
+ titleHeight = this.titleHeight;
if (alignAttr) {
translateY = alignAttr.translateY;
each(this.allItems, function (item) {
var checkbox = item.checkbox,
top;
if (checkbox) {
- top = (translateY + checkbox.y + (scrollOffset || 0) + 3);
+ top = translateY + titleHeight + checkbox.y + (scrollOffset || 0) + 3;
css(checkbox, {
left: (alignAttr.translateX + item.checkboxOffset + checkbox.x - 20) + PX,
top: top + PX,
display: top > translateY - 6 && top < translateY + clipHeight - 6 ? '' : NONE
});
@@ -11495,11 +11679,12 @@
this.legendSymbol = legendSymbol = renderer.symbol(
this.symbol,
(symbolWidth / 2) - radius,
verticalCenter - radius,
2 * radius,
- 2 * radius
+ 2 * radius,
+ markerOptions
)
.add(legendItemGroup);
legendSymbol.isMarker = true;
}
}
@@ -11524,26 +11709,46 @@
// Do it after to work around the core issue
setTimeout(runPositionItem);
});
}
/**
- * The chart class
+ * The Chart class
+ * @param {String|Object} renderTo The DOM element to render to, or its id
* @param {Object} options
* @param {Function} callback Function to run when the chart has loaded
*/
var Chart = Highcharts.Chart = function () {
- this.init.apply(this, arguments);
+ this.getArgs.apply(this, arguments);
};
+ Highcharts.chart = function (a, b, c) {
+ return new Chart(a, b, c);
+ };
+
Chart.prototype = {
/**
* Hook for modules
*/
callbacks: [],
/**
+ * Handle the arguments passed to the constructor
+ * @returns {Array} Arguments without renderTo
+ */
+ getArgs: function () {
+ var args = [].slice.call(arguments);
+
+ // Remove the optional first argument, renderTo, and
+ // set it on this.
+ if (isString(args[0]) || args[0].nodeName) {
+ this.renderTo = args.shift();
+ }
+ this.init(args[0], args[1]);
+ },
+
+ /**
* Initialize the chart
*/
init: function (userOptions, callback) {
// Handle regular options
@@ -11817,11 +12022,11 @@
// redraw if canvas
renderer.draw();
// fire the event
- fireEvent(chart, 'redraw'); // jQuery breaks this when calling it from addEvent. Overwrites chart.redraw
+ fireEvent(chart, 'redraw');
if (isHiddenChart) {
chart.cloneRenderTo(true);
}
@@ -12027,16 +12232,16 @@
optionsChart = chart.options.chart,
widthOption = optionsChart.width,
heightOption = optionsChart.height,
renderTo = chart.renderToClone || chart.renderTo;
- // get inner width and height from jQuery (#824)
+ // Get inner width and height
if (!defined(widthOption)) {
- chart.containerWidth = adapterRun(renderTo, 'width');
+ chart.containerWidth = getStyle(renderTo, 'width');
}
if (!defined(heightOption)) {
- chart.containerHeight = adapterRun(renderTo, 'height');
+ chart.containerHeight = getStyle(renderTo, 'height');
}
chart.chartWidth = mathMax(0, widthOption || chart.containerWidth || 600); // #1393, 1460
chart.chartHeight = mathMax(0, pick(heightOption,
// the offsetHeight of an empty container is 0 in standard browsers, but 19 in IE7:
@@ -12089,19 +12294,20 @@
container,
options = chart.options,
optionsChart = options.chart,
chartWidth,
chartHeight,
- renderTo,
+ renderTo = chart.renderTo,
indexAttrName = 'data-highcharts-chart',
oldChartIndex,
Ren,
- containerId;
+ containerId = 'highcharts-' + idCounter++;
- chart.renderTo = renderTo = optionsChart.renderTo;
- containerId = PREFIX + idCounter++;
-
+ if (!renderTo) {
+ chart.renderTo = renderTo = optionsChart.renderTo;
+ }
+
if (isString(renderTo)) {
chart.renderTo = renderTo = doc.getElementById(renderTo);
}
// Display an error if the renderTo is wrong
@@ -12244,13 +12450,13 @@
*/
reflow: function (e) {
var chart = this,
optionsChart = chart.options.chart,
renderTo = chart.renderTo,
- width = optionsChart.width || adapterRun(renderTo, 'width'),
- height = optionsChart.height || adapterRun(renderTo, 'height'),
- target = e ? e.target : win; // #805 - MooTools doesn't supply e
+ width = optionsChart.width || getStyle(renderTo, 'width'),
+ height = optionsChart.height || getStyle(renderTo, 'height'),
+ target = e ? e.target : win;
// Width and height checks for display:none. Target is doc in IE8 and Opera,
// win in Firefox, Chrome and IE9.
if (!chart.hasUserSize && !chart.isPrinting && width && height && (target === win || target === doc)) { // #1093
if (width !== chart.containerWidth || height !== chart.containerHeight) {
@@ -12751,11 +12957,11 @@
0,
0
)
.on('click', function () {
if (credits.href) {
- location.href = credits.href;
+ win.location.href = credits.href;
}
})
.attr({
align: credits.position.align,
zIndex: 8
@@ -13193,12 +13399,11 @@
series: this.series
});
},
/**
- * Fire an event on the Point object. Must not be renamed to fireEvent, as this
- * causes a name clash in MooTools
+ * Fire an event on the Point object.
* @param {String} eventType
* @param {Object} eventArgs Additional event arguments
* @param {Function} defaultFunction Default event handler
*/
firePointEvent: function (eventType, eventArgs, defaultFunction) {
@@ -14811,20 +15016,19 @@
// Generate it on first call
if (isNew) {
this[prop] = group = this.chart.renderer.g(name)
.attr({
- visibility: visibility,
zIndex: zIndex || 0.1 // IE8 needs this
})
.add(parent);
group.addClass('highcharts-series-' + this.index);
}
// Place it on first and subsequent (redraw) calls
- group[isNew ? 'attr' : 'animate'](this.getPlotBox());
+ group.attr({ visibility: visibility })[isNew ? 'attr' : 'animate'](this.getPlotBox());
return group;
},
/**
* Get the translation and scale for the plot area of this series
@@ -15871,39 +16075,28 @@
*
* @param {Boolean} redraw Whether to redraw the chart or wait for an explicit call
* @param {Boolean|Object} animation Whether to apply animation, and optionally animation
* configuration
*/
-
remove: function (redraw, animation) {
var series = this,
chart = series.chart;
- redraw = pick(redraw, true);
- if (!series.isRemoving) { /* prevent triggering native event in jQuery
- (calling the remove function from the remove event) */
- series.isRemoving = true;
+ // Fire the event with a default handler of removing the point
+ fireEvent(series, 'remove', null, function () {
- // fire the event with a default handler of removing the point
- fireEvent(series, 'remove', null, function () {
+ // Destroy elements
+ series.destroy();
+ // Redraw
+ chart.isDirtyLegend = chart.isDirtyBox = true;
+ chart.linkSeries();
- // destroy elements
- series.destroy();
-
-
- // redraw
- chart.isDirtyLegend = chart.isDirtyBox = true;
- chart.linkSeries();
-
- if (redraw) {
- chart.redraw(animation);
- }
- });
-
- }
- series.isRemoving = false;
+ if (pick(redraw, true)) {
+ chart.redraw(animation);
+ }
+ });
},
/**
* Update the series with a new set of options
*/
@@ -16223,25 +16416,28 @@
each(zones, function (threshold, i) {
props.push(['zoneArea' + i, threshold.color || series.color, threshold.fillColor || options.fillColor]);
});
each(props, function (prop) {
var areaKey = prop[0],
- area = series[areaKey];
+ area = series[areaKey],
+ attr;
// Create or update the area
if (area) { // update
area.animate({ d: areaPath });
} else { // create
+ attr = {
+ fill: prop[2] || prop[1],
+ zIndex: 0 // #1069
+ };
+ if (!prop[2]) {
+ attr['fill-opacity'] = options.fillOpacity || 0.75;
+ }
series[areaKey] = series.chart.renderer.path(areaPath)
- .attr({
- fill: pick(
- prop[2],
- Color(prop[1]).setOpacity(pick(options.fillOpacity, 0.75)).get()
- ),
- zIndex: 0 // #1069
- }).add(series.group);
+ .attr(attr)
+ .add(series.group);
}
});
},
drawLegendSymbol: LegendSymbolMixin.drawRectangle
@@ -16484,22 +16680,22 @@
xAxis = series.xAxis,
yAxis = series.yAxis,
reversedXAxis = xAxis.reversed,
stackKey,
stackGroups = {},
- columnIndex,
columnCount = 0;
// Get the total number of column type series.
// This is called on every series. Consider moving this logic to a
// chart.orderStacks() function and call it on init, addSeries and removeSeries
if (options.grouping === false) {
columnCount = 1;
} else {
each(series.chart.series, function (otherSeries) {
var otherOptions = otherSeries.options,
- otherYAxis = otherSeries.yAxis;
+ otherYAxis = otherSeries.yAxis,
+ columnIndex;
if (otherSeries.type === series.type && otherSeries.visible &&
yAxis.len === otherYAxis.len && yAxis.pos === otherYAxis.pos) { // #642, #2086
if (otherOptions.stacking) {
stackKey = otherSeries.stackKey;
if (stackGroups[stackKey] === UNDEFINED) {
@@ -18544,13 +18740,13 @@
halfPointRange = (axis.pointRange || 0) / 2,
extremes = axis.getExtremes(),
newMin = axis.toValue(startPos - mousePos, true) + halfPointRange,
newMax = axis.toValue(startPos + chart[isX ? 'plotWidth' : 'plotHeight'] - mousePos, true) - halfPointRange,
goingLeft = startPos > mousePos; // #3613
-
+
if (axis.series.length &&
- (goingLeft || newMin > mathMin(extremes.dataMin, extremes.min)) &&
+ (goingLeft || newMin > mathMin(extremes.dataMin, extremes.min)) &&
(!goingLeft || newMax < mathMax(extremes.dataMax, extremes.max))) {
axis.setExtremes(newMin, newMax, false, false, { trigger: 'pan' });
doRedraw = true;
}
@@ -18579,11 +18775,11 @@
series = point.series,
chart = series.chart;
selected = pick(selected, !point.selected);
- // fire the event with the defalut handler
+ // fire the event with the default handler
point.firePointEvent(selected ? 'select' : 'unselect', { accumulate: accumulate }, function () {
point.selected = point.options.selected = selected;
series.options.data[inArray(point, series.data)] = point.options;
point.setState(selected && SELECT_STATE);
@@ -18786,15 +18982,12 @@
if (haloOptions && haloOptions.size) {
if (!halo) {
series.halo = halo = chart.renderer.path()
.add(chart.seriesGroup);
}
- halo.attr(extend(hasSVG ? {
+ halo.attr(extend({
fill: point.color || series.color,
'fill-opacity': haloOptions.opacity
- } : {
- // Old IE doesn't take fill-opacity
- fill: Color(point.color || series.color).setOpacity(haloOptions.opacity).get()
},
haloOptions.attributes))[move ? 'animate' : 'attr']({
d: point.haloPath(haloOptions.size)
});
} else if (halo) {