app/assets/javascripts/highcharts.js in highcharts-rails-5.0.14 vs app/assets/javascripts/highcharts.js in highcharts-rails-6.0.0
- old
+ new
@@ -1,7 +1,7 @@
/**
- * @license Highcharts JS v5.0.14 (2017-07-28)
+ * @license Highcharts JS v6.0.0 (2017-10-04)
*
* (c) 2009-2016 Torstein Honsi
*
* License: www.highcharts.com/license
*/
@@ -19,25 +19,22 @@
/**
* (c) 2010-2017 Torstein Honsi
*
* License: www.highcharts.com/license
*/
- /* global window */
- var win = window,
- doc = win.document;
-
- var SVG_NS = 'http://www.w3.org/2000/svg',
+ /* global win */
+ var doc = win.document,
+ SVG_NS = 'http://www.w3.org/2000/svg',
userAgent = (win.navigator && win.navigator.userAgent) || '',
svg = doc && doc.createElementNS && !!doc.createElementNS(SVG_NS, 'svg').createSVGRect,
- isMS = /(edge|msie|trident)/i.test(userAgent) && !window.opera,
- vml = !svg,
+ isMS = /(edge|msie|trident)/i.test(userAgent) && !win.opera,
isFirefox = /Firefox/.test(userAgent),
hasBidiBug = isFirefox && parseInt(userAgent.split('Firefox/')[1], 10) < 4; // issue #38
var Highcharts = win.Highcharts ? win.Highcharts.error(16, true) : {
product: 'Highcharts',
- version: '5.0.14',
+ version: '6.0.0',
deg2rad: Math.PI * 2 / 360,
doc: doc,
hasBidiBug: hasBidiBug,
hasTouch: doc && doc.documentElement.ontouchstart !== undefined,
isMS: isMS,
@@ -47,11 +44,10 @@
SVG_NS: SVG_NS,
chartCount: 0,
seriesTypes: {},
symbolSizes: {},
svg: svg,
- vml: vml,
win: win,
marginNames: ['plotTop', 'marginRight', 'marginBottom', 'plotLeft'],
noop: function() {
return undefined;
},
@@ -222,35 +218,44 @@
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;
- timer.prop = this.prop;
-
- if (timer() && timers.push(timer) === 1) {
- timer.timerId = setInterval(function() {
-
+ requestAnimationFrame =
+ win.requestAnimationFrame ||
+ function(step) {
+ setTimeout(step, 13);
+ },
+ step = function() {
+ var i;
for (i = 0; i < timers.length; i++) {
if (!timers[i]()) {
timers.splice(i--, 1);
}
}
- if (!timers.length) {
- clearInterval(timer.timerId);
+ if (timers.length) {
+ requestAnimationFrame(step);
}
- }, 13);
+ };
+
+ if (from === to) {
+ delete this.options.curAnim[this.prop];
+ } else { // #7166
+ this.startTime = +new Date();
+ this.start = from;
+ this.end = to;
+ this.unit = unit;
+ this.now = this.start;
+ this.pos = 0;
+
+ timer.elem = this.elem;
+ timer.prop = this.prop;
+
+ if (timer() && timers.push(timer) === 1) {
+ requestAnimationFrame(step);
+ }
}
},
/**
* Run a single step in the animation.
@@ -481,11 +486,10 @@
null,
true
);
};
-
/**
* Utility function to extend an object with the members of another.
*
* @function #extend
* @memberOf Highcharts
@@ -981,11 +985,11 @@
pad = H.pad,
// List all format keys. Custom formats can be added from the outside.
replacements = H.extend({
- //-- Day
+ // Day
// Short weekday, like 'Mon'
'a': shortWeekdays ?
shortWeekdays[day] : langWeekdays[day].substr(0, 3),
// Long weekday, like 'Monday'
'A': langWeekdays[day],
@@ -994,27 +998,27 @@
// Day of the month, 1 through 31
'e': pad(dayOfMonth, 2, ' '),
'w': day,
// Week (none implemented)
- //'W': weekNumber(),
+ // 'W': weekNumber(),
- //-- Month
+ // Month
// Short month, like 'Jan'
'b': lang.shortMonths[month],
// Long month, like 'January'
'B': lang.months[month],
// Two digit month number, 01 through 12
'm': pad(month + 1),
- //-- Year
+ // Year
// Two digits year, like 09 for 2009
'y': fullYear.toString().substr(2, 2),
// Four digits year, like 2009
'Y': fullYear,
- //-- Time
+ // Time
// Two digits hours in 24h format, 00 through 23
'H': pad(hours),
// Hours in 24h format, 0 through 23
'k': hours,
// Two digits hours in 12h format, 00 through 11
@@ -1146,11 +1150,13 @@
len = path.length;
val = ctx;
// Assign deeper paths
for (i = 0; i < len; i++) {
- val = val[path[i]];
+ if (val) {
+ val = val[path[i]];
+ }
}
// Format the replacement
if (valueAndFormat.length) {
val = H.formatSingle(valueAndFormat.join(':'), val);
@@ -1456,11 +1462,11 @@
* in the lang options, or a dot.
* @param {String} [thousandsSep] - The thousands separator, defaults to the one
* given in the lang options, or a space character.
* @returns {String} The formatted number.
*
- * @sample members/highcharts-numberformat/ Custom number format
+ * @sample highcharts/members/highcharts-numberformat/ Custom number format
*/
H.numberFormat = function(number, decimals, decimalPoint, thousandsSep) {
number = +number || 0;
decimals = +decimals;
@@ -1555,15 +1561,20 @@
return Math.min(el.offsetHeight, el.scrollHeight) -
H.getStyle(el, 'padding-top') -
H.getStyle(el, 'padding-bottom');
}
+ if (!win.getComputedStyle) {
+ // SVG not supported, forgot to load oldie.js?
+ H.error(27, true);
+ }
+
// Otherwise, get the computed style
style = win.getComputedStyle(el, undefined);
if (style) {
style = style.getPropertyValue(prop);
- if (H.pick(toInt, true)) {
+ if (H.pick(toInt, prop !== 'opacity')) {
style = H.pInt(style);
}
}
return style;
};
@@ -1576,11 +1587,11 @@
* @param {*} item - The item to search for.
* @param {arr} arr - The array or node collection to search in.
* @returns {Number} - The index within the array, or -1 if not found.
*/
H.inArray = function(item, arr) {
- return arr.indexOf ? arr.indexOf(item) : [].indexOf.call(arr, item);
+ return (H.indexOfPolyfill || Array.prototype.indexOf).call(arr, item);
};
/**
* Filter an array by a callback.
*
@@ -1591,11 +1602,11 @@
* item as the first argument. Return `true` if the item is to be
* preserved.
* @returns {Array} - A new, filtered array.
*/
H.grep = function(arr, callback) {
- return [].filter.call(arr, callback);
+ return (H.filterPolyfill || Array.prototype.filter).call(arr, callback);
};
/**
* Return the value of the first element in the array that satisfies the
* provided testing function.
@@ -1607,11 +1618,11 @@
* item as the first argument. Return `true` if this item satisfies the
* condition.
* @returns {Mixed} - The value of the element.
*/
H.find = function(arr, callback) {
- return [].find.call(arr, callback);
+ return (H.findPolyfill || Array.prototype.find).call(arr, callback);
};
/**
* Map an array by a callback.
*
@@ -1633,10 +1644,30 @@
return results;
};
/**
+ * Reduce an array to a single value.
+ *
+ * @function #reduce
+ * @memberOf Highcharts
+ * @param {Array} arr - The array to reduce.
+ * @param {Function} fn - The callback function. Return the reduced value.
+ * Receives 4 arguments: Accumulated/reduced value, current value, current
+ * array index, and the array.
+ * @param {Mixed} initialValue - The initial value of the accumulator.
+ * @returns {Mixed} - The reduced value.
+ */
+ H.reduce = function(arr, func, initialValue) {
+ return (H.reducePolyfill || Array.prototype.reduce).call(
+ arr,
+ func,
+ initialValue
+ );
+ };
+
+ /**
* Get the element's offset position, corrected for `overflow: auto`.
*
* @function #offset
* @memberOf Highcharts
* @param {HTMLDOMElement} el - The HTML element.
@@ -1694,11 +1725,11 @@
* * index - The item's index in the array.
* * arr - The array that each is being applied to.
* @param {Object} [ctx] The context.
*/
H.each = function(arr, fn, ctx) { // modern browsers
- return Array.prototype.forEach.call(arr, fn, ctx);
+ return (H.forEachPolyfill || Array.prototype.forEach).call(arr, fn, ctx);
};
/**
* Iterate over object key pairs in an object.
*
@@ -1731,39 +1762,18 @@
* fired.
* @returns {Function} A callback function to remove the added event.
*/
H.addEvent = function(el, type, fn) {
- var events = el.hcEvents = el.hcEvents || {};
+ var events = el.hcEvents = el.hcEvents || {},
+ addEventListener = el.addEventListener || H.addEventListenerPolyfill;
- function wrappedFn(e) {
- e.target = e.srcElement || win; // #2820
- fn.call(el, e);
+ // Handle DOM events
+ if (addEventListener) {
+ addEventListener.call(el, type, fn, false);
}
- // Handle DOM events in modern browsers
- if (el.addEventListener) {
- el.addEventListener(type, fn, false);
-
- // Handle old IE implementation
- } else if (el.attachEvent) {
-
- if (!el.hcEventsIE) {
- el.hcEventsIE = {};
- }
-
- // unique function string (#6746)
- if (!fn.hcGetKey) {
- fn.hcGetKey = H.uniqueKey();
- }
-
- // Link wrapped fn with original fn, so we can get this in removeEvent
- el.hcEventsIE[fn.hcGetKey] = wrappedFn;
-
- el.attachEvent('on' + type, wrappedFn);
- }
-
if (!events[type]) {
events[type] = [];
}
events[type].push(fn);
@@ -1791,15 +1801,15 @@
var events,
hcEvents = el.hcEvents,
index;
function removeOneEvent(type, fn) {
- if (el.removeEventListener) {
- el.removeEventListener(type, fn, false);
- } else if (el.attachEvent) {
- fn = el.hcEventsIE[fn.hcGetKey];
- el.detachEvent('on' + type, fn);
+ var removeEventListener =
+ el.removeEventListener || H.removeEventListenerPolyfill;
+
+ if (removeEventListener) {
+ removeEventListener.call(el, type, fn, false);
}
}
function removeAllEvents() {
var types,
@@ -1873,11 +1883,10 @@
eventArguments = eventArguments || {};
if (doc.createEvent && (el.dispatchEvent || el.fireEvent)) {
e = doc.createEvent('Events');
e.initEvent(type, true, true);
- //e.target = el;
H.extend(e, eventArguments);
if (el.dispatchEvent) {
el.dispatchEvent(e);
@@ -2098,114 +2107,10 @@
return charts[H.attr(this[0], 'data-highcharts-chart')];
}
};
}
-
- /**
- * Compatibility section to add support for legacy IE. This can be removed if
- * old IE support is not needed.
- */
- if (doc && !doc.defaultView) {
- H.getStyle = function(el, prop) {
- var val,
- alias = {
- width: 'clientWidth',
- height: 'clientHeight'
- }[prop];
-
- if (el.style[prop]) {
- return H.pInt(el.style[prop]);
- }
- if (prop === 'opacity') {
- prop = 'filter';
- }
-
- // Getting the rendered width and height
- if (alias) {
- el.style.zoom = 1;
- return Math.max(el[alias] - 2 * H.getStyle(el, 'padding'), 0);
- }
-
- 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 : H.pInt(val);
- };
- }
-
- if (!Array.prototype.forEach) {
- H.each = function(arr, fn, ctx) { // legacy
- var i = 0,
- len = arr.length;
- for (; i < len; i++) {
- if (fn.call(ctx, arr[i], i, arr) === false) {
- return i;
- }
- }
- };
- }
-
- if (!Array.prototype.indexOf) {
- H.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) {
- H.grep = function(elements, fn) {
- var ret = [],
- i = 0,
- length = elements.length;
-
- for (; i < length; i++) {
- if (fn(elements[i], i)) {
- ret.push(elements[i]);
- }
- }
-
- return ret;
- };
- }
-
- if (!Array.prototype.find) {
- H.find = function(arr, fn) {
- var i,
- length = arr.length;
-
- for (i = 0; i < length; i++) {
- if (fn(arr[i], i)) {
- return arr[i];
- }
- }
- };
- }
-
- //--- End compatibility section ---
-
}(Highcharts));
(function(H) {
/**
* (c) 2010-2017 Torstein Honsi
*
@@ -2288,11 +2193,11 @@
// Solid colors
} else {
// Bitmasking as input[0] is not working for legacy IE.
- if (input && input.charAt() === '#') {
+ if (input && input.charAt && input.charAt() === '#') {
len = input.length;
input = parseInt(input.substr(1), 16);
// Handle long-form, e.g. #AABBCC
@@ -2415,30 +2320,37 @@
* The intermediate color in rgba notation.
*/
tweenTo: function(to, pos) {
// Check for has alpha, because rgba colors perform worse due to lack of
// support in WebKit.
- var from = this,
+ var fromRgba = this.rgba,
+ toRgba = to.rgba,
hasAlpha,
ret;
- // Unsupported color, return to-color (#3920)
- if (!to.rgba.length) {
+ // Unsupported color, return to-color (#3920, #7034)
+ if (!toRgba.length || !fromRgba || !fromRgba.length) {
ret = to.input || 'none';
// Interpolate
} else {
- from = from.rgba;
- to = to.rgba;
- hasAlpha = (to[3] !== 1 || from[3] !== 1);
+ hasAlpha = (toRgba[3] !== 1 || fromRgba[3] !== 1);
ret = (hasAlpha ? 'rgba(' : 'rgb(') +
- Math.round(to[0] + (from[0] - to[0]) * (1 - pos)) + ',' +
- Math.round(to[1] + (from[1] - to[1]) * (1 - pos)) + ',' +
- Math.round(to[2] + (from[2] - to[2]) * (1 - pos)) +
- (hasAlpha ?
- (',' + (to[3] + (from[3] - to[3]) * (1 - pos))) :
- '') + ')';
+ Math.round(toRgba[0] + (fromRgba[0] - toRgba[0]) * (1 - pos)) +
+ ',' +
+ Math.round(toRgba[1] + (fromRgba[1] - toRgba[1]) * (1 - pos)) +
+ ',' +
+ Math.round(toRgba[2] + (fromRgba[2] - toRgba[2]) * (1 - pos)) +
+ (
+ hasAlpha ?
+ (
+ ',' +
+ (toRgba[3] + (fromRgba[3] - toRgba[3]) * (1 - pos))
+ ) :
+ ''
+ ) +
+ ')';
}
return ret;
}
};
H.color = function(input) {
@@ -2872,13 +2784,14 @@
/**
*
* @typedef {Object} SVGAttributes An object of key-value pairs for SVG
* attributes. Attributes in Highcharts elements for the most parts
* correspond to SVG, but some are specific to Highcharts, like `zIndex`,
- * `rotation`, `translateX`, `translateY`, `scaleX` and `scaleY`. SVG
- * attributes containing a hyphen are _not_ camel-cased, they should be
- * quoted to preserve the hyphen.
+ * `rotation`, `rotationOriginX`, `rotationOriginY`, `translateX`,
+ * `translateY`, `scaleX` and `scaleY`. SVG attributes containing a hyphen
+ * are _not_ camel-cased, they should be quoted to preserve the hyphen.
+ *
* @example
* {
* 'stroke': '#ff0000', // basic
* 'stroke-width': 2, // hyphenated
* 'rotation': 45 // custom
@@ -3094,11 +3007,11 @@
) !== -1;
},
/**
* Remove a class name from the element.
- * @param {string} className The class name to remove.
+ * @param {String|RegExp} className The class name to remove.
* @return {SVGElement} Returns the SVG element for chainability.
*/
removeClass: function(className) {
return this.attr(
'class',
@@ -3431,10 +3344,11 @@
translateY = wrapper.translateY || 0,
scaleX = wrapper.scaleX,
scaleY = wrapper.scaleY,
inverted = wrapper.inverted,
rotation = wrapper.rotation,
+ matrix = wrapper.matrix,
element = wrapper.element,
transform;
// Flipping affects translate as adjustment for flipping around the
// group's axis
@@ -3446,17 +3360,26 @@
// Apply translate. Nearly all transformed elements have translation,
// so instead of checking for translate = 0, do it always (#1767,
// #1846).
transform = ['translate(' + translateX + ',' + translateY + ')'];
+ // apply matrix
+ if (defined(matrix)) {
+ transform.push(
+ 'matrix(' + matrix.join(',') + ')'
+ );
+ }
+
// apply rotation
if (inverted) {
transform.push('rotate(90) scale(-1,1)');
} else if (rotation) { // text rotation
transform.push(
- 'rotate(' + rotation + ' ' + (element.getAttribute('x') || 0) +
- ' ' + (element.getAttribute('y') || 0) + ')'
+ 'rotate(' + rotation + ' ' +
+ pick(this.rotationOriginX, element.getAttribute('x'), 0) +
+ ' ' +
+ pick(this.rotationOriginY, element.getAttribute('y') || 0) + ')'
);
}
// apply scale
if (defined(scaleX) || defined(scaleY)) {
@@ -3521,13 +3444,14 @@
// First call on instanciate
if (alignOptions) {
this.alignOptions = alignOptions;
this.alignByTranslate = alignByTranslate;
- if (!box || isString(box)) { // boxes other than renderer handle this internally
+ if (!box || isString(box)) {
this.alignTo = alignTo = box || 'renderer';
- erase(alignedObjects, this); // prevent duplicates, like legendGroup after resize
+ // prevent duplicates, like legendGroup after resize
+ erase(alignedObjects, this);
alignedObjects.push(this);
box = null; // reassign it below
}
// When called on resize, no arguments are supplied
@@ -3652,26 +3576,32 @@
// SVG elements
if (element.namespaceURI === wrapper.SVG_NS || renderer.forExport) {
try { // Fails in Firefox if the container has display: none.
- // When the text shadow shim is used, we need to hide the fake shadows
- // to get the correct bounding box (#3872)
+ // When the text shadow shim is used, we need to hide the
+ // fake shadows to get the correct bounding box (#3872)
toggleTextShadowShim = this.fakeTS && function(display) {
- each(element.querySelectorAll('.highcharts-text-outline'), function(tspan) {
- tspan.style.display = display;
- });
+ each(
+ element.querySelectorAll(
+ '.highcharts-text-outline'
+ ),
+ function(tspan) {
+ tspan.style.display = display;
+ }
+ );
};
- // Workaround for #3842, Firefox reporting wrong bounding box for shadows
+ // Workaround for #3842, Firefox reporting wrong bounding
+ // box for shadows
if (toggleTextShadowShim) {
toggleTextShadowShim('none');
}
bBox = element.getBBox ?
- // SVG: use extend because IE9 is not allowed to change width and height in case
- // of rotation (below)
+ // SVG: use extend because IE9 is not allowed to change
+ // width and height in case of rotation (below)
extend({}, element.getBBox()) : {
// Legacy IE in export mode
width: element.offsetWidth,
height: element.offsetHeight
@@ -3681,12 +3611,13 @@
if (toggleTextShadowShim) {
toggleTextShadowShim('');
}
} catch (e) {}
- // If the bBox is not set, the try-catch block above failed. The other condition
- // is for Opera that returns a width of -Infinity on hidden elements.
+ // If the bBox is not set, the try-catch block above failed. The
+ // other condition is for Opera that returns a width of
+ // -Infinity on hidden elements.
if (!bBox || bBox.width < 0) {
bBox = {
width: 0,
height: 0
};
@@ -3698,12 +3629,12 @@
bBox = wrapper.htmlGetBBox();
}
- // True SVG elements as well as HTML elements in modern browsers using the .useHTML option
- // need to compensated for rotation
+ // True SVG elements as well as HTML elements in modern browsers
+ // using the .useHTML option need to compensated for rotation
if (renderer.isSVG) {
width = bBox.width;
height = bBox.height;
// Workaround for wrong bounding box in IE, Edge and Chrome on
@@ -3722,17 +3653,19 @@
bBox.height = height = 14;
}
// Adjust for rotated text
if (rotation) {
- bBox.width = Math.abs(height * Math.sin(rad)) + Math.abs(width * Math.cos(rad));
- bBox.height = Math.abs(height * Math.cos(rad)) + Math.abs(width * Math.sin(rad));
+ bBox.width = Math.abs(height * Math.sin(rad)) +
+ Math.abs(width * Math.cos(rad));
+ bBox.height = Math.abs(height * Math.cos(rad)) +
+ Math.abs(width * Math.sin(rad));
}
}
- // Cache it. When loading a chart in a hidden iframe in Firefox and IE/Edge, the
- // bounding box height is 0, so don't cache it (#5620).
+ // Cache it. When loading a chart in a hidden iframe in Firefox and
+ // IE/Edge, the bounding box height is 0, so don't cache it (#5620).
if (cacheKey && bBox.height > 0) {
// Rotate (#4681)
while (cacheKeys.length > 250) {
delete cache[cacheKeys.shift()];
@@ -4012,11 +3945,11 @@
shadow.cutHeight = strokeWidth;
}
if (group) {
group.element.appendChild(shadow);
- } else {
+ } else if (element.parentNode) {
element.parentNode.insertBefore(shadow, element);
}
shadows.push(shadow);
}
@@ -4147,11 +4080,12 @@
titleNode.removeChild(titleNode.firstChild);
}
titleNode.appendChild(
doc.createTextNode(
- (String(pick(value), '')).replace(/<[^>]*>/g, '') // #3276, #3895
+ // #3276, #3895
+ (String(pick(value), '')).replace(/<[^>]*>/g, '')
)
);
},
textSetter: function(value) {
if (value !== this.textStr) {
@@ -4170,11 +4104,12 @@
} else if (value) {
this.colorGradient(value, key, element);
}
},
visibilitySetter: function(value, key, element) {
- // IE9-11 doesn't handle visibilty:inherit well, so we remove the attribute instead (#2881, #3909)
+ // IE9-11 doesn't handle visibilty:inherit well, so we remove the
+ // attribute instead (#2881, #3909)
if (value === 'inherit') {
element.removeAttribute(key);
} else if (this[key] !== value) { // #6747
element.setAttribute(key, value);
}
@@ -4188,93 +4123,129 @@
childNodes,
otherElement,
otherZIndex,
element = this.element,
inserted,
+ undefinedOtherZIndex,
+ svgParent = parentNode === renderer.box,
run = this.added,
i;
if (defined(value)) {
- element.zIndex = value; // So we can read it for other elements in the group
+ // So we can read it for other elements in the group
+ element.zIndex = value;
+
value = +value;
if (this[key] === value) { // Only update when needed (#3865)
run = false;
}
this[key] = value;
}
- // Insert according to this and other elements' zIndex. Before .add() is called,
- // nothing is done. Then on add, or by later calls to zIndexSetter, the node
- // is placed on the right place in the DOM.
+ // Insert according to this and other elements' zIndex. Before .add() is
+ // called, nothing is done. Then on add, or by later calls to
+ // zIndexSetter, the node is placed on the right place in the DOM.
if (run) {
value = this.zIndex;
if (value && parentGroup) {
parentGroup.handleZ = true;
}
childNodes = parentNode.childNodes;
- for (i = 0; i < childNodes.length && !inserted; i++) {
+ for (i = childNodes.length - 1; i >= 0 && !inserted; i--) {
otherElement = childNodes[i];
otherZIndex = otherElement.zIndex;
- if (otherElement !== element && (
- // Insert before the first element with a higher zIndex
- pInt(otherZIndex) > value ||
- // If no zIndex given, insert before the first element with a zIndex
- (!defined(value) && defined(otherZIndex)) ||
+ undefinedOtherZIndex = !defined(otherZIndex);
+
+ if (otherElement !== element) {
+ if (
// Negative zIndex versus no zIndex:
// On all levels except the highest. If the parent is <svg>,
// then we don't want to put items before <desc> or <defs>
- (value < 0 && !defined(otherZIndex) && parentNode !== renderer.box)
-
- )) {
- parentNode.insertBefore(element, otherElement);
- inserted = true;
+ (value < 0 && undefinedOtherZIndex && !svgParent && !i)
+ ) {
+ parentNode.insertBefore(element, childNodes[i]);
+ inserted = true;
+ } else if (
+ // Insert after the first element with a lower zIndex
+ pInt(otherZIndex) <= value ||
+ // If negative zIndex, add this before first undefined zIndex element
+ (undefinedOtherZIndex && (!defined(value) || value >= 0))
+ ) {
+ parentNode.insertBefore(
+ element,
+ childNodes[i + 1] || null // null for oldIE export
+ );
+ inserted = true;
+ }
}
}
+
if (!inserted) {
- parentNode.appendChild(element);
+ parentNode.insertBefore(
+ element,
+ childNodes[svgParent ? 3 : 0] || null // null for oldIE
+ );
+ inserted = true;
}
}
return inserted;
},
_defaultSetter: function(value, key, element) {
element.setAttribute(key, value);
}
});
// Some shared setters and getters
- SVGElement.prototype.yGetter = SVGElement.prototype.xGetter;
- SVGElement.prototype.translateXSetter = SVGElement.prototype.translateYSetter =
- SVGElement.prototype.rotationSetter = SVGElement.prototype.verticalAlignSetter =
- SVGElement.prototype.scaleXSetter = SVGElement.prototype.scaleYSetter = function(value, key) {
+ SVGElement.prototype.yGetter =
+ SVGElement.prototype.xGetter;
+ SVGElement.prototype.translateXSetter =
+ SVGElement.prototype.translateYSetter =
+ SVGElement.prototype.rotationSetter =
+ SVGElement.prototype.verticalAlignSetter =
+ SVGElement.prototype.rotationOriginXSetter =
+ SVGElement.prototype.rotationOriginYSetter =
+ SVGElement.prototype.scaleXSetter =
+ SVGElement.prototype.scaleYSetter =
+ SVGElement.prototype.matrixSetter = function(value, key) {
this[key] = value;
this.doTransform = true;
};
- // WebKit and Batik have problems with a stroke-width of zero, so in this case we remove the
- // stroke attribute altogether. #1270, #1369, #3065, #3072.
- SVGElement.prototype['stroke-widthSetter'] = SVGElement.prototype.strokeSetter = function(value, key, element) {
- this[key] = value;
- // Only apply the stroke attribute if the stroke width is defined and larger than 0
- if (this.stroke && this['stroke-width']) {
- SVGElement.prototype.fillSetter.call(this, this.stroke, 'stroke', element); // use prototype as instance may be overridden
- element.setAttribute('stroke-width', this['stroke-width']);
- this.hasStroke = true;
- } else if (key === 'stroke-width' && value === 0 && this.hasStroke) {
- element.removeAttribute('stroke');
- this.hasStroke = false;
- }
- };
+ // WebKit and Batik have problems with a stroke-width of zero, so in this case
+ // we remove the stroke attribute altogether. #1270, #1369, #3065, #3072.
+ SVGElement.prototype['stroke-widthSetter'] =
+ SVGElement.prototype.strokeSetter = function(value, key, element) {
+ this[key] = value;
+ // Only apply the stroke attribute if the stroke width is defined and larger
+ // than 0
+ if (this.stroke && this['stroke-width']) {
+ // Use prototype as instance may be overridden
+ SVGElement.prototype.fillSetter.call(
+ this,
+ this.stroke,
+ 'stroke',
+ element
+ );
+ element.setAttribute('stroke-width', this['stroke-width']);
+ this.hasStroke = true;
+ } else if (key === 'stroke-width' && value === 0 && this.hasStroke) {
+ element.removeAttribute('stroke');
+ this.hasStroke = false;
+ }
+ };
+
/**
* Allows direct access to the Highcharts rendering layer in order to draw
* primitive shapes like circles, rectangles, paths or text directly on a chart,
* or independent from any chart. The SVGRenderer represents a wrapper object
- * for SVGin modern browsers and through the VMLRenderer, for VML in IE < 8.
+ * for SVG in modern browsers. Through the VMLRenderer, part of the `oldie.js`
+ * module, it also brings vector graphics to IE <= 8.
*
* An existing chart's renderer can be accessed through {@link Chart.renderer}.
* The renderer can also be used completely decoupled from a chart.
*
* @param {HTMLDOMElement} container - Where to put the SVG in the web page.
@@ -4287,12 +4258,14 @@
*
* @example
* // Use directly without a chart object.
* var renderer = new Highcharts.Renderer(parentNode, 600, 400);
*
- * @sample highcharts/members/renderer-on-chart - Annotating a chart programmatically.
- * @sample highcharts/members/renderer-basic - Independent SVG drawing.
+ * @sample highcharts/members/renderer-on-chart
+ * Annotating a chart programmatically.
+ * @sample highcharts/members/renderer-basic
+ * Independent SVG drawing.
*
* @class Highcharts.SVGRenderer
*/
SVGRenderer = H.SVGRenderer = function() {
this.init.apply(this, arguments);
@@ -4353,21 +4326,28 @@
/**
* Page url used for internal references.
* @type {string}
*/
// #24, #672, #1070
- this.url = (isFirefox || isWebKit) && doc.getElementsByTagName('base').length ?
+ this.url = (
+ (isFirefox || isWebKit) &&
+ doc.getElementsByTagName('base').length
+ ) ?
win.location.href
.replace(/#.*?$/, '') // remove the hash
.replace(/<[^>]*>/g, '') // wing cut HTML
- .replace(/([\('\)])/g, '\\$1') // escape parantheses and quotes
- .replace(/ /g, '%20') : // replace spaces (needed for Safari only)
+ // escape parantheses and quotes
+ .replace(/([\('\)])/g, '\\$1')
+ // replace spaces (needed for Safari only)
+ .replace(/ /g, '%20') :
'';
// Add description
desc = this.createElement('desc').add();
- desc.element.appendChild(doc.createTextNode('Created with Highcharts 5.0.14'));
+ desc.element.appendChild(
+ doc.createTextNode('Created with Highcharts 6.0.0')
+ );
/**
* A pointer to the `defs` node of the root SVG.
* @type {SVGElement}
* @name defs
@@ -4384,15 +4364,16 @@
renderer.setSize(width, height, false);
// Issue 110 workaround:
- // In Firefox, if a div is positioned by percentage, its pixel position may land
- // between pixels. The container itself doesn't display this, but an SVG element
- // inside this container will be drawn at subpixel precision. In order to draw
- // sharp lines, this must be compensated for. This doesn't seem to work inside
- // iframes though (like in jsFiddle).
+ // In Firefox, if a div is positioned by percentage, its pixel position
+ // may land between pixels. The container itself doesn't display this,
+ // but an SVG element inside this container will be drawn at subpixel
+ // precision. In order to draw sharp lines, this must be compensated
+ // for. This doesn't seem to work inside iframes though (like in
+ // jsFiddle).
var subPixelFix, rect;
if (isFirefox && container.getBoundingClientRect) {
subPixelFix = function() {
css(container, {
left: 0,
@@ -4422,11 +4403,12 @@
* @return {CSSObject} The style settings mixed with defaults.
*/
getStyle: function(style) {
this.style = extend({
- fontFamily: '"Lucida Grande", "Lucida Sans Unicode", Arial, Helvetica, sans-serif', // default font
+ fontFamily: '"Lucida Grande", "Lucida Sans Unicode", ' +
+ 'Arial, Helvetica, sans-serif',
fontSize: '12px'
}, style);
return this.style;
},
@@ -4441,11 +4423,11 @@
/**
* Detect whether the renderer is hidden. This happens when one of the
* parent elements has `display: none`. Used internally to detect when we
- * needto render preliminarily in another div to get the text bounding boxes
+ * needto render preliminarily in another div to get the text bounding boxes
* right.
*
* @returns {boolean} True if it is hidden.
*/
isHidden: function() { // #608
@@ -4510,12 +4492,14 @@
*
* @private
*/
getRadialAttr: function(radialReference, gradAttr) {
return {
- cx: (radialReference[0] - radialReference[2] / 2) + gradAttr.cx * radialReference[2],
- cy: (radialReference[1] - radialReference[2] / 2) + gradAttr.cy * radialReference[2],
+ cx: (radialReference[0] - radialReference[2] / 2) +
+ gradAttr.cx * radialReference[2],
+ cy: (radialReference[1] - radialReference[2] / 2) +
+ gradAttr.cy * radialReference[2],
r: gradAttr.r * radialReference[2]
};
},
getSpanWidth: function(wrapper, tspan) {
@@ -4523,11 +4507,14 @@
bBox = wrapper.getBBox(true),
actualWidth = bBox.width;
// Old IE cannot measure the actualWidth for SVG elements (#2314)
if (!svg && renderer.forExport) {
- actualWidth = renderer.measureSpanWidth(tspan.firstChild.data, wrapper.styles);
+ actualWidth = renderer.measureSpanWidth(
+ tspan.firstChild.data,
+ wrapper.styles
+ );
}
return actualWidth;
},
applyEllipsis: function(wrapper, tspan, text, width) {
@@ -4574,10 +4561,30 @@
wrapper.rotation = rotation; // Apply rotation again.
return wasTooLong;
},
/**
+ * A collection of characters mapped to HTML entities. When `useHTML` on an
+ * element is true, these entities will be rendered correctly by HTML. In
+ * the SVG pseudo-HTML, they need to be unescaped back to simple characters,
+ * so for example `<` will render as `<`.
+ *
+ * @example
+ * // Add support for unescaping quotes
+ * Highcharts.SVGRenderer.prototype.escapes['"'] = '"';
+ *
+ * @type {Object}
+ */
+ escapes: {
+ '&': '&',
+ '<': '<',
+ '>': '>',
+ "'": ''', // eslint-disable-line quotes
+ '"': '"'
+ },
+
+ /**
* Parse a simple HTML string into SVG tspans. Called internally when text
* is set on an SVGElement. The function supports a subset of HTML tags,
* CSS text features like `width`, `text-overflow`, `white-space`, and
* also attributes like `href` and `style`.
* @private
@@ -4621,12 +4628,18 @@
fontSizeStyle,
// Get the computed size from parent if not explicit
tspan.getAttribute('style') ? tspan : textNode
).h;
},
- unescapeAngleBrackets = function(inputStr) {
- return inputStr.replace(/</g, '<').replace(/>/g, '>');
+ unescapeEntities = function(inputStr) {
+ objectEach(renderer.escapes, function(value, key) {
+ inputStr = inputStr.replace(
+ new RegExp(value, 'g'),
+ key
+ );
+ });
+ return inputStr;
};
// The buildText code is quite heavy, so if we're not changing something
// that affects the text, skip it (#6113).
textCache = [
@@ -4641,29 +4654,35 @@
if (textCache === wrapper.textCache) {
return;
}
wrapper.textCache = textCache;
- /// remove old text
+ // Remove old text
while (i--) {
textNode.removeChild(childNodes[i]);
}
// Skip tspans, add text directly to text node. The forceTSpan is a hook
// used in text outline hack.
- if (!hasMarkup && !textOutline && !ellipsis && !width && textStr.indexOf(' ') === -1) {
- textNode.appendChild(doc.createTextNode(unescapeAngleBrackets(textStr)));
+ if (!hasMarkup &&
+ !textOutline &&
+ !ellipsis &&
+ !width &&
+ textStr.indexOf(' ') === -1
+ ) {
+ textNode.appendChild(doc.createTextNode(unescapeEntities(textStr)));
// Complex strings, add more logic
} else {
clsRegex = /<.*class="([^"]+)".*>/;
styleRegex = /<.*style="([^"]+)".*>/;
hrefRegex = /<.*href="([^"]+)".*>/;
if (tempParent) {
- tempParent.appendChild(textNode); // attach it to the DOM to read offset width
+ // attach it to the DOM to read offset width
+ tempParent.appendChild(textNode);
}
if (hasMarkup) {
lines = textStr
@@ -4688,45 +4707,68 @@
// build the lines
each(lines, function buildTextLines(line, lineNo) {
var spans,
spanNo = 0;
line = line
- .replace(/^\s+|\s+$/g, '') // Trim to prevent useless/costly process on the spaces (#5258)
+ // Trim to prevent useless/costly process on the spaces
+ // (#5258)
+ .replace(/^\s+|\s+$/g, '')
.replace(/<span/g, '|||<span')
.replace(/<\/span>/g, '</span>|||');
spans = line.split('|||');
each(spans, function buildTextSpans(span) {
if (span !== '' || spans.length === 1) {
var attributes = {},
- tspan = doc.createElementNS(renderer.SVG_NS, 'tspan'),
+ tspan = doc.createElementNS(
+ renderer.SVG_NS,
+ 'tspan'
+ ),
spanCls,
spanStyle; // #390
if (clsRegex.test(span)) {
spanCls = span.match(clsRegex)[1];
attr(tspan, 'class', spanCls);
}
if (styleRegex.test(span)) {
- spanStyle = span.match(styleRegex)[1].replace(/(;| |^)color([ :])/, '$1fill$2');
+ spanStyle = span.match(styleRegex)[1].replace(
+ /(;| |^)color([ :])/,
+ '$1fill$2'
+ );
attr(tspan, 'style', spanStyle);
}
- if (hrefRegex.test(span) && !forExport) { // Not for export - #1529
- attr(tspan, 'onclick', 'location.href=\"' + span.match(hrefRegex)[1] + '\"');
+
+ // Not for export - #1529
+ if (hrefRegex.test(span) && !forExport) {
+ attr(
+ tspan,
+ 'onclick',
+ 'location.href=\"' +
+ span.match(hrefRegex)[1] + '\"'
+ );
+ attr(tspan, 'class', 'highcharts-anchor');
+
css(tspan, {
cursor: 'pointer'
});
+
}
- span = unescapeAngleBrackets(span.replace(/<(.|\n)*?>/g, '') || ' ');
+ // Strip away unsupported HTML tags (#7126)
+ span = unescapeEntities(
+ span.replace(/<[a-zA-Z\/](.|\n)*?>/g, '') || ' '
+ );
- // Nested tags aren't supported, and cause crash in Safari (#1596)
+ // Nested tags aren't supported, and cause crash in
+ // Safari (#1596)
if (span !== ' ') {
// add the text node
tspan.appendChild(doc.createTextNode(span));
- if (!spanNo) { // first span in a line, align it to the left
+ // First span in a line, align it to the left
+ if (!spanNo) {
if (lineNo && parentX !== null) {
attributes.x = parentX;
}
} else {
attributes.dx = 0; // #16
@@ -4736,101 +4778,140 @@
attr(tspan, attributes);
// Append it
textNode.appendChild(tspan);
- // first span on subsequent line, add the line height
+ // first span on subsequent line, add the line
+ // height
if (!spanNo && isSubsequentLine) {
- // allow getting the right offset height in exporting in IE
+ // allow getting the right offset height in
+ // exporting in IE
if (!svg && forExport) {
css(tspan, {
display: 'block'
});
}
- // Set the line height based on the font size of either
- // the text element or the tspan element
+ // Set the line height based on the font size of
+ // either the text element or the tspan element
attr(
tspan,
'dy',
getLineHeight(tspan)
);
}
- /*if (width) {
+ /*
+ if (width) {
renderer.breakText(wrapper, width);
- }*/
+ }
+ */
// Check width and apply soft breaks or ellipsis
if (width) {
- var words = span.replace(/([^\^])-/g, '$1- ').split(' '), // #1273
- hasWhiteSpace = spans.length > 1 || lineNo || (words.length > 1 && !noWrap),
+ var words = span.replace(
+ /([^\^])-/g,
+ '$1- '
+ ).split(' '), // #1273
+ hasWhiteSpace = (
+ spans.length > 1 ||
+ lineNo ||
+ (words.length > 1 && !noWrap)
+ ),
tooLong,
rest = [],
actualWidth,
dy = getLineHeight(tspan),
rotation = wrapper.rotation;
if (ellipsis) {
- wasTooLong = renderer.applyEllipsis(wrapper, tspan, span, width);
+ wasTooLong = renderer.applyEllipsis(
+ wrapper,
+ tspan,
+ span,
+ width
+ );
}
- while (!ellipsis && hasWhiteSpace && (words.length || rest.length)) {
- wrapper.rotation = 0; // discard rotation when computing box
- actualWidth = renderer.getSpanWidth(wrapper, tspan);
+ while (!ellipsis &&
+ hasWhiteSpace &&
+ (words.length || rest.length)
+ ) {
+ // discard rotation when computing box
+ wrapper.rotation = 0;
+ actualWidth = renderer.getSpanWidth(
+ wrapper,
+ tspan
+ );
tooLong = actualWidth > width;
- // For ellipsis, do a binary search for the correct string length
+ // For ellipsis, do a binary search for the
+ // correct string length
if (wasTooLong === undefined) {
wasTooLong = tooLong; // First time
}
- // Looping down, this is the first word sequence that is not too long,
- // so we can move on to build the next line.
+ // Looping down, this is the first word
+ // sequence that is not too long, so we can
+ // move on to build the next line.
if (!tooLong || words.length === 1) {
words = rest;
rest = [];
if (words.length && !noWrap) {
- tspan = doc.createElementNS(SVG_NS, 'tspan');
+ tspan = doc.createElementNS(
+ SVG_NS,
+ 'tspan'
+ );
attr(tspan, {
dy: dy,
x: parentX
});
if (spanStyle) { // #390
attr(tspan, 'style', spanStyle);
}
textNode.appendChild(tspan);
}
- if (actualWidth > width) { // a single word is pressing it out
+
+ // a single word is pressing it out
+ if (actualWidth > width) {
width = actualWidth;
}
} else { // append to existing line tspan
tspan.removeChild(tspan.firstChild);
rest.unshift(words.pop());
}
if (words.length) {
- tspan.appendChild(doc.createTextNode(words.join(' ').replace(/- /g, '-')));
+ tspan.appendChild(
+ doc.createTextNode(
+ words.join(' ')
+ .replace(/- /g, '-')
+ )
+ );
}
}
wrapper.rotation = rotation;
}
spanNo++;
}
}
});
- // To avoid beginning lines that doesn't add to the textNode (#6144)
- isSubsequentLine = isSubsequentLine || textNode.childNodes.length;
+ // To avoid beginning lines that doesn't add to the textNode
+ // (#6144)
+ isSubsequentLine = (
+ isSubsequentLine ||
+ textNode.childNodes.length
+ );
});
if (wasTooLong) {
wrapper.attr('title', wrapper.textStr);
}
if (tempParent) {
- tempParent.removeChild(textNode); // attach it to the DOM to read offset width
+ tempParent.removeChild(textNode);
}
// Apply the text outline
if (textOutline && wrapper.applyTextOutline) {
wrapper.applyTextOutline(textOutline);
@@ -4843,11 +4924,12 @@
/*
breakText: function (wrapper, width) {
var bBox = wrapper.getBBox(),
node = wrapper.element,
textLength = node.textContent.length,
- pos = Math.round(width * textLength / bBox.width), // try this position first, based on average character width
+ // try this position first, based on average character width
+ pos = Math.round(width * textLength / bBox.width),
increment = 0,
finalPos;
if (bBox.width > width) {
while (finalPos === undefined) {
@@ -4867,11 +4949,16 @@
}
}
pos += increment;
}
}
- console.log('width', width, 'stringWidth', node.getSubStringLength(0, finalPos))
+ console.log(
+ 'width',
+ width,
+ 'stringWidth',
+ node.getSubStringLength(0, finalPos)
+ )
},
*/
/**
* Returns white for dark colors and black for bright colors.
@@ -4908,12 +4995,32 @@
* @param {SVGAttributes} [disabledState] - SVG attributes for the disabled
* state.
* @param {Symbol} [shape=rect] - The shape type.
* @returns {SVGRenderer} The button element.
*/
- button: function(text, x, y, callback, normalState, hoverState, pressedState, disabledState, shape) {
- var label = this.label(text, x, y, shape, null, null, null, null, 'button'),
+ button: function(
+ text,
+ x,
+ y,
+ callback,
+ normalState,
+ hoverState,
+ pressedState,
+ disabledState,
+ shape
+ ) {
+ var label = this.label(
+ text,
+ x,
+ y,
+ shape,
+ null,
+ null,
+ null,
+ null,
+ 'button'
+ ),
curState = 0;
// Default, non-stylable attributes
label.attr(merge({
'padding': 8,
@@ -4967,11 +5074,12 @@
}, disabledState);
disabledStyle = disabledState.style;
delete disabledState.style;
- // Add the events. IE9 and IE10 need mouseover and mouseout to funciton (#667).
+ // Add the events. IE9 and IE10 need mouseover and mouseout to funciton
+ // (#667).
addEvent(label.element, isMS ? 'mouseover' : 'mouseenter', function() {
if (curState !== 3) {
label.setState(1);
}
});
@@ -4985,16 +5093,30 @@
// Hover state is temporary, don't record it
if (state !== 1) {
label.state = curState = state;
}
// Update visuals
- label.removeClass(/highcharts-button-(normal|hover|pressed|disabled)/)
- .addClass('highcharts-button-' + ['normal', 'hover', 'pressed', 'disabled'][state || 0]);
+ label.removeClass(
+ /highcharts-button-(normal|hover|pressed|disabled)/
+ )
+ .addClass(
+ 'highcharts-button-' + ['normal', 'hover', 'pressed', 'disabled'][state || 0]
+ );
- label.attr([normalState, hoverState, pressedState, disabledState][state || 0])
- .css([normalStyle, hoverStyle, pressedStyle, disabledStyle][state || 0]);
+ label.attr([
+ normalState,
+ hoverState,
+ pressedState,
+ disabledState
+ ][state || 0])
+ .css([
+ normalStyle,
+ hoverStyle,
+ pressedStyle,
+ disabledStyle
+ ][state || 0]);
};
@@ -5024,11 +5146,12 @@
* crisply.
*/
crispLine: function(points, width) {
// normalize to a crisp line
if (points[1] === points[4]) {
- // Substract due to #1129. Now bottom and left axis gridlines behave the same.
+ // Substract due to #1129. Now bottom and left axis gridlines behave
+ // the same.
points[1] = points[4] = Math.round(points[1]) - (width % 2 / 2);
}
if (points[2] === points[5]) {
points[2] = points[5] = Math.round(points[2]) + (width % 2 / 2);
}
@@ -5231,11 +5354,12 @@
width: width,
height: height
}, {
step: function() {
this.attr({
- viewBox: '0 0 ' + this.attr('width') + ' ' + this.attr('height')
+ viewBox: '0 0 ' + this.attr('width') + ' ' +
+ this.attr('height')
});
},
duration: pick(animate, true) ? undefined : 0
});
@@ -5243,12 +5367,13 @@
alignedObjects[i].align();
}
},
/**
- * Create and return an svg group element. Child {@link Highcharts.SVGElement}
- * objects are added to the group by using the group as the first parameter
+ * Create and return an svg group element. Child
+ * {@link Highcharts.SVGElement} objects are added to the group by using the
+ * group as the first parameter
* in {@link Highcharts.SVGElement#add|add()}.
*
* @param {string} [name] The group will be given a class name of
* `highcharts-{name}`. This can be used for styling and scripting.
* @returns {SVGElement} The generated wrapper element.
@@ -5301,18 +5426,20 @@
if (elemWrapper.element.setAttributeNS) {
elemWrapper.element.setAttributeNS('http://www.w3.org/1999/xlink',
'href', src);
} else {
// could be exporting in IE
- // using href throws "not supported" in ie7 and under, requries regex shim to fix later
+ // using href throws "not supported" in ie7 and under, requries
+ // regex shim to fix later
elemWrapper.element.setAttribute('hc-svg-href', src);
}
return elemWrapper;
},
/**
- * Draw a symbol out of pre-defined shape paths from {@link SVGRenderer#symbols}.
+ * Draw a symbol out of pre-defined shape paths from
+ * {@link SVGRenderer#symbols}.
* It is used in Highcharts for point makers, which cake a `symbol` option,
* and label and button backgrounds like in the tooltip and stock flags.
*
* @param {Symbol} symbol - The symbol name.
* @param {number} x - The X coordinate for the top left position.
@@ -5439,25 +5566,26 @@
obj.isImg = true;
if (defined(obj.imgwidth) && defined(obj.imgheight)) {
centerImage();
} else {
- // Initialize image to be 0 size so export will still function if there's no cached sizes.
+ // Initialize image to be 0 size so export will still function
+ // if there's no cached sizes.
obj.attr({
width: 0,
height: 0
});
- // Create a dummy JavaScript image to get the width and height. Due to a bug in IE < 8,
- // the created element must be assigned to a variable in order to load (#292).
+ // Create a dummy JavaScript image to get the width and height.
createElement('img', {
onload: function() {
var chart = charts[ren.chartIndex];
- // Special case for SVGs on IE11, the width is not accessible until the image is
- // part of the DOM (#2854).
+ // Special case for SVGs on IE11, the width is not
+ // accessible until the image is part of the DOM
+ // (#2854).
if (this.width === 0) {
css(this, {
position: 'absolute',
top: '-999em'
});
@@ -5479,11 +5607,12 @@
// Clean up after #2854 workaround.
if (this.parentNode) {
this.parentNode.removeChild(this);
}
- // Fire the load event when all external images are loaded
+ // Fire the load event when all external images are
+ // loaded
ren.imgCount--;
if (!ren.imgCount && chart && chart.onload) {
chart.onload();
}
},
@@ -5607,11 +5736,12 @@
arc.push(open ? '' : 'Z'); // close
return arc;
},
/**
- * Callout shape used for default tooltips, also used for rounded rectangles in VML
+ * Callout shape used for default tooltips, also used for rounded
+ * rectangles in VML
*/
callout: function(x, y, w, h, options) {
var arrowLength = 6,
halfDistance = 6,
r = Math.min((options && options.r) || 0, w, h),
@@ -5623,22 +5753,25 @@
path = [
'M', x + r, y,
'L', x + w - r, y, // top side
'C', x + w, y, x + w, y, x + w, y + r, // top-right corner
'L', x + w, y + h - r, // right side
- 'C', x + w, y + h, x + w, y + h, x + w - r, y + h, // bottom-right corner
+ 'C', x + w, y + h, x + w, y + h, x + w - r, y + h, // bottom-rgt
'L', x + r, y + h, // bottom side
'C', x, y + h, x, y + h, x, y + h - r, // bottom-left corner
'L', x, y + r, // left side
'C', x, y, x, y, x + r, y // top-left corner
];
// Anchor on right side
if (anchorX && anchorX > w) {
// Chevron
- if (anchorY > y + safeDistance && anchorY < y + h - safeDistance) {
+ if (
+ anchorY > y + safeDistance &&
+ anchorY < y + h - safeDistance
+ ) {
path.splice(13, 3,
'L', x + w, anchorY - halfDistance,
x + w + arrowLength, anchorY,
x + w, anchorY + halfDistance,
x + w, y + h - r
@@ -5656,11 +5789,14 @@
// Anchor on left side
} else if (anchorX && anchorX < 0) {
// Chevron
- if (anchorY > y + safeDistance && anchorY < y + h - safeDistance) {
+ if (
+ anchorY > y + safeDistance &&
+ anchorY < y + h - safeDistance
+ ) {
path.splice(33, 3,
'L', x, anchorY + halfDistance,
x - arrowLength, anchorY,
x, anchorY - halfDistance,
x, y + r
@@ -5674,18 +5810,29 @@
x, h / 2,
x, y + r
);
}
- } else if (anchorY && anchorY > h && anchorX > x + safeDistance && anchorX < x + w - safeDistance) { // replace bottom
+ } else if ( // replace bottom
+ anchorY &&
+ anchorY > h &&
+ anchorX > x + safeDistance &&
+ anchorX < x + w - safeDistance
+ ) {
path.splice(23, 3,
'L', anchorX + halfDistance, y + h,
anchorX, y + h + arrowLength,
anchorX - halfDistance, y + h,
x + r, y + h
);
- } else if (anchorY && anchorY < 0 && anchorX > x + safeDistance && anchorX < x + w - safeDistance) { // replace top
+
+ } else if ( // replace top
+ anchorY &&
+ anchorY < 0 &&
+ anchorX > x + safeDistance &&
+ anchorX < x + w - safeDistance
+ ) {
path.splice(3, 3,
'L', anchorX - halfDistance, y,
anchorX, y - arrowLength,
anchorX + halfDistance, y,
w - r, y
@@ -5777,45 +5924,38 @@
*/
text: function(str, x, y, useHTML) {
// declare variables
var renderer = this,
- fakeSVG = !svg && renderer.forExport,
wrapper,
attribs = {};
if (useHTML && (renderer.allowHTML || !renderer.forExport)) {
return renderer.html(str, x, y);
}
- attribs.x = Math.round(x || 0); // X is always needed for line-wrap logic
+ attribs.x = Math.round(x || 0); // X always needed for line-wrap logic
if (y) {
attribs.y = Math.round(y);
}
if (str || str === 0) {
attribs.text = str;
}
wrapper = renderer.createElement('text')
.attr(attribs);
- // Prevent wrapping from creating false offsetWidths in export in legacy IE (#1079, #1063)
- if (fakeSVG) {
- wrapper.css({
- position: 'absolute'
- });
- }
-
if (!useHTML) {
wrapper.xSetter = function(value, key, element) {
var tspans = element.getElementsByTagName('tspan'),
tspan,
parentVal = element.getAttribute(key),
i;
for (i = 0; i < tspans.length; i++) {
tspan = tspans[i];
- // If the x values are equal, the tspan represents a linebreak
+ // If the x values are equal, the tspan represents a
+ // linebreak
if (tspan.getAttribute(key) === parentVal) {
tspan.setAttribute(key, value);
}
}
element.setAttribute(key, value);
@@ -5925,11 +6065,21 @@
* The generated label.
*
* @sample highcharts/members/renderer-label-on-chart/
* A label on the chart
*/
- label: function(str, x, y, shape, anchorX, anchorY, useHTML, baseline, className) {
+ label: function(
+ str,
+ x,
+ y,
+ shape,
+ anchorX,
+ anchorY,
+ useHTML,
+ baseline,
+ className
+ ) {
var renderer = this,
wrapper = renderer.g(className !== 'button' && 'label'),
text = wrapper.text = renderer.text('', 0, 0, useHTML)
.attr({
@@ -5966,38 +6116,48 @@
};
/**
- * This function runs after the label is added to the DOM (when the bounding box is
- * available), and after the text of the label is updated to detect the new bounding
- * box and reflect it in the border box.
+ * This function runs after the label is added to the DOM (when the
+ * bounding box is available), and after the text of the label is
+ * updated to detect the new bounding box and reflect it in the border
+ * box.
*/
updateBoxSize = function() {
var style = text.element.style,
crispAdjust,
attribs = {};
- bBox = (width === undefined || height === undefined || textAlign) && defined(text.textStr) &&
- text.getBBox(); //#3295 && 3514 box failure when string equals 0
- wrapper.width = (width || bBox.width || 0) + 2 * padding + paddingLeft;
+ bBox = (
+ (width === undefined || height === undefined || textAlign) &&
+ defined(text.textStr) &&
+ text.getBBox()
+ ); // #3295 && 3514 box failure when string equals 0
+ wrapper.width = (
+ (width || bBox.width || 0) +
+ 2 * padding +
+ paddingLeft
+ );
wrapper.height = (height || bBox.height || 0) + 2 * padding;
// Update the label-scoped y offset
- baselineOffset = padding + renderer.fontMetrics(style && style.fontSize, text).b;
+ baselineOffset = padding +
+ renderer.fontMetrics(style && style.fontSize, text).b;
if (needsBox) {
// Create the border box if it is not already present
if (!box) {
- wrapper.box = box = renderer.symbols[shape] || hasBGImage ? // Symbol definition exists (#5324)
+ // Symbol definition exists (#5324)
+ wrapper.box = box = renderer.symbols[shape] || hasBGImage ?
renderer.symbol(shape) :
renderer.rect();
- box.addClass(
- (className === 'button' ? '' : 'highcharts-label-box') + // Don't use label className for buttons
+ box.addClass( // Don't use label className for buttons
+ (className === 'button' ? '' : 'highcharts-label-box') +
(className ? ' highcharts-' + className + '-box' : '')
);
box.add(wrapper);
@@ -6014,25 +6174,31 @@
deferredAttr = {};
}
};
/**
- * This function runs after setting text or padding, but only if padding is changed
+ * This function runs after setting text or padding, but only if padding
+ * is changed
*/
updateTextPadding = function() {
var textX = paddingLeft + padding,
textY;
// determin y based on the baseline
textY = baseline ? 0 : baselineOffset;
// compensate for alignment
- if (defined(width) && bBox && (textAlign === 'center' || textAlign === 'right')) {
+ if (
+ defined(width) &&
+ bBox &&
+ (textAlign === 'center' || textAlign === 'right')
+ ) {
textX += {
- center: 0.5,
- right: 1
- }[textAlign] * (width - bBox.width);
+ center: 0.5,
+ right: 1
+ }[textAlign] *
+ (width - bBox.width);
}
// update if anything changed
if (textX !== text.x || textY !== text.y) {
text.attr('x', textX);
@@ -6058,17 +6224,19 @@
deferredAttr[key] = value;
}
};
/**
- * After the text element is added, get the desired size of the border box
- * and add it before the text in the DOM.
+ * After the text element is added, get the desired size of the border
+ * box and add it before the text in the DOM.
*/
wrapper.onAdd = function() {
text.add(wrapper);
wrapper.attr({
- text: (str || str === 0) ? str : '', // alignment is available now // #3295: 0 not rendered if given as a value
+ // Alignment is available now (#3295, 0 not rendered if given
+ // as a value)
+ text: (str || str === 0) ? str : '',
x: x,
y: y
});
if (box && defined(anchorX)) {
@@ -6114,11 +6282,12 @@
center: 0.5,
right: 1
}[value];
if (value !== alignFactor) {
alignFactor = value;
- if (bBox) { // Bounding box exists, means we're dynamically changing
+ // Bounding box exists, means we're dynamically changing
+ if (bBox) {
wrapper.attr({
x: wrapperX
}); // #5134
}
}
@@ -6140,20 +6309,22 @@
}
strokeWidth = this['stroke-width'] = value;
boxAttr(key, value);
};
- wrapper.strokeSetter = wrapper.fillSetter = wrapper.rSetter = function(value, key) {
- if (key !== 'r') {
- if (key === 'fill' && value) {
- needsBox = true;
+ wrapper.strokeSetter =
+ wrapper.fillSetter =
+ wrapper.rSetter = function(value, key) {
+ if (key !== 'r') {
+ if (key === 'fill' && value) {
+ needsBox = true;
+ }
+ // for animation getter (#6776)
+ wrapper[key] = value;
}
- // for animation getter (#6776)
- wrapper[key] = value;
- }
- boxAttr(key, value);
- };
+ boxAttr(key, value);
+ };
wrapper.anchorXSetter = function(value, key) {
anchorX = wrapper.anchorX = value;
boxAttr(key, Math.round(value) - getCrispAdjust() - wrapperX);
};
@@ -6185,11 +6356,13 @@
* @ignore
*/
css: function(styles) {
if (styles) {
var textStyles = {};
- styles = merge(styles); // create a copy to avoid altering the original object (#537)
+ // Create a copy to avoid altering the original object
+ // (#537)
+ styles = merge(styles);
each(wrapper.textProps, function(prop) {
if (styles[prop] !== undefined) {
textStyles[prop] = styles[prop];
delete styles[prop];
}
@@ -6243,11 +6416,15 @@
}
// Call base implementation to destroy the rest
SVGElement.prototype.destroy.call(wrapper);
// Release local pointers (#1298)
- wrapper = renderer = updateBoxSize = updateTextPadding = boxAttr = null;
+ wrapper =
+ renderer =
+ updateBoxSize =
+ updateTextPadding =
+ boxAttr = null;
}
});
}
}); // end SVGRenderer
@@ -6314,16 +6491,10 @@
htmlGetBBox: function() {
var wrapper = this,
element = wrapper.element;
- // faking getBBox in exported SVG in legacy IE (is this a duplicate of
- // the fix for #1079?)
- if (element.nodeName === 'text') {
- element.style.position = 'absolute';
- }
-
return {
x: element.offsetLeft,
y: element.offsetTop,
width: element.offsetWidth,
height: element.offsetHeight
@@ -6459,20 +6630,11 @@
/**
* Set the rotation of an individual HTML span
*/
setSpanRotation: function(rotation, alignCorrection, baseline) {
var rotationStyle = {},
- cssTransformKey =
- isMS ?
- '-ms-transform' :
- isWebKit ?
- '-webkit-transform' :
- isFirefox ?
- 'MozTransform' :
- win.opera ?
- '-o-transform' :
- '';
+ cssTransformKey = this.renderer.getTransformKey();
rotationStyle[cssTransformKey] = rotationStyle.transform =
'rotate(' + rotation + 'deg)';
rotationStyle[cssTransformKey + (isFirefox ? 'Origin' : '-origin')] =
rotationStyle.transformOrigin =
@@ -6489,10 +6651,23 @@
}
});
// Extend SvgRenderer for useHTML option.
extend(SVGRenderer.prototype, /** @lends SVGRenderer.prototype */ {
+
+ getTransformKey: function() {
+ return isMS && !/Edge/.test(win.navigator.userAgent) ?
+ '-ms-transform' :
+ isWebKit ?
+ '-webkit-transform' :
+ isFirefox ?
+ 'MozTransform' :
+ win.opera ?
+ '-o-transform' :
+ '';
+ },
+
/**
* Create HTML text node. This is used by the VML renderer as well as the
* SVG renderer through the useHTML option.
*
* @param {String} str
@@ -6600,10 +6775,24 @@
// is translated
each(parents.reverse(), function(parentGroup) {
var htmlGroupStyle,
cls = attr(parentGroup.element, 'class');
+ // Common translate setter for X and Y on the HTML
+ // group. Using CSS transform instead of left and
+ // right prevents flickering in IE and Edge when
+ // moving tooltip (#6957).
+ function translateSetter(value, key) {
+ parentGroup[key] = value;
+ htmlGroupStyle[renderer.getTransformKey()] =
+ 'translate(' +
+ parentGroup.x + 'px,' +
+ parentGroup.y + 'px)';
+
+ parentGroup.doTransform = true;
+ }
+
if (cls) {
cls = {
className: cls
};
} // else null
@@ -6644,20 +6833,12 @@
arguments
);
}
return parentGroup;
},
- translateXSetter: function(value, key) {
- htmlGroupStyle.left = value + 'px';
- parentGroup[key] = value;
- parentGroup.doTransform = true;
- },
- translateYSetter: function(value, key) {
- htmlGroupStyle.top = value + 'px';
- parentGroup[key] = value;
- parentGroup.doTransform = true;
- }
+ translateXSetter: translateSetter,
+ translateYSetter: translateSetter
});
addSetters(parentGroup, htmlGroupStyle);
});
}
@@ -6685,1163 +6866,11 @@
/**
* (c) 2010-2017 Torstein Honsi
*
* License: www.highcharts.com/license
*/
-
- var VMLRenderer,
- VMLRendererExtension,
- VMLElement,
-
- createElement = H.createElement,
- css = H.css,
- defined = H.defined,
- deg2rad = H.deg2rad,
- discardElement = H.discardElement,
- doc = H.doc,
- each = H.each,
- erase = H.erase,
- extend = H.extend,
- extendClass = H.extendClass,
- isArray = H.isArray,
- isNumber = H.isNumber,
- isObject = H.isObject,
- merge = H.merge,
- noop = H.noop,
- pick = H.pick,
- pInt = H.pInt,
- svg = H.svg,
- SVGElement = H.SVGElement,
- SVGRenderer = H.SVGRenderer,
- win = H.win;
-
- /* ****************************************************************************
- * *
- * START OF INTERNET EXPLORER <= 8 SPECIFIC CODE *
- * *
- * For applications and websites that don't need IE support, like platform *
- * targeted mobile apps and web apps, this code can be removed. *
- * *
- *****************************************************************************/
-
- /**
- * @constructor
- */
- if (!svg) {
-
- /**
- * The VML element wrapper.
- */
- VMLElement = {
-
- docMode8: doc && doc.documentMode === 8,
-
- /**
- * Initialize a new VML element wrapper. It builds the markup as a string
- * to minimize DOM traffic.
- * @param {Object} renderer
- * @param {Object} nodeName
- */
- init: function(renderer, nodeName) {
- var wrapper = this,
- markup = ['<', nodeName, ' filled="f" stroked="f"'],
- style = ['position: ', 'absolute', ';'],
- isDiv = nodeName === 'div';
-
- // divs and shapes need size
- if (nodeName === 'shape' || isDiv) {
- style.push('left:0;top:0;width:1px;height:1px;');
- }
- style.push('visibility: ', isDiv ? 'hidden' : 'visible');
-
- markup.push(' style="', style.join(''), '"/>');
-
- // create element with default attributes and style
- if (nodeName) {
- markup = isDiv || nodeName === 'span' || nodeName === 'img' ?
- markup.join('') :
- renderer.prepVML(markup);
- wrapper.element = createElement(markup);
- }
-
- wrapper.renderer = renderer;
- },
-
- /**
- * Add the node to the given parent
- * @param {Object} parent
- */
- add: function(parent) {
- var wrapper = this,
- renderer = wrapper.renderer,
- element = wrapper.element,
- box = renderer.box,
- inverted = parent && parent.inverted,
-
- // get the parent node
- parentNode = parent ?
- parent.element || parent :
- box;
-
- if (parent) {
- this.parentGroup = parent;
- }
-
- // if the parent group is inverted, apply inversion on all children
- if (inverted) { // only on groups
- renderer.invertChild(element, parentNode);
- }
-
- // append it
- parentNode.appendChild(element);
-
- // align text after adding to be able to read offset
- wrapper.added = true;
- if (wrapper.alignOnAdd && !wrapper.deferUpdateTransform) {
- wrapper.updateTransform();
- }
-
- // fire an event for internal hooks
- if (wrapper.onAdd) {
- wrapper.onAdd();
- }
-
- // IE8 Standards can't set the class name before the element is appended
- if (this.className) {
- this.attr('class', this.className);
- }
-
- return wrapper;
- },
-
- /**
- * VML always uses htmlUpdateTransform
- */
- updateTransform: SVGElement.prototype.htmlUpdateTransform,
-
- /**
- * Set the rotation of a span with oldIE's filter
- */
- setSpanRotation: function() {
- // Adjust for alignment and rotation. Rotation of useHTML content is not yet implemented
- // but it can probably be implemented for Firefox 3.5+ on user request. FF3.5+
- // has support for CSS3 transform. The getBBox method also needs to be updated
- // to compensate for the rotation, like it currently does for SVG.
- // Test case: http://jsfiddle.net/highcharts/Ybt44/
-
- var rotation = this.rotation,
- costheta = Math.cos(rotation * deg2rad),
- sintheta = Math.sin(rotation * deg2rad);
-
- css(this.element, {
- filter: rotation ? ['progid:DXImageTransform.Microsoft.Matrix(M11=', costheta,
- ', M12=', -sintheta, ', M21=', sintheta, ', M22=', costheta,
- ', sizingMethod=\'auto expand\')'
- ].join('') : 'none'
- });
- },
-
- /**
- * Get the positioning correction for the span after rotating.
- */
- getSpanCorrection: function(width, baseline, alignCorrection, rotation, align) {
-
- var costheta = rotation ? Math.cos(rotation * deg2rad) : 1,
- sintheta = rotation ? Math.sin(rotation * deg2rad) : 0,
- height = pick(this.elemHeight, this.element.offsetHeight),
- quad,
- nonLeft = align && align !== 'left';
-
- // correct x and y
- this.xCorr = costheta < 0 && -width;
- this.yCorr = sintheta < 0 && -height;
-
- // correct for baseline and corners spilling out after rotation
- quad = costheta * sintheta < 0;
- this.xCorr += sintheta * baseline * (quad ? 1 - alignCorrection : alignCorrection);
- this.yCorr -= costheta * baseline * (rotation ? (quad ? alignCorrection : 1 - alignCorrection) : 1);
- // correct for the length/height of the text
- if (nonLeft) {
- this.xCorr -= width * alignCorrection * (costheta < 0 ? -1 : 1);
- if (rotation) {
- this.yCorr -= height * alignCorrection * (sintheta < 0 ? -1 : 1);
- }
- css(this.element, {
- textAlign: align
- });
- }
- },
-
- /**
- * Converts a subset of an SVG path definition to its VML counterpart. Takes an array
- * as the parameter and returns a string.
- */
- pathToVML: function(value) {
- // convert paths
- var i = value.length,
- path = [];
-
- while (i--) {
-
- // Multiply by 10 to allow subpixel precision.
- // Substracting half a pixel seems to make the coordinates
- // align with SVG, but this hasn't been tested thoroughly
- if (isNumber(value[i])) {
- path[i] = Math.round(value[i] * 10) - 5;
- } else if (value[i] === 'Z') { // close the path
- path[i] = 'x';
- } else {
- path[i] = value[i];
-
- // When the start X and end X coordinates of an arc are too close,
- // they are rounded to the same value above. In this case, substract or
- // add 1 from the end X and Y positions. #186, #760, #1371, #1410.
- if (value.isArc && (value[i] === 'wa' || value[i] === 'at')) {
- // Start and end X
- if (path[i + 5] === path[i + 7]) {
- path[i + 7] += value[i + 7] > value[i + 5] ? 1 : -1;
- }
- // Start and end Y
- if (path[i + 6] === path[i + 8]) {
- path[i + 8] += value[i + 8] > value[i + 6] ? 1 : -1;
- }
- }
- }
- }
-
-
- // Loop up again to handle path shortcuts (#2132)
- /*while (i++ < path.length) {
- if (path[i] === 'H') { // horizontal line to
- path[i] = 'L';
- path.splice(i + 2, 0, path[i - 1]);
- } else if (path[i] === 'V') { // vertical line to
- path[i] = 'L';
- path.splice(i + 1, 0, path[i - 2]);
- }
- }*/
- return path.join(' ') || 'x';
- },
-
- /**
- * Set the element's clipping to a predefined rectangle
- *
- * @param {String} id The id of the clip rectangle
- */
- clip: function(clipRect) {
- var wrapper = this,
- clipMembers,
- cssRet;
-
- if (clipRect) {
- clipMembers = clipRect.members;
- erase(clipMembers, wrapper); // Ensure unique list of elements (#1258)
- clipMembers.push(wrapper);
- wrapper.destroyClip = function() {
- erase(clipMembers, wrapper);
- };
- cssRet = clipRect.getCSS(wrapper);
-
- } else {
- if (wrapper.destroyClip) {
- wrapper.destroyClip();
- }
- cssRet = {
- clip: wrapper.docMode8 ? 'inherit' : 'rect(auto)'
- }; // #1214
- }
-
- return wrapper.css(cssRet);
-
- },
-
- /**
- * Set styles for the element
- * @param {Object} styles
- */
- css: SVGElement.prototype.htmlCss,
-
- /**
- * Removes a child either by removeChild or move to garbageBin.
- * Issue 490; in VML removeChild results in Orphaned nodes according to sIEve, discardElement does not.
- */
- safeRemoveChild: function(element) {
- // discardElement will detach the node from its parent before attaching it
- // to the garbage bin. Therefore it is important that the node is attached and have parent.
- if (element.parentNode) {
- discardElement(element);
- }
- },
-
- /**
- * Extend element.destroy by removing it from the clip members array
- */
- destroy: function() {
- if (this.destroyClip) {
- this.destroyClip();
- }
-
- return SVGElement.prototype.destroy.apply(this);
- },
-
- /**
- * Add an event listener. VML override for normalizing event parameters.
- * @param {String} eventType
- * @param {Function} handler
- */
- on: function(eventType, handler) {
- // simplest possible event model for internal use
- this.element['on' + eventType] = function() {
- var evt = win.event;
- evt.target = evt.srcElement;
- handler(evt);
- };
- return this;
- },
-
- /**
- * In stacked columns, cut off the shadows so that they don't overlap
- */
- cutOffPath: function(path, length) {
-
- var len;
-
- path = path.split(/[ ,]/); // The extra comma tricks the trailing comma remover in "gulp scripts" task
- len = path.length;
-
- if (len === 9 || len === 11) {
- path[len - 4] = path[len - 2] = pInt(path[len - 2]) - 10 * length;
- }
- return path.join(' ');
- },
-
- /**
- * Apply a drop shadow by copying elements and giving them different strokes
- * @param {Boolean|Object} shadowOptions
- */
- shadow: function(shadowOptions, group, cutOff) {
- var shadows = [],
- i,
- element = this.element,
- renderer = this.renderer,
- shadow,
- elemStyle = element.style,
- markup,
- path = element.path,
- strokeWidth,
- modifiedPath,
- shadowWidth,
- shadowElementOpacity;
-
- // some times empty paths are not strings
- if (path && typeof path.value !== 'string') {
- path = 'x';
- }
- modifiedPath = path;
-
- if (shadowOptions) {
- shadowWidth = pick(shadowOptions.width, 3);
- shadowElementOpacity = (shadowOptions.opacity || 0.15) / shadowWidth;
- for (i = 1; i <= 3; i++) {
-
- strokeWidth = (shadowWidth * 2) + 1 - (2 * i);
-
- // Cut off shadows for stacked column items
- if (cutOff) {
- modifiedPath = this.cutOffPath(path.value, strokeWidth + 0.5);
- }
-
- markup = ['<shape isShadow="true" strokeweight="', strokeWidth,
- '" filled="false" path="', modifiedPath,
- '" coordsize="10 10" style="', element.style.cssText, '" />'
- ];
-
- shadow = createElement(renderer.prepVML(markup),
- null, {
- left: pInt(elemStyle.left) + pick(shadowOptions.offsetX, 1),
- top: pInt(elemStyle.top) + pick(shadowOptions.offsetY, 1)
- }
- );
- if (cutOff) {
- shadow.cutOff = strokeWidth + 1;
- }
-
- // apply the opacity
- markup = [
- '<stroke color="',
- shadowOptions.color || '#000000',
- '" opacity="', shadowElementOpacity * i, '"/>'
- ];
- createElement(renderer.prepVML(markup), null, null, shadow);
-
-
- // insert it
- if (group) {
- group.element.appendChild(shadow);
- } else {
- element.parentNode.insertBefore(shadow, element);
- }
-
- // record it
- shadows.push(shadow);
-
- }
-
- this.shadows = shadows;
- }
- return this;
- },
- updateShadows: noop, // Used in SVG only
-
- setAttr: function(key, value) {
- if (this.docMode8) { // IE8 setAttribute bug
- this.element[key] = value;
- } else {
- this.element.setAttribute(key, value);
- }
- },
- classSetter: function(value) {
- // IE8 Standards mode has problems retrieving the className unless set like this.
- // IE8 Standards can't set the class name before the element is appended.
- (this.added ? this.element : this).className = value;
- },
- dashstyleSetter: function(value, key, element) {
- var strokeElem = element.getElementsByTagName('stroke')[0] ||
- createElement(this.renderer.prepVML(['<stroke/>']), null, null, element);
- strokeElem[key] = value || 'solid';
- this[key] = value;
- /* because changing stroke-width will change the dash length
- and cause an epileptic effect */
- },
- dSetter: function(value, key, element) {
- var i,
- shadows = this.shadows;
- value = value || [];
- this.d = value.join && value.join(' '); // used in getter for animation
-
- element.path = value = this.pathToVML(value);
-
- // update shadows
- if (shadows) {
- i = shadows.length;
- while (i--) {
- shadows[i].path = shadows[i].cutOff ? this.cutOffPath(value, shadows[i].cutOff) : value;
- }
- }
- this.setAttr(key, value);
- },
- fillSetter: function(value, key, element) {
- var nodeName = element.nodeName;
- if (nodeName === 'SPAN') { // text color
- element.style.color = value;
- } 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 = -Math.round(Math.sin(value * deg2rad) + 1) + 'px';
- style.top = Math.round(Math.cos(value * deg2rad)) + 'px';
- },
- strokeSetter: function(value, key, element) {
- 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)) {
- value += 'px';
- }
- this.setAttr('strokeweight', value);
- },
- titleSetter: function(value, key) {
- this.setAttr(key, value);
- },
- visibilitySetter: function(value, key, element) {
-
- // Handle inherited visibility
- if (value === 'inherit') {
- value = 'visible';
- }
-
- // Let the shadow follow the main element
- if (this.shadows) {
- each(this.shadows, function(shadow) {
- shadow.style[key] = value;
- });
- }
-
- // Instead of toggling the visibility CSS property, move the div out of the viewport.
- // This works around #61 and #586
- if (element.nodeName === 'DIV') {
- value = value === 'hidden' ? '-999em' : 0;
-
- // In order to redraw, IE7 needs the div to be visible when tucked away
- // outside the viewport. So the visibility is actually opposite of
- // the expected value. This applies to the tooltip only.
- if (!this.docMode8) {
- element.style[key] = value ? 'visible' : 'hidden';
- }
- key = 'top';
- }
- element.style[key] = value;
- },
- xSetter: function(value, key, element) {
- this[key] = value; // used in getter
-
- if (key === 'x') {
- key = 'left';
- } else if (key === 'y') {
- key = 'top';
- }
- /* else {
- value = Math.max(0, value); // don't set width or height below zero (#311)
- }*/
-
- // clipping rectangle special
- if (this.updateClipping) {
- this[key] = value; // the key is now 'left' or 'top' for 'x' and 'y'
- this.updateClipping();
- } else {
- // normal
- element.style[key] = value;
- }
- },
- zIndexSetter: function(value, key, element) {
- element.style[key] = value;
- }
- };
- VMLElement['stroke-opacitySetter'] = VMLElement['fill-opacitySetter'];
- H.VMLElement = VMLElement = extendClass(SVGElement, VMLElement);
-
- // Some shared setters
- VMLElement.prototype.ySetter =
- VMLElement.prototype.widthSetter =
- VMLElement.prototype.heightSetter =
- VMLElement.prototype.xSetter;
-
-
- /**
- * The VML renderer
- */
- VMLRendererExtension = { // inherit SVGRenderer
-
- Element: VMLElement,
- isIE8: win.navigator.userAgent.indexOf('MSIE 8.0') > -1,
-
-
- /**
- * Initialize the VMLRenderer
- * @param {Object} container
- * @param {Number} width
- * @param {Number} height
- */
- init: function(container, width, height) {
- var renderer = this,
- boxWrapper,
- box,
- css;
-
- renderer.alignedObjects = [];
-
- boxWrapper = renderer.createElement('div')
- .css({
- position: 'relative'
- });
- box = boxWrapper.element;
- container.appendChild(boxWrapper.element);
-
-
- // generate the containing box
- renderer.isVML = true;
- renderer.box = box;
- renderer.boxWrapper = boxWrapper;
- renderer.gradients = {};
- renderer.cache = {}; // Cache for numerical bounding boxes
- renderer.cacheKeys = [];
- renderer.imgCount = 0;
-
-
- renderer.setSize(width, height, false);
-
- // The only way to make IE6 and IE7 print is to use a global namespace. However,
- // with IE8 the only way to make the dynamic shapes visible in screen and print mode
- // seems to be to add the xmlns attribute and the behaviour style inline.
- if (!doc.namespaces.hcv) {
-
- doc.namespaces.add('hcv', 'urn:schemas-microsoft-com:vml');
-
- // Setup default CSS (#2153, #2368, #2384)
- css = 'hcv\\:fill, hcv\\:path, hcv\\:shape, hcv\\:stroke' +
- '{ behavior:url(#default#VML); display: inline-block; } ';
- try {
- doc.createStyleSheet().cssText = css;
- } catch (e) {
- doc.styleSheets[0].cssText += css;
- }
-
- }
- },
-
-
- /**
- * Detect whether the renderer is hidden. This happens when one of the parent elements
- * has display: none
- */
- isHidden: function() {
- return !this.box.offsetWidth;
- },
-
- /**
- * Define a clipping rectangle. In VML it is accomplished by storing the values
- * for setting the CSS style to all associated members.
- *
- * @param {Number} x
- * @param {Number} y
- * @param {Number} width
- * @param {Number} height
- */
- clipRect: function(x, y, width, height) {
-
- // create a dummy element
- var clipRect = this.createElement(),
- isObj = isObject(x);
-
- // mimic a rectangle with its style object for automatic updating in attr
- return extend(clipRect, {
- members: [],
- count: 0,
- left: (isObj ? x.x : x) + 1,
- top: (isObj ? x.y : y) + 1,
- width: (isObj ? x.width : width) - 1,
- height: (isObj ? x.height : height) - 1,
- getCSS: function(wrapper) {
- var element = wrapper.element,
- nodeName = element.nodeName,
- isShape = nodeName === 'shape',
- inverted = wrapper.inverted,
- rect = this,
- top = rect.top - (isShape ? element.offsetTop : 0),
- left = rect.left,
- right = left + rect.width,
- bottom = top + rect.height,
- ret = {
- clip: 'rect(' +
- Math.round(inverted ? left : top) + 'px,' +
- Math.round(inverted ? bottom : right) + 'px,' +
- Math.round(inverted ? right : bottom) + 'px,' +
- Math.round(inverted ? top : left) + 'px)'
- };
-
- // issue 74 workaround
- if (!inverted && wrapper.docMode8 && nodeName === 'DIV') {
- extend(ret, {
- width: right + 'px',
- height: bottom + 'px'
- });
- }
- return ret;
- },
-
- // used in attr and animation to update the clipping of all members
- updateClipping: function() {
- each(clipRect.members, function(member) {
- // Member.element is falsy on deleted series, like in
- // stock/members/series-remove demo. Should be removed
- // from members, but this will do.
- if (member.element) {
- member.css(clipRect.getCSS(member));
- }
- });
- }
- });
-
- },
-
-
- /**
- * Take a color and return it if it's a string, make it a gradient if it's a
- * gradient configuration object, and apply opacity.
- *
- * @param {Object} color The color or config object
- */
- color: function(color, elem, prop, wrapper) {
- var renderer = this,
- colorObject,
- regexRgba = /^rgba/,
- markup,
- fillType,
- ret = 'none';
-
- // Check for linear or radial gradient
- if (color && color.linearGradient) {
- fillType = 'gradient';
- } else if (color && color.radialGradient) {
- fillType = 'pattern';
- }
-
-
- if (fillType) {
-
- var stopColor,
- stopOpacity,
- gradient = color.linearGradient || color.radialGradient,
- x1,
- y1,
- x2,
- y2,
- opacity1,
- opacity2,
- color1,
- color2,
- fillAttr = '',
- stops = color.stops,
- firstStop,
- lastStop,
- colors = [],
- addFillNode = function() {
- // Add the fill subnode. When colors attribute is used, the meanings of opacity and o:opacity2
- // are reversed.
- markup = ['<fill colors="' + colors.join(',') +
- '" opacity="', opacity2, '" o:opacity2="',
- opacity1, '" type="', fillType, '" ', fillAttr,
- 'focus="100%" method="any" />'
- ];
- createElement(renderer.prepVML(markup), null, null, elem);
- };
-
- // Extend from 0 to 1
- firstStop = stops[0];
- lastStop = stops[stops.length - 1];
- if (firstStop[0] > 0) {
- stops.unshift([
- 0,
- firstStop[1]
- ]);
- }
- if (lastStop[0] < 1) {
- stops.push([
- 1,
- lastStop[1]
- ]);
- }
-
- // Compute the stops
- each(stops, function(stop, i) {
- if (regexRgba.test(stop[1])) {
- colorObject = H.color(stop[1]);
- stopColor = colorObject.get('rgb');
- stopOpacity = colorObject.get('a');
- } else {
- stopColor = stop[1];
- stopOpacity = 1;
- }
-
- // Build the color attribute
- colors.push((stop[0] * 100) + '% ' + stopColor);
-
- // Only start and end opacities are allowed, so we use the first and the last
- if (!i) {
- opacity1 = stopOpacity;
- color2 = stopColor;
- } else {
- opacity2 = stopOpacity;
- color1 = stopColor;
- }
- });
-
- // Apply the gradient to fills only.
- if (prop === 'fill') {
-
- // Handle linear gradient angle
- if (fillType === 'gradient') {
- x1 = gradient.x1 || gradient[0] || 0;
- y1 = gradient.y1 || gradient[1] || 0;
- x2 = gradient.x2 || gradient[2] || 0;
- y2 = gradient.y2 || gradient[3] || 0;
- fillAttr = 'angle="' + (90 - Math.atan(
- (y2 - y1) / // y vector
- (x2 - x1) // x vector
- ) * 180 / Math.PI) + '"';
-
- addFillNode();
-
- // Radial (circular) gradient
- } else {
-
- var r = gradient.r,
- sizex = r * 2,
- sizey = r * 2,
- cx = gradient.cx,
- cy = gradient.cy,
- radialReference = elem.radialReference,
- bBox,
- applyRadialGradient = function() {
- if (radialReference) {
- bBox = wrapper.getBBox();
- cx += (radialReference[0] - bBox.x) / bBox.width - 0.5;
- cy += (radialReference[1] - bBox.y) / bBox.height - 0.5;
- sizex *= radialReference[2] / bBox.width;
- sizey *= radialReference[2] / bBox.height;
- }
- fillAttr = 'src="' + H.getOptions().global.VMLRadialGradientURL + '" ' +
- 'size="' + sizex + ',' + sizey + '" ' +
- 'origin="0.5,0.5" ' +
- 'position="' + cx + ',' + cy + '" ' +
- 'color2="' + color2 + '" ';
-
- addFillNode();
- };
-
- // Apply radial gradient
- if (wrapper.added) {
- applyRadialGradient();
- } else {
- // We need to know the bounding box to get the size and position right
- wrapper.onAdd = applyRadialGradient;
- }
-
- // The fill element's color attribute is broken in IE8 standards mode, so we
- // need to set the parent shape's fillcolor attribute instead.
- ret = color1;
- }
-
- // 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
- // to hold the opacity component
- } else if (regexRgba.test(color) && elem.tagName !== 'IMG') {
-
- colorObject = H.color(color);
-
- wrapper[prop + '-opacitySetter'](colorObject.get('a'), prop, elem);
-
- ret = colorObject.get('rgb');
-
-
- } else {
- var propNodes = elem.getElementsByTagName(prop); // 'stroke' or 'fill' node
- if (propNodes.length) {
- propNodes[0].opacity = 1;
- propNodes[0].type = 'solid';
- }
- ret = color;
- }
-
- return ret;
- },
-
- /**
- * Take a VML string and prepare it for either IE8 or IE6/IE7.
- * @param {Array} markup A string array of the VML markup to prepare
- */
- prepVML: function(markup) {
- var vmlStyle = 'display:inline-block;behavior:url(#default#VML);',
- isIE8 = this.isIE8;
-
- markup = markup.join('');
-
- if (isIE8) { // add xmlns and style inline
- markup = markup.replace('/>', ' xmlns="urn:schemas-microsoft-com:vml" />');
- if (markup.indexOf('style="') === -1) {
- markup = markup.replace('/>', ' style="' + vmlStyle + '" />');
- } else {
- markup = markup.replace('style="', 'style="' + vmlStyle);
- }
-
- } else { // add namespace
- markup = markup.replace('<', '<hcv:');
- }
-
- return markup;
- },
-
- /**
- * Create rotated and aligned text
- * @param {String} str
- * @param {Number} x
- * @param {Number} y
- */
- text: SVGRenderer.prototype.html,
-
- /**
- * Create and return a path element
- * @param {Array} path
- */
- path: function(path) {
- var attr = {
- // subpixel precision down to 0.1 (width and height = 1px)
- coordsize: '10 10'
- };
- if (isArray(path)) {
- attr.d = path;
- } else if (isObject(path)) { // attributes
- extend(attr, path);
- }
- // create the shape
- return this.createElement('shape').attr(attr);
- },
-
- /**
- * Create and return a circle element. In VML circles are implemented as
- * shapes, which is faster than v:oval
- * @param {Number} x
- * @param {Number} y
- * @param {Number} r
- */
- circle: function(x, y, r) {
- var circle = this.symbol('circle');
- if (isObject(x)) {
- r = x.r;
- y = x.y;
- x = x.x;
- }
- circle.isCircle = true; // Causes x and y to mean center (#1682)
- circle.r = r;
- return circle.attr({
- x: x,
- y: y
- });
- },
-
- /**
- * Create a group using an outer div and an inner v:group to allow rotating
- * and flipping. A simple v:group would have problems with positioning
- * child HTML elements and CSS clip.
- *
- * @param {String} name The name of the group
- */
- g: function(name) {
- var wrapper,
- attribs;
-
- // set the class name
- if (name) {
- attribs = {
- 'className': 'highcharts-' + name,
- 'class': 'highcharts-' + name
- };
- }
-
- // the div to hold HTML and clipping
- wrapper = this.createElement('div').attr(attribs);
-
- return wrapper;
- },
-
- /**
- * VML override to create a regular HTML image
- * @param {String} src
- * @param {Number} x
- * @param {Number} y
- * @param {Number} width
- * @param {Number} height
- */
- image: function(src, x, y, width, height) {
- var obj = this.createElement('img')
- .attr({
- src: src
- });
-
- if (arguments.length > 1) {
- obj.attr({
- x: x,
- y: y,
- width: width,
- height: height
- });
- }
- return obj;
- },
-
- /**
- * For rectangles, VML uses a shape for rect to overcome bugs and rotation problems
- */
- createElement: function(nodeName) {
- return nodeName === 'rect' ?
- this.symbol(nodeName) :
- SVGRenderer.prototype.createElement.call(this, nodeName);
- },
-
- /**
- * In the VML renderer, each child of an inverted div (group) is inverted
- * @param {Object} element
- * @param {Object} parentNode
- */
- invertChild: function(element, parentNode) {
- var ren = this,
- parentStyle = parentNode.style,
- imgStyle = element.tagName === 'IMG' && element.style; // #1111
-
- css(element, {
- flip: 'x',
- left: pInt(parentStyle.width) - (imgStyle ? pInt(imgStyle.top) : 1),
- top: pInt(parentStyle.height) - (imgStyle ? pInt(imgStyle.left) : 1),
- rotation: -90
- });
-
- // Recursively invert child elements, needed for nested composite
- // shapes like box plots and error bars. #1680, #1806.
- each(element.childNodes, function(child) {
- ren.invertChild(child, element);
- });
- },
-
- /**
- * Symbol definitions that override the parent SVG renderer's symbols
- *
- */
- symbols: {
- // VML specific arc function
- arc: function(x, y, w, h, options) {
- var start = options.start,
- end = options.end,
- radius = options.r || w || h,
- innerRadius = options.innerR,
- cosStart = Math.cos(start),
- sinStart = Math.sin(start),
- cosEnd = Math.cos(end),
- sinEnd = Math.sin(end),
- ret;
-
- if (end - start === 0) { // no angle, don't show it.
- return ['x'];
- }
-
- ret = [
- 'wa', // clockwise arc to
- x - radius, // left
- y - radius, // top
- x + radius, // right
- y + radius, // bottom
- x + radius * cosStart, // start x
- y + radius * sinStart, // start y
- x + radius * cosEnd, // end x
- y + radius * sinEnd // end y
- ];
-
- if (options.open && !innerRadius) {
- ret.push(
- 'e',
- 'M',
- x, // - innerRadius,
- y // - innerRadius
- );
- }
-
- ret.push(
- 'at', // anti clockwise arc to
- x - innerRadius, // left
- y - innerRadius, // top
- x + innerRadius, // right
- y + innerRadius, // bottom
- x + innerRadius * cosEnd, // start x
- y + innerRadius * sinEnd, // start y
- x + innerRadius * cosStart, // end x
- y + innerRadius * sinStart, // end y
- 'x', // finish path
- 'e' // close
- );
-
- ret.isArc = true;
- return ret;
-
- },
- // Add circle symbol path. This performs significantly faster than v:oval.
- circle: function(x, y, w, h, wrapper) {
-
- if (wrapper && defined(wrapper.r)) {
- w = h = 2 * wrapper.r;
- }
-
- // Center correction, #1682
- if (wrapper && wrapper.isCircle) {
- x -= w / 2;
- y -= h / 2;
- }
-
- // Return the path
- return [
- 'wa', // clockwisearcto
- x, // left
- y, // top
- x + w, // right
- y + h, // bottom
- x + w, // start x
- y + h / 2, // start y
- x + w, // end x
- y + h / 2, // end y
- //'x', // finish path
- 'e' // close
- ];
- },
- /**
- * Add rectangle symbol path which eases rotation and omits arcsize problems
- * compared to the built-in VML roundrect shape. When borders are not rounded,
- * use the simpler square path, else use the callout path without the arrow.
- */
- rect: function(x, y, w, h, options) {
- return SVGRenderer.prototype.symbols[!defined(options) || !options.r ? 'square' : 'callout'].call(0, x, y, w, h, options);
- }
- }
- };
- H.VMLRenderer = VMLRenderer = function() {
- this.init.apply(this, arguments);
- };
- VMLRenderer.prototype = merge(SVGRenderer.prototype, VMLRendererExtension);
-
- // general renderer
- H.Renderer = VMLRenderer;
- }
-
- // This method is used with exporting in old IE, when emulating SVG (see #2314)
- SVGRenderer.prototype.measureSpanWidth = function(text, styles) {
- var measuringSpan = doc.createElement('span'),
- offsetWidth,
- textNode = doc.createTextNode(text);
-
- measuringSpan.appendChild(textNode);
- css(measuringSpan, styles);
- this.box.appendChild(measuringSpan);
- offsetWidth = measuringSpan.offsetWidth;
- discardElement(measuringSpan); // #2463
- return offsetWidth;
- };
-
-
- /* ****************************************************************************
- * *
- * END OF INTERNET EXPLORER <= 8 SPECIFIC CODE *
- * *
- *****************************************************************************/
-
-
- }(Highcharts));
- (function(H) {
- /**
- * (c) 2010-2017 Torstein Honsi
- *
- * License: www.highcharts.com/license
- */
var color = H.color,
- each = H.each,
getTZOffset = H.getTZOffset,
isTouchDevice = H.isTouchDevice,
merge = H.merge,
pick = H.pick,
svg = H.svg,
@@ -7862,51 +6891,59 @@
*
* Default colors can also be set on a series or series.type basis,
* see [column.colors](#plotOptions.column.colors), [pie.colors](#plotOptions.
* pie.colors).
*
- * In [styled mode](http://www.highcharts.com/docs/chart-design-and-
- * style/style-by-css), the colors option doesn't exist. Instead, colors
+ * In styled mode, the colors option doesn't exist. Instead, colors
* are defined in CSS and applied either through series or point class
* names, or through the [chart.colorCount](#chart.colorCount) option.
*
*
* ### Legacy
*
* In Highcharts 3.x, the default colors were:
*
- * <pre>colors: ['#2f7ed8', '#0d233a', '#8bbc21', '#910000', '#1aadce',
+ * <pre>colors: ['#2f7ed8', '#0d233a', '#8bbc21', '#910000', '#1aadce',
+ * '#492970', '#f28f43', '#77a1e5', '#c42525', '#a6c96a']</pre>
*
- * '#492970', '#f28f43', '#77a1e5', '#c42525', '#a6c96a']</pre>
- *
* In Highcharts 2.x, the default colors were:
*
- * <pre>colors: ['#4572A7', '#AA4643', '#89A54E', '#80699B', '#3D96AE',
- *
+ * <pre>colors: ['#4572A7', '#AA4643', '#89A54E', '#80699B', '#3D96AE',
* '#DB843D', '#92A8CD', '#A47D7C', '#B5CA92']</pre>
*
* @type {Array<Color>}
* @sample {highcharts} highcharts/chart/colors/ Assign a global color theme
- * @default [ "#7cb5ec" , "#434348" , "#90ed7d" , "#f7a35c" , "#8085e9" ,
- * "#f15c80" , "#e4d354" , "#2b908f" , "#f45b5b" , "#91e8e1"]
- * @product highcharts highstock highmaps
+ * @default ["#7cb5ec", "#434348", "#90ed7d", "#f7a35c", "#8085e9",
+ * "#f15c80", "#e4d354", "#2b908f", "#f45b5b", "#91e8e1"]
*/
colors: '#7cb5ec #434348 #90ed7d #f7a35c #8085e9 #f15c80 #e4d354 #2b908f #f45b5b #91e8e1'.split(' '),
+
/**
+ * Styled mode only. Configuration object for adding SVG definitions for
+ * reusable elements. See [gradients, shadows and patterns](http://www.
+ * highcharts.com/docs/chart-design-and-style/gradients-shadows-and-
+ * patterns) for more information and code examples.
+ *
+ * @type {Object}
+ * @since 5.0.0
+ * @apioption defs
*/
+
+ /**
+ * @ignore
+ */
symbols: ['circle', 'diamond', 'square', 'triangle', 'triangle-down'],
lang: {
/**
* The loading text that appears when the chart is set into the loading
* state following a call to `chart.showLoading`.
*
* @type {String}
* @default Loading...
- * @product highcharts highstock highmaps
*/
loading: 'Loading...',
/**
* An array containing the months names. Corresponds to the `%B` format
@@ -7914,11 +6951,10 @@
*
* @type {Array<String>}
* @default [ "January" , "February" , "March" , "April" , "May" ,
* "June" , "July" , "August" , "September" , "October" ,
* "November" , "December"]
- * @product highcharts highstock highmaps
*/
months: [
'January', 'February', 'March', 'April', 'May', 'June', 'July',
'August', 'September', 'October', 'November', 'December'
],
@@ -7940,61 +6976,91 @@
* An array containing the weekday names.
*
* @type {Array<String>}
* @default ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday",
* "Friday", "Saturday"]
- * @product highcharts highstock highmaps
*/
weekdays: [
'Sunday', 'Monday', 'Tuesday', 'Wednesday',
'Thursday', 'Friday', 'Saturday'
],
- // invalidDate: '',
/**
+ * Short week days, starting Sunday. If not specified, Highcharts uses
+ * the first three letters of the `lang.weekdays` option.
+ *
+ * @type {Array<String>}
+ * @sample highcharts/lang/shortweekdays/
+ * Finnish two-letter abbreviations
+ * @since 4.2.4
+ * @apioption lang.shortWeekdays
+ */
+
+ /**
+ * What to show in a date field for invalid dates. Defaults to an empty
+ * string.
+ *
+ * @type {String}
+ * @since 4.1.8
+ * @product highcharts highstock
+ * @apioption lang.invalidDate
+ */
+
+ /**
* The default decimal point used in the `Highcharts.numberFormat`
* method unless otherwise specified in the function arguments.
*
* @type {String}
* @default .
* @since 1.2.2
- * @product highcharts highstock highmaps
*/
decimalPoint: '.',
/**
* [Metric prefixes](http://en.wikipedia.org/wiki/Metric_prefix) used
* to shorten high numbers in axis labels. Replacing any of the positions
* with `null` causes the full number to be written. Setting `numericSymbols`
* to `null` disables shortening altogether.
*
* @type {Array<String>}
- * @sample {highcharts} highcharts/lang/numericsymbols/ Replacing the symbols with text
- * @sample {highstock} highcharts/lang/numericsymbols/ Replacing the symbols with text
+ * @sample {highcharts} highcharts/lang/numericsymbols/
+ * Replacing the symbols with text
+ * @sample {highstock} highcharts/lang/numericsymbols/
+ * Replacing the symbols with text
* @default [ "k" , "M" , "G" , "T" , "P" , "E"]
* @since 2.3.0
- * @product highcharts highstock highmaps
*/
- numericSymbols: ['k', 'M', 'G', 'T', 'P', 'E'], // SI prefixes used in axis labels
+ numericSymbols: ['k', 'M', 'G', 'T', 'P', 'E'],
/**
+ * The magnitude of [numericSymbols](#lang.numericSymbol) replacements.
+ * Use 10000 for Japanese, Korean and various Chinese locales, which
+ * use symbols for 10^4, 10^8 and 10^12.
+ *
+ * @type {Number}
+ * @sample highcharts/lang/numericsymbolmagnitude/
+ * 10000 magnitude for Japanese
+ * @default 1000
+ * @since 5.0.3
+ * @apioption lang.numericSymbolMagnitude
+ */
+
+ /**
* The text for the label appearing when a chart is zoomed.
*
* @type {String}
* @default Reset zoom
* @since 1.2.4
- * @product highcharts highstock highmaps
*/
resetZoom: 'Reset zoom',
/**
* The tooltip title for the label appearing when a chart is zoomed.
*
* @type {String}
* @default Reset zoom level 1:1
* @since 1.2.4
- * @product highcharts highstock highmaps
*/
resetZoomTitle: 'Reset zoom level 1:1',
/**
* The default thousands separator used in the `Highcharts.numberFormat`
@@ -8006,27 +7072,25 @@
* The default is a single space.
*
* @type {String}
* @default
* @since 1.2.2
- * @product highcharts highstock highmaps
*/
thousandsSep: ' '
},
/**
* Global options that don't apply to each chart. These options, like
* the `lang` options, must be set using the `Highcharts.setOptions`
* method.
*
* <pre>Highcharts.setOptions({
- * global: {
- * useUTC: false
- * }
+ * global: {
+ * useUTC: false
+ * }
* });</pre>
- *
- * @product highcharts highstock highmaps
+ *
*/
global: {
/**
* Whether to use UTC time for axis scaling, tickmark placement and
@@ -8038,29 +7102,95 @@
*
* @type {Boolean}
* @sample {highcharts} highcharts/global/useutc-true/ True by default
* @sample {highcharts} highcharts/global/useutc-false/ False
* @default true
- * @product highcharts highstock highmaps
*/
- useUTC: true,
- //timezoneOffset: 0,
+ useUTC: true
+ /**
+ * A custom `Date` class for advanced date handling. For example,
+ * [JDate](https://githubcom/tahajahangir/jdate) can be hooked in to
+ * handle Jalali dates.
+ *
+ * @type {Object}
+ * @since 4.0.4
+ * @product highcharts highstock
+ * @apioption global.Date
+ */
/**
- * Path to the pattern image required by VML browsers in order to
- * draw radial gradients.
+ * _Canvg rendering for Android 2.x is removed as of Highcharts 5.0\.
+ * Use the [libURL](#exporting.libURL) option to configure exporting._
*
+ * The URL to the additional file to lazy load for Android 2.x devices.
+ * These devices don't support SVG, so we download a helper file that
+ * contains [canvg](http://code.google.com/p/canvg/), its dependency
+ * rbcolor, and our own CanVG Renderer class. To avoid hotlinking to
+ * our site, you can install canvas-tools.js on your own server and
+ * change this option accordingly.
+ *
* @type {String}
- * @default {highcharts} http://code.highcharts.com/{version}/gfx/vml-radial-gradient.png
- * @default {highstock} http://code.highcharts.com/highstock/{version}/gfx/vml-radial-gradient.png
- * @default {highmaps} http://code.highcharts.com/{version}/gfx/vml-radial-gradient.png
- * @since 2.3.0
- * @product highcharts highstock highmaps
+ * @deprecated
+ * @default http://code.highcharts.com/{version}/modules/canvas-tools.js
+ * @product highcharts highmaps
+ * @apioption global.canvasToolsURL
*/
- VMLRadialGradientURL: 'http://code.highcharts.com/5.0.14/gfx/vml-radial-gradient.png'
+ /**
+ * A callback to return the time zone offset for a given datetime. It
+ * takes the timestamp in terms of milliseconds since January 1 1970,
+ * and returns the timezone offset in minutes. This provides a hook
+ * for drawing time based charts in specific time zones using their
+ * local DST crossover dates, with the help of external libraries.
+ *
+ * @type {Function}
+ * @see [global.timezoneOffset](#global.timezoneOffset)
+ * @sample {highcharts} highcharts/global/gettimezoneoffset/
+ * Use moment.js to draw Oslo time regardless of browser locale
+ * @sample {highstock} highcharts/global/gettimezoneoffset/
+ * Use moment.js to draw Oslo time regardless of browser locale
+ * @since 4.1.0
+ * @product highcharts highstock
+ * @apioption global.getTimezoneOffset
+ */
+
+ /**
+ * Requires [moment.js](http://momentjs.com/). If the timezone option
+ * is specified, it creates a default
+ * [getTimezoneOffset](#global.getTimezoneOffset) function that looks
+ * up the specified timezone in moment.js. If moment.js is not included,
+ * this throws a Highcharts error in the console, but does not crash the
+ * chart.
+ *
+ * @type {String}
+ * @see [getTimezoneOffset](#global.getTimezoneOffset)
+ * @sample {highcharts} highcharts/global/timezone/ Europe/Oslo
+ * @sample {highstock} highcharts/global/timezone/ Europe/Oslo
+ * @default undefined
+ * @since 5.0.7
+ * @product highcharts highstock
+ * @apioption global.timezone
+ */
+
+ /**
+ * The timezone offset in minutes. Positive values are west, negative
+ * values are east of UTC, as in the ECMAScript [getTimezoneOffset](https://developer.
+ * mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getTimezoneOffset)
+ * method. Use this to display UTC based data in a predefined time zone.
+ *
+ * @type {Number}
+ * @see [global.getTimezoneOffset](#global.getTimezoneOffset)
+ * @sample {highcharts} highcharts/global/timezoneoffset/
+ * Timezone offset
+ * @sample {highstock} highcharts/global/timezoneoffset/
+ * Timezone offset
+ * @default 0
+ * @since 3.0.8
+ * @product highcharts highstock
+ * @apioption global.timezoneOffset
+ */
},
chart: {
/**
* When using multiple axis, the ticks of two or more opposite axes
@@ -8166,14 +7296,14 @@
* and each axis' value at the clicked spot. The primary axes are `event.
* xAxis[0]` and `event.yAxis[0]`. Remember the unit of a datetime axis
* is milliseconds since 1970-01-01 00:00:00.
*
* <pre>click: function(e) {
- * console.log(
- * Highcharts.dateFormat('%Y-%m-%d %H:%M:%S', e.xAxis[0].value),
- * e.yAxis[0].value
- * )
+ * console.log(
+ * Highcharts.dateFormat('%Y-%m-%d %H:%M:%S', e.xAxis[0].value),
+ * e.yAxis[0].value
+ * )
* }</pre>
*
* @type {Function}
* @context Chart
* @sample {highcharts} highcharts/chart/events-click/
@@ -8252,18 +7382,17 @@
* and each axis' min and max values. The primary axes are `event.xAxis[0]`
* and `event.yAxis[0]`. Remember the unit of a datetime axis is milliseconds
* since 1970-01-01 00:00:00.
*
* <pre>selection: function(event) {
- * // log the min and max of the primary, datetime x-axis
- * console.log(
- * Highcharts.dateFormat('%Y-%m-%d %H:%M:%S', event.xAxis[0].min),
- *
- * Highcharts.dateFormat('%Y-%m-%d %H:%M:%S', event.xAxis[0].max)
- * );
- * // log the min and max of the y axis
- * console.log(event.yAxis[0].min, event.yAxis[0].max);
+ * // log the min and max of the primary, datetime x-axis
+ * console.log(
+ * Highcharts.dateFormat('%Y-%m-%d %H:%M:%S', event.xAxis[0].min),
+ * Highcharts.dateFormat('%Y-%m-%d %H:%M:%S', event.xAxis[0].max)
+ * );
+ * // log the min and max of the y axis
+ * console.log(event.yAxis[0].min, event.yAxis[0].max);
* }</pre>
*
* @type {Function}
* @sample {highcharts} highcharts/chart/events-selection/
* Report on selection and reset
@@ -8418,11 +7547,10 @@
* @type {Number}
* @sample {highcharts} highcharts/chart/borderradius/ 20px radius
* @sample {highstock} stock/chart/border/ 10px radius
* @sample {highmaps} maps/chart/border/ Border options
* @default 0
- * @product highcharts highstock highmaps
*/
borderRadius: 0,
/**
@@ -8492,19 +7620,17 @@
*
* @type {Array<Number>}
* @see [chart.margin](#chart.margin)
* @default [10, 10, 15, 10]
* @since 3.0.6
- * @product highcharts highstock highmaps
*/
spacing: [10, 10, 15, 10],
/**
* The button that appears after a selection zoom, allowing the user
* to reset zoom.
- *
- * @product highcharts highstock highmaps
+ *
*/
resetZoomButton: {
/**
* A collection of attributes for the button. The object takes SVG
@@ -8512,18 +7638,20 @@
* radius. The theme also supports `style`, a collection of CSS properties
* for the text. Equivalent attributes for the hover state are given
* in `theme.states.hover`.
*
* @type {Object}
- * @sample {highcharts} highcharts/chart/resetzoombutton-theme/ Theming the button
- * @sample {highstock} highcharts/chart/resetzoombutton-theme/ Theming the button
+ * @sample {highcharts} highcharts/chart/resetzoombutton-theme/
+ * Theming the button
+ * @sample {highstock} highcharts/chart/resetzoombutton-theme/
+ * Theming the button
* @since 2.2
- * @product highcharts highstock highmaps
*/
theme: {
/**
+ * The Z index for the reset zoom button.
*/
zIndex: 20
},
/**
@@ -8535,11 +7663,10 @@
* @sample {highstock} highcharts/chart/resetzoombutton-position/
* Above the plot area
* @sample {highmaps} highcharts/chart/resetzoombutton-position/
* Above the plot area
* @since 2.2
- * @product highcharts highstock highmaps
*/
position: {
/**
* The horizontal alignment of the button.
@@ -8595,11 +7722,10 @@
* @type {Number}
* @sample {highcharts} highcharts/chart/width/ 800px wide
* @sample {highstock} stock/chart/width/ 800px wide
* @sample {highmaps} maps/chart/size/ Chart with explicit size
* @default null
- * @product highcharts highstock highmaps
*/
width: null,
/**
* An explicit height for the chart. If a _number_, the height is
@@ -8620,59 +7746,48 @@
* @sample {highmaps} maps/chart/size/
* Chart with explicit size
* @sample highcharts/chart/height-percent/
* Highcharts with percentage height
* @default null
- * @product highcharts highstock highmaps
*/
height: null,
/**
* The color of the outer chart border.
*
* @type {Color}
- * @see In [styled mode](http://www.highcharts.com/docs/chart-design-and-
- * style/style-by-css), the stroke is set with the `.highcharts-background`
+ * @see In styled mode, the stroke is set with the `.highcharts-background`
* class.
* @sample {highcharts} highcharts/chart/bordercolor/ Brown border
* @sample {highstock} stock/chart/border/ Brown border
* @sample {highmaps} maps/chart/border/ Border options
* @default #335cad
- * @product highcharts highstock highmaps
*/
borderColor: '#335cad',
/**
* The pixel width of the outer chart border.
*
* @type {Number}
- * @see In [styled mode](http://www.highcharts.com/docs/chart-design-and-
- * style/style-by-css), the stroke is set with the `.highcharts-background`
+ * @see In styled mode, the stroke is set with the `.highcharts-background`
* class.
* @sample {highcharts} highcharts/chart/borderwidth/ 5px border
* @sample {highstock} stock/chart/border/
* 2px border
* @sample {highmaps} maps/chart/border/
* Border options
* @default 0
* @apioption chart.borderWidth
*/
- //style: {
- // fontFamily: '"Lucida Grande", "Lucida Sans Unicode", Verdana, Arial, Helvetica, sans-serif', // default font
- // fontSize: '12px'
- //},
-
/**
* The background color or gradient for the outer chart area.
*
* @type {Color}
- * @see In [styled mode](http://www.highcharts.com/docs/chart-design-and-
- * style/style-by-css), the background is set with the `.highcharts-
- * background` class.
+ * @see In styled mode, the background is set with the `.highcharts-background` class.
* @sample {highcharts} highcharts/chart/backgroundcolor-color/ Color
* @sample {highcharts} highcharts/chart/backgroundcolor-gradient/ Gradient
* @sample {highstock} stock/chart/backgroundcolor-color/
* Color
* @sample {highstock} stock/chart/backgroundcolor-gradient/
@@ -8680,21 +7795,18 @@
* @sample {highmaps} maps/chart/backgroundcolor-color/
* Color
* @sample {highmaps} maps/chart/backgroundcolor-gradient/
* Gradient
* @default #FFFFFF
- * @product highcharts highstock highmaps
*/
backgroundColor: '#ffffff',
/**
* The background color or gradient for the plot area.
*
* @type {Color}
- * @see In [styled mode](http://www.highcharts.com/docs/chart-design-and-
- * style/style-by-css), the plot background is set with the `.highcharts-
- * plot-background` class.
+ * @see In styled mode, the plot background is set with the `.highcharts-plot-background` class.
* @sample {highcharts} highcharts/chart/plotbackgroundcolor-color/
* Color
* @sample {highcharts} highcharts/chart/plotbackgroundcolor-gradient/
* Gradient
* @sample {highstock} stock/chart/plotbackgroundcolor-color/
@@ -8715,12 +7827,11 @@
* as the background for the entire chart, set a CSS background image
* to the container element. Note that for the image to be applied to
* exported charts, its URL needs to be accessible by the export server.
*
* @type {String}
- * @see In [styled mode](http://www.highcharts.com/docs/chart-design-and-
- * style/style-by-css), a plot background image can be set with the
+ * @see In styled mode, a plot background image can be set with the
* `.highcharts-plot-background` class and a [custom pattern](http://www.
* highcharts.com/docs/chart-design-and-style/gradients-shadows-and-
* patterns).
* @sample {highcharts} highcharts/chart/plotbackgroundimage/ Skies
* @sample {highstock} stock/chart/plotbackgroundimage/ Skies
@@ -8730,18 +7841,16 @@
/**
* The color of the inner chart or plot area border.
*
* @type {Color}
- * @see In [styled mode](http://www.highcharts.com/docs/chart-design-and-
- * style/style-by-css), a plot border stroke can be set with the `.
+ * @see In styled mode, a plot border stroke can be set with the `.
* highcharts-plot-border` class.
* @sample {highcharts} highcharts/chart/plotbordercolor/ Blue border
* @sample {highstock} stock/chart/plotborder/ Blue border
* @sample {highmaps} maps/chart/plotborder/ Plot border options
* @default #cccccc
- * @product highcharts highstock highmaps
*/
plotBorderColor: '#cccccc'
/**
@@ -8832,12 +7941,11 @@
/**
* The background color of the marker square when selecting (zooming
* in on) an area of the chart.
*
* @type {Color}
- * @see In [styled mode](http://www.highcharts.com/docs/chart-design-and-
- * style/style-by-css), the selection marker fill is set with the
+ * @see In styled mode, the selection marker fill is set with the
* `.highcharts-selection-marker` class.
* @default rgba(51,92,173,0.25)
* @since 2.1.7
* @apioption chart.selectionMarkerFill
*/
@@ -8926,11 +8034,11 @@
* area, axis title and labels, title, subtitle or legend in top
* position).
*
* @type {Number}
* @sample {highcharts} highcharts/chart/spacingtop-100/
- * A top spacing of 100
+ * A top spacing of 100
* @sample {highcharts} highcharts/chart/spacingtop-10/
* Floating chart title makes the plot area align to the default
* spacingTop of 10.
* @sample {highstock} stock/chart/spacingtop/
* A top spacing of 100
@@ -8945,13 +8053,11 @@
* Additional CSS styles to apply inline to the container `div`. Note
* that since the default font styles are applied in the renderer, it
* is ignorant of the individual chart options and must be set globally.
*
* @type {CSSObject}
- * @see In [styled mode](http://www.highcharts.com/docs/chart-design-and-
- * style/style-by-css), general chart styles can be set with the `.highcharts-
- * root` class.
+ * @see In styled mode, general chart styles can be set with the `.highcharts-root` class.
* @sample {highcharts} highcharts/chart/style-serif-font/
* Using a serif type font
* @sample {highcharts} highcharts/css/em/
* Styled mode with relative font sizes
* @sample {highstock} stock/chart/style/
@@ -9002,25 +8108,22 @@
/**
* The chart's main title.
*
* @sample {highmaps} maps/title/title/ Title options demonstrated
- * @product highcharts highstock highmaps
*/
title: {
/**
* The title of the chart. To disable the title, set the `text` to
* `null`.
*
* @type {String}
* @sample {highcharts} highcharts/title/text/ Custom title
* @sample {highstock} stock/chart/title-text/ Custom title
- * @default {highcharts} Chart title
+ * @default {highcharts|highmaps} Chart title
* @default {highstock} null
- * @default {highmaps} Chart title
- * @product highcharts highstock highmaps
*/
text: 'Chart title',
/**
* The horizontal alignment of the title. Can be one of "left", "center"
@@ -9030,14 +8133,12 @@
* @type {String}
* @sample {highcharts} highcharts/title/align/ Aligned to the plot area (x = 70px = margin left - spacing left)
* @sample {highstock} stock/chart/title-align/ Aligned to the plot area (x = 50px = margin left - spacing left)
* @default center
* @since 2.0
- * @product highcharts highstock highmaps
*/
align: 'center',
- // floating: false,
/**
* The margin between the title and the plot area, or if a subtitle
* is present, the margin between the subtitle and the plot area.
*
@@ -9045,17 +8146,12 @@
* @sample {highcharts} highcharts/title/margin-50/ A chart title margin of 50
* @sample {highcharts} highcharts/title/margin-subtitle/ The same margin applied with a subtitle
* @sample {highstock} stock/chart/title-margin/ A chart title margin of 50
* @default 15
* @since 2.1
- * @product highcharts highstock highmaps
*/
margin: 15,
- // x: 0,
- // verticalAlign: 'top',
- // y: null,
- // style: {}, // defined inline
/**
* Adjustment made to the title width, normally to reserve space for
* the exporting burger menu.
*
@@ -9063,24 +8159,106 @@
* @sample {highcharts} highcharts/title/widthadjust/ Wider menu, greater padding
* @sample {highstock} highcharts/title/widthadjust/ Wider menu, greater padding
* @sample {highmaps} highcharts/title/widthadjust/ Wider menu, greater padding
* @default -44
* @since 4.2.5
- * @product highcharts highstock highmaps
*/
widthAdjust: -44
+ /**
+ * When the title is floating, the plot area will not move to make space
+ * for it.
+ *
+ * @type {Boolean}
+ * @sample {highcharts} highcharts/chart/zoomtype-none/ False by default
+ * @sample {highcharts} highcharts/title/floating/
+ * True - title on top of the plot area
+ * @sample {highstock} stock/chart/title-floating/
+ * True - title on top of the plot area
+ * @default false
+ * @since 2.1
+ * @apioption title.floating
+ */
+
+ /**
+ * CSS styles for the title. Use this for font styling, but use `align`,
+ * `x` and `y` for text alignment.
+ *
+ * In styled mode, the title style is given in the `.highcharts-title` class.
+ *
+ * @type {CSSObject}
+ * @sample {highcharts} highcharts/title/style/ Custom color and weight
+ * @sample {highcharts} highcharts/css/titles/ Styled mode
+ * @sample {highstock} stock/chart/title-style/ Custom color and weight
+ * @sample {highstock} highcharts/css/titles/ Styled mode
+ * @sample {highmaps} highcharts/css/titles/ Styled mode
+ * @default {highcharts,highmaps} { "color": "#333333", "fontSize": "18px" }
+ * @default {highstock} { "color": "#333333", "fontSize": "16px" }
+ * @apioption title.style
+ */
+
+ /**
+ * Whether to [use HTML](http://www.highcharts.com/docs/chart-concepts/labels-
+ * and-string-formatting#html) to render the text.
+ *
+ * @type {Boolean}
+ * @default false
+ * @apioption title.useHTML
+ */
+
+ /**
+ * The vertical alignment of the title. Can be one of `"top"`, `"middle"`
+ * and `"bottom"`. When a value is given, the title behaves as if [floating](#title.
+ * floating) were `true`.
+ *
+ * @validvalue ["top", "middle", "bottom"]
+ * @type {String}
+ * @sample {highcharts} highcharts/title/verticalalign/
+ * Chart title in bottom right corner
+ * @sample {highstock} stock/chart/title-verticalalign/
+ * Chart title in bottom right corner
+ * @since 2.1
+ * @apioption title.verticalAlign
+ */
+
+ /**
+ * The x position of the title relative to the alignment within chart.
+ * spacingLeft and chart.spacingRight.
+ *
+ * @type {Number}
+ * @sample {highcharts} highcharts/title/align/
+ * Aligned to the plot area (x = 70px = margin left - spacing left)
+ * @sample {highstock} stock/chart/title-align/
+ * Aligned to the plot area (x = 50px = margin left - spacing left)
+ * @default 0
+ * @since 2.0
+ * @apioption title.x
+ */
+
+ /**
+ * The y position of the title relative to the alignment within [chart.
+ * spacingTop](#chart.spacingTop) and [chart.spacingBottom](#chart.spacingBottom).
+ * By default it depends on the font size.
+ *
+ * @type {Number}
+ * @sample {highcharts} highcharts/title/y/
+ * Title inside the plot area
+ * @sample {highstock} stock/chart/title-verticalalign/
+ * Chart title in bottom right corner
+ * @since 2.0
+ * @apioption title.y
+ */
+
},
/**
* The chart's subtitle. This can be used both to display a subtitle below
* the main title, and to display random text anywhere in the chart. The
* subtitle can be updated after chart initialization through the
* `Chart.setTitle` method.
*
* @sample {highmaps} maps/title/subtitle/ Subtitle options demonstrated
- * @product highcharts highstock highmaps
*/
subtitle: {
/**
* The subtitle of the chart.
@@ -9088,11 +8266,10 @@
* @type {String}
* @sample {highcharts} highcharts/subtitle/text/ Custom subtitle
* @sample {highcharts} highcharts/subtitle/text-formatted/ Formatted and linked text.
* @sample {highstock} stock/chart/subtitle-text Custom subtitle
* @sample {highstock} stock/chart/subtitle-text-formatted Formatted and linked text.
- * @product highcharts highstock highmaps
*/
text: '',
/**
* The horizontal alignment of the subtitle. Can be one of "left",
@@ -9102,18 +8279,12 @@
* @type {String}
* @sample {highcharts} highcharts/subtitle/align/ Footnote at right of plot area
* @sample {highstock} stock/chart/subtitle-footnote Footnote at bottom right of plot area
* @default center
* @since 2.0
- * @product highcharts highstock highmaps
*/
align: 'center',
- // floating: false
- // x: 0,
- // verticalAlign: 'top',
- // y: null,
- // style: {}, // defined inline
/**
* Adjustment made to the subtitle width, normally to reserve space
* for the exporting burger menu.
*
@@ -9122,13 +8293,101 @@
* @sample {highcharts} highcharts/title/widthadjust/ Wider menu, greater padding
* @sample {highstock} highcharts/title/widthadjust/ Wider menu, greater padding
* @sample {highmaps} highcharts/title/widthadjust/ Wider menu, greater padding
* @default -44
* @since 4.2.5
- * @product highcharts highstock highmaps
*/
widthAdjust: -44
+
+ /**
+ * When the subtitle is floating, the plot area will not move to make
+ * space for it.
+ *
+ * @type {Boolean}
+ * @sample {highcharts} highcharts/subtitle/floating/
+ * Floating title and subtitle
+ * @sample {highstock} stock/chart/subtitle-footnote
+ * Footnote floating at bottom right of plot area
+ * @default false
+ * @since 2.1
+ * @apioption subtitle.floating
+ */
+
+ /**
+ * CSS styles for the title.
+ *
+ * In styled mode, the subtitle style is given in the `.highcharts-subtitle` class.
+ *
+ * @type {CSSObject}
+ * @sample {highcharts} highcharts/subtitle/style/
+ * Custom color and weight
+ * @sample {highcharts} highcharts/css/titles/
+ * Styled mode
+ * @sample {highstock} stock/chart/subtitle-style
+ * Custom color and weight
+ * @sample {highstock} highcharts/css/titles/
+ * Styled mode
+ * @sample {highmaps} highcharts/css/titles/
+ * Styled mode
+ * @default { "color": "#666666" }
+ * @apioption subtitle.style
+ */
+
+ /**
+ * Whether to [use HTML](http://www.highcharts.com/docs/chart-concepts/labels-
+ * and-string-formatting#html) to render the text.
+ *
+ * @type {Boolean}
+ * @default false
+ * @apioption subtitle.useHTML
+ */
+
+ /**
+ * The vertical alignment of the title. Can be one of "top", "middle"
+ * and "bottom". When a value is given, the title behaves as floating.
+ *
+ * @validvalue ["top", "middle", "bottom"]
+ * @type {String}
+ * @sample {highcharts} highcharts/subtitle/verticalalign/
+ * Footnote at the bottom right of plot area
+ * @sample {highstock} stock/chart/subtitle-footnote
+ * Footnote at the bottom right of plot area
+ * @default
+ * @since 2.1
+ * @apioption subtitle.verticalAlign
+ */
+
+ /**
+ * The x position of the subtitle relative to the alignment within chart.
+ * spacingLeft and chart.spacingRight.
+ *
+ * @type {Number}
+ * @sample {highcharts} highcharts/subtitle/align/
+ * Footnote at right of plot area
+ * @sample {highstock} stock/chart/subtitle-footnote
+ * Footnote at the bottom right of plot area
+ * @default 0
+ * @since 2.0
+ * @apioption subtitle.x
+ */
+
+ /**
+ * The y position of the subtitle relative to the alignment within chart.
+ * spacingTop and chart.spacingBottom. By default the subtitle is laid
+ * out below the title unless the title is floating.
+ *
+ * @type {Number}
+ * @sample {highcharts} highcharts/subtitle/verticalalign/
+ * Footnote at the bottom right of plot area
+ * @sample {highstock} stock/chart/subtitle-footnote
+ * Footnote at the bottom right of plot area
+ * @default {highcharts} null
+ * @default {highstock} null
+ * @default {highmaps}
+ * @since 2.0
+ * @apioption subtitle.y
+ */
},
/**
* The plotOptions is a wrapper object for config objects for each series
* type. The config objects for each series can also be overridden for
@@ -9137,39 +8396,55 @@
* Configuration options for the series are given in three levels. Options
* for all series in a chart are given in the [plotOptions.series](#plotOptions.
* series) object. Then options for all series of a specific type are
* given in the plotOptions of that type, for example plotOptions.line.
* Next, options for one single series are given in [the series array](#series).
- *
- * @product highcharts highstock highmaps
+ *
*/
plotOptions: {},
/**
* HTML labels that can be positioned anywhere in the chart area.
- *
- * @product highcharts highstock highmaps
+ *
*/
labels: {
- //items: [],
/**
+ * A HTML label that can be positioned anywhere in the chart area.
+ *
+ * @type {Array<Object>}
+ * @apioption labels.items
+ */
+
+ /**
+ * Inner HTML or text for the label.
+ *
+ * @type {String}
+ * @apioption labels.items.html
+ */
+
+ /**
+ * CSS styles for each label. To position the label, use left and top
+ * like this:
+ *
+ * <pre>style: {
+ * left: '100px',
+ * top: '100px'
+ * }</pre>
+ *
+ * @type {CSSObject}
+ * @apioption labels.items.style
+ */
+
+ /**
* Shared CSS styles for all labels.
*
* @type {CSSObject}
* @default { "color": "#333333" }
- * @product highcharts highstock highmaps
*/
style: {
- //font: defaultFont,
-
- /**
- */
position: 'absolute',
-
- /**
- */
color: '#333333'
}
},
/**
@@ -9187,19 +8462,43 @@
* Either as a gradient, or as multiple legend items for `dataClasses`.
*/
legend: {
/**
+ * The background color of the legend.
+ *
+ * @type {Color}
+ * @see In styled mode, the legend background fill can be applied with
+ * the `.highcharts-legend-box` class.
+ * @sample {highcharts} highcharts/legend/backgroundcolor/ Yellowish background
+ * @sample {highstock} stock/legend/align/ Various legend options
+ * @sample {highmaps} maps/legend/border-background/ Border and background options
+ * @apioption legend.backgroundColor
+ */
+
+ /**
+ * The width of the drawn border around the legend.
+ *
+ * @type {Number}
+ * @see In styled mode, the legend border stroke width can be applied
+ * with the `.highcharts-legend-box` class.
+ * @sample {highcharts} highcharts/legend/borderwidth/ 2px border width
+ * @sample {highstock} stock/legend/align/ Various legend options
+ * @sample {highmaps} maps/legend/border-background/ Border and background options
+ * @default 0
+ * @apioption legend.borderWidth
+ */
+
+ /**
* Enable or disable the legend.
*
* @type {Boolean}
* @sample {highcharts} highcharts/legend/enabled-false/ Legend disabled
* @sample {highstock} stock/legend/align/ Various legend options
* @sample {highmaps} maps/legend/enabled-false/ Legend disabled
* @default {highstock} false
* @default {highmaps} true
- * @product highcharts highstock highmaps
*/
enabled: true,
/**
* The horizontal alignment of the legend box within the chart area.
@@ -9209,36 +8508,109 @@
* `layout` option will determine whether to place it above/below
* or on the side of the plot area.
*
* @validvalue ["left", "center", "right"]
* @type {String}
- * @sample {highcharts} highcharts/legend/align/ Legend at the right of the chart
- * @sample {highstock} stock/legend/align/ Various legend options
- * @sample {highmaps} maps/legend/alignment/ Legend alignment
- * @default center
+ * @sample {highcharts} highcharts/legend/align/
+ * Legend at the right of the chart
+ * @sample {highstock} stock/legend/align/
+ * Various legend options
+ * @sample {highmaps} maps/legend/alignment/
+ * Legend alignment
* @since 2.0
- * @product highcharts highstock highmaps
*/
align: 'center',
- //floating: false,
/**
+ * When the legend is floating, the plot area ignores it and is allowed
+ * to be placed below it.
+ *
+ * @type {Boolean}
+ * @sample {highcharts} highcharts/legend/floating-false/ False by default
+ * @sample {highcharts} highcharts/legend/floating-true/ True
+ * @sample {highmaps} maps/legend/alignment/ Floating legend
+ * @default false
+ * @since 2.1
+ * @apioption legend.floating
+ */
+
+ /**
* The layout of the legend items. Can be one of "horizontal" or "vertical".
*
* @validvalue ["horizontal", "vertical"]
* @type {String}
* @sample {highcharts} highcharts/legend/layout-horizontal/ Horizontal by default
* @sample {highcharts} highcharts/legend/layout-vertical/ Vertical
* @sample {highstock} stock/legend/layout-horizontal/ Horizontal by default
* @sample {highmaps} maps/legend/padding-itemmargin/ Vertical with data classes
* @sample {highmaps} maps/legend/layout-vertical/ Vertical with color axis gradient
* @default horizontal
- * @product highcharts highstock highmaps
*/
layout: 'horizontal',
/**
+ * In a legend with horizontal layout, the itemDistance defines the
+ * pixel distance between each item.
+ *
+ * @type {Number}
+ * @sample {highcharts} highcharts/legend/layout-horizontal/ 50px item distance
+ * @sample {highstock} highcharts/legend/layout-horizontal/ 50px item distance
+ * @default {highcharts} 20
+ * @default {highstock} 20
+ * @default {highmaps} 8
+ * @since 3.0.3
+ * @apioption legend.itemDistance
+ */
+
+ /**
+ * The pixel bottom margin for each legend item.
+ *
+ * @type {Number}
+ * @sample {highcharts} highcharts/legend/padding-itemmargin/ Padding and item margins demonstrated
+ * @sample {highstock} highcharts/legend/padding-itemmargin/ Padding and item margins demonstrated
+ * @sample {highmaps} maps/legend/padding-itemmargin/ Padding and item margins demonstrated
+ * @default 0
+ * @since 2.2.0
+ * @apioption legend.itemMarginBottom
+ */
+
+ /**
+ * The pixel top margin for each legend item.
+ *
+ * @type {Number}
+ * @sample {highcharts} highcharts/legend/padding-itemmargin/ Padding and item margins demonstrated
+ * @sample {highstock} highcharts/legend/padding-itemmargin/ Padding and item margins demonstrated
+ * @sample {highmaps} maps/legend/padding-itemmargin/ Padding and item margins demonstrated
+ * @default 0
+ * @since 2.2.0
+ * @apioption legend.itemMarginTop
+ */
+
+ /**
+ * The width for each legend item. This is useful in a horizontal layout
+ * with many items when you want the items to align vertically. .
+ *
+ * @type {Number}
+ * @sample {highcharts} highcharts/legend/itemwidth-default/ Null by default
+ * @sample {highcharts} highcharts/legend/itemwidth-80/ 80 for aligned legend items
+ * @default null
+ * @since 2.0
+ * @apioption legend.itemWidth
+ */
+
+ /**
+ * A [format string](http://www.highcharts.com/docs/chart-concepts/labels-
+ * and-string-formatting) for each legend label. Available variables
+ * relates to properties on the series, or the point in case of pies.
+ *
+ * @type {String}
+ * @default {name}
+ * @since 1.3
+ * @apioption legend.labelFormat
+ */
+
+ /**
* Callback function to format each of the series' labels. The `this`
* keyword refers to the series object, or the point object in case
* of pie charts. By default the series or point name is printed.
*
* @productdesc {highmaps}
@@ -9251,24 +8623,57 @@
* @context {Series|Point}
*/
labelFormatter: function() {
return this.name;
},
- //borderWidth: 0,
/**
+ * Line height for the legend items. Deprecated as of 2.1\. Instead,
+ * the line height for each item can be set using itemStyle.lineHeight,
+ * and the padding between items using itemMarginTop and itemMarginBottom.
+ *
+ * @type {Number}
+ * @sample {highcharts} highcharts/legend/lineheight/ Setting padding
+ * @default 16
+ * @since 2.0
+ * @product highcharts
+ * @apioption legend.lineHeight
+ */
+
+ /**
+ * If the plot area sized is calculated automatically and the legend
+ * is not floating, the legend margin is the space between the legend
+ * and the axis labels or plot area.
+ *
+ * @type {Number}
+ * @sample {highcharts} highcharts/legend/margin-default/ 12 pixels by default
+ * @sample {highcharts} highcharts/legend/margin-30/ 30 pixels
+ * @default 12
+ * @since 2.1
+ * @apioption legend.margin
+ */
+
+ /**
+ * Maximum pixel height for the legend. When the maximum height is extended,
+ * navigation will show.
+ *
+ * @type {Number}
+ * @default undefined
+ * @since 2.3.0
+ * @apioption legend.maxHeight
+ */
+
+ /**
* The color of the drawn border around the legend.
*
* @type {Color}
- * @see In [styled mode](http://www.highcharts.com/docs/chart-design-and-
- * style/style-by-css), the legend border stroke can be applied with
+ * @see In styled mode, the legend border stroke can be applied with
* the `.highcharts-legend-box` class.
* @sample {highcharts} highcharts/legend/bordercolor/ Brown border
* @sample {highstock} stock/legend/align/ Various legend options
* @sample {highmaps} maps/legend/border-background/ Border and background options
* @default #999999
- * @product highcharts highstock highmaps
*/
borderColor: '#999999',
/**
* The border corner radius of the legend.
@@ -9276,145 +8681,219 @@
* @type {Number}
* @sample {highcharts} highcharts/legend/borderradius-default/ Square by default
* @sample {highcharts} highcharts/legend/borderradius-round/ 5px rounded
* @sample {highmaps} maps/legend/border-background/ Border and background options
* @default 0
- * @product highcharts highstock highmaps
*/
borderRadius: 0,
/**
* Options for the paging or navigation appearing when the legend
* is overflown. Navigation works well on screen, but not in static
* exported images. One way of working around that is to [increase
* the chart height in export](http://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/highcharts/legend/navigation-
* enabled-false/).
- *
- * @product highcharts highstock highmaps
+ *
*/
navigation: {
/**
* The color for the active up or down arrow in the legend page navigation.
*
* @type {Color}
- * @see In [styled mode](http://www.highcharts.com/docs/chart-design-and-
- * style/style-by-css), the active arrow be styled with the `.highcharts-
- * legend-nav-active` class.
+ * @see In styled mode, the active arrow be styled with the `.highcharts-legend-nav-active` class.
* @sample {highcharts} highcharts/legend/navigation/ Legend page navigation demonstrated
* @sample {highstock} highcharts/legend/navigation/ Legend page navigation demonstrated
* @default #003399
* @since 2.2.4
- * @product highcharts highstock highmaps
*/
activeColor: '#003399',
/**
* The color of the inactive up or down arrow in the legend page
* navigation. .
*
* @type {Color}
- * @see In [styled mode](http://www.highcharts.com/docs/chart-design-and-
- * style/style-by-css), the inactive arrow be styled with the `.highcharts-
- * legend-nav-inactive` class.
- * @sample {highcharts} highcharts/legend/navigation/ Legend page navigation demonstrated
- * @sample {highstock} highcharts/legend/navigation/ Legend page navigation demonstrated
+ * @see In styled mode, the inactive arrow be styled with the
+ * `.highcharts-legend-nav-inactive` class.
+ * @sample {highcharts} highcharts/legend/navigation/
+ * Legend page navigation demonstrated
+ * @sample {highstock} highcharts/legend/navigation/
+ * Legend page navigation demonstrated
* @default {highcharts} #cccccc
* @default {highstock} #cccccc
* @default {highmaps} ##cccccc
* @since 2.2.4
- * @product highcharts highstock highmaps
*/
inactiveColor: '#cccccc'
- // animation: true,
- // arrowSize: 12
- // style: {} // text styles
+
+ /**
+ * How to animate the pages when navigating up or down. A value of `true`
+ * applies the default navigation given in the chart.animation option.
+ * Additional options can be given as an object containing values for
+ * easing and duration.
+ *
+ * @type {Boolean|Object}
+ * @sample {highcharts} highcharts/legend/navigation/
+ * Legend page navigation demonstrated
+ * @sample {highstock} highcharts/legend/navigation/
+ * Legend page navigation demonstrated
+ * @default true
+ * @since 2.2.4
+ * @apioption legend.navigation.animation
+ */
+
+ /**
+ * The pixel size of the up and down arrows in the legend paging
+ * navigation.
+ *
+ * @type {Number}
+ * @sample {highcharts} highcharts/legend/navigation/
+ * Legend page navigation demonstrated
+ * @sample {highstock} highcharts/legend/navigation/
+ * Legend page navigation demonstrated
+ * @default 12
+ * @since 2.2.4
+ * @apioption legend.navigation.arrowSize
+ */
+
+ /**
+ * Whether to enable the legend navigation. In most cases, disabling
+ * the navigation results in an unwanted overflow.
+ *
+ * See also the [adapt chart to legend](http://www.highcharts.com/plugin-
+ * registry/single/8/Adapt-Chart-To-Legend) plugin for a solution to
+ * extend the chart height to make room for the legend, optionally in
+ * exported charts only.
+ *
+ * @type {Boolean}
+ * @default true
+ * @since 4.2.4
+ * @apioption legend.navigation.enabled
+ */
+
+ /**
+ * Text styles for the legend page navigation.
+ *
+ * @type {CSSObject}
+ * @see In styled mode, the navigation items are styled with the
+ * `.highcharts-legend-navigation` class.
+ * @sample {highcharts} highcharts/legend/navigation/
+ * Legend page navigation demonstrated
+ * @sample {highstock} highcharts/legend/navigation/
+ * Legend page navigation demonstrated
+ * @since 2.2.4
+ * @apioption legend.navigation.style
+ */
},
- // margin: 20,
- // reversed: false,
- // backgroundColor: null,
- /*style: {
- padding: '5px'
- },*/
+ /**
+ * The inner padding of the legend box.
+ *
+ * @type {Number}
+ * @sample {highcharts} highcharts/legend/padding-itemmargin/
+ * Padding and item margins demonstrated
+ * @sample {highstock} highcharts/legend/padding-itemmargin/
+ * Padding and item margins demonstrated
+ * @sample {highmaps} maps/legend/padding-itemmargin/
+ * Padding and item margins demonstrated
+ * @default 8
+ * @since 2.2.0
+ * @apioption legend.padding
+ */
/**
+ * Whether to reverse the order of the legend items compared to the
+ * order of the series or points as defined in the configuration object.
+ *
+ * @type {Boolean}
+ * @see [yAxis.reversedStacks](#yAxis.reversedStacks),
+ * [series.legendIndex](#series.legendIndex)
+ * @sample {highcharts} highcharts/legend/reversed/
+ * Stacked bar with reversed legend
+ * @default false
+ * @since 1.2.5
+ * @apioption legend.reversed
+ */
+
+ /**
+ * Whether to show the symbol on the right side of the text rather than
+ * the left side. This is common in Arabic and Hebraic.
+ *
+ * @type {Boolean}
+ * @sample {highcharts} highcharts/legend/rtl/ Symbol to the right
+ * @default false
+ * @since 2.2
+ * @product highcharts highmaps
+ * @apioption legend.rtl
+ */
+
+ /**
+ * CSS styles for the legend area. In the 1.x versions the position
+ * of the legend area was determined by CSS. In 2.x, the position is
+ * determined by properties like `align`, `verticalAlign`, `x` and `y`,
+ * but the styles are still parsed for backwards compatibility.
+ *
+ * @type {CSSObject}
+ * @deprecated
+ * @product highcharts highstock
+ * @apioption legend.style
+ */
+
+
+
+ /**
* CSS styles for each legend item. Only a subset of CSS is supported,
* notably those options related to text. The default `textOverflow`
* property makes long texts truncate. Set it to `null` to wrap text
* instead. A `width` property can be added to control the text width.
*
* @type {CSSObject}
- * @see In [styled mode](http://www.highcharts.com/docs/chart-design-and-
- * style/style-by-css), the legend items can be styled with the `.
+ * @see In styled mode, the legend items can be styled with the `.
* highcharts-legend-item` class.
* @sample {highcharts} highcharts/legend/itemstyle/ Bold black text
* @sample {highmaps} maps/legend/itemstyle/ Item text styles
* @default { "color": "#333333", "cursor": "pointer", "fontSize": "12px", "fontWeight": "bold", "textOverflow": "ellipsis" }
- * @product highcharts highstock highmaps
*/
itemStyle: {
-
- /**
- */
color: '#333333',
-
- /**
- */
fontSize: '12px',
-
- /**
- */
fontWeight: 'bold',
-
- /**
- */
textOverflow: 'ellipsis'
},
/**
* CSS styles for each legend item in hover mode. Only a subset of
* CSS is supported, notably those options related to text. Properties
* are inherited from `style` unless overridden here.
*
* @type {CSSObject}
- * @see In [styled mode](http://www.highcharts.com/docs/chart-design-and-
- * style/style-by-css), the hovered legend items can be styled with
+ * @see In styled mode, the hovered legend items can be styled with
* the `.highcharts-legend-item:hover` pesudo-class.
* @sample {highcharts} highcharts/legend/itemhoverstyle/ Red on hover
* @sample {highmaps} maps/legend/itemstyle/ Item text styles
* @default { "color": "#000000" }
- * @product highcharts highstock highmaps
*/
itemHoverStyle: {
- //cursor: 'pointer', removed as of #601
-
- /**
- */
color: '#000000'
},
/**
* CSS styles for each legend item when the corresponding series or
* point is hidden. Only a subset of CSS is supported, notably those
* options related to text. Properties are inherited from `style`
* unless overridden here.
*
* @type {CSSObject}
- * @see In [styled mode](http://www.highcharts.com/docs/chart-design-and-
- * style/style-by-css), the hidden legend items can be styled with
+ * @see In styled mode, the hidden legend items can be styled with
* the `.highcharts-legend-item-hidden` class.
* @sample {highcharts} highcharts/legend/itemhiddenstyle/ Darker gray color
* @default { "color": "#cccccc" }
- * @product highcharts highstock highmaps
*/
itemHiddenStyle: {
-
- /**
- */
color: '#cccccc'
},
/**
* Whether to apply a drop shadow to the legend. A `backgroundColor`
@@ -9428,29 +8907,21 @@
* @sample {highstock} stock/legend/align/
* Various legend options
* @sample {highmaps} maps/legend/border-background/
* Border and background options
* @default false
- * @product highcharts highstock highmaps
*/
shadow: false,
/**
+ * Default styling for the checkbox next to a legend item when
+ * `showCheckbox` is true.
*/
itemCheckboxStyle: {
-
- /**
- */
position: 'absolute',
-
- /**
- */
width: '13px', // for IE precision
-
- /**
- */
height: '13px'
},
// itemWidth: undefined,
/**
@@ -9459,11 +8930,10 @@
* legend items.
*
* @type {Boolean}
* @default true
* @since 5.0.0
- * @product highcharts highstock highmaps
*/
squareSymbol: true,
/**
* The pixel height of the symbol for series types that use a rectangle
@@ -9538,11 +9008,10 @@
* item text.
*
* @type {Number}
* @sample {highcharts} highcharts/legend/symbolpadding/ Greater symbol width and padding
* @default 5
- * @product highcharts highstock highmaps
*/
symbolPadding: 5,
/**
* The vertical alignment of the legend box. Can be one of `top`,
@@ -9558,11 +9027,10 @@
* @sample {highcharts} highcharts/legend/verticalalign/ Legend 100px from the top of the chart
* @sample {highstock} stock/legend/align/ Various legend options
* @sample {highmaps} maps/legend/alignment/ Legend alignment
* @default bottom
* @since 2.0
- * @product highcharts highstock highmaps
*/
verticalAlign: 'bottom',
// width: undefined,
/**
@@ -9572,11 +9040,10 @@
*
* @type {Number}
* @sample {highcharts} highcharts/legend/width/ Aligned to the plot area
* @default 0
* @since 2.0
- * @product highcharts highstock highmaps
*/
x: 0,
/**
* The vertical offset of the legend relative to it's vertical alignment
@@ -9587,41 +9054,42 @@
* @sample {highcharts} highcharts/legend/verticalalign/ Legend 100px from the top of the chart
* @sample {highstock} stock/legend/align/ Various legend options
* @sample {highmaps} maps/legend/alignment/ Legend alignment
* @default 0
* @since 2.0
- * @product highcharts highstock highmaps
*/
y: 0,
/**
* A title to be added on top of the legend.
*
* @sample {highcharts} highcharts/legend/title/ Legend title
* @sample {highmaps} maps/legend/alignment/ Legend with title
* @since 3.0
- * @product highcharts highstock highmaps
*/
title: {
- //text: null,
+ /**
+ * A text or HTML string for the title.
+ *
+ * @type {String}
+ * @default null
+ * @since 3.0
+ * @apioption legend.title.text
+ */
+
/**
* Generic CSS styles for the legend title.
*
* @type {CSSObject}
- * @see In [styled mode](http://www.highcharts.com/docs/chart-design-and-
- * style/style-by-css), the legend title is styled with the `.highcharts-
- * legend-title` class.
+ * @see In styled mode, the legend title is styled with the
+ * `.highcharts-legend-title` class.
* @default {"fontWeight":"bold"}
* @since 3.0
- * @product highcharts highstock highmaps
*/
style: {
-
- /**
- */
fontWeight: 'bold'
}
}
},
@@ -9633,12 +9101,11 @@
* appears after an explicit call to `chart.showLoading()`. It is a
* utility for developers to communicate to the end user that something
* is going on, for example while retrieving new data via an XHR connection.
* The "Loading..." text itself is not part of this configuration
* object, but part of the `lang` object.
- *
- * @product highcharts highstock highmaps
+ *
*/
loading: {
/**
* The duration in milliseconds of the fade out effect.
@@ -9663,18 +9130,16 @@
/**
* CSS styles for the loading label `span`.
*
* @type {CSSObject}
- * @see In [styled mode](http://www.highcharts.com/docs/chart-design-and-
- * style/style-by-css), the loading label is styled with the
+ * @see In styled mode, the loading label is styled with the
* `.highcharts-legend-loading-inner` class.
* @sample {highcharts|highmaps} highcharts/loading/labelstyle/ Vertically centered
* @sample {highstock} stock/loading/general/ Label styles
* @default { "fontWeight": "bold", "position": "relative", "top": "45%" }
* @since 1.2.0
- * @product highcharts highstock highmaps
*/
labelStyle: {
fontWeight: 'bold',
position: 'relative',
top: '45%'
@@ -9682,13 +9147,11 @@
/**
* CSS styles for the loading screen that covers the plot area.
*
* @type {CSSObject}
- * @see In [styled mode](http://www.highcharts.com/docs/chart-design-and-
- * style/style-by-css), the loading label is styled with the `.highcharts-
- * legend-loading` class.
+ * @see In styled mode, the loading label is styled with the `.highcharts-legend-loading` class.
* @sample {highcharts|highmaps} highcharts/loading/style/ Gray plot area, white text
* @sample {highstock} stock/loading/general/ Gray plot area, white text
* @default { "position": "absolute", "backgroundColor": "#ffffff", "opacity": 0.5, "textAlign": "center" }
* @since 1.2.0
*/
@@ -9703,47 +9166,42 @@
/**
* Options for the tooltip that appears when the user hovers over a
* series or point.
- *
- * @product highcharts highstock highmaps
+ *
*/
tooltip: {
/**
* Enable or disable the tooltip.
*
* @type {Boolean}
* @sample {highcharts} highcharts/tooltip/enabled/ Disabled
* @sample {highcharts} highcharts/plotoptions/series-point-events-mouseover/ Disable tooltip and show values on chart instead
* @default true
- * @product highcharts highstock highmaps
*/
enabled: true,
/**
* Enable or disable animation of the tooltip. In slow legacy IE browsers
* the animation is disabled by default.
*
* @type {Boolean}
* @default true
* @since 2.3.0
- * @product highcharts highstock highmaps
*/
animation: svg,
- //crosshairs: null,
/**
* The radius of the rounded border corners.
*
* @type {Number}
* @sample {highcharts} highcharts/tooltip/bordercolor-default/ 5px by default
* @sample {highcharts} highcharts/tooltip/borderradius-0/ Square borders
* @sample {highmaps} maps/tooltip/background-border/ Background and border demo
* @default 3
- * @product highcharts highstock highmaps
*/
borderRadius: 3,
/**
* For series on a datetime axes, the date format in the tooltip's
@@ -9753,56 +9211,32 @@
* dateFormat).
*
* Defaults to:
*
* <pre>{
- * millisecond:"%A, %b %e, %H:%M:%S.%L",
- * second:"%A, %b %e, %H:%M:%S",
- * minute:"%A, %b %e, %H:%M",
- * hour:"%A, %b %e, %H:%M",
- * day:"%A, %b %e, %Y",
- * week:"Week from %A, %b %e, %Y",
- * month:"%B %Y",
- * year:"%Y"
+ * millisecond:"%A, %b %e, %H:%M:%S.%L",
+ * second:"%A, %b %e, %H:%M:%S",
+ * minute:"%A, %b %e, %H:%M",
+ * hour:"%A, %b %e, %H:%M",
+ * day:"%A, %b %e, %Y",
+ * week:"Week from %A, %b %e, %Y",
+ * month:"%B %Y",
+ * year:"%Y"
* }</pre>
*
* @type {Object}
* @see [xAxis.dateTimeLabelFormats](#xAxis.dateTimeLabelFormats)
* @product highcharts highstock
*/
dateTimeLabelFormats: {
-
- /**
- */
millisecond: '%A, %b %e, %H:%M:%S.%L',
-
- /**
- */
second: '%A, %b %e, %H:%M:%S',
-
- /**
- */
minute: '%A, %b %e, %H:%M',
-
- /**
- */
hour: '%A, %b %e, %H:%M',
-
- /**
- */
day: '%A, %b %e, %Y',
-
- /**
- */
week: 'Week from %A, %b %e, %Y',
-
- /**
- */
month: '%B %Y',
-
- /**
- */
year: '%Y'
},
/**
* A string to append to the tooltip format.
@@ -9813,28 +9247,20 @@
* @default false
* @since 2.2
* @product highcharts highmaps
*/
footerFormat: '',
- //formatter: defaultFormatter,
- /* todo: em font-size when finished comparing against HC4
- headerFormat: '<span style="font-size: 0.85em">{point.key}</span><br/>',
- */
/**
* Padding inside the tooltip, in pixels.
*
* @type {Number}
* @default 8
* @since 5.0.0
- * @product highcharts highstock highmaps
*/
padding: 8,
- //shape: 'callout',
- //shared: false,
-
/**
* Proximity snap for graphs or single points. It defaults to 10 for
* mouse-powered devices and 25 for touch devices.
*
* Note that in most cases the whole plot area captures the mouse
@@ -9854,44 +9280,38 @@
/**
* The background color or gradient for the tooltip.
*
- * In [styled mode](http://www.highcharts.com/docs/chart-design-and-
- * style/style-by-css), the stroke width is set in the `.highcharts-
- * tooltip-box` class.
+ * In styled mode, the stroke width is set in the `.highcharts-tooltip-box` class.
*
* @type {Color}
* @sample {highcharts} highcharts/tooltip/backgroundcolor-solid/ Yellowish background
* @sample {highcharts} highcharts/tooltip/backgroundcolor-gradient/ Gradient
* @sample {highcharts} highcharts/css/tooltip-border-background/ Tooltip in styled mode
* @sample {highstock} stock/tooltip/general/ Custom tooltip
* @sample {highstock} highcharts/css/tooltip-border-background/ Tooltip in styled mode
* @sample {highmaps} maps/tooltip/background-border/ Background and border demo
* @sample {highmaps} highcharts/css/tooltip-border-background/ Tooltip in styled mode
* @default rgba(247,247,247,0.85)
- * @product highcharts highstock highmaps
*/
backgroundColor: color('#f7f7f7').setOpacity(0.85).get(),
/**
* The pixel width of the tooltip border.
*
- * In [styled mode](http://www.highcharts.com/docs/chart-design-and-
- * style/style-by-css), the stroke width is set in the `.highcharts-
- * tooltip-box` class.
+ * In styled mode, the stroke width is set in the `.highcharts-tooltip-box` class.
*
* @type {Number}
* @sample {highcharts} highcharts/tooltip/bordercolor-default/ 2px by default
* @sample {highcharts} highcharts/tooltip/borderwidth/ No border (shadow only)
* @sample {highcharts} highcharts/css/tooltip-border-background/ Tooltip in styled mode
* @sample {highstock} stock/tooltip/general/ Custom tooltip
* @sample {highstock} highcharts/css/tooltip-border-background/ Tooltip in styled mode
* @sample {highmaps} maps/tooltip/background-border/ Background and border demo
* @sample {highmaps} highcharts/css/tooltip-border-background/ Tooltip in styled mode
* @default 1
- * @product highcharts highstock highmaps
*/
borderWidth: 1,
/**
* The HTML of the tooltip header line. Variables are enclosed by
@@ -9899,18 +9319,16 @@
* `series.color` and other members from the `point` and `series`
* objects. The `point.key` variable contains the category name, x
* value or datetime string depending on the type of axis. For datetime
* axes, the `point.key` date format can be set using tooltip.xDateFormat.
*
- *
- * Defaults to `<span style="font-size: 10px">{point.key}</span><br/>`
- *
* @type {String}
- * @sample {highcharts} highcharts/tooltip/footerformat/ A HTML table in the tooltip
- * @sample {highstock} highcharts/tooltip/footerformat/ A HTML table in the tooltip
+ * @sample {highcharts} highcharts/tooltip/footerformat/
+ * A HTML table in the tooltip
+ * @sample {highstock} highcharts/tooltip/footerformat/
+ * A HTML table in the tooltip
* @sample {highmaps} maps/tooltip/format/ Format demo
- * @product highcharts highstock highmaps
*/
headerFormat: '<span style="font-size: 10px">{point.key}</span><br/>',
/**
* The HTML of the point's line in the tooltip. Variables are enclosed
@@ -9918,20 +9336,18 @@
* name and series.color and other properties on the same form. Furthermore,
* point.y can be extended by the `tooltip.valuePrefix` and `tooltip.
* valueSuffix` variables. This can also be overridden for each series,
* which makes it a good hook for displaying units.
*
- * In [styled mode](http://www.highcharts.com/docs/chart-design-and-
- * style/style-by-css), the dot is colored by a class name rather
+ * In styled mode, the dot is colored by a class name rather
* than the point color.
*
* @type {String}
* @sample {highcharts} highcharts/tooltip/pointformat/ A different point format with value suffix
* @sample {highmaps} maps/tooltip/format/ Format demo
* @default <span style="color:{point.color}">\u25CF</span> {series.name}: <b>{point.y}</b><br/>
* @since 2.2
- * @product highcharts highstock highmaps
*/
pointFormat: '<span style="color:{point.color}">\u25CF</span> {series.name}: <b>{point.y}</b><br/>',
/**
* Whether to apply a drop shadow to the tooltip.
@@ -9939,58 +9355,322 @@
* @type {Boolean}
* @sample {highcharts} highcharts/tooltip/bordercolor-default/ True by default
* @sample {highcharts} highcharts/tooltip/shadow/ False
* @sample {highmaps} maps/tooltip/positioner/ Fixed tooltip position, border and shadow disabled
* @default true
- * @product highcharts highstock highmaps
*/
shadow: true,
/**
* CSS styles for the tooltip. The tooltip can also be styled through
* the CSS class `.highcharts-tooltip`.
*
* @type {CSSObject}
* @sample {highcharts} highcharts/tooltip/style/ Greater padding, bold text
* @default { "color": "#333333", "cursor": "default", "fontSize": "12px", "pointerEvents": "none", "whiteSpace": "nowrap" }
- * @product highcharts highstock highmaps
*/
style: {
-
- /**
- */
color: '#333333',
-
- /**
- */
cursor: 'default',
-
- /**
- */
fontSize: '12px',
-
- /**
- */
pointerEvents: 'none', // #1686 http://caniuse.com/#feat=pointer-events
-
- /**
- */
whiteSpace: 'nowrap'
}
- //xDateFormat: '%A, %b %e, %Y',
- //valueDecimals: null,
- //valuePrefix: '',
- //valueSuffix: ''
+
+
+ /**
+ * The color of the tooltip border. When `null`, the border takes the
+ * color of the corresponding series or point.
+ *
+ * @type {Color}
+ * @sample {highcharts} highcharts/tooltip/bordercolor-default/
+ * Follow series by default
+ * @sample {highcharts} highcharts/tooltip/bordercolor-black/
+ * Black border
+ * @sample {highstock} stock/tooltip/general/
+ * Styled tooltip
+ * @sample {highmaps} maps/tooltip/background-border/
+ * Background and border demo
+ * @default null
+ * @apioption tooltip.borderColor
+ */
+
+ /**
+ * Since 4.1, the crosshair definitions are moved to the Axis object
+ * in order for a better separation from the tooltip. See [xAxis.crosshair](#xAxis.
+ * crosshair)<a>.</a>
+ *
+ * @type {Mixed}
+ * @deprecated
+ * @sample {highcharts} highcharts/tooltip/crosshairs-x/
+ * Enable a crosshair for the x value
+ * @default true
+ * @apioption tooltip.crosshairs
+ */
+
+ /**
+ * Whether the tooltip should follow the mouse as it moves across columns,
+ * pie slices and other point types with an extent. By default it behaves
+ * this way for scatter, bubble and pie series by override in the `plotOptions`
+ * for those series types.
+ *
+ * For touch moves to behave the same way, [followTouchMove](#tooltip.
+ * followTouchMove) must be `true` also.
+ *
+ * @type {Boolean}
+ * @default {highcharts} false
+ * @default {highstock} false
+ * @default {highmaps} true
+ * @since 3.0
+ * @apioption tooltip.followPointer
+ */
+
+ /**
+ * Whether the tooltip should follow the finger as it moves on a touch
+ * device. If this is `true` and [chart.panning](#chart.panning) is
+ * set,`followTouchMove` will take over one-finger touches, so the user
+ * needs to use two fingers for zooming and panning.
+ *
+ * @type {Boolean}
+ * @default {highcharts} true
+ * @default {highstock} true
+ * @default {highmaps} false
+ * @since 3.0.1
+ * @apioption tooltip.followTouchMove
+ */
+
+ /**
+ * Callback function to format the text of the tooltip from scratch. Return
+ * `false` to disable tooltip for a specific point on series.
+ *
+ * A subset of HTML is supported. Unless `useHTML` is true, the HTML of the
+ * tooltip is parsed and converted to SVG, therefore this isn't a complete HTML
+ * renderer. The following tags are supported: `<b>`, `<strong>`, `<i>`, `<em>`,
+ * `<br/>`, `<span>`. Spans can be styled with a `style` attribute,
+ * but only text-related CSS that is shared with SVG is handled.
+ *
+ * Since version 2.1 the tooltip can be shared between multiple series
+ * through the `shared` option. The available data in the formatter
+ * differ a bit depending on whether the tooltip is shared or not. In
+ * a shared tooltip, all properties except `x`, which is common for
+ * all points, are kept in an array, `this.points`.
+ *
+ * Available data are:
+ *
+ * <dl>
+ *
+ * <dt>this.percentage (not shared) / this.points[i].percentage (shared)</dt>
+ *
+ * <dd>Stacked series and pies only. The point's percentage of the total.
+ * </dd>
+ *
+ * <dt>this.point (not shared) / this.points[i].point (shared)</dt>
+ *
+ * <dd>The point object. The point name, if defined, is available through
+ * `this.point.name`.</dd>
+ *
+ * <dt>this.points</dt>
+ *
+ * <dd>In a shared tooltip, this is an array containing all other properties
+ * for each point.</dd>
+ *
+ * <dt>this.series (not shared) / this.points[i].series (shared)</dt>
+ *
+ * <dd>The series object. The series name is available through
+ * `this.series.name`.</dd>
+ *
+ * <dt>this.total (not shared) / this.points[i].total (shared)</dt>
+ *
+ * <dd>Stacked series only. The total value at this point's x value.
+ * </dd>
+ *
+ * <dt>this.x</dt>
+ *
+ * <dd>The x value. This property is the same regardless of the tooltip
+ * being shared or not.</dd>
+ *
+ * <dt>this.y (not shared) / this.points[i].y (shared)</dt>
+ *
+ * <dd>The y value.</dd>
+ *
+ * </dl>
+ *
+ * @type {Function}
+ * @sample {highcharts} highcharts/tooltip/formatter-simple/
+ * Simple string formatting
+ * @sample {highcharts} highcharts/tooltip/formatter-shared/
+ * Formatting with shared tooltip
+ * @sample {highstock} stock/tooltip/formatter/
+ * Formatting with shared tooltip
+ * @sample {highmaps} maps/tooltip/formatter/
+ * String formatting
+ * @apioption tooltip.formatter
+ */
+
+ /**
+ * The number of milliseconds to wait until the tooltip is hidden when
+ * mouse out from a point or chart.
+ *
+ * @type {Number}
+ * @default 500
+ * @since 3.0
+ * @product highcharts highmaps
+ * @apioption tooltip.hideDelay
+ */
+
+ /**
+ * A callback function for formatting the HTML output for a single point
+ * in the tooltip. Like the `pointFormat` string, but with more flexibility.
+ *
+ * @type {Function}
+ * @context Point
+ * @since 4.1.0
+ * @apioption tooltip.pointFormatter
+ */
+
+ /**
+ * A callback function to place the tooltip in a default position. The
+ * callback receives three parameters: `labelWidth`, `labelHeight` and
+ * `point`, where point contains values for `plotX` and `plotY` telling
+ * where the reference point is in the plot area. Add `chart.plotLeft`
+ * and `chart.plotTop` to get the full coordinates.
+ *
+ * The return should be an object containing x and y values, for example
+ * `{ x: 100, y: 100 }`.
+ *
+ * @type {Function}
+ * @sample {highcharts} highcharts/tooltip/positioner/ A fixed tooltip position
+ * @sample {highstock} stock/tooltip/positioner/ A fixed tooltip position on top of the chart
+ * @sample {highmaps} maps/tooltip/positioner/ A fixed tooltip position
+ * @since 2.2.4
+ * @apioption tooltip.positioner
+ */
+
+ /**
+ * The name of a symbol to use for the border around the tooltip.
+ *
+ * @type {String}
+ * @default callout
+ * @validvalue ["callout", "square"]
+ * @since 4.0
+ * @apioption tooltip.shape
+ */
+
+ /**
+ * When the tooltip is shared, the entire plot area will capture mouse
+ * movement or touch events. Tooltip texts for series types with ordered
+ * data (not pie, scatter, flags etc) will be shown in a single bubble.
+ * This is recommended for single series charts and for tablet/mobile
+ * optimized charts.
+ *
+ * See also [tooltip.split](#tooltip.split), that is better suited for
+ * charts with many series, especially line-type series.
+ *
+ * @type {Boolean}
+ * @sample {highcharts} highcharts/tooltip/shared-false/ False by default
+ * @sample {highcharts} highcharts/tooltip/shared-true/ True
+ * @sample {highcharts} highcharts/tooltip/shared-x-crosshair/ True with x axis crosshair
+ * @sample {highcharts} highcharts/tooltip/shared-true-mixed-types/ True with mixed series types
+ * @default false
+ * @since 2.1
+ * @product highcharts highstock
+ * @apioption tooltip.shared
+ */
+
+ /**
+ * Split the tooltip into one label per series, with the header close
+ * to the axis. This is recommended over [shared](#tooltip.shared) tooltips
+ * for charts with multiple line series, generally making them easier
+ * to read.
+ *
+ * @productdesc {highstock} In Highstock, tooltips are split by default
+ * since v6.0.0. Stock charts typically contain multi-dimension points
+ * and multiple panes, making split tooltips the preferred layout over
+ * the previous `shared` tooltip.
+ *
+ * @type {Boolean}
+ * @sample {highcharts} highcharts/tooltip/split/ Split tooltip
+ * @sample {highstock} highcharts/tooltip/split/ Split tooltip
+ * @sample {highmaps} highcharts/tooltip/split/ Split tooltip
+ * @default {highcharts} false
+ * @default {highstock} true
+ * @product highcharts highstock
+ * @since 5.0.0
+ * @apioption tooltip.split
+ */
+
+ /**
+ * Use HTML to render the contents of the tooltip instead of SVG. Using
+ * HTML allows advanced formatting like tables and images in the tooltip.
+ * It is also recommended for rtl languages as it works around rtl
+ * bugs in early Firefox.
+ *
+ * @type {Boolean}
+ * @sample {highcharts} highcharts/tooltip/footerformat/ A table for value alignment
+ * @sample {highcharts} highcharts/tooltip/fullhtml/ Full HTML tooltip
+ * @sample {highstock} highcharts/tooltip/footerformat/ A table for value alignment
+ * @sample {highstock} highcharts/tooltip/fullhtml/ Full HTML tooltip
+ * @sample {highmaps} maps/tooltip/usehtml/ Pure HTML tooltip
+ * @default false
+ * @since 2.2
+ * @apioption tooltip.useHTML
+ */
+
+ /**
+ * How many decimals to show in each series' y value. This is overridable
+ * in each series' tooltip options object. The default is to preserve
+ * all decimals.
+ *
+ * @type {Number}
+ * @sample {highcharts} highcharts/tooltip/valuedecimals/ Set decimals, prefix and suffix for the value
+ * @sample {highstock} highcharts/tooltip/valuedecimals/ Set decimals, prefix and suffix for the value
+ * @sample {highmaps} maps/tooltip/valuedecimals/ Set decimals, prefix and suffix for the value
+ * @since 2.2
+ * @apioption tooltip.valueDecimals
+ */
+
+ /**
+ * A string to prepend to each series' y value. Overridable in each
+ * series' tooltip options object.
+ *
+ * @type {String}
+ * @sample {highcharts} highcharts/tooltip/valuedecimals/ Set decimals, prefix and suffix for the value
+ * @sample {highstock} highcharts/tooltip/valuedecimals/ Set decimals, prefix and suffix for the value
+ * @sample {highmaps} maps/tooltip/valuedecimals/ Set decimals, prefix and suffix for the value
+ * @since 2.2
+ * @apioption tooltip.valuePrefix
+ */
+
+ /**
+ * A string to append to each series' y value. Overridable in each series'
+ * tooltip options object.
+ *
+ * @type {String}
+ * @sample {highcharts} highcharts/tooltip/valuedecimals/ Set decimals, prefix and suffix for the value
+ * @sample {highstock} highcharts/tooltip/valuedecimals/ Set decimals, prefix and suffix for the value
+ * @sample {highmaps} maps/tooltip/valuedecimals/ Set decimals, prefix and suffix for the value
+ * @since 2.2
+ * @apioption tooltip.valueSuffix
+ */
+
+ /**
+ * The format for the date in the tooltip header if the X axis is a
+ * datetime axis. The default is a best guess based on the smallest
+ * distance between points in the chart.
+ *
+ * @type {String}
+ * @sample {highcharts} highcharts/tooltip/xdateformat/ A different format
+ * @product highcharts highstock
+ * @apioption tooltip.xDateFormat
+ */
},
/**
* Highchart by default puts a credits label in the lower right corner
* of the chart. This can be changed using these options.
- *
- * @product highcharts highstock highmaps
*/
credits: {
/**
* Whether to show the credits text.
@@ -9998,11 +9678,10 @@
* @type {Boolean}
* @sample {highcharts} highcharts/credits/enabled-false/ Credits disabled
* @sample {highstock} stock/credits/enabled/ Credits disabled
* @sample {highmaps} maps/credits/enabled-false/ Credits disabled
* @default true
- * @product highcharts highstock highmaps
*/
enabled: true,
/**
* The URL for the credits label.
@@ -10011,11 +9690,10 @@
* @sample {highcharts} highcharts/credits/href/ Custom URL and text
* @sample {highmaps} maps/credits/customized/ Custom URL and text
* @default {highcharts} http://www.highcharts.com
* @default {highstock} "http://www.highcharts.com"
* @default {highmaps} http://www.highcharts.com
- * @product highcharts highstock highmaps
*/
href: 'http://www.highcharts.com',
/**
* Position configuration for the credits label.
@@ -10024,76 +9702,60 @@
* @sample {highcharts} highcharts/credits/position-left/ Left aligned
* @sample {highcharts} highcharts/credits/position-left/ Left aligned
* @sample {highmaps} maps/credits/customized/ Left aligned
* @sample {highmaps} maps/credits/customized/ Left aligned
* @since 2.1
- * @product highcharts highstock highmaps
*/
position: {
/**
* Horizontal alignment of the credits.
*
* @validvalue ["left", "center", "right"]
* @type {String}
* @default right
- * @product highcharts highstock highmaps
*/
align: 'right',
/**
* Horizontal pixel offset of the credits.
*
* @type {Number}
* @default -10
- * @product highcharts highstock highmaps
*/
x: -10,
/**
* Vertical alignment of the credits.
*
* @validvalue ["top", "middle", "bottom"]
* @type {String}
* @default bottom
- * @product highcharts highstock highmaps
*/
verticalAlign: 'bottom',
/**
* Vertical pixel offset of the credits.
*
* @type {Number}
* @default -5
- * @product highcharts highstock highmaps
*/
y: -5
},
/**
* CSS styles for the credits label.
*
* @type {CSSObject}
- * @see In [styled mode](http://www.highcharts.com/docs/chart-design-and-
- * style/style-by-css), credits styles can be set with the `.highcharts-
- * credits` class.
+ * @see In styled mode, credits styles can be set with the
+ * `.highcharts-credits` class.
* @default { "cursor": "pointer", "color": "#999999", "fontSize": "10px" }
- * @product highcharts highstock highmaps
*/
style: {
-
- /**
- */
cursor: 'pointer',
-
- /**
- */
color: '#999999',
-
- /**
- */
fontSize: '9px'
},
/**
@@ -10155,11 +9817,14 @@
function setTimeMethods() {
var globalOptions = H.defaultOptions.global,
Date,
useUTC = globalOptions.useUTC,
GET = useUTC ? 'getUTC' : 'get',
- SET = useUTC ? 'setUTC' : 'set';
+ SET = useUTC ? 'setUTC' : 'set',
+ setters = ['Minutes', 'Hours', 'Day', 'Date', 'Month', 'FullYear'],
+ getters = setters.concat(['Milliseconds', 'Seconds']),
+ n;
H.Date = Date = globalOptions.Date || win.Date; // Allow using a different Date class
Date.hcTimezoneOffset = useUTC && globalOptions.timezoneOffset;
Date.hcGetTimezoneOffset = getTimezoneOffsetOption();
Date.hcMakeTime = function(year, month, date, hours, minutes, seconds) {
@@ -10177,16 +9842,19 @@
pick(seconds, 0)
).getTime();
}
return d;
};
- each(['Minutes', 'Hours', 'Day', 'Date', 'Month', 'FullYear'], function(s) {
- Date['hcGet' + s] = GET + s;
- });
- each(['Milliseconds', 'Seconds', 'Minutes', 'Hours', 'Date', 'Month', 'FullYear'], function(s) {
- Date['hcSet' + s] = SET + s;
- });
+
+ // Dynamically set setters and getters. Use for loop, H.each is not yet
+ // overridden in oldIE.
+ for (n = 0; n < setters.length; n++) {
+ Date['hcGet' + setters[n]] = GET + setters[n];
+ }
+ for (n = 0; n < getters.length; n++) {
+ Date['hcSet' + getters[n]] = SET + getters[n];
+ }
}
/**
* Merge the default options with custom options and return the new options
* structure. Commonly used for defining reusable templates.
@@ -10276,16 +9944,17 @@
pos,
label = tick.label,
tickPositionInfo = tickPositions.info,
dateTimeLabelFormat;
- // Set the datetime label format. If a higher rank is set for this position, use that. If not,
- // use the general format.
+ // Set the datetime label format. If a higher rank is set for this
+ // position, use that. If not, use the general format.
if (axis.isDatetimeAxis && tickPositionInfo) {
dateTimeLabelFormat =
options.dateTimeLabelFormats[
- tickPositionInfo.higherRanks[pos] || tickPositionInfo.unitName
+ tickPositionInfo.higherRanks[pos] ||
+ tickPositionInfo.unitName
];
}
// set properties for access in render method
tick.isFirst = isFirst;
tick.isLast = isLast;
@@ -10299,13 +9968,10 @@
dateTimeLabelFormat: dateTimeLabelFormat,
value: axis.isLog ? correctFloat(axis.lin2log(value)) : value,
pos: pos
});
- // prepare CSS
- //css = width && { width: Math.max(1, Math.round(width - 2 * (labelOptions.padding || 10))) + 'px' };
-
// first call
if (!defined(label)) {
tick.label = label =
defined(str) && labelOptions.enabled ?
@@ -10314,18 +9980,22 @@
0,
0,
labelOptions.useHTML
)
- // without position absolute, IE export sometimes is wrong
+ // without position absolute, IE export sometimes is
+ // wrong.
.css(merge(labelOptions.style))
.add(axis.labelGroup) :
null;
- tick.labelLength = label && label.getBBox().width; // Un-rotated length
- tick.rotation = 0; // Base value to detect change for new calls to getBBox
+ // Un-rotated length
+ tick.labelLength = label && label.getBBox().width;
+ // Base value to detect change for new calls to getBBox
+ tick.rotation = 0;
+
// update
} else if (label) {
label.attr({
text: str
});
@@ -10340,20 +10010,23 @@
this.label.getBBox()[this.axis.horiz ? 'height' : 'width'] :
0;
},
/**
- * Handle the label overflow by adjusting the labels to the left and right edge, or
- * hide them if they collide into the neighbour label.
+ * Handle the label overflow by adjusting the labels to the left and right
+ * edge, or hide them if they collide into the neighbour label.
*/
handleOverflow: function(xy) {
var axis = this.axis,
pxPos = xy.x,
chartWidth = axis.chart.chartWidth,
spacing = axis.chart.spacing,
leftBound = pick(axis.labelLeft, Math.min(axis.pos, spacing[3])),
- rightBound = pick(axis.labelRight, Math.max(axis.pos + axis.len, chartWidth - spacing[1])),
+ rightBound = pick(
+ axis.labelRight,
+ Math.max(axis.pos + axis.len, chartWidth - spacing[1])
+ ),
label = this.label,
rotation = this.rotation,
factor = {
left: 0,
center: 0.5,
@@ -10367,40 +10040,58 @@
leftPos,
rightPos,
textWidth,
css = {};
- // Check if the label overshoots the chart spacing box. If it does, move it.
- // If it now overshoots the slotWidth, add ellipsis.
+ // Check if the label overshoots the chart spacing box. If it does, move
+ // it. If it now overshoots the slotWidth, add ellipsis.
if (!rotation) {
leftPos = pxPos - factor * labelWidth;
rightPos = pxPos + (1 - factor) * labelWidth;
if (leftPos < leftBound) {
modifiedSlotWidth = xy.x + modifiedSlotWidth * (1 - factor) - leftBound;
} else if (rightPos > rightBound) {
- modifiedSlotWidth = rightBound - xy.x + modifiedSlotWidth * factor;
+ modifiedSlotWidth =
+ rightBound - xy.x + modifiedSlotWidth * factor;
goRight = -1;
}
modifiedSlotWidth = Math.min(slotWidth, modifiedSlotWidth); // #4177
if (modifiedSlotWidth < slotWidth && axis.labelAlign === 'center') {
- xy.x += goRight * (slotWidth - modifiedSlotWidth - xCorrection *
- (slotWidth - Math.min(labelWidth, modifiedSlotWidth)));
+ xy.x += (
+ goRight *
+ (
+ slotWidth -
+ modifiedSlotWidth -
+ xCorrection * (
+ slotWidth - Math.min(labelWidth, modifiedSlotWidth)
+ )
+ )
+ );
}
- // If the label width exceeds the available space, set a text width to be
- // picked up below. Also, if a width has been set before, we need to set a new
- // one because the reported labelWidth will be limited by the box (#3938).
- if (labelWidth > modifiedSlotWidth || (axis.autoRotation && (label.styles || {}).width)) {
+ // If the label width exceeds the available space, set a text width
+ // to be picked up below. Also, if a width has been set before, we
+ // need to set a new one because the reported labelWidth will be
+ // limited by the box (#3938).
+ if (
+ labelWidth > modifiedSlotWidth ||
+ (axis.autoRotation && (label.styles || {}).width)
+ ) {
textWidth = modifiedSlotWidth;
}
- // Add ellipsis to prevent rotated labels to be clipped against the edge of the chart
+ // Add ellipsis to prevent rotated labels to be clipped against the edge
+ // of the chart
} else if (rotation < 0 && pxPos - factor * labelWidth < leftBound) {
- textWidth = Math.round(pxPos / Math.cos(rotation * deg2rad) - leftBound);
+ textWidth = Math.round(
+ pxPos / Math.cos(rotation * deg2rad) - leftBound
+ );
} else if (rotation > 0 && pxPos + factor * labelWidth > rightBound) {
- textWidth = Math.round((chartWidth - pxPos) / Math.cos(rotation * deg2rad));
+ textWidth = Math.round(
+ (chartWidth - pxPos) / Math.cos(rotation * deg2rad)
+ );
}
if (textWidth) {
css.width = textWidth;
if (!(axis.options.labels.style || {}).textOverflow) {
@@ -10418,26 +10109,60 @@
chart = axis.chart,
cHeight = (old && chart.oldChartHeight) || chart.chartHeight;
return {
x: horiz ?
- axis.translate(pos + tickmarkOffset, null, null, old) + axis.transB : axis.left + axis.offset +
- (axis.opposite ?
- ((old && chart.oldChartWidth) || chart.chartWidth) - axis.right - axis.left :
- 0
+ (
+ axis.translate(pos + tickmarkOffset, null, null, old) +
+ axis.transB
+ ) :
+ (
+ axis.left +
+ axis.offset +
+ (
+ axis.opposite ?
+ (
+ (
+ (old && chart.oldChartWidth) ||
+ chart.chartWidth
+ ) -
+ axis.right -
+ axis.left
+ ) :
+ 0
+ )
),
y: horiz ?
- cHeight - axis.bottom + axis.offset - (axis.opposite ? axis.height : 0) : cHeight - axis.translate(pos + tickmarkOffset, null, null, old) - axis.transB
+ (
+ cHeight -
+ axis.bottom +
+ axis.offset -
+ (axis.opposite ? axis.height : 0)
+ ) :
+ (
+ cHeight -
+ axis.translate(pos + tickmarkOffset, null, null, old) -
+ axis.transB
+ )
};
},
/**
* Get the x, y position of the tick label
*/
- getLabelPosition: function(x, y, label, horiz, labelOptions, tickmarkOffset, index, step) {
+ getLabelPosition: function(
+ x,
+ y,
+ label,
+ horiz,
+ labelOptions,
+ tickmarkOffset,
+ index,
+ step
+ ) {
var axis = this.axis,
transA = axis.transA,
reversed = axis.reversed,
staggerLines = axis.staggerLines,
rotCorr = axis.tickRotCorr || {
@@ -10452,11 +10177,12 @@
yOffset = label.rotation ? -8 : -label.getBBox().height;
} else if (axis.side === 2) {
yOffset = rotCorr.y + 8;
} else {
// #3140, #3140
- yOffset = Math.cos(label.rotation * deg2rad) * (rotCorr.y - label.getBBox(false, 0).height / 2);
+ yOffset = Math.cos(label.rotation * deg2rad) *
+ (rotCorr.y - label.getBBox(false, 0).height / 2);
}
}
x = x + labelOptions.x + rotCorr.x - (tickmarkOffset && horiz ?
tickmarkOffset * transA * (reversed ? -1 : 1) : 0);
@@ -10692,11 +10418,10 @@
tick.isNewLabel = false;
} else {
label.attr('y', -9999); // #1338
tick.isNewLabel = true;
}
- tick.isNew = false;
}
},
/**
* Put everything in place
@@ -10726,10 +10451,12 @@
// create the tick mark
this.renderMark(xy, opacity, reverseCrisp);
// the label is created on init - now move it into place
this.renderLabel(xy, old, opacity, index);
+
+ tick.isNew = false;
},
/**
* Destructor for the tick prototype
*/
@@ -10829,65 +10556,43 @@
// alternateGridColor: null,
// categories: [],
/**
* For a datetime axis, the scale will automatically adjust to the
- * appropriate unit. This member gives the default string representations
- * used for each unit. For intermediate values, different units may
- * be used, for example the `day` unit can be used on midnight and
- * `hour` unit be used for intermediate values on the same axis. For
- * an overview of the replacement codes, see [dateFormat](#Highcharts.
- * dateFormat). Defaults to:
+ * appropriate unit. This member gives the default string
+ * representations used for each unit. For intermediate values,
+ * different units may be used, for example the `day` unit can be used
+ * on midnight and `hour` unit be used for intermediate values on the
+ * same axis. For an overview of the replacement codes, see
+ * [dateFormat](#Highcharts.dateFormat). Defaults to:
*
* <pre>{
- * millisecond: '%H:%M:%S.%L',
- * second: '%H:%M:%S',
- * minute: '%H:%M',
- * hour: '%H:%M',
- * day: '%e. %b',
- * week: '%e. %b',
- * month: '%b \'%y',
- * year: '%Y'
+ * millisecond: '%H:%M:%S.%L',
+ * second: '%H:%M:%S',
+ * minute: '%H:%M',
+ * hour: '%H:%M',
+ * day: '%e. %b',
+ * week: '%e. %b',
+ * month: '%b \'%y',
+ * year: '%Y'
* }</pre>
*
* @type {Object}
- * @sample {highcharts} highcharts/xaxis/datetimelabelformats/ Different day format on X axis
- * @sample {highstock} stock/xaxis/datetimelabelformats/ More information in x axis labels
+ * @sample {highcharts} highcharts/xaxis/datetimelabelformats/
+ * Different day format on X axis
+ * @sample {highstock} stock/xaxis/datetimelabelformats/
+ * More information in x axis labels
* @product highcharts highstock
*/
dateTimeLabelFormats: {
-
- /**
- */
millisecond: '%H:%M:%S.%L',
-
- /**
- */
second: '%H:%M:%S',
-
- /**
- */
minute: '%H:%M',
-
- /**
- */
hour: '%H:%M',
-
- /**
- */
day: '%e. %b',
-
- /**
- */
week: '%e. %b',
-
- /**
- */
month: '%b \'%y',
-
- /**
- */
year: '%Y'
},
/**
* Whether to force the axis to end on a tick. Use this option with
@@ -10898,11 +10603,10 @@
* @sample {highcharts} highcharts/yaxis/endontick/ False
* @sample {highstock} stock/demo/basic-line/ True by default
* @sample {highstock} stock/xaxis/endontick/ False
* @default false
* @since 1.2.0
- * @product highcharts highstock highmaps
*/
endOnTick: false,
// reversed: false,
@@ -10918,87 +10622,72 @@
/**
* Enable or disable the axis labels.
*
* @type {Boolean}
- * @sample {highcharts} highcharts/xaxis/labels-enabled/ X axis labels disabled
- * @sample {highstock} stock/xaxis/labels-enabled/ X axis labels disabled
+ * @sample {highcharts} highcharts/xaxis/labels-enabled/
+ * X axis labels disabled
+ * @sample {highstock} stock/xaxis/labels-enabled/
+ * X axis labels disabled
* @default {highstock} true
* @default {highmaps} false
- * @product highcharts highstock highmaps
*/
enabled: true,
// rotation: 0,
// align: 'center',
// step: null,
/**
* CSS styles for the label. Use `whiteSpace: 'nowrap'` to prevent
- * wrapping of category labels. Use `textOverflow: 'none'` to prevent
- * ellipsis (dots).
+ * wrapping of category labels. Use `textOverflow: 'none'` to
+ * prevent ellipsis (dots).
*
- * In [styled mode](http://www.highcharts.com/docs/chart-design-and-
- * style/style-by-css), the labels are styled with the `.highcharts-
- * axis-labels` class.
+ * In styled mode, the labels are styled with the
+ * `.highcharts-axis-labels` class.
*
* @type {CSSObject}
- * @sample {highcharts} highcharts/xaxis/labels-style/ Red X axis labels
- * @default { "color": "#666666", "cursor": "default", "fontSize": "11px" }
- * @product highcharts highstock highmaps
+ * @sample {highcharts} highcharts/xaxis/labels-style/
+ * Red X axis labels
*/
style: {
-
- /**
- */
color: '#666666',
-
- /**
- */
cursor: 'default',
-
- /**
- */
fontSize: '11px'
},
/**
* The x position offset of the label relative to the tick position
* on the axis.
*
* @type {Number}
- * @sample {highcharts} highcharts/xaxis/labels-x/ Y axis labels placed on grid lines
+ * @sample {highcharts} highcharts/xaxis/labels-x/
+ * Y axis labels placed on grid lines
* @default 0
- * @product highcharts highstock highmaps
*/
x: 0
- //y: undefined
- /*formatter: function () {
- return this.value;
- },*/
},
- //linkedTo: null,
- //max: undefined,
- //min: undefined,
/**
* Padding of the min value relative to the length of the axis. A
* padding of 0.05 will make a 100px axis 5px longer. This is useful
* when you don't want the lowest data value to appear on the edge
* of the plot area. When the axis' `min` option is set or a min extreme
* is set using `axis.setExtremes()`, the minPadding will be ignored.
*
* @type {Number}
- * @sample {highcharts} highcharts/yaxis/minpadding/ Min padding of 0.2
- * @sample {highstock} stock/xaxis/minpadding-maxpadding/ Greater min- and maxPadding
- * @sample {highmaps} maps/chart/plotbackgroundcolor-gradient/ Add some padding
+ * @sample {highcharts} highcharts/yaxis/minpadding/
+ * Min padding of 0.2
+ * @sample {highstock} stock/xaxis/minpadding-maxpadding/
+ * Greater min- and maxPadding
+ * @sample {highmaps} maps/chart/plotbackgroundcolor-gradient/
+ * Add some padding
* @default {highcharts} 0.01
* @default {highstock} 0
* @default {highmaps} 0
* @since 1.2.0
- * @product highcharts highstock highmaps
*/
minPadding: 0.01,
/**
* Padding of the max value relative to the length of the axis. A
@@ -11006,73 +10695,61 @@
* when you don't want the highest data value to appear on the edge
* of the plot area. When the axis' `max` option is set or a max extreme
* is set using `axis.setExtremes()`, the maxPadding will be ignored.
*
* @type {Number}
- * @sample {highcharts} highcharts/yaxis/maxpadding/ Max padding of 0.25 on y axis
- * @sample {highstock} stock/xaxis/minpadding-maxpadding/ Greater min- and maxPadding
- * @sample {highmaps} maps/chart/plotbackgroundcolor-gradient/ Add some padding
+ * @sample {highcharts} highcharts/yaxis/maxpadding/
+ * Max padding of 0.25 on y axis
+ * @sample {highstock} stock/xaxis/minpadding-maxpadding/
+ * Greater min- and maxPadding
+ * @sample {highmaps} maps/chart/plotbackgroundcolor-gradient/
+ * Add some padding
* @default {highcharts} 0.01
* @default {highstock} 0
* @default {highmaps} 0
* @since 1.2.0
- * @product highcharts highstock highmaps
*/
maxPadding: 0.01,
- //minRange: null,
- //minorTickInterval: null,
/**
* The pixel length of the minor tick marks.
*
* @type {Number}
* @sample {highcharts} highcharts/yaxis/minorticklength/ 10px on Y axis
* @sample {highstock} stock/xaxis/minorticks/ 10px on Y axis
* @default 2
- * @product highcharts highstock highmaps
*/
minorTickLength: 2,
/**
* The position of the minor tick marks relative to the axis line.
* Can be one of `inside` and `outside`.
*
* @validvalue ["inside", "outside"]
* @type {String}
- * @sample {highcharts} highcharts/yaxis/minortickposition-outside/ Outside by default
- * @sample {highcharts} highcharts/yaxis/minortickposition-inside/ Inside
- * @sample {highstock} stock/xaxis/minorticks/ Inside
+ * @sample {highcharts} highcharts/yaxis/minortickposition-outside/
+ * Outside by default
+ * @sample {highcharts} highcharts/yaxis/minortickposition-inside/
+ * Inside
+ * @sample {highstock} stock/xaxis/minorticks/ Inside
* @default outside
- * @product highcharts highstock highmaps
*/
minorTickPosition: 'outside', // inside or outside
- //opposite: false,
- //offset: 0,
- //plotBands: [{
- // events: {},
- // zIndex: 1,
- // labels: { align, x, verticalAlign, y, style, rotation, textAlign }
- //}],
- //plotLines: [{
- // events: {}
- // dashStyle: {}
- // zIndex:
- // labels: { align, x, verticalAlign, y, style, rotation, textAlign }
- //}],
- //reversed: false,
- // showFirstLabel: true,
- // showLastLabel: true,
/**
* For datetime axes, this decides where to put the tick between weeks.
* 0 = Sunday, 1 = Monday.
*
* @type {Number}
- * @sample {highcharts} highcharts/xaxis/startofweek-monday/ Monday by default
- * @sample {highcharts} highcharts/xaxis/startofweek-sunday/ Sunday
- * @sample {highstock} stock/xaxis/startofweek-1 Monday by default
- * @sample {highstock} stock/xaxis/startofweek-0 Sunday
+ * @sample {highcharts} highcharts/xaxis/startofweek-monday/
+ * Monday by default
+ * @sample {highcharts} highcharts/xaxis/startofweek-sunday/
+ * Sunday
+ * @sample {highstock} stock/xaxis/startofweek-1
+ * Monday by default
+ * @sample {highstock} stock/xaxis/startofweek-0
+ * Sunday
* @default 1
* @product highcharts highstock
*/
startOfWeek: 1,
@@ -11083,27 +10760,30 @@
* @productdesc {highstock}
* In Highstock, `startOnTick` is always false when the navigator is
* enabled, to prevent jumpy scrolling.
*
* @type {Boolean}
- * @sample {highcharts} highcharts/xaxis/startontick-false/ False by default
- * @sample {highcharts} highcharts/xaxis/startontick-true/ True
- * @sample {highstock} stock/xaxis/endontick/ False for Y axis
+ * @sample {highcharts} highcharts/xaxis/startontick-false/
+ * False by default
+ * @sample {highcharts} highcharts/xaxis/startontick-true/
+ * True
+ * @sample {highstock} stock/xaxis/endontick/
+ * False for Y axis
* @default false
* @since 1.2.0
*/
startOnTick: false,
- //tickInterval: null,
/**
* The pixel length of the main tick marks.
*
* @type {Number}
- * @sample {highcharts} highcharts/xaxis/ticklength/ 20 px tick length on the X axis
- * @sample {highstock} stock/xaxis/ticks/ Formatted ticks on X axis
+ * @sample {highcharts} highcharts/xaxis/ticklength/
+ * 20 px tick length on the X axis
+ * @sample {highstock} stock/xaxis/ticks/
+ * Formatted ticks on X axis
* @default 10
- * @product highcharts highstock highmaps
*/
tickLength: 10,
/**
* For categorized axes only. If `on` the tick mark is placed in the
@@ -11111,12 +10791,14 @@
* categories. The default is `between` if the `tickInterval` is 1,
* else `on`.
*
* @validvalue [null, "on", "between"]
* @type {String}
- * @sample {highcharts} highcharts/xaxis/tickmarkplacement-between/ "between" by default
- * @sample {highcharts} highcharts/xaxis/tickmarkplacement-on/ "on"
+ * @sample {highcharts} highcharts/xaxis/tickmarkplacement-between/
+ * "between" by default
+ * @sample {highcharts} highcharts/xaxis/tickmarkplacement-on/
+ * "on"
* @default null
* @product highcharts
*/
tickmarkPlacement: 'between', // on or between
@@ -11130,31 +10812,35 @@
* denser than the data points.
*
* Defaults to `72` for the Y axis and `100` for the X axis.
*
* @type {Number}
- * @see [tickInterval](#xAxis.tickInterval), [tickPositioner](#xAxis.tickPositioner),
- * [tickPositions](#xAxis.tickPositions)-
- * @sample {highcharts} highcharts/xaxis/tickpixelinterval-50/ 50 px on X axis
- * @sample {highstock} stock/xaxis/tickpixelinterval/ 200 px on X axis
- * @product highcharts highstock highmaps
+ * @see [tickInterval](#xAxis.tickInterval),
+ * [tickPositioner](#xAxis.tickPositioner),
+ * [tickPositions](#xAxis.tickPositions).
+ * @sample {highcharts} highcharts/xaxis/tickpixelinterval-50/
+ * 50 px on X axis
+ * @sample {highstock} stock/xaxis/tickpixelinterval/
+ * 200 px on X axis
*/
tickPixelInterval: 100,
/**
* The position of the major tick marks relative to the axis line.
* Can be one of `inside` and `outside`.
*
* @validvalue ["inside", "outside"]
* @type {String}
- * @sample {highcharts} highcharts/xaxis/tickposition-outside/ "outside" by default
- * @sample {highcharts} highcharts/xaxis/tickposition-inside/ "inside"
- * @sample {highstock} stock/xaxis/ticks/ Formatted ticks on X axis
+ * @sample {highcharts} highcharts/xaxis/tickposition-outside/
+ * "outside" by default
+ * @sample {highcharts} highcharts/xaxis/tickposition-inside/
+ * "inside"
+ * @sample {highstock} stock/xaxis/ticks/
+ * Formatted ticks on X axis
* @default {highcharts} outside
* @default {highstock} "outside"
* @default {highmaps} outside
- * @product highcharts highstock highmaps
*/
tickPosition: 'outside',
/**
* The axis title, showing next to the axis line.
@@ -11163,207 +10849,202 @@
* In Highmaps, the axis is hidden by default, but adding an axis title
* is still possible. X axis and Y axis titles will appear at the bottom
* and left by default.
*/
title: {
- //text: null,
/**
- * Alignment of the title relative to the axis values. Possible values
- * are "low", "middle" or "high".
+ * Alignment of the title relative to the axis values. Possible
+ * values are "low", "middle" or "high".
*
* @validvalue ["low", "middle", "high"]
* @type {String}
- * @sample {highcharts} highcharts/xaxis/title-align-low/ "low"
- * @sample {highcharts} highcharts/xaxis/title-align-center/ "middle" by default
- * @sample {highcharts} highcharts/xaxis/title-align-high/ "high"
- * @sample {highcharts} highcharts/yaxis/title-offset/ Place the Y axis title on top of the axis
- * @sample {highstock} stock/xaxis/title-align/ Aligned to "high" value
+ * @sample {highcharts} highcharts/xaxis/title-align-low/
+ * "low"
+ * @sample {highcharts} highcharts/xaxis/title-align-center/
+ * "middle" by default
+ * @sample {highcharts} highcharts/xaxis/title-align-high/
+ * "high"
+ * @sample {highcharts} highcharts/yaxis/title-offset/
+ * Place the Y axis title on top of the axis
+ * @sample {highstock} stock/xaxis/title-align/
+ * Aligned to "high" value
* @default {highcharts} middle
* @default {highstock} "middle"
* @default {highmaps} middle
- * @product highcharts highstock highmaps
*/
align: 'middle', // low, middle or high
- //margin: 0 for horizontal, 10 for vertical axes,
- // reserveSpace: true,
- //rotation: 0,
- //side: 'outside',
+
/**
* CSS styles for the title. If the title text is longer than the
* axis length, it will wrap to multiple lines by default. This can
* be customized by setting `textOverflow: 'ellipsis'`, by
* setting a specific `width` or by setting `wordSpace: 'nowrap'`.
*
*
- * In [styled mode](http://www.highcharts.com/docs/chart-design-and-
- * style/style-by-css), the stroke width is given in the
+ * In styled mode, the stroke width is given in the
* `.highcharts-axis-title` class.
*
* @type {CSSObject}
* @sample {highcharts} highcharts/xaxis/title-style/ Red
* @sample {highcharts} highcharts/css/axis/ Styled mode
* @default { "color": "#666666" }
- * @product highcharts highstock highmaps
*/
style: {
-
- /**
- */
color: '#666666'
}
- //x: 0,
- //y: 0
},
/**
* The type of axis. Can be one of `linear`, `logarithmic`, `datetime`
- * or `category`. In a datetime axis, the numbers are given in milliseconds,
- * and tick marks are placed on appropriate values like full hours
- * or days. In a category axis, the [point names](#series<line>.data.
- * name) of the chart's series are used for categories, if not a [categories](#xAxis.
- * categories) array is defined.
+ * or `category`. In a datetime axis, the numbers are given in
+ * milliseconds, and tick marks are placed on appropriate values like
+ * full hours or days. In a category axis, the
+ * [point names](#series.line.data.name) of the chart's series are used
+ * for categories, if not a [categories](#xAxis.categories) array is
+ * defined.
*
* @validvalue ["linear", "logarithmic", "datetime", "category"]
* @type {String}
- * @sample {highcharts} highcharts/xaxis/type-linear/ Linear
- * @sample {highcharts} highcharts/yaxis/type-log/ Logarithmic
- * @sample {highcharts} highcharts/yaxis/type-log-minorgrid/ Logarithmic with minor grid lines
- * @sample {highcharts} highcharts/xaxis/type-log-both/ Logarithmic on two axes
- * @sample {highcharts} highcharts/yaxis/type-log-negative/ Logarithmic with extension to emulate negative values
+ * @sample {highcharts} highcharts/xaxis/type-linear/
+ * Linear
+ * @sample {highcharts} highcharts/yaxis/type-log/
+ * Logarithmic
+ * @sample {highcharts} highcharts/yaxis/type-log-minorgrid/
+ * Logarithmic with minor grid lines
+ * @sample {highcharts} highcharts/xaxis/type-log-both/
+ * Logarithmic on two axes
+ * @sample {highcharts} highcharts/yaxis/type-log-negative/
+ * Logarithmic with extension to emulate negative values
* @default linear
* @product highcharts
*/
type: 'linear', // linear, logarithmic or datetime
- //visible: true
+
/**
* Color of the minor, secondary grid lines.
*
- * In [styled mode](http://www.highcharts.com/docs/chart-design-and-
- * style/style-by-css), the stroke width is given in the `.highcharts-
- * minor-grid-line` class.
+ * In styled mode, the stroke width is given in the
+ * `.highcharts-minor-grid-line` class.
*
* @type {Color}
- * @sample {highcharts} highcharts/yaxis/minorgridlinecolor/ Bright grey lines from Y axis
- * @sample {highcharts} highcharts/css/axis-grid/ Styled mode
- * @sample {highstock} stock/xaxis/minorgridlinecolor/ Bright grey lines from Y axis
- * @sample {highstock} highcharts/css/axis-grid/ Styled mode
+ * @sample {highcharts} highcharts/yaxis/minorgridlinecolor/
+ * Bright grey lines from Y axis
+ * @sample {highcharts} highcharts/css/axis-grid/
+ * Styled mode
+ * @sample {highstock} stock/xaxis/minorgridlinecolor/
+ * Bright grey lines from Y axis
+ * @sample {highstock} highcharts/css/axis-grid/
+ * Styled mode
* @default #f2f2f2
- * @product highcharts highstock highmaps
*/
minorGridLineColor: '#f2f2f2',
// minorGridLineDashStyle: null,
/**
* Width of the minor, secondary grid lines.
*
- * In [styled mode](http://www.highcharts.com/docs/chart-design-and-
- * style/style-by-css), the stroke width is given in the `.highcharts-
- * grid-line` class.
+ * In styled mode, the stroke width is given in the
+ * `.highcharts-grid-line` class.
*
* @type {Number}
- * @sample {highcharts} highcharts/yaxis/minorgridlinewidth/ 2px lines from Y axis
- * @sample {highcharts} highcharts/css/axis-grid/ Styled mode
- * @sample {highstock} stock/xaxis/minorgridlinewidth/ 2px lines from Y axis
- * @sample {highstock} highcharts/css/axis-grid/ Styled mode
+ * @sample {highcharts} highcharts/yaxis/minorgridlinewidth/
+ * 2px lines from Y axis
+ * @sample {highcharts} highcharts/css/axis-grid/
+ * Styled mode
+ * @sample {highstock} stock/xaxis/minorgridlinewidth/
+ * 2px lines from Y axis
+ * @sample {highstock} highcharts/css/axis-grid/
+ * Styled mode
* @default 1
- * @product highcharts highstock highmaps
*/
minorGridLineWidth: 1,
/**
* Color for the minor tick marks.
*
* @type {Color}
- * @sample {highcharts} highcharts/yaxis/minortickcolor/ Black tick marks on Y axis
- * @sample {highstock} stock/xaxis/minorticks/ Black tick marks on Y axis
+ * @sample {highcharts} highcharts/yaxis/minortickcolor/
+ * Black tick marks on Y axis
+ * @sample {highstock} stock/xaxis/minorticks/
+ * Black tick marks on Y axis
* @default #999999
- * @product highcharts highstock highmaps
*/
minorTickColor: '#999999',
- //minorTickWidth: 0,
/**
* The color of the line marking the axis itself.
*
- * In [styled mode](http://www.highcharts.com/docs/chart-design-and-
- * style/style-by-css), the line stroke is given in the `.highcharts-
- * axis-line` or `.highcharts-xaxis-line` class.
+ * In styled mode, the line stroke is given in the
+ * `.highcharts-axis-line` or `.highcharts-xaxis-line` class.
*
* @productdesc {highmaps}
* In Highmaps, the axis line is hidden by default.
*
* @type {Color}
* @sample {highcharts} highcharts/yaxis/linecolor/ A red line on Y axis
* @sample {highcharts} highcharts/css/axis/ Axes in styled mode
* @sample {highstock} stock/xaxis/linecolor/ A red line on X axis
* @sample {highstock} highcharts/css/axis/ Axes in styled mode
* @default #ccd6eb
- * @product highcharts highstock highmaps
*/
lineColor: '#ccd6eb',
/**
* The width of the line marking the axis itself.
*
- * In [styled mode](http://www.highcharts.com/docs/chart-design-and-
- * style/style-by-css), the stroke width is given in the `.highcharts-
- * axis-line` or `.highcharts-xaxis-line` class.
+ * In styled mode, the stroke width is given in the
+ * `.highcharts-axis-line` or `.highcharts-xaxis-line` class.
*
* @type {Number}
* @sample {highcharts} highcharts/yaxis/linecolor/ A 1px line on Y axis
* @sample {highcharts} highcharts/css/axis/ Axes in styled mode
* @sample {highstock} stock/xaxis/linewidth/ A 2px line on X axis
* @sample {highstock} highcharts/css/axis/ Axes in styled mode
* @default {highcharts} 1
* @default {highstock} 1
* @default {highmaps} 0
- * @product highcharts highstock highmaps
*/
lineWidth: 1,
/**
* Color of the grid lines extending the ticks across the plot area.
*
- * In [styled mode](http://www.highcharts.com/docs/chart-design-and-
- * style/style-by-css), the stroke is given in the `.highcharts-grid-
- * line` class.
+ * In styled mode, the stroke is given in the `.highcharts-grid-line`
+ * class.
*
* @productdesc {highmaps}
* In Highmaps, the grid lines are hidden by default.
*
* @type {Color}
* @sample {highcharts} highcharts/yaxis/gridlinecolor/ Green lines
* @sample {highcharts} highcharts/css/axis-grid/ Styled mode
* @sample {highstock} stock/xaxis/gridlinecolor/ Green lines
* @sample {highstock} highcharts/css/axis-grid/ Styled mode
* @default #e6e6e6
- * @product highcharts highstock highmaps
*/
gridLineColor: '#e6e6e6',
// gridLineDashStyle: 'solid',
// gridLineWidth: 0,
/**
* Color for the main tick marks.
*
- * In [styled mode](http://www.highcharts.com/docs/chart-design-and-
- * style/style-by-css), the stroke is given in the `.highcharts-tick`
+ * In styled mode, the stroke is given in the `.highcharts-tick`
* class.
*
* @type {Color}
* @sample {highcharts} highcharts/xaxis/tickcolor/ Red ticks on X axis
* @sample {highcharts} highcharts/css/axis-grid/ Styled mode
* @sample {highstock} stock/xaxis/ticks/ Formatted ticks on X axis
* @sample {highstock} highcharts/css/axis-grid/ Styled mode
* @default #ccd6eb
- * @product highcharts highstock highmaps
*/
tickColor: '#ccd6eb'
// tickWidth: 1
},
@@ -11393,40 +11074,39 @@
* @since 1.2.0
* @product highcharts highstock
*/
endOnTick: true,
- /**
- */
tickPixelInterval: 72,
/**
* Whether to show the last tick label. Defaults to `true` on cartesian
* charts, and `false` on polar charts.
*
* @type {Boolean}
- * @sample {highcharts} highcharts/xaxis/showlastlabel-true/ Set to true on X axis
- * @sample {highstock} stock/xaxis/showfirstlabel/ Labels below plot lines on Y axis
+ * @sample {highcharts} highcharts/xaxis/showlastlabel-true/
+ * Set to true on X axis
+ * @sample {highstock} stock/xaxis/showfirstlabel/
+ * Labels below plot lines on Y axis
* @default false
* @product highcharts highstock
*/
showLastLabel: true,
/**
* @extends xAxis.labels
- * @product highcharts highstock highmaps
*/
labels: {
/**
* The x position offset of the label relative to the tick position
* on the axis. Defaults to -15 for left axis, 15 for right axis.
*
* @type {Number}
- * @sample {highcharts} highcharts/xaxis/labels-x/ Y axis labels placed on grid lines
+ * @sample {highcharts} highcharts/xaxis/labels-x/
+ * Y axis labels placed on grid lines
* @default 0
- * @product highcharts highstock highmaps
*/
x: -8
},
/**
@@ -11435,12 +11115,14 @@
* when you don't want the highest data value to appear on the edge
* of the plot area. When the axis' `max` option is set or a max extreme
* is set using `axis.setExtremes()`, the maxPadding will be ignored.
*
* @type {Number}
- * @sample {highcharts} highcharts/yaxis/maxpadding-02/ Max padding of 0.2
- * @sample {highstock} stock/xaxis/minpadding-maxpadding/ Greater min- and maxPadding
+ * @sample {highcharts} highcharts/yaxis/maxpadding-02/
+ * Max padding of 0.2
+ * @sample {highstock} stock/xaxis/minpadding-maxpadding/
+ * Greater min- and maxPadding
* @default 0.05
* @since 1.2.0
* @product highcharts highstock
*/
maxPadding: 0.05,
@@ -11451,12 +11133,14 @@
* when you don't want the lowest data value to appear on the edge
* of the plot area. When the axis' `min` option is set or a max extreme
* is set using `axis.setExtremes()`, the maxPadding will be ignored.
*
* @type {Number}
- * @sample {highcharts} highcharts/yaxis/minpadding/ Min padding of 0.2
- * @sample {highstock} stock/xaxis/minpadding-maxpadding/ Greater min- and maxPadding
+ * @sample {highcharts} highcharts/yaxis/minpadding/
+ * Min padding of 0.2
+ * @sample {highstock} stock/xaxis/minpadding-maxpadding/
+ * Greater min- and maxPadding
* @default 0.05
* @since 1.2.0
* @product highcharts highstock
*/
minPadding: 0.05,
@@ -11464,33 +11148,34 @@
/**
* Whether to force the axis to start on a tick. Use this option with
* the `maxPadding` option to control the axis start.
*
* @type {Boolean}
- * @sample {highcharts} highcharts/xaxis/startontick-false/ False by default
- * @sample {highcharts} highcharts/xaxis/startontick-true/ True
- * @sample {highstock} stock/xaxis/endontick/ False for Y axis
+ * @sample {highcharts} highcharts/xaxis/startontick-false/
+ * False by default
+ * @sample {highcharts} highcharts/xaxis/startontick-true/
+ * True
+ * @sample {highstock} stock/xaxis/endontick/
+ * False for Y axis
* @default true
* @since 1.2.0
* @product highcharts highstock
*/
startOnTick: true,
/**
* @extends xAxis.title
- * @product highcharts highstock highmaps
*/
title: {
/**
- * The rotation of the text in degrees. 0 is horizontal, 270 is vertical
- * reading from bottom to top.
+ * The rotation of the text in degrees. 0 is horizontal, 270 is
+ * vertical reading from bottom to top.
*
* @type {Number}
* @sample {highcharts} highcharts/yaxis/title-offset/ Horizontal
* @default 270
- * @product highcharts highstock highmaps
*/
rotation: 270,
/**
* The actual text of the axis title. Horizontal texts can contain
@@ -11530,32 +11215,28 @@
/**
* Enable or disable the stack total labels.
*
* @type {Boolean}
- * @sample {highcharts} highcharts/yaxis/stacklabels-enabled/ Enabled stack total labels
+ * @sample {highcharts} highcharts/yaxis/stacklabels-enabled/
+ * Enabled stack total labels
* @since 2.1.5
* @product highcharts
*/
enabled: false,
- //align: dynamic,
- //y: dynamic,
- //x: dynamic,
- //verticalAlign: dynamic,
- //textAlign: dynamic,
- //rotation: 0,
/**
* Callback JavaScript function to format the label. The value is
* given by `this.total`. Defaults to:
*
* <pre>function() {
- * return this.total;
+ * return this.total;
* }</pre>
*
* @type {Function}
- * @sample {highcharts} highcharts/yaxis/stacklabels-formatter/ Added units to stack total value
+ * @sample {highcharts} highcharts/yaxis/stacklabels-formatter/
+ * Added units to stack total value
* @since 2.1.5
* @product highcharts
*/
formatter: function() {
return H.numberFormat(this.total, -1);
@@ -11563,36 +11244,23 @@
/**
* CSS styles for the label.
*
- * In [styled mode](http://www.highcharts.com/docs/chart-design-and-
- * style/style-by-css), the styles are set in the `.highcharts-stack-
- * label` class.
+ * In styled mode, the styles are set in the
+ * `.highcharts-stack-label` class.
*
* @type {CSSObject}
- * @sample {highcharts} highcharts/yaxis/stacklabels-style/ Red stack total labels
- * @default { "color": "#000000", "fontSize": "11px", "fontWeight": "bold", "textShadow": "1px 1px contrast, -1px -1px contrast, -1px 1px contrast, 1px -1px contrast" }
+ * @sample {highcharts} highcharts/yaxis/stacklabels-style/
+ * Red stack total labels
* @since 2.1.5
* @product highcharts
*/
style: {
-
- /**
- */
fontSize: '11px',
-
- /**
- */
fontWeight: 'bold',
-
- /**
- */
color: '#000000',
-
- /**
- */
textOutline: '1px contrast'
}
},
@@ -11762,11 +11430,10 @@
// Flag, stagger lines or not
axis.userOptions = userOptions;
- //axis.axisTitleMargin = undefined,// = options.title.margin,
axis.minPixelPadding = 0;
/**
* Whether the axis is reversed. Based on the `axis.reversed`,
@@ -11783,28 +11450,20 @@
// Initial categories
axis.hasNames = type === 'category' || options.categories === true;
axis.categories = options.categories || axis.hasNames;
axis.names = axis.names || []; // Preserve on update (#3830)
- // Elements
- //axis.axisGroup = undefined;
- //axis.gridGroup = undefined;
- //axis.axisTitle = undefined;
- //axis.axisLine = undefined;
-
// Placeholder for plotlines and plotbands groups
axis.plotLinesAndBandsGroups = {};
// Shorthand types
axis.isLog = type === 'logarithmic';
axis.isDatetimeAxis = isDatetimeAxis;
axis.positiveValuesOnly = axis.isLog && !axis.allowNegativeLog;
// Flag, if axis is linked to another axis
axis.isLinked = defined(options.linkedTo);
- // Linked axis.
- //axis.linkedParent = undefined;
// Major ticks
axis.ticks = {};
axis.labelEdge = [];
// Minor ticks
@@ -11815,38 +11474,21 @@
// Alternate bands
axis.alternateBands = {};
// Axis metrics
- //axis.left = undefined;
- //axis.top = undefined;
- //axis.width = undefined;
- //axis.height = undefined;
- //axis.bottom = undefined;
- //axis.right = undefined;
- //axis.transA = undefined;
- //axis.transB = undefined;
- //axis.oldTransA = undefined;
axis.len = 0;
- //axis.oldMin = undefined;
- //axis.oldMax = undefined;
- //axis.oldUserMin = undefined;
- //axis.oldUserMax = undefined;
- //axis.oldAxisLength = undefined;
axis.minRange = axis.userMinRange = options.minRange || options.maxZoom;
axis.range = options.range;
axis.offset = options.offset || 0;
// Dictionary for stacks
axis.stacks = {};
axis.oldStacks = {};
axis.stacksTouched = 0;
- // Min and max in the data
- //axis.dataMin = undefined,
- //axis.dataMax = undefined,
/**
* The maximum value of the axis. In a logarithmic axis, this is the
* logarithm of the real value, and the real value can be obtained from
* {@link Axis#getExtremes}.
@@ -11865,13 +11507,10 @@
* @memberOf Axis
* @type {Number}
*/
axis.min = null;
- // User set min and max
- //axis.userMin = undefined,
- //axis.userMax = undefined,
/**
* The processed crosshair options.
*
* @name crosshair
@@ -11992,11 +11631,16 @@
// places as well, we can move this logic to the numberFormatter and
// enable it by a parameter.
while (i-- && ret === undefined) {
multi = Math.pow(numSymMagnitude, i + 1);
if (
+ // Only accept a numeric symbol when the distance is more
+ // than a full unit. So for example if the symbol is k, we
+ // don't accept numbers like 0.5k.
numericSymbolDetector >= multi &&
+ // Accept one decimal before the symbol. Accepts 0.5k but
+ // not 0.25k. How does this work with the previous?
(value * 10) % multi === 0 &&
numericSymbols[i] !== null &&
value !== 0
) { // #5480
ret = H.numberFormat(value / multi, -1) + numericSymbols[i];
@@ -12065,11 +11709,12 @@
!(seriesDataMin instanceof Date) // #5010
) {
xData = grep(xData, function(x) {
return isNumber(x);
});
- seriesDataMin = arrayMin(xData); // Do it again with valid data
+ // Do it again with valid data
+ seriesDataMin = arrayMin(xData);
}
axis.dataMin = Math.min(
pick(axis.dataMin, xData[0]),
seriesDataMin
@@ -12124,26 +11769,37 @@
* Translate from axis value to pixel position on the chart, or back. Use
* the `toPixels` and `toValue` functions in applications.
*
* @private
*/
- translate: function(val, backwards, cvsCoord, old, handleLog, pointPlacement) {
+ translate: function(
+ val,
+ backwards,
+ cvsCoord,
+ old,
+ handleLog,
+ pointPlacement
+ ) {
var axis = this.linkedParent || this, // #1417
sign = 1,
cvsOffset = 0,
localA = old ? axis.oldTransA : axis.transA,
localMin = old ? axis.oldMin : axis.min,
returnValue,
minPixelPadding = axis.minPixelPadding,
- doPostTranslate = (axis.isOrdinal || axis.isBroken || (axis.isLog && handleLog)) && axis.lin2val;
+ doPostTranslate = (
+ axis.isOrdinal ||
+ axis.isBroken ||
+ (axis.isLog && handleLog)
+ ) && axis.lin2val;
if (!localA) {
localA = axis.transA;
}
- // In vertical axes, the canvas coordinates start from 0 at the top like in
- // SVG.
+ // In vertical axes, the canvas coordinates start from 0 at the top like
+ // in SVG.
if (cvsCoord) {
sign *= -1; // canvas coordinates inverts the value
cvsOffset = axis.len;
}
@@ -12166,13 +11822,18 @@
// From value to pixels
} else {
if (doPostTranslate) { // log and ordinal axes
val = axis.val2lin(val);
}
- returnValue = sign * (val - localMin) * localA + cvsOffset +
- (sign * minPixelPadding) +
- (isNumber(pointPlacement) ? localA * pointPlacement : 0);
+ returnValue = isNumber(localMin) ?
+ (
+ sign * (val - localMin) * localA +
+ cvsOffset +
+ (sign * minPixelPadding) +
+ (isNumber(pointPlacement) ? localA * pointPlacement : 0)
+ ) :
+ undefined;
}
return returnValue;
},
@@ -12257,16 +11918,19 @@
}
}
return x;
};
- translatedValue = pick(translatedValue, axis.translate(value, null, null, old));
+ translatedValue = pick(
+ translatedValue,
+ axis.translate(value, null, null, old)
+ );
x1 = x2 = Math.round(translatedValue + transB);
y1 = y2 = Math.round(cHeight - translatedValue - transB);
if (!isNumber(translatedValue)) { // no min or max
skip = true;
-
+ force = false; // #7175, don't force it when path is invalid
} else if (axis.horiz) {
y1 = axisTop;
y2 = cHeight - axis.bottom;
x1 = x2 = between(x1, axisLeft, axisLeft + axis.width);
} else {
@@ -12274,11 +11938,14 @@
x2 = cWidth - axis.right;
y1 = y2 = between(y1, axisTop, axisTop + axis.height);
}
return skip && !force ?
null :
- chart.renderer.crispLine(['M', x1, y1, 'L', x2, y2], lineWidth || 1);
+ chart.renderer.crispLine(
+ ['M', x1, y1, 'L', x2, y2],
+ lineWidth || 1
+ );
},
/**
* Internal function to et the tick positions of a linear axis to round
* values like whole tens or every five.
@@ -12294,12 +11961,14 @@
* An array of axis values where ticks should be placed.
*/
getLinearTickPositions: function(tickInterval, min, max) {
var pos,
lastPos,
- roundedMin = correctFloat(Math.floor(min / tickInterval) * tickInterval),
- roundedMax = correctFloat(Math.ceil(max / tickInterval) * tickInterval),
+ roundedMin =
+ correctFloat(Math.floor(min / tickInterval) * tickInterval),
+ roundedMax =
+ correctFloat(Math.ceil(max / tickInterval) * tickInterval),
tickPositions = [];
// For single points, add a tick regardless of the relative position
// (#2662, #6274)
if (this.single) {
@@ -12314,12 +11983,13 @@
tickPositions.push(pos);
// Always add the raw tickInterval, not the corrected one.
pos = correctFloat(pos + tickInterval);
- // If the interval is not big enough in the current min - max range to actually increase
- // the loop variable, we need to break out to prevent endless loop. Issue #619
+ // If the interval is not big enough in the current min - max range
+ // to actually increase the loop variable, we need to break out to
+ // prevent endless loop. Issue #619
if (pos === lastPos) {
break;
}
// Record the last value
@@ -12327,10 +11997,26 @@
}
return tickPositions;
},
/**
+ * Resolve the new minorTicks/minorTickInterval options into the legacy
+ * loosely typed minorTickInterval option.
+ */
+ getMinorTickInterval: function() {
+ var options = this.options;
+
+ if (options.minorTicks === true) {
+ return pick(options.minorTickInterval, 'auto');
+ }
+ if (options.minorTicks === false) {
+ return null;
+ }
+ return options.minorTickInterval;
+ },
+
+ /**
* Internal function to return the minor tick positions. For logarithmic
* axes, the same logic as for major ticks is reused.
*
* @return {Array.<Number>}
* An array of axis values where ticks should be placed.
@@ -12345,11 +12031,12 @@
pointRangePadding = axis.pointRangePadding || 0,
min = axis.min - pointRangePadding, // #1498
max = axis.max + pointRangePadding, // #1498
range = max - min;
- // If minor ticks get too dense, they are hard to read, and may cause long running script. So we don't draw them.
+ // If minor ticks get too dense, they are hard to read, and may cause
+ // long running script. So we don't draw them.
if (range && range / minorTickInterval < axis.len / 3) { // #3875
if (axis.isLog) {
// For each interval in the major ticks, compute the minor ticks
// separately.
@@ -12365,11 +12052,14 @@
)
);
}
});
- } else if (axis.isDatetimeAxis && options.minorTickInterval === 'auto') { // #1314
+ } else if (
+ axis.isDatetimeAxis &&
+ this.getMinorTickInterval() === 'auto'
+ ) { // #1314
minorTickPositions = minorTickPositions.concat(
axis.getTimeTicks(
axis.normalizeTimeTickInterval(minorTickInterval),
min,
max,
@@ -12394,14 +12084,15 @@
}
return minorTickPositions;
},
/**
- * Adjust the min and max for the minimum range. Keep in mind that the series data is
- * not yet processed, so we don't have information on data cropping and grouping, or
- * updated axis.pointRange or series.pointRange. The data can't be processed until
- * we have finally established min and max.
+ * Adjust the min and max for the minimum range. Keep in mind that the
+ * series data is not yet processed, so we don't have information on data
+ * cropping and grouping, or updated axis.pointRange or series.pointRange.
+ * The data can't be processed until we have finally established min and
+ * max.
*
* @private
*/
adjustForMinRange: function() {
var axis = this,
@@ -12425,23 +12116,30 @@
if (defined(options.min) || defined(options.max)) {
axis.minRange = null; // don't do this again
} else {
- // Find the closest distance between raw data points, as opposed to
- // closestPointRange that applies to processed points (cropped and grouped)
+ // Find the closest distance between raw data points, as opposed
+ // to closestPointRange that applies to processed points
+ // (cropped and grouped)
each(axis.series, function(series) {
xData = series.xData;
loopLength = series.xIncrement ? 1 : xData.length - 1;
for (i = loopLength; i > 0; i--) {
distance = xData[i] - xData[i - 1];
- if (closestDataRange === undefined || distance < closestDataRange) {
+ if (
+ closestDataRange === undefined ||
+ distance < closestDataRange
+ ) {
closestDataRange = distance;
}
}
});
- axis.minRange = Math.min(closestDataRange * 5, axis.dataMax - axis.dataMin);
+ axis.minRange = Math.min(
+ closestDataRange * 5,
+ axis.dataMax - axis.dataMin
+ );
}
}
// if minRange is exceeded, adjust
if (max - min < axis.minRange) {
@@ -12450,18 +12148,24 @@
minRange = axis.minRange;
zoomOffset = (minRange - max + min) / 2;
// if min and max options have been set, don't go beyond it
minArgs = [min - zoomOffset, pick(options.min, min - zoomOffset)];
- if (spaceAvailable) { // if space is available, stay within the data range
- minArgs[2] = axis.isLog ? axis.log2lin(axis.dataMin) : axis.dataMin;
+ // If space is available, stay within the data range
+ if (spaceAvailable) {
+ minArgs[2] = axis.isLog ?
+ axis.log2lin(axis.dataMin) :
+ axis.dataMin;
}
min = arrayMax(minArgs);
maxArgs = [min + minRange, pick(options.max, min + minRange)];
- if (spaceAvailable) { // if space is availabe, stay within the data range
- maxArgs[2] = axis.isLog ? axis.log2lin(axis.dataMax) : axis.dataMax;
+ // If space is availabe, stay within the data range
+ if (spaceAvailable) {
+ maxArgs[2] = axis.isLog ?
+ axis.log2lin(axis.dataMax) :
+ axis.dataMax;
}
max = arrayMin(maxArgs);
// now if the max is adjusted, adjust the min back
@@ -12600,11 +12304,12 @@
ordinalCorrection,
hasCategories = !!axis.categories,
transA = axis.transA,
isXAxis = axis.isXAxis;
- // Adjust translation for padding. Y axis with categories need to go through the same (#1784).
+ // Adjust translation for padding. Y axis with categories need to go
+ // through the same (#1784).
if (isXAxis || hasCategories || pointRange) {
// Get the closest points
closestPointRange = axis.getClosest();
@@ -12613,47 +12318,61 @@
pointRangePadding = linkedParent.pointRangePadding;
} else {
each(axis.series, function(series) {
var seriesPointRange = hasCategories ?
1 :
- (isXAxis ?
- pick(series.options.pointRange, closestPointRange, 0) :
- (axis.axisPointRange || 0)), // #2806
+ (
+ isXAxis ?
+ pick(
+ series.options.pointRange,
+ closestPointRange,
+ 0
+ ) :
+ (axis.axisPointRange || 0)
+ ), // #2806
pointPlacement = series.options.pointPlacement;
pointRange = Math.max(pointRange, seriesPointRange);
if (!axis.single) {
- // minPointOffset is the value padding to the left of the axis in order to make
- // room for points with a pointRange, typically columns. When the pointPlacement option
- // is 'between' or 'on', this padding does not apply.
+ // minPointOffset is the value padding to the left of
+ // the axis in order to make room for points with a
+ // pointRange, typically columns. When the
+ // pointPlacement option is 'between' or 'on', this
+ // padding does not apply.
minPointOffset = Math.max(
minPointOffset,
isString(pointPlacement) ? 0 : seriesPointRange / 2
);
- // Determine the total padding needed to the length of the axis to make room for the
- // pointRange. If the series' pointPlacement is 'on', no padding is added.
+ // Determine the total padding needed to the length of
+ // the axis to make room for the pointRange. If the
+ // series' pointPlacement is 'on', no padding is added.
pointRangePadding = Math.max(
pointRangePadding,
pointPlacement === 'on' ? 0 : seriesPointRange
);
}
});
}
// Record minPointOffset and pointRangePadding
- ordinalCorrection = axis.ordinalSlope && closestPointRange ? axis.ordinalSlope / closestPointRange : 1; // #988, #1853
- axis.minPointOffset = minPointOffset = minPointOffset * ordinalCorrection;
- axis.pointRangePadding = pointRangePadding = pointRangePadding * ordinalCorrection;
+ ordinalCorrection = axis.ordinalSlope && closestPointRange ?
+ axis.ordinalSlope / closestPointRange :
+ 1; // #988, #1853
+ axis.minPointOffset = minPointOffset =
+ minPointOffset * ordinalCorrection;
+ axis.pointRangePadding =
+ pointRangePadding = pointRangePadding * ordinalCorrection;
- // pointRange means the width reserved for each point, like in a column chart
+ // pointRange means the width reserved for each point, like in a
+ // column chart
axis.pointRange = Math.min(pointRange, range);
- // closestPointRange means the closest distance between points. In columns
- // it is mostly equal to pointRange, but in lines pointRange is 0 while closestPointRange
- // is some other value
+ // closestPointRange means the closest distance between points. In
+ // columns it is mostly equal to pointRange, but in lines pointRange
+ // is 0 while closestPointRange is some other value
if (isXAxis) {
axis.closestPointRange = closestPointRange;
}
}
@@ -12662,11 +12381,13 @@
axis.oldTransA = transA;
}
axis.translationSlope = axis.transA = transA =
axis.options.staticScale ||
axis.len / ((range + pointRangePadding) || 1);
- axis.transB = axis.horiz ? axis.left : axis.bottom; // translation addend
+
+ // Translation addend
+ axis.transB = axis.horiz ? axis.left : axis.bottom;
axis.minPixelPadding = transA * minPointOffset;
},
minFromRange: function() {
return this.max - this.range;
@@ -12712,12 +12433,18 @@
// Linked axis gets the extremes from the parent axis
if (isLinked) {
axis.linkedParent = chart[axis.coll][options.linkedTo];
linkedParentExtremes = axis.linkedParent.getExtremes();
- axis.min = pick(linkedParentExtremes.min, linkedParentExtremes.dataMin);
- axis.max = pick(linkedParentExtremes.max, linkedParentExtremes.dataMax);
+ axis.min = pick(
+ linkedParentExtremes.min,
+ linkedParentExtremes.dataMin
+ );
+ axis.max = pick(
+ linkedParentExtremes.max,
+ linkedParentExtremes.dataMax
+ );
if (options.type !== axis.linkedParent.options.type) {
H.error(11, 1); // Can't link axes of different type
}
// Initial min and max from the extreme data values
@@ -12754,11 +12481,12 @@
axis.max = correctFloat(log2lin(axis.max), 15);
}
// handle zoomed range
if (axis.range && defined(axis.max)) {
- axis.userMin = axis.min = hardMin = Math.max(axis.dataMin, axis.minFromRange()); // #618, #6773
+ axis.userMin = axis.min = hardMin =
+ Math.max(axis.dataMin, axis.minFromRange()); // #618, #6773
axis.userMax = hardMax = axis.max;
axis.range = null; // don't use it when running setExtremes
}
@@ -12771,13 +12499,20 @@
}
// adjust min and max for the minimum range
axis.adjustForMinRange();
- // Pad the values to get clear of the chart's edges. To avoid tickInterval taking the padding
- // into account, we do this after computing tick interval (#1337).
- if (!categories && !axis.axisPointRange && !axis.usePercentage && !isLinked && defined(axis.min) && defined(axis.max)) {
+ // Pad the values to get clear of the chart's edges. To avoid
+ // tickInterval taking the padding into account, we do this after
+ // computing tick interval (#1337).
+ if (!categories &&
+ !axis.axisPointRange &&
+ !axis.usePercentage &&
+ !isLinked &&
+ defined(axis.min) &&
+ defined(axis.max)
+ ) {
length = axis.max - axis.min;
if (length) {
if (!defined(hardMin) && minPadding) {
axis.min -= length * minPadding;
}
@@ -12800,47 +12535,72 @@
if (isNumber(options.ceiling)) {
axis.max = Math.min(axis.max, options.ceiling);
}
- // When the threshold is soft, adjust the extreme value only if
- // the data extreme and the padded extreme land on either side of the threshold. For example,
- // a series of [0, 1, 2, 3] would make the yAxis add a tick for -1 because of the
- // default minPadding and startOnTick options. This is prevented by the softThreshold
- // option.
+ // When the threshold is soft, adjust the extreme value only if the data
+ // extreme and the padded extreme land on either side of the threshold.
+ // For example, a series of [0, 1, 2, 3] would make the yAxis add a tick
+ // for -1 because of the default minPadding and startOnTick options.
+ // This is prevented by the softThreshold option.
if (softThreshold && defined(axis.dataMin)) {
threshold = threshold || 0;
- if (!defined(hardMin) && axis.min < threshold && axis.dataMin >= threshold) {
+ if (!defined(hardMin) &&
+ axis.min < threshold &&
+ axis.dataMin >= threshold
+ ) {
axis.min = threshold;
- } else if (!defined(hardMax) && axis.max > threshold && axis.dataMax <= threshold) {
+
+ } else if (!defined(hardMax) &&
+ axis.max > threshold &&
+ axis.dataMax <= threshold
+ ) {
axis.max = threshold;
}
}
// get tickInterval
- if (axis.min === axis.max || axis.min === undefined || axis.max === undefined) {
+ if (
+ axis.min === axis.max ||
+ axis.min === undefined ||
+ axis.max === undefined
+ ) {
axis.tickInterval = 1;
- } else if (isLinked && !tickIntervalOption &&
- tickPixelIntervalOption === axis.linkedParent.options.tickPixelInterval) {
- axis.tickInterval = tickIntervalOption = axis.linkedParent.tickInterval;
+
+ } else if (
+ isLinked &&
+ !tickIntervalOption &&
+ tickPixelIntervalOption ===
+ axis.linkedParent.options.tickPixelInterval
+ ) {
+ axis.tickInterval = tickIntervalOption =
+ axis.linkedParent.tickInterval;
+
} else {
axis.tickInterval = pick(
tickIntervalOption,
- this.tickAmount ? ((axis.max - axis.min) / Math.max(this.tickAmount - 1, 1)) : undefined,
- categories ? // for categoried axis, 1 is default, for linear axis use tickPix
+ this.tickAmount ?
+ ((axis.max - axis.min) / Math.max(this.tickAmount - 1, 1)) :
+ undefined,
+ // For categoried axis, 1 is default, for linear axis use
+ // tickPix
+ categories ?
1 :
// don't let it be more than the data range
- (axis.max - axis.min) * tickPixelIntervalOption / Math.max(axis.len, tickPixelIntervalOption)
+ (axis.max - axis.min) * tickPixelIntervalOption /
+ Math.max(axis.len, tickPixelIntervalOption)
);
}
- // Now we're finished detecting min and max, crop and group series data. This
- // is in turn needed in order to find tick positions in ordinal axes.
+ // Now we're finished detecting min and max, crop and group series data.
+ // This is in turn needed in order to find tick positions in ordinal axes.
if (isXAxis && !secondPass) {
each(axis.series, function(series) {
- series.processData(axis.min !== axis.oldMin || axis.max !== axis.oldMax);
+ series.processData(
+ axis.min !== axis.oldMin || axis.max !== axis.oldMax
+ );
});
}
// set the translation factor used in translate function
axis.setAxisTranslation(true);
@@ -12853,30 +12613,43 @@
// hook for extensions, used in Highstock ordinal axes
if (axis.postProcessTickInterval) {
axis.tickInterval = axis.postProcessTickInterval(axis.tickInterval);
}
- // In column-like charts, don't cramp in more ticks than there are points (#1943, #4184)
+ // In column-like charts, don't cramp in more ticks than there are
+ // points (#1943, #4184)
if (axis.pointRange && !tickIntervalOption) {
axis.tickInterval = Math.max(axis.pointRange, axis.tickInterval);
}
- // Before normalizing the tick interval, handle minimum tick interval. This applies only if tickInterval is not defined.
- minTickInterval = pick(options.minTickInterval, axis.isDatetimeAxis && axis.closestPointRange);
+ // Before normalizing the tick interval, handle minimum tick interval.
+ // This applies only if tickInterval is not defined.
+ minTickInterval = pick(
+ options.minTickInterval,
+ axis.isDatetimeAxis && axis.closestPointRange
+ );
if (!tickIntervalOption && axis.tickInterval < minTickInterval) {
axis.tickInterval = minTickInterval;
}
// for linear axes, get magnitude and normalize the interval
if (!isDatetimeAxis && !isLog && !tickIntervalOption) {
axis.tickInterval = normalizeTickInterval(
axis.tickInterval,
null,
getMagnitude(axis.tickInterval),
- // If the tick interval is between 0.5 and 5 and the axis max is in the order of
- // thousands, chances are we are dealing with years. Don't allow decimals. #3363.
- pick(options.allowDecimals, !(axis.tickInterval > 0.5 && axis.tickInterval < 5 && axis.max > 1000 && axis.max < 9999)), !!this.tickAmount
+ // If the tick interval is between 0.5 and 5 and the axis max is
+ // in the order of thousands, chances are we are dealing with
+ // years. Don't allow decimals. #3363.
+ pick(
+ options.allowDecimals, !(
+ axis.tickInterval > 0.5 &&
+ axis.tickInterval < 5 &&
+ axis.max > 1000 &&
+ axis.max < 9999
+ )
+ ), !!this.tickAmount
);
}
// Prevent ticks from getting so close that we can't draw the labels
if (!this.tickAmount) {
@@ -12892,22 +12665,29 @@
setTickPositions: function() {
var options = this.options,
tickPositions,
tickPositionsOption = options.tickPositions,
+ minorTickIntervalOption = this.getMinorTickInterval(),
tickPositioner = options.tickPositioner,
startOnTick = options.startOnTick,
endOnTick = options.endOnTick;
// Set the tickmarkOffset
- this.tickmarkOffset = (this.categories && options.tickmarkPlacement === 'between' &&
- this.tickInterval === 1) ? 0.5 : 0; // #3202
+ this.tickmarkOffset = (
+ this.categories &&
+ options.tickmarkPlacement === 'between' &&
+ this.tickInterval === 1
+ ) ? 0.5 : 0; // #3202
// get minorTickInterval
- this.minorTickInterval = options.minorTickInterval === 'auto' && this.tickInterval ?
- this.tickInterval / 5 : options.minorTickInterval;
+ this.minorTickInterval =
+ minorTickIntervalOption === 'auto' &&
+ this.tickInterval ?
+ this.tickInterval / 5 :
+ minorTickIntervalOption;
// When there is only one point, or all points have the same value on
// this axis, then min and max are equal and tickPositions.length is 0
// or 1. In this case, add some padding in order to center the point,
// but leave it with one tick. #1337.
@@ -12921,12 +12701,13 @@
// Between integers and decimals are not allowed (#6274)
options.allowDecimals !== false
);
- // Find the tick positions
- this.tickPositions = tickPositions = tickPositionsOption && tickPositionsOption.slice(); // Work on a copy (#1565)
+ // Find the tick positions. Work on a copy (#1565)
+ this.tickPositions = tickPositions =
+ tickPositionsOption && tickPositionsOption.slice();
if (!tickPositions) {
if (this.isDatetimeAxis) {
tickPositions = this.getTimeTicks(
this.normalizeTimeTickInterval(
@@ -12959,13 +12740,16 @@
tickPositions = [tickPositions[0], tickPositions.pop()];
}
this.tickPositions = tickPositions;
- // Run the tick positioner callback, that allows modifying auto tick positions.
+ // Run the tick positioner callback, that allows modifying auto tick
+ // positions.
if (tickPositioner) {
- tickPositioner = tickPositioner.apply(this, [this.min, this.max]);
+ tickPositioner = tickPositioner.apply(
+ this, [this.min, this.max]
+ );
if (tickPositioner) {
this.tickPositions = tickPositions = tickPositioner;
}
}
@@ -13009,11 +12793,12 @@
}
if (endOnTick) {
this.max = roundedMax;
} else {
- while (this.max + minPointOffset < tickPositions[tickPositions.length - 1]) {
+ while (this.max + minPointOffset <
+ tickPositions[tickPositions.length - 1]) {
tickPositions.pop();
}
}
// If no tick are left, set one tick in the middle (#3195)
@@ -13076,22 +12861,29 @@
getTickAmount: function() {
var options = this.options,
tickAmount = options.tickAmount,
tickPixelInterval = options.tickPixelInterval;
- if (!defined(options.tickInterval) && this.len < tickPixelInterval && !this.isRadial &&
- !this.isLog && options.startOnTick && options.endOnTick) {
+ if (!defined(options.tickInterval) &&
+ this.len < tickPixelInterval &&
+ !this.isRadial &&
+ !this.isLog &&
+ options.startOnTick &&
+ options.endOnTick
+ ) {
tickAmount = 2;
}
if (!tickAmount && this.alignToOthers()) {
- // Add 1 because 4 tick intervals require 5 ticks (including first and last)
+ // Add 1 because 4 tick intervals require 5 ticks (including first
+ // and last)
tickAmount = Math.ceil(this.len / tickPixelInterval) + 1;
}
- // For tick amounts of 2 and 3, compute five ticks and remove the intermediate ones. This
- // prevents the axis from adding ticks that are too far away from the data extremes.
+ // For tick amounts of 2 and 3, compute five ticks and remove the
+ // intermediate ones. This prevents the axis from adding ticks that are
+ // too far away from the data extremes.
if (tickAmount < 4) {
this.finalTickAmt = tickAmount;
tickAmount = 5;
}
@@ -13131,12 +12923,14 @@
// The finalTickAmt property is set in getTickAmount
if (defined(finalTickAmt)) {
i = len = tickPositions.length;
while (i--) {
if (
- (finalTickAmt === 3 && i % 2 === 1) || // Remove every other tick
- (finalTickAmt <= 2 && i > 0 && i < len - 1) // Remove all but first and last
+ // Remove every other tick
+ (finalTickAmt === 3 && i % 2 === 1) ||
+ // Remove all but first and last
+ (finalTickAmt <= 2 && i > 0 && i < len - 1)
) {
tickPositions.splice(i, 1);
}
}
this.finalTickAmt = undefined;
@@ -13157,24 +12951,34 @@
axis.oldMax = axis.max;
axis.oldAxisLength = axis.len;
// set the new axisLength
axis.setAxisSize();
- //axisLength = horiz ? axisWidth : axisHeight;
isDirtyAxisLength = axis.len !== axis.oldAxisLength;
// is there new data?
each(axis.series, function(series) {
- if (series.isDirtyData || series.isDirty ||
- series.xAxis.isDirty) { // when x axis is dirty, we need new data extremes for y as well
+ if (
+ series.isDirtyData ||
+ series.isDirty ||
+ // When x axis is dirty, we need new data extremes for y as well
+ series.xAxis.isDirty
+ ) {
isDirtyData = true;
}
});
// do we really need to go through all this?
- if (isDirtyAxisLength || isDirtyData || axis.isLinked || axis.forceRedraw ||
- axis.userMin !== axis.oldUserMin || axis.userMax !== axis.oldUserMax || axis.alignToOthers()) {
+ if (
+ isDirtyAxisLength ||
+ isDirtyData ||
+ axis.isLinked ||
+ axis.forceRedraw ||
+ axis.userMin !== axis.oldUserMin ||
+ axis.userMax !== axis.oldUserMax ||
+ axis.alignToOthers()
+ ) {
if (axis.resetStacks) {
axis.resetStacks();
}
@@ -13184,17 +12988,22 @@
axis.getSeriesExtremes();
// get fixed positions based on tickInterval
axis.setTickInterval();
- // record old values to decide whether a rescale is necessary later on (#540)
+ // record old values to decide whether a rescale is necessary later
+ // on (#540)
axis.oldUserMin = axis.userMin;
axis.oldUserMax = axis.userMax;
- // Mark as dirty if it is not already set to dirty and extremes have changed. #595.
+ // Mark as dirty if it is not already set to dirty and extremes have
+ // changed. #595.
if (!axis.isDirty) {
- axis.isDirty = isDirtyAxisLength || axis.min !== axis.oldMin || axis.max !== axis.oldMax;
+ axis.isDirty =
+ isDirtyAxisLength ||
+ axis.min !== axis.oldMin ||
+ axis.max !== axis.oldMax;
}
} else if (axis.cleanStacks) {
axis.cleanStacks();
}
},
@@ -13245,11 +13054,11 @@
min: newMin,
max: newMax
});
// Fire the event
- fireEvent(axis, 'setExtremes', eventArguments, function() { // the default event handler
+ fireEvent(axis, 'setExtremes', eventArguments, function() {
axis.userMin = newMin;
axis.userMax = newMax;
axis.eventArgs = eventArguments;
@@ -13272,13 +13081,15 @@
min = Math.min(dataMin, pick(options.min, dataMin)),
max = Math.max(dataMax, pick(options.max, dataMax));
if (newMin !== this.min || newMax !== this.max) { // #5790
- // Prevent pinch zooming out of range. Check for defined is for #1946. #1734.
+ // Prevent pinch zooming out of range. Check for defined is for
+ // #1946. #1734.
if (!this.allowZoomOutside) {
- // #6014, sometimes newMax will be smaller than min (or newMin will be larger than max).
+ // #6014, sometimes newMax will be smaller than min (or newMin
+ // will be larger than max).
if (defined(dataMin)) {
if (newMin < min) {
newMin = min;
}
if (newMin > max) {
@@ -13318,11 +13129,12 @@
* @private
*/
setAxisSize: function() {
var chart = this.chart,
options = this.options,
- offsets = options.offsets || [0, 0, 0, 0], // top / right / bottom / left
+ // [top, right, bottom, left]
+ offsets = options.offsets || [0, 0, 0, 0],
horiz = this.horiz,
// Check for percentage based input values. Rounding fixes problems
// with column overflow and plot line filtering (#4898, #4899)
width = this.width = Math.round(H.relativeLength(
@@ -13380,11 +13192,11 @@
* Get the current extremes for the axis.
*
* @returns {Extremes}
* An object containing extremes information.
*
- * @sample members/axis-getextremes/
+ * @sample highcharts/members/axis-getextremes/
* Report extremes by click on a button
* @sample maps/members/axis-getextremes/
* Get extremes in Highmaps
*/
getExtremes: function() {
@@ -13465,11 +13277,14 @@
* An array of tickLength and tickWidth
*/
tickSize: function(prefix) {
var options = this.options,
tickLength = options[prefix + 'Length'],
- tickWidth = pick(options[prefix + 'Width'], prefix === 'tick' && this.isXAxis ? 1 : 0); // X axis defaults to 1
+ tickWidth = pick(
+ options[prefix + 'Width'],
+ prefix === 'tick' && this.isXAxis ? 1 : 0 // X axis default 1
+ );
if (tickWidth && tickLength) {
// Negate the length
if (options[prefix + 'Position'] === 'inside') {
tickLength = -tickLength;
@@ -13502,18 +13317,21 @@
unsquish: function() {
var labelOptions = this.options.labels,
horiz = this.horiz,
tickInterval = this.tickInterval,
newTickInterval = tickInterval,
- slotSize = this.len / (((this.categories ? 1 : 0) + this.max - this.min) / tickInterval),
+ slotSize = this.len / (
+ ((this.categories ? 1 : 0) + this.max - this.min) / tickInterval
+ ),
rotation,
rotationOption = labelOptions.rotation,
labelMetrics = this.labelMetrics(),
step,
bestScore = Number.MAX_VALUE,
autoRotation,
- // Return the multiple of tickInterval that is needed to avoid collision
+ // Return the multiple of tickInterval that is needed to avoid
+ // collision
getStep = function(spaceNeeded) {
var step = spaceNeeded / (slotSize || 1);
step = step > 1 ? Math.ceil(step) : 1;
return step * tickInterval;
};
@@ -13568,19 +13386,24 @@
getSlotWidth: function() {
// #5086, #1580, #1931
var chart = this.chart,
horiz = this.horiz,
labelOptions = this.options.labels,
- slotCount = Math.max(this.tickPositions.length - (this.categories ? 0 : 1), 1),
+ slotCount = Math.max(
+ this.tickPositions.length - (this.categories ? 0 : 1),
+ 1
+ ),
marginLeft = chart.margin[3];
return (
horiz &&
(labelOptions.step || 0) < 2 &&
!labelOptions.rotation && // #4415
((this.staggerLines || 1) * this.len) / slotCount
) || (!horiz && (
+ // #7028
+ (labelOptions.style && parseInt(labelOptions.style.width, 10)) ||
(marginLeft && (marginLeft - chart.spacing[3])) ||
chart.chartWidth * 0.33
));
},
@@ -13949,20 +13772,13 @@
hasData && tickPositions.length && tickSize ?
tickSize[0] + directionFactor * axis.offset :
0 // #4866
);
- // Decide the clipping needed to keep the graph inside the plot area and
- // axis lines
- clip = Math.floor(axis.axisLine.strokeWidth() / 2) * 2; // #4308, #4371
- if (options.offset > 0) {
- clip -= options.offset * 2;
- }
- clipOffset[invertedSide] = Math.max(
- clipOffset[invertedSide] || clip,
- clip
- );
+ // Decide the clipping needed to keep the graph inside the plot area and axis lines
+ clip = options.offset ? 0 : Math.floor(axis.axisLine.strokeWidth() / 2) * 2; // #4308, #4371
+ clipOffset[invertedSide] = Math.max(clipOffset[invertedSide], clip);
},
/**
* Internal function to get the path for the axis line. Extended for polar
* charts.
@@ -14163,11 +13979,10 @@
from,
to;
// Reset
axis.labelEdge.length = 0;
- //axis.justifyToPlot = overflow === 'justify';
axis.overlap = false;
// Mark all elements inActive before we go over and mark the active ones
each([ticks, minorTicks, alternateBands], function(coll) {
objectEach(coll, function(tick) {
@@ -14456,10 +14271,12 @@
// Presentational attributes
graphic.attr({
'stroke': options.color || (categorized ? color('#ccd6eb').setOpacity(0.25).get() : '#cccccc'),
'stroke-width': pick(options.width, 1)
+ }).css({
+ 'pointer-events': 'none'
});
if (options.dashStyle) {
graphic.attr({
dashstyle: options.dashStyle
});
@@ -14840,11 +14657,13 @@
// we might as well handle the tick positions like a linear axis. For
// example 1.01, 1.02, 1.03, 1.04.
} else {
var realMin = lin2log(min),
realMax = lin2log(max),
- tickIntervalOption = options[minor ? 'minorTickInterval' : 'tickInterval'],
+ tickIntervalOption = minor ?
+ this.getMinorTickInterval() :
+ options.tickInterval,
filteredTickIntervalOption = tickIntervalOption === 'auto' ? null : tickIntervalOption,
tickPixelIntervalOption = options.tickPixelInterval / (minor ? 5 : 1),
totalPixelLength = minor ? axisLength / axis.tickPositions.length : axisLength;
interval = pick(
@@ -14936,11 +14755,12 @@
path = [],
color = options.color,
zIndex = pick(options.zIndex, 0),
events = options.events,
attribs = {
- 'class': 'highcharts-plot-' + (isBand ? 'band ' : 'line ') + (options.className || '')
+ 'class': 'highcharts-plot-' + (isBand ? 'band ' : 'line ') +
+ (options.className || '')
},
groupAttribs = {},
renderer = axis.chart.renderer,
groupName = isBand ? 'bands' : 'lines',
group,
@@ -14979,11 +14799,12 @@
groupAttribs.zIndex = zIndex;
groupName += '-' + zIndex;
group = axis.plotLinesAndBandsGroups[groupName];
if (!group) {
- axis.plotLinesAndBandsGroups[groupName] = group = renderer.g('plot-' + groupName)
+ axis.plotLinesAndBandsGroups[groupName] = group =
+ renderer.g('plot-' + groupName)
.attr(groupAttribs).add();
}
// Create the path
if (isNew) {
@@ -15031,12 +14852,19 @@
}
}
}
// the plot band/line label
- if (optionsLabel && defined(optionsLabel.text) && path && path.length &&
- axis.width > 0 && axis.height > 0 && !path.flat) {
+ if (
+ optionsLabel &&
+ defined(optionsLabel.text) &&
+ path &&
+ path.length &&
+ axis.width > 0 &&
+ axis.height > 0 &&
+ !path.flat
+ ) {
// apply defaults
optionsLabel = merge({
align: horiz && isBand && 'center',
x: horiz ? !isBand && 4 : 10,
verticalAlign: !horiz && isBand && 'middle',
@@ -15060,21 +14888,22 @@
renderLabel: function(optionsLabel, path, isBand, zIndex) {
var plotLine = this,
label = plotLine.label,
renderer = plotLine.axis.chart.renderer,
attribs,
- xs,
- ys,
+ xBounds,
+ yBounds,
x,
y;
// add the SVG element
if (!label) {
attribs = {
align: optionsLabel.textAlign || optionsLabel.align,
rotation: optionsLabel.rotation,
- 'class': 'highcharts-plot-' + (isBand ? 'band' : 'line') + '-label ' + (optionsLabel.className || '')
+ 'class': 'highcharts-plot-' + (isBand ? 'band' : 'line') +
+ '-label ' + (optionsLabel.className || '')
};
attribs.zIndex = zIndex;
plotLine.label = label = renderer.text(
@@ -15091,20 +14920,21 @@
}
// get the bounding box and align the label
// #3000 changed to better handle choice between plotband or plotline
- xs = [path[1], path[4], (isBand ? path[6] : path[1])];
- ys = [path[2], path[5], (isBand ? path[7] : path[2])];
- x = arrayMin(xs);
- y = arrayMin(ys);
+ xBounds = path.xBounds || [path[1], path[4], (isBand ? path[6] : path[1])];
+ yBounds = path.yBounds || [path[2], path[5], (isBand ? path[7] : path[2])];
+ x = arrayMin(xBounds);
+ y = arrayMin(yBounds);
+
label.align(optionsLabel, false, {
x: x,
y: y,
- width: arrayMax(xs) - x,
- height: arrayMax(ys) - y
+ width: arrayMax(xBounds) - x,
+ height: arrayMax(yBounds) - y
});
label.show();
},
/**
@@ -15156,11 +14986,12 @@
}
// Add 1 pixel, when coordinates are the same
path.push(
horiz && toPath[4] === path[4] ? toPath[4] + plus : toPath[4], !horiz && toPath[5] === path[5] ? toPath[5] + plus : toPath[5],
- horiz && toPath[1] === path[1] ? toPath[1] + plus : toPath[1], !horiz && toPath[2] === path[2] ? toPath[2] + plus : toPath[2]
+ horiz && toPath[1] === path[1] ? toPath[1] + plus : toPath[1], !horiz && toPath[2] === path[2] ? toPath[2] + plus : toPath[2],
+ 'z'
);
} else { // outside the axis area
path = null;
}
@@ -15318,13 +15149,10 @@
// Save the chart and options
this.chart = chart;
this.options = options;
- // Keep track of the current series
- //this.currentSeries = undefined;
-
// List of crosshairs
this.crosshairs = [];
// Current values of x and y when animating
this.now = {
@@ -15449,21 +15277,25 @@
* @private
*/
move: function(x, y, anchorX, anchorY) {
var tooltip = this,
now = tooltip.now,
- animate = tooltip.options.animation !== false && !tooltip.isHidden &&
- // When we get close to the target position, abort animation and land on the right place (#3056)
+ animate = tooltip.options.animation !== false &&
+ !tooltip.isHidden &&
+ // When we get close to the target position, abort animation and
+ // land on the right place (#3056)
(Math.abs(x - now.x) > 1 || Math.abs(y - now.y) > 1),
skipAnchor = tooltip.followPointer || tooltip.len > 1;
// Get intermediate values for animation
extend(now, {
x: animate ? (2 * now.x + x) / 3 : x,
y: animate ? (now.y + y) / 2 : y,
- anchorX: skipAnchor ? undefined : animate ? (2 * now.anchorX + anchorX) / 3 : anchorX,
- anchorY: skipAnchor ? undefined : animate ? (now.anchorY + anchorY) / 2 : anchorY
+ anchorX: skipAnchor ?
+ undefined : animate ? (2 * now.anchorX + anchorX) / 3 : anchorX,
+ anchorY: skipAnchor ?
+ undefined : animate ? (now.anchorY + anchorY) / 2 : anchorY
});
// Move to the intermediate value
tooltip.getLabel().attr(now);
@@ -15489,11 +15321,12 @@
/**
* Hide the tooltip
*/
hide: function(delay) {
var tooltip = this;
- clearTimeout(this.hideTimer); // disallow duplicate timers (#1728, #1766)
+ // disallow duplicate timers (#1728, #1766)
+ clearTimeout(this.hideTimer);
delay = pick(delay, this.options.hideDelay, 500);
if (!this.isHidden) {
this.hideTimer = syncTimeout(function() {
tooltip.getLabel()[delay ? 'fadeOut' : 'hide']();
tooltip.isHidden = true;
@@ -15534,22 +15367,29 @@
// When shared, use the average position
if (!ret) {
each(points, function(point) {
yAxis = point.series.yAxis;
xAxis = point.series.xAxis;
- plotX += point.plotX + (!inverted && xAxis ? xAxis.left - plotLeft : 0);
- plotY += (point.plotLow ? (point.plotLow + point.plotHigh) / 2 : point.plotY) +
+ plotX += point.plotX +
+ (!inverted && xAxis ? xAxis.left - plotLeft : 0);
+ plotY +=
+ (
+ point.plotLow ?
+ (point.plotLow + point.plotHigh) / 2 :
+ point.plotY
+ ) +
(!inverted && yAxis ? yAxis.top - plotTop : 0); // #1151
});
plotX /= points.length;
plotY /= points.length;
ret = [
inverted ? chart.plotWidth - plotY : plotX,
this.shared && !inverted && points.length > 1 && mouseEvent ?
- mouseEvent.chartY - plotTop : // place shared tooltip next to the mouse (#424)
+ // place shared tooltip next to the mouse (#424)
+ mouseEvent.chartY - plotTop :
inverted ? chart.plotHeight - plotX : plotY
];
}
return map(ret, Math.round);
@@ -15573,27 +15413,41 @@
second = ['x', chart.chartWidth, boxWidth,
point.plotX + chart.plotLeft, chart.plotLeft,
chart.plotLeft + chart.plotWidth
],
// The far side is right or bottom
- preferFarSide = !this.followPointer && pick(point.ttBelow, !chart.inverted === !!point.negative), // #4984
+ preferFarSide = !this.followPointer && pick(
+ point.ttBelow, !chart.inverted === !!point.negative
+ ), // #4984
+
/**
- * Handle the preferred dimension. When the preferred dimension is tooltip
- * on top or bottom of the point, it will look for space there.
+ * Handle the preferred dimension. When the preferred dimension is
+ * tooltip on top or bottom of the point, it will look for space
+ * there.
*/
- firstDimension = function(dim, outerSize, innerSize, point, min, max) {
+ firstDimension = function(
+ dim,
+ outerSize,
+ innerSize,
+ point,
+ min,
+ max
+ ) {
var roomLeft = innerSize < point - distance,
roomRight = point + distance + innerSize < outerSize,
alignedLeft = point - distance - innerSize,
alignedRight = point + distance;
if (preferFarSide && roomRight) {
ret[dim] = alignedRight;
} else if (!preferFarSide && roomLeft) {
ret[dim] = alignedLeft;
} else if (roomLeft) {
- ret[dim] = Math.min(max - innerSize, alignedLeft - h < 0 ? alignedLeft : alignedLeft - h);
+ ret[dim] = Math.min(
+ max - innerSize,
+ alignedLeft - h < 0 ? alignedLeft : alignedLeft - h
+ );
} else if (roomRight) {
ret[dim] = Math.max(
min,
alignedRight + h + innerSize > outerSize ?
alignedRight :
@@ -15602,14 +15456,14 @@
} else {
return false;
}
},
/**
- * Handle the secondary dimension. If the preferred dimension is tooltip
- * on top or bottom of the point, the second dimension is to align the tooltip
- * above the point, trying to align center but allowing left or right
- * align within the chart box.
+ * Handle the secondary dimension. If the preferred dimension is
+ * tooltip on top or bottom of the point, the second dimension is to
+ * align the tooltip above the point, trying to align center but
+ * allowing left or right align within the chart box.
*/
secondDimension = function(dim, outerSize, innerSize, point) {
var retVal;
// Too close to the edge, return false and swap dimensions
@@ -15636,11 +15490,14 @@
second = temp;
swapped = count;
},
run = function() {
if (firstDimension.apply(0, first) !== false) {
- if (secondDimension.apply(0, second) === false && !swapped) {
+ if (
+ secondDimension.apply(0, second) === false &&
+ !swapped
+ ) {
swap(true);
run();
}
} else if (!swapped) {
swap(true);
@@ -15659,12 +15516,12 @@
return ret;
},
/**
- * In case no user defined formatter is given, this will be used. Note that the context
- * here is an object holding point, series, x, y etc.
+ * In case no user defined formatter is given, this will be used. Note that
+ * the context here is an object holding point, series, x, y etc.
*
* @returns {String|Array<String>}
*/
defaultFormatter: function(tooltip) {
var items = this.points || splat(this),
@@ -15706,11 +15563,12 @@
}
clearTimeout(this.hideTimer);
// get the reference point coordinates (pie charts use tooltipPos)
- tooltip.followPointer = splat(point)[0].series.tooltipOptions.followPointer;
+ tooltip.followPointer = splat(point)[0].series.tooltipOptions
+ .followPointer;
anchor = tooltip.getAnchor(point, mouseEvent);
x = anchor[0];
y = anchor[1];
// shared tooltip, array is sent over
@@ -15773,15 +15631,23 @@
text: text && text.join ? text.join('') : text
});
// Set the stroke color of the box to reflect the point
label.removeClass(/highcharts-color-[\d]+/g)
- .addClass('highcharts-color-' + pick(point.colorIndex, currentSeries.colorIndex));
+ .addClass(
+ 'highcharts-color-' +
+ pick(point.colorIndex, currentSeries.colorIndex)
+ );
label.attr({
- stroke: options.borderColor || point.color || currentSeries.color || '#666666'
+ stroke: (
+ options.borderColor ||
+ point.color ||
+ currentSeries.color ||
+ '#666666'
+ )
});
tooltip.updatePosition({
plotX: x,
@@ -15809,10 +15675,14 @@
rightAligned = true,
options = this.options,
headerHeight = 0,
tooltipLabel = this.getLabel();
+ // Graceful degradation for legacy formatters
+ if (H.isString(labels)) {
+ labels = [false, labels];
+ }
// Create the individual labels for header and points, ignore footer
each(labels.slice(0, points.length + 1), function(str, i) {
if (str !== false) {
var point = points[i - 1] ||
// Item 0 is the header. Instead of this, we could also
@@ -15973,13 +15843,17 @@
day: 3
},
lastN = 'millisecond'; // for sub-millisecond data, #4223
for (n in timeUnits) {
- // If the range is exactly one week and we're looking at a Sunday/Monday, go for the week format
- if (range === timeUnits.week && +dateFormat('%w', date) === startOfWeek &&
- dateStr.substr(6) === blank.substr(6)) {
+ // If the range is exactly one week and we're looking at a
+ // Sunday/Monday, go for the week format
+ if (
+ range === timeUnits.week &&
+ +dateFormat('%w', date) === startOfWeek &&
+ dateStr.substr(6) === blank.substr(6)
+ ) {
n = 'week';
break;
}
// The first format that is too great for the range
@@ -15988,15 +15862,19 @@
break;
}
// If the point is placed every day at 23:59, we need to show
// the minutes as well. #2637.
- if (strpos[n] && dateStr.substr(strpos[n]) !== blank.substr(strpos[n])) {
+ if (
+ strpos[n] &&
+ dateStr.substr(strpos[n]) !== blank.substr(strpos[n])
+ ) {
break;
}
- // Weeks are outside the hierarchy, only apply them on Mondays/Sundays like in the first condition
+ // Weeks are outside the hierarchy, only apply them on
+ // Mondays/Sundays like in the first condition
if (n !== 'week') {
lastN = n;
}
}
@@ -16037,38 +15915,61 @@
var footOrHead = isFooter ? 'footer' : 'header',
series = labelConfig.series,
tooltipOptions = series.tooltipOptions,
xDateFormat = tooltipOptions.xDateFormat,
xAxis = series.xAxis,
- isDateTime = xAxis && xAxis.options.type === 'datetime' && isNumber(labelConfig.key),
+ isDateTime = (
+ xAxis &&
+ xAxis.options.type === 'datetime' &&
+ isNumber(labelConfig.key)
+ ),
formatString = tooltipOptions[footOrHead + 'Format'];
- // Guess the best date format based on the closest point distance (#568, #3418)
+ // Guess the best date format based on the closest point distance (#568,
+ // #3418)
if (isDateTime && !xDateFormat) {
- xDateFormat = this.getXDateFormat(labelConfig, tooltipOptions, xAxis);
+ xDateFormat = this.getXDateFormat(
+ labelConfig,
+ tooltipOptions,
+ xAxis
+ );
}
// Insert the footer date format if any
if (isDateTime && xDateFormat) {
- formatString = formatString.replace('{point.key}', '{point.key:' + xDateFormat + '}');
+ each(
+ (labelConfig.point && labelConfig.point.tooltipDateKeys) || ['key'],
+ function(key) {
+ formatString = formatString.replace(
+ '{point.' + key + '}',
+ '{point.' + key + ':' + xDateFormat + '}'
+ );
+ }
+ );
}
return format(formatString, {
point: labelConfig,
series: series
});
},
/**
- * Build the body (lines) of the tooltip by iterating over the items and returning one entry for each item,
- * abstracting this functionality allows to easily overwrite and extend it.
+ * Build the body (lines) of the tooltip by iterating over the items and
+ * returning one entry for each item, abstracting this functionality allows
+ * to easily overwrite and extend it.
*/
bodyFormatter: function(items) {
return map(items, function(item) {
var tooltipOptions = item.series.tooltipOptions;
- return (tooltipOptions.pointFormatter || item.point.tooltipFormatter)
- .call(item.point, tooltipOptions.pointFormat);
+ return (
+ tooltipOptions.pointFormatter ||
+ item.point.tooltipFormatter
+ ).call(
+ item.point,
+ tooltipOptions[(item.point.formatPrefix || 'point') + 'Format']
+ );
});
}
};
@@ -16093,12 +15994,11 @@
isObject = H.isObject,
offset = H.offset,
pick = H.pick,
removeEvent = H.removeEvent,
splat = H.splat,
- Tooltip = H.Tooltip,
- win = H.win;
+ Tooltip = H.Tooltip;
/**
* The mouse and touch tracker object. Each {@link Chart} item has one
* assosiated Pointer item that can be accessed from the {@link Chart.pointer}
* property.
@@ -16188,41 +16088,23 @@
*
* @return {PointerEvent}
* A browser event with extended properties `chartX` and `chartY`.
*/
normalize: function(e, chartPosition) {
- var chartX,
- chartY,
- ePos;
+ var ePos;
- // IE normalizing
- e = e || win.event;
- if (!e.target) {
- e.target = e.srcElement;
- }
-
// iOS (#2757)
ePos = e.touches ? (e.touches.length ? e.touches.item(0) : e.changedTouches[0]) : e;
// Get mouse position
if (!chartPosition) {
this.chartPosition = chartPosition = offset(this.chart.container);
}
- // chartX and chartY
- if (ePos.pageX === undefined) { // IE < 9. #886.
- chartX = Math.max(e.x, e.clientX - chartPosition.left); // #2005, #2129: the second case is
- // for IE10 quirks mode within framesets
- chartY = e.y;
- } else {
- chartX = ePos.pageX - chartPosition.left;
- chartY = ePos.pageY - chartPosition.top;
- }
-
return extend(e, {
- chartX: Math.round(chartX),
- chartY: Math.round(chartY)
+ chartX: Math.round(ePos.pageX - chartPosition.left),
+ chartY: Math.round(ePos.pageY - chartPosition.top)
});
},
/**
* Get the click position in terms of axis values.
@@ -16360,15 +16242,17 @@
existingHoverPoint,
existingHoverSeries,
series,
isDirectTouch,
shared,
- coordinates
+ coordinates,
+ params
) {
var hoverPoint,
hoverPoints = [],
hoverSeries = existingHoverSeries,
+ isBoosting = params && params.isBoosting,
useExisting = !!(isDirectTouch && existingHoverPoint),
notSticky = hoverSeries && !hoverSeries.stickyTracking,
filter = function(s) {
return (
s.visible &&
@@ -16402,21 +16286,27 @@
});
// Get all points with the same x value as the hoverPoint
each(searchSeries, function(s) {
var point = find(s.points, function(p) {
- return p.x === hoverPoint.x;
+ return p.x === hoverPoint.x && !p.isNull;
});
- if (isObject(point) && !point.isNull) {
+ if (isObject(point)) {
+ /*
+ * Boost returns a minimal point. Convert it to a usable
+ * point for tooltip and states.
+ */
+ if (isBoosting) {
+ point = s.getPoint(point);
+ }
hoverPoints.push(point);
}
});
} else {
hoverPoints.push(hoverPoint);
}
}
-
return {
hoverPoint: hoverPoint,
hoverSeries: hoverSeries,
hoverPoints: hoverPoints
};
@@ -16429,11 +16319,13 @@
*/
runPointActions: function(e, p) {
var pointer = this,
chart = pointer.chart,
series = chart.series,
- tooltip = chart.tooltip,
+ tooltip = chart.tooltip && chart.tooltip.options.enabled ?
+ chart.tooltip :
+ undefined,
shared = tooltip ? tooltip.shared : false,
hoverPoint = p || chart.hoverPoint,
hoverSeries = hoverPoint && hoverPoint.series || chart.hoverSeries,
// onMouseOver or already hovering a series with directTouch
isDirectTouch = !!p || (
@@ -16444,16 +16336,19 @@
hoverPoint,
hoverSeries,
series,
isDirectTouch,
shared,
- e
+ e, {
+ isBoosting: chart.isBoosting
+ }
),
useSharedTooltip,
followPointer,
anchor,
points;
+
// Update variables from hoverData.
hoverPoint = hoverData.hoverPoint;
points = hoverData.hoverPoints;
hoverSeries = hoverData.hoverSeries;
followPointer = hoverSeries && hoverSeries.tooltipOptions.followPointer;
@@ -16483,10 +16378,16 @@
// If tracking is on series in stead of on each point,
// fire mouseOver on hover point. // #4448
if (chart.hoverPoint) {
chart.hoverPoint.firePointEvent('mouseOut');
}
+
+ // Hover point may have been destroyed in the event handlers (#7127)
+ if (!hoverPoint.series) {
+ return;
+ }
+
hoverPoint.firePointEvent('mouseOver');
chart.hoverPoints = points;
chart.hoverPoint = hoverPoint;
// Draw tooltip if necessary
if (tooltip) {
@@ -16934,14 +16835,22 @@
},
onTrackerMouseOut: function(e) {
var series = this.chart.hoverSeries,
relatedTarget = e.relatedTarget || e.toElement;
+
this.isDirectTouch = false;
- if (series && relatedTarget && !series.stickyTracking &&
+
+ if (
+ series &&
+ relatedTarget &&
+ !series.stickyTracking &&
!this.inClass(relatedTarget, 'highcharts-tooltip') &&
- (!this.inClass(relatedTarget, 'highcharts-series-' + series.index) || // #2499, #4465
+ (!this.inClass(
+ relatedTarget,
+ 'highcharts-series-' + series.index
+ ) || // #2499, #4465
!this.inClass(relatedTarget, 'highcharts-tracker') // #5553
)
) {
series.onMouseOut();
}
@@ -17083,21 +16992,45 @@
extend(Pointer.prototype, /** @lends Pointer.prototype */ {
/**
* Run translation operations
*/
- pinchTranslate: function(pinchDown, touches, transform, selectionMarker, clip, lastValidTouch) {
+ pinchTranslate: function(
+ pinchDown,
+ touches,
+ transform,
+ selectionMarker,
+ clip,
+ lastValidTouch
+ ) {
if (this.zoomHor) {
- this.pinchTranslateDirection(true, pinchDown, touches, transform, selectionMarker, clip, lastValidTouch);
+ this.pinchTranslateDirection(
+ true,
+ pinchDown,
+ touches,
+ transform,
+ selectionMarker,
+ clip,
+ lastValidTouch
+ );
}
if (this.zoomVert) {
- this.pinchTranslateDirection(false, pinchDown, touches, transform, selectionMarker, clip, lastValidTouch);
+ this.pinchTranslateDirection(
+ false,
+ pinchDown,
+ touches,
+ transform,
+ selectionMarker,
+ clip,
+ lastValidTouch
+ );
}
},
/**
- * Run translation operations for each direction (horizontal and vertical) independently
+ * Run translation operations for each direction (horizontal and vertical)
+ * independently
*/
pinchTranslateDirection: function(horiz, pinchDown, touches, transform,
selectionMarker, clip, lastValidTouch, forcedScale) {
var chart = this.chart,
xy = horiz ? 'x' : 'y',
@@ -17120,42 +17053,50 @@
transformScale,
scaleKey,
setScale = function() {
// Don't zoom if fingers are too close on this axis
if (!singleTouch && Math.abs(touch0Start - touch1Start) > 20) {
- scale = forcedScale || Math.abs(touch0Now - touch1Now) / Math.abs(touch0Start - touch1Start);
+ scale = forcedScale ||
+ Math.abs(touch0Now - touch1Now) /
+ Math.abs(touch0Start - touch1Start);
}
clipXY = ((plotLeftTop - touch0Now) / scale) + touch0Start;
- selectionWH = chart['plot' + (horiz ? 'Width' : 'Height')] / scale;
+ selectionWH = chart['plot' + (horiz ? 'Width' : 'Height')] /
+ scale;
};
// Set the scale, first pass
setScale();
- selectionXY = clipXY; // the clip position (x or y) is altered if out of bounds, the selection position is not
+ // The clip position (x or y) is altered if out of bounds, the selection
+ // position is not
+ selectionXY = clipXY;
// Out of bounds
if (selectionXY < bounds.min) {
selectionXY = bounds.min;
outOfBounds = true;
} else if (selectionXY + selectionWH > bounds.max) {
selectionXY = bounds.max - selectionWH;
outOfBounds = true;
}
- // Is the chart dragged off its bounds, determined by dataMin and dataMax?
+ // Is the chart dragged off its bounds, determined by dataMin and
+ // dataMax?
if (outOfBounds) {
- // Modify the touchNow position in order to create an elastic drag movement. This indicates
- // to the user that the chart is responsive but can't be dragged further.
+ // Modify the touchNow position in order to create an elastic drag
+ // movement. This indicates to the user that the chart is responsive
+ // but can't be dragged further.
touch0Now -= 0.8 * (touch0Now - lastValidTouch[xy][0]);
if (!singleTouch) {
touch1Now -= 0.8 * (touch1Now - lastValidTouch[xy][1]);
}
- // Set the scale, second pass to adapt to the modified touchNow positions
+ // Set the scale, second pass to adapt to the modified touchNow
+ // positions
setScale();
} else {
lastValidTouch[xy] = [touch0Now, touch1Now];
}
@@ -17169,11 +17110,12 @@
transformScale = inverted ? 1 / scale : scale;
selectionMarker[wh] = selectionWH;
selectionMarker[xy] = selectionXY;
transform[scaleKey] = scale;
- transform['translate' + XY] = (transformScale * plotLeftTop) + (touch0Now - (transformScale * touch0Start));
+ transform['translate' + XY] = (transformScale * plotLeftTop) +
+ (touch0Now - (transformScale * touch0Start));
},
/**
* Handle touch events with two touches
*/
@@ -17186,21 +17128,24 @@
touchesLength = touches.length,
lastValidTouch = self.lastValidTouch,
hasZoom = self.hasZoom,
selectionMarker = self.selectionMarker,
transform = {},
- fireClickEvent = touchesLength === 1 && ((self.inClass(e.target, 'highcharts-tracker') &&
+ fireClickEvent = touchesLength === 1 &&
+ ((self.inClass(e.target, 'highcharts-tracker') &&
chart.runTrackerClick) || self.runChartClick),
clip = {};
- // Don't initiate panning until the user has pinched. This prevents us from
- // blocking page scrolling as users scroll down a long page (#4210).
+ // Don't initiate panning until the user has pinched. This prevents us
+ // from blocking page scrolling as users scroll down a long page
+ // (#4210).
if (touchesLength > 1) {
self.initiated = true;
}
- // On touch devices, only proceed to trigger click if a handler is defined
+ // On touch devices, only proceed to trigger click if a handler is
+ // defined
if (hasZoom && self.initiated && !fireClickEvent) {
e.preventDefault();
}
// Normalize each touch
@@ -17214,51 +17159,71 @@
pinchDown[i] = {
chartX: e.chartX,
chartY: e.chartY
};
});
- lastValidTouch.x = [pinchDown[0].chartX, pinchDown[1] && pinchDown[1].chartX];
- lastValidTouch.y = [pinchDown[0].chartY, pinchDown[1] && pinchDown[1].chartY];
+ lastValidTouch.x = [pinchDown[0].chartX, pinchDown[1] &&
+ pinchDown[1].chartX
+ ];
+ lastValidTouch.y = [pinchDown[0].chartY, pinchDown[1] &&
+ pinchDown[1].chartY
+ ];
// Identify the data bounds in pixels
each(chart.axes, function(axis) {
if (axis.zoomEnabled) {
var bounds = chart.bounds[axis.horiz ? 'h' : 'v'],
minPixelPadding = axis.minPixelPadding,
- min = axis.toPixels(pick(axis.options.min, axis.dataMin)),
- max = axis.toPixels(pick(axis.options.max, axis.dataMax)),
+ min = axis.toPixels(
+ pick(axis.options.min, axis.dataMin)
+ ),
+ max = axis.toPixels(
+ pick(axis.options.max, axis.dataMax)
+ ),
absMin = Math.min(min, max),
absMax = Math.max(min, max);
// Store the bounds for use in the touchmove handler
bounds.min = Math.min(axis.pos, absMin - minPixelPadding);
- bounds.max = Math.max(axis.pos + axis.len, absMax + minPixelPadding);
+ bounds.max = Math.max(
+ axis.pos + axis.len,
+ absMax + minPixelPadding
+ );
}
});
self.res = true; // reset on next move
// Optionally move the tooltip on touchmove
} else if (self.followTouchMove && touchesLength === 1) {
this.runPointActions(self.normalize(e));
// Event type is touchmove, handle panning and pinching
- } else if (pinchDown.length) { // can be 0 when releasing, if touchend fires first
+ } else if (pinchDown.length) { // can be 0 when releasing, if touchend
+ // fires first
// Set the marker
if (!selectionMarker) {
self.selectionMarker = selectionMarker = extend({
destroy: noop,
touch: true
}, chart.plotBox);
}
- self.pinchTranslate(pinchDown, touches, transform, selectionMarker, clip, lastValidTouch);
+ self.pinchTranslate(
+ pinchDown,
+ touches,
+ transform,
+ selectionMarker,
+ clip,
+ lastValidTouch
+ );
self.hasPinched = hasZoom;
- // Scale and translate the groups to provide visual feedback during pinching
+ // Scale and translate the groups to provide visual feedback during
+ // pinching
self.scaleGroups(transform, clip);
if (self.res) {
self.res = false;
this.reset(false, 0);
@@ -17295,15 +17260,16 @@
// Run mouse events and display tooltip etc
if (start) {
this.runPointActions(e);
}
- // Android fires touchmove events after the touchstart even if the
- // finger hasn't moved, or moved only a pixel or two. In iOS however,
- // the touchmove doesn't fire unless the finger moves more than ~4px.
- // So we emulate this behaviour in Android by checking how much it
- // moved, and cancelling on small distances. #3450.
+ // Android fires touchmove events after the touchstart even if
+ // the finger hasn't moved, or moved only a pixel or two. In iOS
+ // however, the touchmove doesn't fire unless the finger moves
+ // more than ~4px. So we emulate this behaviour in Android by
+ // checking how much it moved, and cancelling on small
+ // distances. #3450.
if (e.type === 'touchmove') {
pinchDown = this.pinchDown;
hasMoved = pinchDown[0] ? Math.sqrt( // #5266
Math.pow(pinchDown[0].chartX - e.chartX, 2) +
Math.pow(pinchDown[0].chartY - e.chartY, 2)
@@ -17942,16 +17908,18 @@
itemMarginBottom;
legend.lastLineHeight = 0; // reset for next line (#915, #3976)
}
// If the item exceeds the height, start a new column
- /*if (!horizontal && legend.itemY + options.y +
+ /*
+ if (!horizontal && legend.itemY + options.y +
itemHeight > chart.chartHeight - spacingTop - spacingBottom) {
legend.itemY = legend.initialItemY;
legend.itemX += legend.maxItemWidth;
legend.maxItemWidth = 0;
- }*/
+ }
+ */
// Set the edge positions
legend.maxItemWidth = Math.max(legend.maxItemWidth, itemWidth);
legend.lastItemY = itemMarginTop + legend.itemY + itemMarginBottom;
legend.lastLineHeight = Math.max( // #915
@@ -18178,23 +18146,10 @@
// in the final position
each(allItems, function(item) {
legend.positionItem(item);
});
- // 1.x compatibility: positioning based on style
- /*var props = ['left', 'right', 'top', 'bottom'],
- prop,
- i = 4;
- while (i--) {
- prop = props[i];
- if (options.style[prop] && options.style[prop] !== 'auto') {
- options[i < 2 ? 'align' : 'verticalAlign'] = prop;
- options[i < 2 ? 'x' : 'y'] =
- pInt(options.style[prop]) * (i % 2 ? -1 : 1);
- }
- }*/
-
if (display) {
legendGroup.align(merge(options, {
width: legendWidth,
height: legendHeight
}), true, 'spacingBox');
@@ -18596,11 +18551,10 @@
defined = H.defined,
each = H.each,
extend = H.extend,
find = H.find,
fireEvent = H.fireEvent,
- getStyle = H.getStyle,
grep = H.grep,
isNumber = H.isNumber,
isObject = H.isObject,
isString = H.isString,
Legend = H.Legend, // @todo add as requirement
@@ -18613,12 +18567,11 @@
removeEvent = H.removeEvent,
seriesTypes = H.seriesTypes,
splat = H.splat,
svg = H.svg,
syncTimeout = H.syncTimeout,
- win = H.win,
- Renderer = H.Renderer;
+ win = H.win;
/**
* The Chart class. The recommended constructor is {@link Highcharts#chart}.
* @class Highcharts.Chart
* @param {String|HTMLDOMElement} renderTo
* The DOM element to render to, or its id.
@@ -18732,16 +18685,19 @@
var chartEvents = optionsChart.events;
this.margin = [];
this.spacing = [];
- //this.runChartClick = chartEvents && !!chartEvents.click;
this.bounds = {
h: {},
v: {}
}; // Pixel data bounds for touch zoom
+ // An array of functions that returns labels that should be considered
+ // for anti-collision
+ this.labelCollectors = [];
+
this.callback = callback;
this.isResizing = 0;
/**
* The options structure for the chart. It contains members for the sub
@@ -18794,37 +18750,11 @@
*/
this.hasCartesianSeries = optionsChart.showAxes;
- //this.axisOffset = undefined;
- //this.inverted = undefined;
- //this.loadingShown = undefined;
- //this.container = undefined;
- //this.chartWidth = undefined;
- //this.chartHeight = undefined;
- //this.marginRight = undefined;
- //this.marginBottom = undefined;
- //this.containerWidth = undefined;
- //this.containerHeight = undefined;
- //this.oldChartWidth = undefined;
- //this.oldChartHeight = undefined;
- //this.renderTo = undefined;
-
- //this.spacingBox = undefined
-
- //this.legend = undefined;
-
- // Elements
- //this.chartBackground = undefined;
- //this.plotBackground = undefined;
- //this.plotBGImage = undefined;
- //this.plotBorder = undefined;
- //this.loadingDiv = undefined;
- //this.loadingSpan = undefined;
-
var chart = this;
// Add the chart to the global lookup
chart.index = charts.length;
@@ -19367,14 +19297,14 @@
heightOption = optionsChart.height,
renderTo = chart.renderTo;
// Get inner width and height
if (!defined(widthOption)) {
- chart.containerWidth = getStyle(renderTo, 'width');
+ chart.containerWidth = H.getStyle(renderTo, 'width');
}
if (!defined(heightOption)) {
- chart.containerHeight = getStyle(renderTo, 'height');
+ chart.containerHeight = H.getStyle(renderTo, 'height');
}
/**
* The current pixel width of the chart.
*
@@ -19396,11 +19326,12 @@
chart.chartHeight = Math.max(
0,
H.relativeLength(
heightOption,
chart.chartWidth
- ) || chart.containerHeight || 400
+ ) ||
+ (chart.containerHeight > 1 ? chart.containerHeight : 400)
);
},
/**
* If the renderTo element has no offsetWidth, most likely one or more of
@@ -19418,17 +19349,18 @@
tempStyle;
if (!revert) {
while (node && node.style) {
// When rendering to a detached node, it needs to be temporarily
- // attached in order to read styling and bounding boxes (#5783).
- if (!doc.body.contains(node)) {
+ // attached in order to read styling and bounding boxes (#5783,
+ // #7024).
+ if (!doc.body.contains(node) && !node.parentNode) {
node.hcOrigDetached = true;
doc.body.appendChild(node);
}
if (
- getStyle(node, 'display', false) === 'none' ||
+ H.getStyle(node, 'display', false) === 'none' ||
node.hcOricDetached
) {
node.hcOrigStyle = {
display: node.style.display,
height: node.style.height,
@@ -19582,11 +19514,12 @@
// cache the cursor (#1650)
chart._cursor = container.style.cursor;
// Initialize the renderer
- Ren = H[optionsChart.renderer] || Renderer;
+ Ren = H[optionsChart.renderer] || H.Renderer;
+
/**
* The renderer instance of the chart. Each chart instance has only one
* associated renderer.
* @type {SVGRenderer}
* @name renderer
@@ -19633,22 +19566,25 @@
titleOffset + chart.options.title.margin + spacing[0]
);
}
// Adjust for legend
- if (chart.legend.display) {
+ if (chart.legend && chart.legend.display) {
chart.legend.adjustMargins(margin, spacing);
}
// adjust for scroller
if (chart.extraMargin) {
chart[chart.extraMargin.type] =
(chart[chart.extraMargin.type] || 0) + chart.extraMargin.value;
}
- if (chart.extraTopMargin) {
- chart.plotTop += chart.extraTopMargin;
+
+ // adjust for rangeSelector
+ if (chart.adjustPlotArea) {
+ chart.adjustPlotArea();
}
+
if (!skipAxes) {
this.getAxisMargins();
}
},
@@ -19702,12 +19638,12 @@
renderTo = chart.renderTo,
hasUserSize = (
defined(optionsChart.width) &&
defined(optionsChart.height)
),
- width = optionsChart.width || getStyle(renderTo, 'width'),
- height = optionsChart.height || getStyle(renderTo, 'height'),
+ width = optionsChart.width || H.getStyle(renderTo, 'width'),
+ height = optionsChart.height || H.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 (!hasUserSize &&
@@ -19870,15 +19806,10 @@
plotTop,
plotWidth,
plotHeight,
plotBorderWidth;
- function clipOffsetSide(side) {
- var offset = clipOffset[side] || 0;
- return Math.max(plotBorderWidth || offset, offset) / 2;
- }
-
/**
* The current left position of the plot area in pixels.
*
* @name plotLeft
* @memberOf Chart
@@ -19937,25 +19868,25 @@
width: plotWidth,
height: plotHeight
};
plotBorderWidth = 2 * Math.floor(chart.plotBorderWidth / 2);
- clipX = Math.ceil(clipOffsetSide(3));
- clipY = Math.ceil(clipOffsetSide(0));
+ clipX = Math.ceil(Math.max(plotBorderWidth, clipOffset[3]) / 2);
+ clipY = Math.ceil(Math.max(plotBorderWidth, clipOffset[0]) / 2);
chart.clipBox = {
x: clipX,
y: clipY,
width: Math.floor(
chart.plotSizeX -
- clipOffsetSide(1) -
+ Math.max(plotBorderWidth, clipOffset[1]) / 2 -
clipX
),
height: Math.max(
0,
Math.floor(
chart.plotSizeY -
- clipOffsetSide(2) -
+ Math.max(plotBorderWidth, clipOffset[2]) / 2 -
clipY
)
)
};
@@ -19993,11 +19924,11 @@
// chart.marginRight, chart.marginBottom.
each(marginNames, function(m, side) {
chart[m] = pick(chart.margin[side], chart.spacing[side]);
});
chart.axisOffset = [0, 0, 0, 0]; // top, right, bottom, left
- chart.clipOffset = [];
+ chart.clipOffset = [0, 0, 0, 0];
},
/**
* Internal function to draw or redraw the borders and backgrounds for chart
* and plot area.
@@ -20132,11 +20063,11 @@
plotBorder[verb](plotBorder.crisp({
x: plotLeft,
y: plotTop,
width: plotWidth,
height: plotHeight
- }, -plotBorder.strokeWidth())); //#3282 plotBorder should be negative;
+ }, -plotBorder.strokeWidth())); // #3282 plotBorder should be negative;
// reset
chart.isDirtyBox = false;
},
@@ -21096,13 +21027,14 @@
syncTimeout = H.syncTimeout,
win = H.win;
/**
* This is the base series prototype that all other series types inherit from.
- * A new series is initialized either through the {@link https://api.highcharts.com/highcharts/series|
- * series} option structure, or after the chart is initialized, through {@link
- * Highcharts.Chart#addSeries}.
+ * A new series is initialized either through the
+ * {@link https://api.highcharts.com/highcharts/series|series} option structure,
+ * or after the chart is initialized, through
+ * {@link Highcharts.Chart#addSeries}.
*
* The object can be accessed in a number of ways. All series and point event
* handlers give a reference to the `series` object. The chart object has a
* {@link Highcharts.Chart.series|series} property that is a collection of all
* the chart's series. The point objects and axis objects also have the same
@@ -21111,33 +21043,34 @@
* Another way to reference the series programmatically is by `id`. Add an id
* in the series configuration options, and get the series object by {@link
* Highcharts.Chart#get}.
*
* Configuration options for the series are given in three levels. Options for
- * all series in a chart are given in the {@link https://api.highcharts.com/highcharts/plotOptions.series|
+ * all series in a chart are given in the
+ * {@link https://api.highcharts.com/highcharts/plotOptions.series|
* plotOptions.series} object. Then options for all series of a specific type
* are given in the plotOptions of that type, for example `plotOptions.line`.
* Next, options for one single series are given in the series array, or as
* arguements to `chart.addSeries`.
*
* The data in the series is stored in various arrays.
*
* - First, `series.options.data` contains all the original config options for
* each point whether added by options or methods like `series.addPoint`.
* - Next, `series.data` contains those values converted to points, but in case
- * the series data length exceeds the `cropThreshold`, or if the data is grouped,
- * `series.data` doesn't contain all the points. It only contains the points that
- * have been created on demand.
+ * the series data length exceeds the `cropThreshold`, or if the data is
+ * grouped, `series.data` doesn't contain all the points. It only contains the
+ * points that have been created on demand.
* - Then there's `series.points` that contains all currently visible point
* objects. In case of cropping, the cropped-away points are not part of this
* array. The `series.points` array starts at `series.cropStart` compared to
- * `series.data` and `series.options.data`. If however the series data is grouped,
- * these can't be correlated one to one.
- * - `series.xData` and `series.processedXData` contain clean x values, equivalent
- * to `series.data` and `series.points`.
- * - `series.yData` and `series.processedYData` contain clean y values, equivalent
- * to `series.data` and `series.points`.
+ * `series.data` and `series.options.data`. If however the series data is
+ * grouped, these can't be correlated one to one.
+ * - `series.xData` and `series.processedXData` contain clean x values,
+ * equivalent to `series.data` and `series.points`.
+ * - `series.yData` and `series.processedYData` contain clean y values,
+ * equivalent to `series.data` and `series.points`.
*
* @class Highcharts.Series
* @param {Highcharts.Chart} chart
* The chart instance.
* @param {Options.plotOptions.series} options
@@ -21149,30 +21082,36 @@
* General options for all series types.
* @optionparent plotOptions.series
*/
H.Series = H.seriesType('line', null, { // base series options
- //cursor: 'default',
- //dashStyle: null,
- //linecap: 'round',
+ /**
+ * The SVG value used for the `stroke-linecap` and `stroke-linejoin`
+ * of a line graph. Round means that lines are rounded in the ends and
+ * bends.
+ *
+ * @validvalue ["round", "butt", "square"]
+ * @type {String}
+ * @default round
+ * @since 3.0.7
+ * @apioption plotOptions.line.linecap
+ */
-
-
/**
* Pixel with of the graph line.
*
* @type {Number}
- * @see In [styled mode](http://www.highcharts.com/docs/chart-design-and-
- * style/style-by-css), the line stroke-width can be set with the
+ * @see In styled mode, the line stroke-width can be set with the
* `.highcharts-graph` class name.
- * @sample {highcharts} highcharts/plotoptions/series-linewidth-general/ On all series
- * @sample {highcharts} highcharts/plotoptions/series-linewidth-specific/ On one single series
+ * @sample {highcharts} highcharts/plotoptions/series-linewidth-general/
+ * On all series
+ * @sample {highcharts} highcharts/plotoptions/series-linewidth-specific/
+ * On one single series
* @default 2
* @product highcharts highstock
*/
lineWidth: 2,
- //shadow: false,
/**
* For some series, there is a limit that shuts down initial animation
* by default when the total number of points in the chart is too high.
@@ -21186,26 +21125,27 @@
/**
* Allow this series' points to be selected by clicking on the graphic
* (columns, point markers, pie slices, map areas etc).
*
- * @see [Chart#getSelectedPoints](../class-reference/Highcharts.Chart#getSelectedPoints).
+ * @see [Chart#getSelectedPoints]
+ * (../class-reference/Highcharts.Chart#getSelectedPoints).
*
* @type {Boolean}
* @sample {highcharts} highcharts/plotoptions/series-allowpointselect-line/
* Line
- * @sample {highcharts} highcharts/plotoptions/series-allowpointselect-column/
+ * @sample {highcharts}
+ * highcharts/plotoptions/series-allowpointselect-column/
* Column
* @sample {highcharts} highcharts/plotoptions/series-allowpointselect-pie/
* Pie
* @sample {highmaps} maps/plotoptions/series-allowpointselect/
* Map area
* @sample {highmaps} maps/plotoptions/mapbubble-allowpointselect/
* Map bubble
* @default false
* @since 1.2.0
- * @product highcharts highstock highmaps
*/
allowPointSelect: false,
@@ -21243,12 +21183,11 @@
* <dd>The duration of the animation in milliseconds.</dd>
*
* <dt>easing</dt>
*
* <dd>A string reference to an easing function set on the `Math` object.
- * See [the easing demo](http://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/highcharts/plotoptions/series-
- * animation-easing/).</dd>
+ * See the _Custom easing function_ demo below.</dd>
*
* </dl>
*
* Due to poor performance, animation is disabled in old IE browsers
* for several chart types.
@@ -21271,14 +21210,10 @@
* @default {highcharts} true
* @default {highstock} true
* @default {highmaps} false
*/
animation: {
-
-
- /**
- */
duration: 1000
},
/**
* A class name to apply to the series' graphical elements.
@@ -21292,16 +21227,15 @@
* The main color of the series. In line type series it applies to the
* line and the point markers unless otherwise specified. In bar type
* series it applies to the bars unless a color is specified per point.
* The default value is pulled from the `options.colors` array.
*
- * In [styled mode](http://www.highcharts.com/docs/chart-design-and-
- * style/style-by-css), the color can be defined by the [colorIndex](#plotOptions.
- * series.colorIndex) option. Also, the series color can be set with
- * the `.highcharts-series`, `.highcharts-color-{n}`, `.highcharts-{type}-
- * series` or `.highcharts-series-{n}` class, or individual classes
- * given by the `className` option.
+ * In styled mode, the color can be defined by the
+ * [colorIndex](#plotOptions.series.colorIndex) option. Also, the series
+ * color can be set with the `.highcharts-series`, `.highcharts-color-{n}`,
+ * `.highcharts-{type}-series` or `.highcharts-series-{n}` class, or
+ * individual classes given by the `className` option.
*
* @productdesc {highmaps}
* In maps, the series color is rarely used, as most choropleth maps use the
* color to denote the value of each point. The series color can however be
* used in a map with multiple series holding categorized data.
@@ -21317,12 +21251,11 @@
* Category map by multiple series
* @apioption plotOptions.series.color
*/
/**
- * [Styled mode](http://www.highcharts.com/docs/chart-design-and-style/style-
- * by-css) only. A specific color index to use for the series, so its
+ * Styled mode only. A specific color index to use for the series, so its
* graphic representations are given the class name `highcharts-color-
* {n}`.
*
* @type {Number}
* @since 5.0.0
@@ -21349,12 +21282,11 @@
* to the series, to signal to the user that the points and lines can
* be clicked.
*
* @validvalue [null, "default", "none", "help", "pointer", "crosshair"]
* @type {String}
- * @see In [styled mode](http://www.highcharts.com/docs/chart-design-and-
- * style/style-by-css), the series cursor can be set with the same classes
+ * @see In styled mode, the series cursor can be set with the same classes
* as listed under [series.color](#plotOptions.series.color).
* @sample {highcharts} highcharts/plotoptions/series-cursor-line/
* On line graph
* @sample {highcharts} highcharts/plotoptions/series-cursor-column/
* On columns
@@ -21388,14 +21320,15 @@
*
* @validvalue ["Solid", "ShortDash", "ShortDot", "ShortDashDot",
* "ShortDashDotDot", "Dot", "Dash" ,"LongDash", "DashDot",
* "LongDashDot", "LongDashDotDot"]
* @type {String}
- * @see In [styled mode](http://www.highcharts.com/docs/chart-design-and-
- * style/style-by-css), the [stroke dash-array](http://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/highcharts/css/series-
- * dashstyle/) can be set with the same classes as listed under [series.
- * color](#plotOptions.series.color).
+ * @see In styled mode, the [stroke dash-array](http://jsfiddle.net/gh/get/
+ * library/pure/highcharts/highcharts/tree/master/samples/highcharts/css/
+ * series-dashstyle/) can be set with the same classes as listed under
+ * [series.color](#plotOptions.series.color).
+ *
* @sample {highcharts} highcharts/plotoptions/series-dashstyle-all/
* Possible values demonstrated
* @sample {highcharts} highcharts/plotoptions/series-dashstyle/
* Chart suitable for printing in black and white
* @sample {highstock} highcharts/plotoptions/series-dashstyle-all/
@@ -21429,12 +21362,16 @@
* Enable or disable the mouse tracking for a specific series. This
* includes point tooltips and click events on graphs and points. For
* large datasets it improves performance.
*
* @type {Boolean}
- * @sample {highcharts} highcharts/plotoptions/series-enablemousetracking-false/ No mouse tracking
- * @sample {highmaps} maps/plotoptions/series-enablemousetracking-false/ No mouse tracking
+ * @sample {highcharts}
+ * highcharts/plotoptions/series-enablemousetracking-false/
+ * No mouse tracking
+ * @sample {highmaps}
+ * maps/plotoptions/series-enablemousetracking-false/
+ * No mouse tracking
* @default true
* @apioption plotOptions.series.enableMouseTracking
*/
/**
@@ -21445,13 +21382,12 @@
* description to the series.
*
* Requires the Accessibility module.
*
* @type {Boolean}
- * @sample {highcharts} highcharts/accessibility/art-grants/ Accessible data visualization
- * @sample {highstock} highcharts/accessibility/art-grants/ Accessible data visualization
- * @sample {highmaps} highcharts/accessibility/art-grants/ Accessible data visualization
+ * @sample highcharts/accessibility/art-grants/
+ * Accessible data visualization
* @default undefined
* @since 5.0.12
* @apioption plotOptions.series.exposeElementToA11y
*/
@@ -21467,24 +21403,56 @@
* @product highcharts highstock
* @apioption plotOptions.series.getExtremesFromAll
*/
/**
+ * An id for the series. This can be used after render time to get a
+ * pointer to the series object through `chart.get()`.
+ *
+ * @type {String}
+ * @sample {highcharts} highcharts/plotoptions/series-id/ Get series by id
+ * @since 1.2.0
+ * @apioption series.id
+ */
+
+ /**
+ * The index of the series in the chart, affecting the internal index
+ * in the `chart.series` array, the visible Z index as well as the order
+ * in the legend.
+ *
+ * @type {Number}
+ * @default undefined
+ * @since 2.3.0
+ * @apioption series.index
+ */
+
+ /**
* An array specifying which option maps to which key in the data point
* array. This makes it convenient to work with unstructured data arrays
* from different sources.
*
* @type {Array<String>}
- * @see [series.data](#series<line>.data)
- * @sample {highcharts} highcharts/series/data-keys/ An extended data array with keys
- * @sample {highstock} highcharts/series/data-keys/ An extended data array with keys
+ * @see [series.data](#series.line.data)
+ * @sample {highcharts|highstock} highcharts/series/data-keys/
+ * An extended data array with keys
* @since 4.1.6
* @product highcharts highstock
* @apioption plotOptions.series.keys
*/
/**
+ * The sequential index of the series in the legend.
+ *
+ * @sample {highcharts|highstock} highcharts/series/legendindex/
+ * Legend in opposite order
+ * @type {Number}
+ * @see [legend.reversed](#legend.reversed), [yAxis.reversedStacks](#yAxis.
+ * reversedStacks)
+ * @apioption series.legendIndex
+ */
+
+ /**
* The line cap used for line ends and line joins on the graph.
*
* @validvalue ["round", "square"]
* @type {String}
* @default round
@@ -21505,25 +21473,40 @@
* @product highcharts highstock
* @apioption plotOptions.series.linkedTo
*/
/**
+ * The name of the series as shown in the legend, tooltip etc.
+ *
+ * @type {String}
+ * @sample {highcharts} highcharts/series/name/ Series name
+ * @sample {highmaps} maps/demo/category-map/ Series name
+ * @apioption series.name
+ */
+
+ /**
* The color for the parts of the graph or points that are below the
* [threshold](#plotOptions.series.threshold).
*
* @type {Color}
- * @see In [styled mode](http://www.highcharts.com/docs/chart-design-and-
- * style/style-by-css), a negative color is applied by setting this
- * option to `true` combined with the `.highcharts-negative` class name
- * ([view live demo](http://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/highcharts/css/series-
- * negative-color/)).
- * @sample {highcharts} highcharts/plotoptions/series-negative-color/ Spline, area and column
- * @sample {highcharts} highcharts/plotoptions/arearange-negativecolor/ Arearange
- * @sample {highstock} highcharts/plotoptions/series-negative-color/ Spline, area and column
- * @sample {highstock} highcharts/plotoptions/arearange-negativecolor/ Arearange
- * @sample {highmaps} highcharts/plotoptions/series-negative-color/ Spline, area and column
- * @sample {highmaps} highcharts/plotoptions/arearange-negativecolor/ Arearange
+ * @see In styled mode, a negative color is applied by setting this
+ * option to `true` combined with the `.highcharts-negative` class name.
+ *
+ * @sample {highcharts} highcharts/plotoptions/series-negative-color/
+ * Spline, area and column
+ * @sample {highcharts} highcharts/plotoptions/arearange-negativecolor/
+ * Arearange
+ * @sample {highcharts} highcharts/css/series-negative-color/
+ * Styled mode
+ * @sample {highstock} highcharts/plotoptions/series-negative-color/
+ * Spline, area and column
+ * @sample {highstock} highcharts/plotoptions/arearange-negativecolor/
+ * Arearange
+ * @sample {highmaps} highcharts/plotoptions/series-negative-color/
+ * Spline, area and column
+ * @sample {highmaps} highcharts/plotoptions/arearange-negativecolor/
+ * Arearange
* @default null
* @since 3.0
* @apioption plotOptions.series.negativeColor
*/
@@ -21539,11 +21522,12 @@
/**
* If no x values are given for the points in a series, `pointInterval`
* defines the interval of the x values. For example, if a series contains
* one value every decade starting from year 0, set `pointInterval` to
- * 10. In true `datetime` axes, the `pointInterval` is set in milliseconds.
+ * `10`. In true `datetime` axes, the `pointInterval` is set in
+ * milliseconds.
*
* It can be also be combined with `pointIntervalUnit` to draw irregular
* time intervals.
*
* @type {Number}
@@ -21555,21 +21539,23 @@
* @product highcharts highstock
* @apioption plotOptions.series.pointInterval
*/
/**
- * On datetime series, this allows for setting the [pointInterval](#plotOptions.
- * series.pointInterval) to irregular time units, `day`, `month` and
- * `year`. A day is usually the same as 24 hours, but pointIntervalUnit
- * also takes the DST crossover into consideration when dealing with
- * local time. Combine this option with `pointInterval` to draw weeks,
- * quarters, 6 months, 10 years etc.
+ * On datetime series, this allows for setting the
+ * [pointInterval](#plotOptions.series.pointInterval) to irregular time
+ * units, `day`, `month` and `year`. A day is usually the same as 24 hours,
+ * but `pointIntervalUnit` also takes the DST crossover into consideration
+ * when dealing with local time. Combine this option with `pointInterval`
+ * to draw weeks, quarters, 6 months, 10 years etc.
*
* @validvalue [null, "day", "month", "year"]
* @type {String}
- * @sample {highcharts} highcharts/plotoptions/series-pointintervalunit/ One point a month
- * @sample {highstock} highcharts/plotoptions/series-pointintervalunit/ One point a month
+ * @sample {highcharts} highcharts/plotoptions/series-pointintervalunit/
+ * One point a month
+ * @sample {highstock} highcharts/plotoptions/series-pointintervalunit/
+ * One point a month
* @since 4.1.0
* @product highcharts highstock
* @apioption plotOptions.series.pointIntervalUnit
*/
@@ -21596,14 +21582,16 @@
* Defaults to `null` in cartesian charts, `"between"` in polar charts.
*
* @validvalue [null, "on", "between"]
* @type {String|Number}
* @see [xAxis.tickmarkPlacement](#xAxis.tickmarkPlacement)
- * @sample {highcharts} highcharts/plotoptions/series-pointplacement-between/ Between in a column chart
- * @sample {highcharts} highcharts/plotoptions/series-pointplacement-numeric/ Numeric placement for custom layout
- * @sample {highstock} highcharts/plotoptions/series-pointplacement-between/ Between in a column chart
- * @sample {highstock} highcharts/plotoptions/series-pointplacement-numeric/ Numeric placement for custom layout
+ * @sample {highcharts|highstock}
+ * highcharts/plotoptions/series-pointplacement-between/
+ * Between in a column chart
+ * @sample {highcharts|highstock}
+ * highcharts/plotoptions/series-pointplacement-numeric/
+ * Numeric placement for custom layout
* @default null
* @since 2.3.0
* @product highcharts highstock
* @apioption plotOptions.series.pointPlacement
*/
@@ -21612,13 +21600,16 @@
* If no x values are given for the points in a series, pointStart defines
* on what value to start. For example, if a series contains one yearly
* value starting from 1945, set pointStart to 1945.
*
* @type {Number}
- * @sample {highcharts} highcharts/plotoptions/series-pointstart-linear/ Linear
- * @sample {highcharts} highcharts/plotoptions/series-pointstart-datetime/ Datetime
- * @sample {highstock} stock/plotoptions/pointinterval-pointstart/ Using pointStart and pointInterval
+ * @sample {highcharts} highcharts/plotoptions/series-pointstart-linear/
+ * Linear
+ * @sample {highcharts} highcharts/plotoptions/series-pointstart-datetime/
+ * Datetime
+ * @sample {highstock} stock/plotoptions/pointinterval-pointstart/
+ * Using pointStart and pointInterval
* @default 0
* @product highcharts highstock
* @apioption plotOptions.series.pointStart
*/
@@ -21650,11 +21641,12 @@
* Whether to display this particular series or series type in the legend.
* The default value is `true` for standalone series, `false` for linked
* series.
*
* @type {Boolean}
- * @sample {highcharts} highcharts/plotoptions/series-showinlegend/ One series in the legend, one hidden
+ * @sample {highcharts} highcharts/plotoptions/series-showinlegend/
+ * One series in the legend, one hidden
* @default true
* @apioption plotOptions.series.showInLegend
*/
/**
@@ -21665,27 +21657,51 @@
* @since 5.0.12
* @apioption plotOptions.series.skipKeyboardNavigation
*/
/**
+ * This option allows grouping series in a stacked chart. The stack
+ * option can be a string or a number or anything else, as long as the
+ * grouped series' stack options match each other.
+ *
+ * @type {String}
+ * @sample {highcharts} highcharts/series/stack/ Stacked and grouped columns
+ * @default null
+ * @since 2.1
+ * @product highcharts highstock
+ * @apioption series.stack
+ */
+
+ /**
* Whether to stack the values of each series on top of each other.
- * Possible values are null to disable, "normal" to stack by value or
- * "percent". When stacking is enabled, data must be sorted in ascending
- * X order.
+ * Possible values are `null` to disable, `"normal"` to stack by value or
+ * `"percent"`. When stacking is enabled, data must be sorted in ascending
+ * X order. A special stacking option is with the streamgraph series type,
+ * where the stacking option is set to `"stream"`.
*
* @validvalue [null, "normal", "percent"]
* @type {String}
* @see [yAxis.reversedStacks](#yAxis.reversedStacks)
- * @sample {highcharts} highcharts/plotoptions/series-stacking-line/ Line
- * @sample {highcharts} highcharts/plotoptions/series-stacking-column/ Column
- * @sample {highcharts} highcharts/plotoptions/series-stacking-bar/ Bar
- * @sample {highcharts} highcharts/plotoptions/series-stacking-area/ Area
- * @sample {highcharts} highcharts/plotoptions/series-stacking-percent-line/ Line
- * @sample {highcharts} highcharts/plotoptions/series-stacking-percent-column/ Column
- * @sample {highcharts} highcharts/plotoptions/series-stacking-percent-bar/ Bar
- * @sample {highcharts} highcharts/plotoptions/series-stacking-percent-area/ Area
- * @sample {highstock} stock/plotoptions/stacking/ Area
+ * @sample {highcharts} highcharts/plotoptions/series-stacking-line/
+ * Line
+ * @sample {highcharts} highcharts/plotoptions/series-stacking-column/
+ * Column
+ * @sample {highcharts} highcharts/plotoptions/series-stacking-bar/
+ * Bar
+ * @sample {highcharts} highcharts/plotoptions/series-stacking-area/
+ * Area
+ * @sample {highcharts} highcharts/plotoptions/series-stacking-percent-line/
+ * Line
+ * @sample {highcharts}
+ * highcharts/plotoptions/series-stacking-percent-column/
+ * Column
+ * @sample {highcharts} highcharts/plotoptions/series-stacking-percent-bar/
+ * Bar
+ * @sample {highcharts} highcharts/plotoptions/series-stacking-percent-area/
+ * Area
+ * @sample {highstock} stock/plotoptions/stacking/
+ * Area
* @default null
* @product highcharts highstock
* @apioption plotOptions.series.stacking
*/
@@ -21693,72 +21709,259 @@
* Whether to apply steps to the line. Possible values are `left`, `center`
* and `right`.
*
* @validvalue [null, "left", "center", "right"]
* @type {String}
- * @sample {highcharts} highcharts/plotoptions/line-step/ Different step line options
- * @sample {highcharts} highcharts/plotoptions/area-step/ Stepped, stacked area
- * @sample {highstock} stock/plotoptions/line-step/ Step line
+ * @sample {highcharts} highcharts/plotoptions/line-step/
+ * Different step line options
+ * @sample {highcharts} highcharts/plotoptions/area-step/
+ * Stepped, stacked area
+ * @sample {highstock} stock/plotoptions/line-step/
+ * Step line
* @default {highcharts} null
* @default {highstock} false
* @since 1.2.5
* @product highcharts highstock
* @apioption plotOptions.series.step
*/
/**
* The threshold, also called zero level or base level. For line type
- * series this is only used in conjunction with [negativeColor](#plotOptions.
- * series.negativeColor).
+ * series this is only used in conjunction with
+ * [negativeColor](#plotOptions.series.negativeColor).
*
* @type {Number}
* @see [softThreshold](#plotOptions.series.softThreshold).
* @default 0
* @since 3.0
* @product highcharts highstock
* @apioption plotOptions.series.threshold
*/
/**
+ * The type of series, for example `line` or `column`.
+ *
+ * @validvalue [null, "line", "spline", "column", "area", "areaspline",
+ * "pie", "arearange", "areasplinerange", "boxplot", "bubble",
+ * "columnrange", "errorbar", "funnel", "gauge", "scatter",
+ * "waterfall"]
+ * @type {String}
+ * @sample {highcharts} highcharts/series/type/
+ * Line and column in the same chart
+ * @sample {highmaps} maps/demo/mapline-mappoint/
+ * Multiple types in the same map
+ * @apioption series.type
+ */
+
+ /**
* Set the initial visibility of the series.
*
* @type {Boolean}
- * @sample {highcharts} highcharts/plotoptions/series-visible/ Two series, one hidden and one visible
- * @sample {highstock} stock/plotoptions/series-visibility/ Hidden series
+ * @sample {highcharts} highcharts/plotoptions/series-visible/
+ * Two series, one hidden and one visible
+ * @sample {highstock} stock/plotoptions/series-visibility/
+ * Hidden series
* @default true
* @apioption plotOptions.series.visible
*/
/**
+ * When using dual or multiple x axes, this number defines which xAxis
+ * the particular series is connected to. It refers to either the [axis
+ * id](#xAxis.id) or the index of the axis in the xAxis array, with
+ * 0 being the first.
+ *
+ * @type {Number|String}
+ * @default 0
+ * @product highcharts highstock
+ * @apioption series.xAxis
+ */
+
+ /**
+ * When using dual or multiple y axes, this number defines which yAxis
+ * the particular series is connected to. It refers to either the [axis
+ * id](#yAxis.id) or the index of the axis in the yAxis array, with
+ * 0 being the first.
+ *
+ * @type {Number|String}
+ * @sample {highcharts} highcharts/series/yaxis/
+ * Apply the column series to the secondary Y axis
+ * @default 0
+ * @product highcharts highstock
+ * @apioption series.yAxis
+ */
+
+ /**
* Defines the Axis on which the zones are applied.
*
* @type {String}
- * @see [zones](#plotOption.series.zones)
- * @sample {highcharts} highcharts/series/color-zones-zoneaxis-x/ Zones on the X-Axis
- * @sample {highstock} highcharts/series/color-zones-zoneaxis-x/ Zones on the X-Axis
+ * @see [zones](#plotOptions.series.zones)
+ * @sample {highcharts} highcharts/series/color-zones-zoneaxis-x/
+ * Zones on the X-Axis
+ * @sample {highstock} highcharts/series/color-zones-zoneaxis-x/
+ * Zones on the X-Axis
* @default y
* @since 4.1.0
* @product highcharts highstock
* @apioption plotOptions.series.zoneAxis
*/
/**
- * @product highcharts highstock highmaps
+ * Define the visual z index of the series.
+ *
+ * @type {Number}
+ * @sample {highcharts} highcharts/plotoptions/series-zindex-default/
+ * With no z index, the series defined last are on top
+ * @sample {highcharts} highcharts/plotoptions/series-zindex/
+ * With a z index, the series with the highest z index is on top
+ * @sample {highstock} highcharts/plotoptions/series-zindex-default/
+ * With no z index, the series defined last are on top
+ * @sample {highstock} highcharts/plotoptions/series-zindex/
+ * With a z index, the series with the highest z index is on top
+ * @product highcharts highstock
+ * @apioption series.zIndex
*/
- events: {},
+ /**
+ * General event handlers for the series items. These event hooks can also
+ * be attached to the series at run time using the `Highcharts.addEvent`
+ * function.
+ */
+ events: {
+ /**
+ * Fires after the series has finished its initial animation, or in
+ * case animation is disabled, immediately as the series is displayed.
+ *
+ * @type {Function}
+ * @context Series
+ * @sample {highcharts}
+ * highcharts/plotoptions/series-events-afteranimate/
+ * Show label after animate
+ * @sample {highstock}
+ * highcharts/plotoptions/series-events-afteranimate/
+ * Show label after animate
+ * @since 4.0
+ * @product highcharts highstock
+ * @apioption plotOptions.series.events.afterAnimate
+ */
+ /**
+ * Fires when the checkbox next to the series' name in the legend is
+ * clicked. One parameter, `event`, is passed to the function. The state
+ * of the checkbox is found by `event.checked`. The checked item is
+ * found by `event.item`. Return `false` to prevent the default action
+ * which is to toggle the select state of the series.
+ *
+ * @type {Function}
+ * @context Series
+ * @sample {highcharts}
+ * highcharts/plotoptions/series-events-checkboxclick/
+ * Alert checkbox status
+ * @since 1.2.0
+ * @apioption plotOptions.series.events.checkboxClick
+ */
+
+ /**
+ * Fires when the series is clicked. One parameter, `event`, is passed
+ * to the function, containing common event information. Additionally,
+ * `event.point` holds a pointer to the nearest point on the graph.
+ *
+ * @type {Function}
+ * @context Series
+ * @sample {highcharts} highcharts/plotoptions/series-events-click/
+ * Alert click info
+ * @sample {highstock} stock/plotoptions/series-events-click/
+ * Alert click info
+ * @sample {highmaps} maps/plotoptions/series-events-click/
+ * Display click info in subtitle
+ * @apioption plotOptions.series.events.click
+ */
+
+ /**
+ * Fires when the series is hidden after chart generation time, either
+ * by clicking the legend item or by calling `.hide()`.
+ *
+ * @type {Function}
+ * @context Series
+ * @sample {highcharts} highcharts/plotoptions/series-events-hide/
+ * Alert when the series is hidden by clicking the legend item
+ * @since 1.2.0
+ * @apioption plotOptions.series.events.hide
+ */
+
+ /**
+ * Fires when the legend item belonging to the series is clicked. One
+ * parameter, `event`, is passed to the function. The default action
+ * is to toggle the visibility of the series. This can be prevented
+ * by returning `false` or calling `event.preventDefault()`.
+ *
+ * @type {Function}
+ * @context Series
+ * @sample {highcharts}
+ * highcharts/plotoptions/series-events-legenditemclick/
+ * Confirm hiding and showing
+ * @apioption plotOptions.series.events.legendItemClick
+ */
+
+ /**
+ * Fires when the mouse leaves the graph. One parameter, `event`, is
+ * passed to the function, containing common event information. If the
+ * [stickyTracking](#plotOptions.series) option is true, `mouseOut`
+ * doesn't happen before the mouse enters another graph or leaves the
+ * plot area.
+ *
+ * @type {Function}
+ * @context Series
+ * @sample {highcharts}
+ * highcharts/plotoptions/series-events-mouseover-sticky/
+ * With sticky tracking by default
+ * @sample {highcharts}
+ * highcharts/plotoptions/series-events-mouseover-no-sticky/
+ * Without sticky tracking
+ * @apioption plotOptions.series.events.mouseOut
+ */
+
+ /**
+ * Fires when the mouse enters the graph. One parameter, `event`, is
+ * passed to the function, containing common event information.
+ *
+ * @type {Function}
+ * @context Series
+ * @sample {highcharts}
+ * highcharts/plotoptions/series-events-mouseover-sticky/
+ * With sticky tracking by default
+ * @sample {highcharts}
+ * highcharts/plotoptions/series-events-mouseover-no-sticky/
+ * Without sticky tracking
+ * @apioption plotOptions.series.events.mouseOver
+ */
+
+ /**
+ * Fires when the series is shown after chart generation time, either
+ * by clicking the legend item or by calling `.show()`.
+ *
+ * @type {Function}
+ * @context Series
+ * @sample {highcharts} highcharts/plotoptions/series-events-show/
+ * Alert when the series is shown by clicking the legend item.
+ * @since 1.2.0
+ * @apioption plotOptions.series.events.show
+ */
+
+ },
+
+
+
/**
* Options for the point markers of line-like series. Properties like
* `fillColor`, `lineColor` and `lineWidth` define the visual appearance
* of the markers. Other series types, like column series, don't have
* markers, but have visual options on the series level instead.
*
- * In [styled mode](http://www.highcharts.com/docs/chart-design-and-
- * style/style-by-css), the markers can be styled with the `.highcharts-
- * point`, `.highcharts-point-hover` and `.highcharts-point-select`
+ * In styled mode, the markers can be styled with the `.highcharts-point`,
+ * `.highcharts-point-hover` and `.highcharts-point-select`
* class names.
*
* @product highcharts highstock
*/
marker: {
@@ -21767,11 +21970,12 @@
/**
* The width of the point marker's outline.
*
* @type {Number}
- * @sample {highcharts} highcharts/plotoptions/series-marker-fillcolor/ 2px blue marker
+ * @sample {highcharts} highcharts/plotoptions/series-marker-fillcolor/
+ * 2px blue marker
* @default 0
* @product highcharts highstock
*/
lineWidth: 0,
@@ -21779,71 +21983,195 @@
/**
* The color of the point marker's outline. When `null`, the series'
* or point's color is used.
*
* @type {Color}
- * @sample {highcharts} highcharts/plotoptions/series-marker-fillcolor/ Inherit from series color (null)
- * @default #ffffff
+ * @sample {highcharts} highcharts/plotoptions/series-marker-fillcolor/
+ * Inherit from series color (null)
* @product highcharts highstock
*/
lineColor: '#ffffff',
- //fillColor: null,
- //enabled: true,
- //symbol: null,
+ /**
+ * The fill color of the point marker. When `null`, the series' or
+ * point's color is used.
+ *
+ * @type {Color}
+ * @sample {highcharts} highcharts/plotoptions/series-marker-fillcolor/
+ * White fill
+ * @default null
+ * @product highcharts highstock
+ * @apioption plotOptions.series.marker.fillColor
+ */
+
/**
+ * Enable or disable the point marker. If `null`, the markers are hidden
+ * when the data is dense, and shown for more widespread data points.
+ *
+ * @type {Boolean}
+ * @sample {highcharts} highcharts/plotoptions/series-marker-enabled/
+ * Disabled markers
+ * @sample {highcharts}
+ * highcharts/plotoptions/series-marker-enabled-false/
+ * Disabled in normal state but enabled on hover
+ * @sample {highstock} stock/plotoptions/series-marker/
+ * Enabled markers
+ * @default {highcharts} null
+ * @default {highstock} false
+ * @product highcharts highstock
+ * @apioption plotOptions.series.marker.enabled
+ */
+
+ /**
+ * Image markers only. Set the image width explicitly. When using this
+ * option, a `width` must also be set.
+ *
+ * @type {Number}
+ * @sample {highcharts}
+ * highcharts/plotoptions/series-marker-width-height/
+ * Fixed width and height
+ * @sample {highstock}
+ * highcharts/plotoptions/series-marker-width-height/
+ * Fixed width and height
+ * @default null
+ * @since 4.0.4
+ * @product highcharts highstock
+ * @apioption plotOptions.series.marker.height
+ */
+
+ /**
+ * A predefined shape or symbol for the marker. When null, the symbol
+ * is pulled from options.symbols. Other possible values are "circle",
+ * "square", "diamond", "triangle" and "triangle-down".
+ *
+ * Additionally, the URL to a graphic can be given on this form:
+ * "url(graphic.png)". Note that for the image to be applied to exported
+ * charts, its URL needs to be accessible by the export server.
+ *
+ * Custom callbacks for symbol path generation can also be added to
+ * `Highcharts.SVGRenderer.prototype.symbols`. The callback is then
+ * used by its method name, as shown in the demo.
+ *
+ * @validvalue [null, "circle", "square", "diamond", "triangle",
+ * "triangle-down"]
+ * @type {String}
+ * @sample {highcharts} highcharts/plotoptions/series-marker-symbol/
+ * Predefined, graphic and custom markers
+ * @sample {highstock} highcharts/plotoptions/series-marker-symbol/
+ * Predefined, graphic and custom markers
+ * @default null
+ * @product highcharts highstock
+ * @apioption plotOptions.series.marker.symbol
+ */
+
+ /**
* The radius of the point marker.
*
* @type {Number}
- * @sample {highcharts} highcharts/plotoptions/series-marker-radius/ Bigger markers
+ * @sample {highcharts} highcharts/plotoptions/series-marker-radius/
+ * Bigger markers
* @default 4
* @product highcharts highstock
*/
radius: 4,
-
/**
+ * Image markers only. Set the image width explicitly. When using this
+ * option, a `height` must also be set.
+ *
+ * @type {Number}
+ * @sample {highcharts}
+ * highcharts/plotoptions/series-marker-width-height/
+ * Fixed width and height
+ * @sample {highstock}
+ * highcharts/plotoptions/series-marker-width-height/
+ * Fixed width and height
+ * @default null
+ * @since 4.0.4
* @product highcharts highstock
+ * @apioption plotOptions.series.marker.width
*/
- states: { // states for a single point
-
+ /**
+ * States for a single point marker.
+ * @product highcharts highstock
+ */
+ states: {
/**
+ * The hover state for a single point marker.
* @product highcharts highstock
*/
hover: {
-
-
/**
+ * Animation when hovering over the marker.
*/
animation: {
-
-
- /**
- */
duration: 50
},
-
-
/**
* Enable or disable the point marker.
*
* @type {Boolean}
- * @sample {highcharts} highcharts/plotoptions/series-marker-states-hover-enabled/ Disabled hover state
+ * @sample {highcharts}
+ * highcharts/plotoptions/series-marker-states-hover-enabled/
+ * Disabled hover state
* @default true
* @product highcharts highstock
*/
enabled: true,
+ /**
+ * The fill color of the marker in hover state.
+ *
+ * @type {Color}
+ * @default null
+ * @product highcharts highstock
+ * @apioption plotOptions.series.marker.states.hover.fillColor
+ */
+ /**
+ * The color of the point marker's outline. When `null`, the
+ * series' or point's color is used.
+ *
+ * @type {Color}
+ * @sample {highcharts}
+ * highcharts/plotoptions/series-marker-states-hover-linecolor/
+ * White fill color, black line color
+ * @default #ffffff
+ * @product highcharts highstock
+ * @apioption plotOptions.series.marker.states.hover.lineColor
+ */
/**
+ * The width of the point marker's outline.
+ *
+ * @type {Number}
+ * @sample {highcharts}
+ * highcharts/plotoptions/series-marker-states-hover-linewidth/
+ * 3px line width
+ * @default 0
+ * @product highcharts highstock
+ * @apioption plotOptions.series.marker.states.hover.lineWidth
+ */
+
+ /**
+ * The radius of the point marker. In hover state, it defaults to the
+ * normal state's radius + 2 as per the [radiusPlus](#plotOptions.series.
+ * marker.states.hover.radiusPlus) option.
+ *
+ * @type {Number}
+ * @sample {highcharts} highcharts/plotoptions/series-marker-states-hover-radius/ 10px radius
+ * @product highcharts highstock
+ * @apioption plotOptions.series.marker.states.hover.radius
+ */
+
+ /**
* The number of pixels to increase the radius of the hovered point.
*
* @type {Number}
* @sample {highcharts} highcharts/plotoptions/series-states-hover-linewidthplus/ 5 pixels greater radius on hover
* @sample {highstock} highcharts/plotoptions/series-states-hover-linewidthplus/ 5 pixels greater radius on hover
@@ -21853,11 +22181,10 @@
*/
radiusPlus: 2,
-
/**
* The additional line width for a hovered point.
*
* @type {Number}
* @sample {highcharts} highcharts/plotoptions/series-states-hover-linewidthplus/ 2 pixels wider on hover
@@ -21880,17 +22207,27 @@
*
* @product highcharts highstock
*/
select: {
+ /**
+ * Enable or disable visible feedback for selection.
+ *
+ * @type {Boolean}
+ * @sample {highcharts} highcharts/plotoptions/series-marker-states-select-enabled/
+ * Disabled select state
+ * @default true
+ * @product highcharts highstock
+ * @apioption plotOptions.series.marker.states.select.enabled
+ */
-
/**
* The fill color of the point marker.
*
* @type {Color}
- * @sample {highcharts} highcharts/plotoptions/series-marker-states-select-fillcolor/ Solid red discs for selected points
+ * @sample {highcharts} highcharts/plotoptions/series-marker-states-select-fillcolor/
+ * Solid red discs for selected points
* @default null
* @product highcharts highstock
*/
fillColor: '#cccccc',
@@ -21899,11 +22236,12 @@
/**
* The color of the point marker's outline. When `null`, the series'
* or point's color is used.
*
* @type {Color}
- * @sample {highcharts} highcharts/plotoptions/series-marker-states-select-linecolor/ Red line color for selected points
+ * @sample {highcharts} highcharts/plotoptions/series-marker-states-select-linecolor/
+ * Red line color for selected points
* @default #000000
* @product highcharts highstock
*/
lineColor: '#000000',
@@ -21911,47 +22249,145 @@
/**
* The width of the point marker's outline.
*
* @type {Number}
- * @sample {highcharts} highcharts/plotoptions/series-marker-states-select-linewidth/ 3px line width for selected points
+ * @sample {highcharts} highcharts/plotoptions/series-marker-states-select-linewidth/
+ * 3px line width for selected points
* @default 0
* @product highcharts highstock
*/
lineWidth: 2
+
+ /**
+ * The radius of the point marker. In hover state, it defaults to the
+ * normal state's radius + 2.
+ *
+ * @type {Number}
+ * @sample {highcharts} highcharts/plotoptions/series-marker-states-select-radius/
+ * 10px radius for selected points
+ * @product highcharts highstock
+ * @apioption plotOptions.series.marker.states.select.radius
+ */
+
}
}
},
/**
- * Properties for each single point
- *
- * @product highcharts highstock highmaps
+ * Properties for each single point.
*/
point: {
/**
- * Events for each single point
- *
- * @product highcharts highstock highmaps
+ * Events for each single point.
*/
- events: {}
+ events: {
+
+ /**
+ * Fires when a point is clicked. One parameter, `event`, is passed
+ * to the function, containing common event information.
+ *
+ * If the `series.allowPointSelect` option is true, the default action
+ * for the point's click event is to toggle the point's select state.
+ * Returning `false` cancels this action.
+ *
+ * @type {Function}
+ * @context Point
+ * @sample {highcharts} highcharts/plotoptions/series-point-events-click/ Click marker to alert values
+ * @sample {highcharts} highcharts/plotoptions/series-point-events-click-column/ Click column
+ * @sample {highcharts} highcharts/plotoptions/series-point-events-click-url/ Go to URL
+ * @sample {highmaps} maps/plotoptions/series-point-events-click/ Click marker to display values
+ * @sample {highmaps} maps/plotoptions/series-point-events-click-url/ Go to URL
+ * @apioption plotOptions.series.point.events.click
+ */
+
+ /**
+ * Fires when the mouse leaves the area close to the point. One parameter,
+ * `event`, is passed to the function, containing common event information.
+ *
+ * @type {Function}
+ * @context Point
+ * @sample {highcharts} highcharts/plotoptions/series-point-events-mouseover/ Show values in the chart's corner on mouse over
+ * @apioption plotOptions.series.point.events.mouseOut
+ */
+
+ /**
+ * Fires when the mouse enters the area close to the point. One parameter,
+ * `event`, is passed to the function, containing common event information.
+ *
+ * @type {Function}
+ * @context Point
+ * @sample {highcharts} highcharts/plotoptions/series-point-events-mouseover/ Show values in the chart's corner on mouse over
+ * @apioption plotOptions.series.point.events.mouseOver
+ */
+
+ /**
+ * Fires when the point is removed using the `.remove()` method. One
+ * parameter, `event`, is passed to the function. Returning `false`
+ * cancels the operation.
+ *
+ * @type {Function}
+ * @context Point
+ * @sample {highcharts} highcharts/plotoptions/series-point-events-remove/ Remove point and confirm
+ * @since 1.2.0
+ * @apioption plotOptions.series.point.events.remove
+ */
+
+ /**
+ * Fires when the point is selected either programmatically or following
+ * a click on the point. One parameter, `event`, is passed to the function.
+ * Returning `false` cancels the operation.
+ *
+ * @type {Function}
+ * @context Point
+ * @sample {highcharts} highcharts/plotoptions/series-point-events-select/ Report the last selected point
+ * @sample {highmaps} maps/plotoptions/series-allowpointselect/ Report select and unselect
+ * @since 1.2.0
+ * @apioption plotOptions.series.point.events.select
+ */
+
+ /**
+ * Fires when the point is unselected either programmatically or following
+ * a click on the point. One parameter, `event`, is passed to the function.
+ * Returning `false` cancels the operation.
+ *
+ * @type {Function}
+ * @context Point
+ * @sample {highcharts} highcharts/plotoptions/series-point-events-unselect/ Report the last unselected point
+ * @sample {highmaps} maps/plotoptions/series-allowpointselect/ Report select and unselect
+ * @since 1.2.0
+ * @apioption plotOptions.series.point.events.unselect
+ */
+
+ /**
+ * Fires when the point is updated programmatically through the `.update()`
+ * method. One parameter, `event`, is passed to the function. The new
+ * point options can be accessed through `event.options`. Returning
+ * `false` cancels the operation.
+ *
+ * @type {Function}
+ * @context Point
+ * @sample {highcharts} highcharts/plotoptions/series-point-events-update/ Confirm point updating
+ * @since 1.2.0
+ * @apioption plotOptions.series.point.events.update
+ */
+
+ }
},
/**
* Options for the series data labels, appearing next to each data
* point.
*
- * In [styled mode](http://www.highcharts.com/docs/chart-design-and-
- * style/style-by-css), the data labels can be styled wtih the `.highcharts-
- * data-label-box` and `.highcharts-data-label` class names ([see example](http://jsfiddle.
+ * In styled mode, the data labels can be styled wtih the `.highcharts-data-label-box` and `.highcharts-data-label` class names ([see example](http://jsfiddle.
* net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/highcharts/css/series-
* datalabels)).
*/
dataLabels: {
@@ -22010,12 +22446,11 @@
* @since 2.2.1
* @apioption plotOptions.series.dataLabels.borderWidth
*/
/**
- * A class name for the data label. Particularly in [styled mode](http://www.
- * highcharts.com/docs/chart-design-and-style/style-by-css), this can
+ * A class name for the data label. Particularly in styled mode, this can
* be used to give each series' or point's data label unique styling.
* In addition to this option, a default color class name is added
* so that we can give the labels a [contrast text shadow](http://jsfiddle.
* net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/highcharts/css/data-
* label-contrast/).
@@ -22157,11 +22592,10 @@
*
* </table>
*
* @type {Function}
* @sample {highmaps} maps/plotoptions/series-datalabels-format/ Formatted value
- * @product highcharts highstock highmaps
*/
formatter: function() {
return this.y === null ? '' : H.numberFormat(this.y, -1);
},
@@ -22169,17 +22603,21 @@
/**
* Styles for the label. The default `color` setting is `"contrast"`,
* which is a pseudo color that Highcharts picks up and applies the
* maximum contrast to the underlying point item, for example the
- * bar in a bar chart. The `textOutline` is a pseudo property that
+ * bar in a bar chart.
+ *
+ * The `textOutline` is a pseudo property that
* applies an outline of the given width with the given color, which
* by default is the maximum contrast to the text. So a bright text
* color will result in a black text outline for maximum readability
* on a mixed background. In some cases, especially with grayscale
* text, the text outline doesn't work well, in which cases it can
- * be disabled by setting it to `"none"`.
+ * be disabled by setting it to `"none"`. When `useHTML` is true, the
+ * `textOutline` will not be picked up. In this, case, the same effect
+ * can be acheived through the `text-shadow` CSS property.
*
* @type {CSSObject}
* @sample {highcharts} highcharts/plotoptions/series-datalabels-style/
* Bold labels
* @sample {highmaps} maps/demo/color-axis/ Bold labels
@@ -22192,12 +22630,11 @@
color: 'contrast',
textOutline: '1px contrast'
},
/**
- * The background color or gradient for the data label. Defaults to
- * `undefined`.
+ * The background color or gradient for the data label.
*
* @type {Color}
* @sample {highcharts} highcharts/plotoptions/series-datalabels-box/ Data labels box options
* @sample {highmaps} maps/plotoptions/series-datalabels-box/ Data labels box options
* @since 2.2.1
@@ -22271,33 +22708,30 @@
* negative values.
*
* @validvalue ["top", "middle", "bottom"]
* @type {String}
* @since 2.3.3
- * @product highcharts highstock highmaps
*/
verticalAlign: 'bottom', // above singular point
/**
* The x position offset of the label relative to the point.
*
* @type {Number}
* @sample {highcharts} highcharts/plotoptions/series-datalabels-rotation/ Vertical and positioned
* @default 0
- * @product highcharts highstock highmaps
*/
x: 0,
/**
* The y position offset of the label relative to the point.
*
* @type {Number}
* @sample {highcharts} highcharts/plotoptions/series-datalabels-rotation/ Vertical and positioned
* @default -6
- * @product highcharts highstock highmaps
*/
y: 0,
/**
@@ -22310,11 +22744,10 @@
* @sample {highmaps} maps/plotoptions/series-datalabels-box/ Data labels box options
* @default {highcharts} 5
* @default {highstock} 5
* @default {highmaps} 0
* @since 2.2.1
- * @product highcharts highstock highmaps
*/
padding: 5
/**
* The name of a symbol to use for the border around the label. Symbols
@@ -22372,16 +22805,11 @@
* @type {Number}
* @default 0
* @product highstock
*/
pointRange: 0,
- //pointStart: 0,
- //pointInterval: 1,
- //showInLegend: null, // auto = false for linked series
-
-
/**
* When this is true, the series will not cause the Y axis to cross
* the zero plane (or [threshold](#plotOptions.series.threshold) option)
* unless the data actually crosses the plane.
*
@@ -22400,23 +22828,33 @@
/**
* A wrapper object for all the series options in specific states.
*
* @type {plotOptions.series.states}
- * @product highcharts highstock highmaps
*/
- states: { // states for the entire series
+ states: {
/**
- * Options for the hovered series
- *
- * @product highcharts highstock highmaps
+ * Options for the hovered series. These settings override the normal
+ * state options when a series is moused over or touched.
+ *
*/
hover: {
- //enabled: false,
+ /**
+ * Enable separate styles for the hovered series to visualize that the
+ * user hovers either the series itself or the legend. .
+ *
+ * @type {Boolean}
+ * @sample {highcharts} highcharts/plotoptions/series-states-hover-enabled/ Line
+ * @sample {highcharts} highcharts/plotoptions/series-states-hover-enabled-column/ Column
+ * @sample {highcharts} highcharts/plotoptions/series-states-hover-enabled-pie/ Pie
+ * @default true
+ * @since 1.2
+ * @apioption plotOptions.series.states.hover.enabled
+ */
/**
* Animation setting for hovering the graph in line-type series.
*
@@ -22424,26 +22862,40 @@
* @default { "duration": 50 }
* @since 5.0.8
* @product highcharts
*/
animation: {
-
-
-
/**
+ * The duration of the hover animation in milliseconds. By
+ * default the hover state animates quickly in, and slowly back
+ * to normal.
*/
duration: 50
},
+ /**
+ * Pixel with of the graph line. By default this property is
+ * undefined, and the `lineWidthPlus` property dictates how much
+ * to increase the linewidth from normal state.
+ *
+ * @type {Number}
+ * @sample {highcharts} highcharts/plotoptions/series-states-hover-linewidth/
+ * 5px line on hover
+ * @default undefined
+ * @product highcharts highstock
+ * @apioption plotOptions.series.states.hover.lineWidth
+ */
/**
* The additional line width for the graph of a hovered series.
*
* @type {Number}
- * @sample {highcharts} highcharts/plotoptions/series-states-hover-linewidthplus/ 5 pixels wider
- * @sample {highstock} highcharts/plotoptions/series-states-hover-linewidthplus/ 5 pixels wider
+ * @sample {highcharts} highcharts/plotoptions/series-states-hover-linewidthplus/
+ * 5 pixels wider
+ * @sample {highstock} highcharts/plotoptions/series-states-hover-linewidthplus/
+ * 5 pixels wider
* @default 1
* @since 4.0.3
* @product highcharts highstock
*/
lineWidthPlus: 1,
@@ -22472,22 +22924,29 @@
* type series as well as outside the hovered slice in pie charts.
* By default the halo is filled by the current point or series
* color with an opacity of 0.25\. The halo can be disabled by setting
* the `halo` option to `false`.
*
- * In [styled mode](http://www.highcharts.com/docs/chart-design-and-
- * style/style-by-css), the halo is styled with the `.highcharts-
- * halo` class, with colors inherited from `.highcharts-color-{n}`.
+ * In styled mode, the halo is styled with the `.highcharts-halo` class, with colors inherited from `.highcharts-color-{n}`.
*
* @type {Object}
* @sample {highcharts} highcharts/plotoptions/halo/ Halo options
* @sample {highstock} highcharts/plotoptions/halo/ Halo options
* @since 4.0
* @product highcharts highstock
*/
halo: {
+ /**
+ * A collection of SVG attributes to override the appearance of the
+ * halo, for example `fill`, `stroke` and `stroke-width`.
+ *
+ * @type {Object}
+ * @since 4.0
+ * @product highcharts highstock
+ * @apioption plotOptions.series.states.hover.halo.attributes
+ */
/**
* The pixel size of the halo. For point markers this is the radius
* of the halo. For pie slices it is the width of the halo outside
@@ -22526,19 +22985,15 @@
* programmatically.
*
* @type {Object}
* @extends plotOptions.series.states.hover
* @excluding brightness
- * @sample {highmaps} maps/plotoptions/series-allowpointselect/ Allow point select demo
+ * @sample {highmaps} maps/plotoptions/series-allowpointselect/
+ * Allow point select demo
* @product highmaps
*/
select: {
-
-
-
- /**
- */
marker: {}
}
},
@@ -22560,24 +23015,25 @@
* False
* @default {highcharts} true
* @default {highstock} true
* @default {highmaps} false
* @since 2.0
- * @product highcharts highstock highmaps
*/
stickyTracking: true,
- //tooltip: {
- //pointFormat: '<span style="color:{point.color}">\u25CF</span>' +
- // '{series.name}: <b>{point.y}</b>'
- //valueDecimals: null,
- //xDateFormat: '%A, %b %e, %Y',
- //valuePrefix: '',
- //ySuffix: ''
- //}
+ /**
+ * A configuration object for the tooltip rendering of each single series.
+ * Properties are inherited from [tooltip](#tooltip), but only the
+ * following properties can be defined on a series level.
+ *
+ * @type {Object}
+ * @extends tooltip
+ * @excluding animation,backgroundColor,borderColor,borderRadius,borderWidth,crosshairs,enabled,formatter,positioner,shadow,shared,shape,snap,style,useHTML
+ * @since 2.3
+ * @apioption plotOptions.series.tooltip
+ */
-
/**
* When a series contains a data array that is longer than this, only
* one dimensional arrays of numbers, or two dimensional arrays with
* x and y values are allowed. Also, only the first point is tested,
* and the rest are assumed to be the same format. This saves expensive
@@ -22587,15 +23043,89 @@
* @default 1000
* @since 2.2
* @product highcharts highstock
*/
turboThreshold: 1000,
- // zIndex: null
+ /**
+ * An array defining zones within a series. Zones can be applied to
+ * the X axis, Y axis or Z axis for bubbles, according to the `zoneAxis`
+ * option.
+ *
+ * In styled mode, the color zones are styled with the `.highcharts-
+ * zone-{n}` class, or custom classed from the `className` option ([view
+ * live demo](http://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/highcharts/css/color-
+ * zones/)).
+ *
+ * @type {Array}
+ * @see [zoneAxis](#plotOptions.series.zoneAxis)
+ * @sample {highcharts} highcharts/series/color-zones-simple/ Color zones
+ * @sample {highstock} highcharts/series/color-zones-simple/ Color zones
+ * @since 4.1.0
+ * @product highcharts highstock
+ * @apioption plotOptions.series.zones
+ */
+ /**
+ * Styled mode only. A custom class name for the zone.
+ *
+ * @type {String}
+ * @sample {highcharts} highcharts/css/color-zones/ Zones styled by class name
+ * @sample {highstock} highcharts/css/color-zones/ Zones styled by class name
+ * @sample {highmaps} highcharts/css/color-zones/ Zones styled by class name
+ * @since 5.0.0
+ * @apioption plotOptions.series.zones.className
+ */
/**
+ * Defines the color of the series.
+ *
+ * @type {Color}
+ * @see [series color](#plotOptions.series.color)
+ * @since 4.1.0
+ * @product highcharts highstock
+ * @apioption plotOptions.series.zones.color
+ */
+
+ /**
+ * A name for the dash style to use for the graph.
+ *
+ * @type {String}
+ * @see [series.dashStyle](#plotOptions.series.dashStyle)
+ * @sample {highcharts} highcharts/series/color-zones-dashstyle-dot/
+ * Dashed line indicates prognosis
+ * @sample {highstock} highcharts/series/color-zones-dashstyle-dot/
+ * Dashed line indicates prognosis
+ * @since 4.1.0
+ * @product highcharts highstock
+ * @apioption plotOptions.series.zones.dashStyle
+ */
+
+ /**
+ * Defines the fill color for the series (in area type series)
+ *
+ * @type {Color}
+ * @see [fillColor](#plotOptions.area.fillColor)
+ * @since 4.1.0
+ * @product highcharts highstock
+ * @apioption plotOptions.series.zones.fillColor
+ */
+
+ /**
+ * The value up to where the zone extends, if undefined the zones stretches
+ * to the last value in the series.
+ *
+ * @type {Number}
+ * @default undefined
+ * @since 4.1.0
+ * @product highcharts highstock
+ * @apioption plotOptions.series.zones.value
+ */
+
+
+
+ /**
* Determines whether the series should look for the nearest point
* in both dimensions or just the x-dimension when hovering the series.
* Defaults to `'xy'` for scatter series and `'x'` for most other
* series. If the data has duplicate x-values, it is recommended to
* set this to `'xy'` to allow hovering over all points.
@@ -22603,15 +23133,17 @@
* Applies only to series types using nearest neighbor search (not
* direct hover) for tooltip.
*
* @validvalue ['x', 'xy']
* @type {String}
- * @sample {highcharts} highcharts/series/findnearestpointby/ Different hover behaviors
- * @sample {highstock} highcharts/series/findnearestpointby/ Different hover behaviors
- * @sample {highmaps} highcharts/series/findnearestpointby/ Different hover behaviors
+ * @sample {highcharts} highcharts/series/findnearestpointby/
+ * Different hover behaviors
+ * @sample {highstock} highcharts/series/findnearestpointby/
+ * Different hover behaviors
+ * @sample {highmaps} highcharts/series/findnearestpointby/
+ * Different hover behaviors
* @since 5.0.10
- * @product highcharts highstock highmaps
*/
findNearestPointBy: 'x'
}, /** @lends Highcharts.Series.prototype */ {
isCartesian: true,
@@ -23107,11 +23639,11 @@
* or a different amount of points, as handled by the `updatePoints`
* parameter.
*
* @param {SeriesDataOptions} data
* Takes an array of data in the same format as described under
- * `series<type>data` for the given series type.
+ * `series.typedata` for the given series type.
* @param {Boolean} [redraw=true]
* Whether to redraw the chart after the series is altered. If doing
* more operations on the chart, it is a good idea to set redraw to
* false and call {@link Chart#redraw} after.
* @param {AnimationOptions} [animation]
@@ -23239,11 +23771,11 @@
}
}
// Forgetting to cast strings to numbers is a common caveat when
// handling CSV or JSON
- if (isString(yData[0])) {
+ if (yData && isString(yData[0])) {
H.error(14, true);
}
series.data = [];
series.options.data = series.userOptions.data = data;
@@ -23541,16 +24073,20 @@
}
}
}
/**
- * Read only. An array containing the series' data point objects. To
+ * Read only. An array containing those values converted to points, but
+ * in case the series data length exceeds the `cropThreshold`, or if the
+ * data is grouped, `series.data` doesn't contain all the points. It
+ * only contains the points that have been created on demand. To
* modify the data, use {@link Highcharts.Series#setData} or {@link
* Highcharts.Point#update}.
*
* @name data
* @memberOf Highcharts.Series
+ * @see Series.points
* @type {Array.<Highcharts.Point>}
*/
series.data = data;
/**
@@ -23559,11 +24095,11 @@
* `series.points` array starts at `series.cropStart` compared to
* `series.data` and `series.options.data`. If however the series data
* is grouped, these can't be correlated one to one. To
* modify the data, use {@link Highcharts.Series#setData} or {@link
* Highcharts.Point#update}.
- * @name point
+ * @name points
* @memberof Series
* @type {Array.<Point>}
*/
series.points = points;
},
@@ -23602,19 +24138,19 @@
x = xData[i];
y = yData[i];
// For points within the visible range, including the first point
- // outside the visible range, consider y extremes
+ // outside the visible range (#7061), consider y extremes.
validValue =
(isNumber(y, true) || isArray(y)) &&
(!yAxis.positiveValuesOnly || (y.length || y > 0));
withinRange =
this.getExtremesFromAll ||
this.options.getExtremesFromAll ||
this.cropped ||
- ((xData[i] || x) >= xMin && (xData[i] || x) <= xMax);
+ ((xData[i + 1] || x) >= xMin && (xData[i - 1] || x) <= xMax);
if (validValue && withinRange) {
j = y.length;
if (j) { // array, like ohlc or range data
@@ -23860,12 +24396,16 @@
if (!clipRect) {
// When animation is set, prepare the initial positions
if (animation) {
clipBox.width = 0;
+ if (inverted) {
+ clipBox.x = chart.plotSizeX;
+ }
- chart[sharedClipKey + 'm'] = markerClipRect = renderer.clipRect(-99, // include the width of the first marker
+ chart[sharedClipKey + 'm'] = markerClipRect = renderer.clipRect(
+ inverted ? chart.plotSizeX + 99 : -99, // include the width of the first marker
inverted ? -chart.plotLeft : -chart.plotTop,
99,
inverted ? chart.chartWidth : chart.chartHeight
);
}
@@ -23933,16 +24473,18 @@
} else {
sharedClipKey = this.sharedClipKey;
clipRect = chart[sharedClipKey];
if (clipRect) {
clipRect.animate({
- width: chart.plotSizeX
+ width: chart.plotSizeX,
+ x: 0
}, animation);
}
if (chart[sharedClipKey + 'm']) {
chart[sharedClipKey + 'm'].animate({
- width: chart.plotSizeX + 99
+ width: chart.plotSizeX + 99,
+ x: 0
}, animation);
}
// Delete this function to allow it only once
series.animate = null;
@@ -24449,11 +24991,10 @@
}
// Helpers for animation
if (graph) {
graph.startX = graphPath.xMap;
- //graph.shiftUnit = options.step ? 2 : 1;
graph.isArea = graphPath.isArea; // For arearange animation
}
});
},
@@ -24534,11 +25075,11 @@
clipAttr.y = chart.plotWidth - clipAttr.y;
}
}
- /// VML SUPPPORT
+ // VML SUPPPORT
if (inverted && renderer.isVML) {
if (axis.isXAxis) {
clipAttr = {
x: 0,
y: reversed ? pxPosMin : pxPosMax,
@@ -24552,11 +25093,11 @@
width: clipAttr.height,
height: chart.chartHeight
};
}
}
- /// END OF VML SUPPORT
+ // END OF VML SUPPORT
if (clips[i]) {
clips[i].animate(clipAttr);
} else {
@@ -24649,12 +25190,17 @@
group.addClass(
(
'highcharts-' + name +
' highcharts-series-' + this.index +
' highcharts-' + this.type + '-series ' +
- 'highcharts-color-' + this.colorIndex + ' ' +
- (this.options.className || '')
+ (
+ defined(this.colorIndex) ?
+ 'highcharts-color-' + this.colorIndex + ' ' :
+ ''
+ ) +
+ (this.options.className || '') +
+ (group.hasClass('highcharts-tracker') ? ' highcharts-tracker' : '')
),
true
);
// Place it on first and subsequent (redraw) calls
@@ -24990,10 +25536,218 @@
}
}
}); // end Series prototype
+ /**
+ * A line series displays information as a series of data points connected by
+ * straight line segments.
+ *
+ * @sample {highcharts} highcharts/demo/line-basic/ Line chart
+ * @sample {highstock} stock/demo/basic-line/ Line chart
+ *
+ * @extends plotOptions.series
+ * @product highcharts highstock
+ * @apioption plotOptions.line
+ */
+
+ /**
+ * A `line` series. If the [type](#series.line.type) option is not
+ * specified, it is inherited from [chart.type](#chart.type).
+ *
+ * For options that apply to multiple series, it is recommended to add
+ * them to the [plotOptions.series](#plotOptions.series) options structure.
+ * To apply to all series of this specific type, apply it to [plotOptions.
+ * line](#plotOptions.line).
+ *
+ * @type {Object}
+ * @extends series,plotOptions.line
+ * @excluding dataParser,dataURL
+ * @product highcharts highstock
+ * @apioption series.line
+ */
+
+ /**
+ * An array of data points for the series. For the `line` series type,
+ * points can be given in the following ways:
+ *
+ * 1. An array of numerical values. In this case, the numerical values
+ * will be interpreted as `y` options. The `x` values will be automatically
+ * calculated, either starting at 0 and incremented by 1, or from `pointStart`
+ * and `pointInterval` given in the series options. If the axis has
+ * categories, these will be used. Example:
+ *
+ * ```js
+ * data: [0, 5, 3, 5]
+ * ```
+ *
+ * 2. An array of arrays with 2 values. In this case, the values correspond
+ * to `x,y`. If the first value is a string, it is applied as the name
+ * of the point, and the `x` value is inferred.
+ *
+ * ```js
+ * data: [
+ * [0, 1],
+ * [1, 2],
+ * [2, 8]
+ * ]
+ * ```
+ *
+ * 3. An array of objects with named values. The objects are point
+ * configuration objects as seen below. If the total number of data
+ * points exceeds the series' [turboThreshold](#series.line.turboThreshold),
+ * this option is not available.
+ *
+ * ```js
+ * data: [{
+ * x: 1,
+ * y: 9,
+ * name: "Point2",
+ * color: "#00FF00"
+ * }, {
+ * x: 1,
+ * y: 6,
+ * name: "Point1",
+ * color: "#FF00FF"
+ * }]
+ * ```
+ *
+ * @type {Array<Object|Array|Number>}
+ * @sample {highcharts} highcharts/chart/reflow-true/ Numerical values
+ * @sample {highcharts} highcharts/series/data-array-of-arrays/ Arrays of numeric x and y
+ * @sample {highcharts} highcharts/series/data-array-of-arrays-datetime/ Arrays of datetime x and y
+ * @sample {highcharts} highcharts/series/data-array-of-name-value/ Arrays of point.name and y
+ * @sample {highcharts} highcharts/series/data-array-of-objects/ Config objects
+ * @apioption series.line.data
+ */
+
+ /**
+ * An additional, individual class name for the data point's graphic
+ * representation.
+ *
+ * @type {String}
+ * @since 5.0.0
+ * @product highcharts
+ * @apioption series.line.data.className
+ */
+
+ /**
+ * Individual color for the point. By default the color is pulled from
+ * the global `colors` array.
+ *
+ * @type {Color}
+ * @sample {highcharts} highcharts/point/color/ Mark the highest point
+ * @default undefined
+ * @product highcharts highstock
+ * @apioption series.line.data.color
+ */
+
+ /**
+ * Styled mode only. A specific color index to use for the point, so its
+ * graphic representations are given the class name `highcharts-color-
+ * {n}`.
+ *
+ * @type {Number}
+ * @since 5.0.0
+ * @product highcharts
+ * @apioption series.line.data.colorIndex
+ */
+
+ /**
+ * Individual data label for each point. The options are the same as
+ * the ones for [plotOptions.series.dataLabels](#plotOptions.series.
+ * dataLabels)
+ *
+ * @type {Object}
+ * @sample {highcharts} highcharts/point/datalabels/ Show a label for the last value
+ * @sample {highstock} highcharts/point/datalabels/ Show a label for the last value
+ * @product highcharts highstock
+ * @apioption series.line.data.dataLabels
+ */
+
+ /**
+ * A description of the point to add to the screen reader information
+ * about the point. Requires the Accessibility module.
+ *
+ * @type {String}
+ * @default undefined
+ * @since 5.0.0
+ * @apioption series.line.data.description
+ */
+
+ /**
+ * An id for the point. This can be used after render time to get a
+ * pointer to the point object through `chart.get()`.
+ *
+ * @type {String}
+ * @sample {highcharts} highcharts/point/id/ Remove an id'd point
+ * @default null
+ * @since 1.2.0
+ * @product highcharts highstock
+ * @apioption series.line.data.id
+ */
+
+ /**
+ * The rank for this point's data label in case of collision. If two
+ * data labels are about to overlap, only the one with the highest `labelrank`
+ * will be drawn.
+ *
+ * @type {Number}
+ * @apioption series.line.data.labelrank
+ */
+
+ /**
+ * The name of the point as shown in the legend, tooltip, dataLabel
+ * etc.
+ *
+ * @type {String}
+ * @sample {highcharts} highcharts/series/data-array-of-objects/ Point names
+ * @see [xAxis.uniqueNames](#xAxis.uniqueNames)
+ * @apioption series.line.data.name
+ */
+
+ /**
+ * Whether the data point is selected initially.
+ *
+ * @type {Boolean}
+ * @default false
+ * @product highcharts highstock
+ * @apioption series.line.data.selected
+ */
+
+ /**
+ * The x value of the point. For datetime axes, the X value is the timestamp
+ * in milliseconds since 1970.
+ *
+ * @type {Number}
+ * @product highcharts highstock
+ * @apioption series.line.data.x
+ */
+
+ /**
+ * The y value of the point.
+ *
+ * @type {Number}
+ * @default null
+ * @product highcharts highstock
+ * @apioption series.line.data.y
+ */
+
+ /**
+ * Individual point events
+ *
+ * @extends plotOptions.series.point.events
+ * @product highcharts highstock
+ * @apioption series.line.data.events
+ */
+
+ /**
+ * @extends plotOptions.series.marker
+ * @product highcharts highstock
+ * @apioption series.line.data.marker
+ */
+
}(Highcharts));
(function(H) {
/**
* (c) 2010-2017 Torstein Honsi
*
@@ -25112,11 +25866,11 @@
0,
1
),
yZero = axis.translate(0), // stack origin
h = Math.abs(y - yZero), // stack height
- x = chart.xAxis[0].translate(stackItem.x) + xOffset, // stack x position
+ x = chart.xAxis[0].translate(stackItem.x) + xOffset, // x position
stackBox = stackItem.getStackBox(chart, stackItem, x, y, xWidth, h),
label = stackItem.label,
alignAttr;
if (label) {
@@ -25190,15 +25944,13 @@
i = len;
while (i--) {
axisSeries[reversedStacks ? i : len - i - 1].setStackedPoints();
}
- // Loop up again to compute percent stack
- if (this.usePercentage) {
- for (i = 0; i < len; i++) {
- axisSeries[i].setPercentStacks();
- }
+ // Loop up again to compute percent and stream stack
+ for (i = 0; i < len; i++) {
+ axisSeries[i].modifyStacks();
}
}
};
Axis.prototype.renderStackTotals = function() {
@@ -25409,47 +26161,56 @@
};
/**
* Iterate over all stacks and compute the absolute values to percent
*/
- Series.prototype.setPercentStacks = function() {
+ Series.prototype.modifyStacks = function() {
var series = this,
stackKey = series.stackKey,
stacks = series.yAxis.stacks,
processedXData = series.processedXData,
- stackIndicator;
+ stackIndicator,
+ stacking = series.options.stacking;
- each([stackKey, '-' + stackKey], function(key) {
- var i = processedXData.length,
- x,
- stack,
- pointExtremes,
- totalFactor;
-
- while (i--) {
- x = processedXData[i];
- stackIndicator = series.getStackIndicator(
- stackIndicator,
+ if (series[stacking + 'Stacker']) { // Modifier function exists
+ each([stackKey, '-' + stackKey], function(key) {
+ var i = processedXData.length,
x,
- series.index,
- key
- );
- stack = stacks[key] && stacks[key][x];
- pointExtremes = stack && stack.points[stackIndicator.key];
- if (pointExtremes) {
- totalFactor = stack.total ? 100 / stack.total : 0;
- // Y bottom value
- pointExtremes[0] = correctFloat(pointExtremes[0] * totalFactor);
- // Y value
- pointExtremes[1] = correctFloat(pointExtremes[1] * totalFactor);
- series.stackedYData[i] = pointExtremes[1];
+ stack,
+ pointExtremes;
+
+ while (i--) {
+ x = processedXData[i];
+ stackIndicator = series.getStackIndicator(
+ stackIndicator,
+ x,
+ series.index,
+ key
+ );
+ stack = stacks[key] && stacks[key][x];
+ pointExtremes = stack && stack.points[stackIndicator.key];
+ if (pointExtremes) {
+ series[stacking + 'Stacker'](pointExtremes, stack, i);
+ }
}
- }
- });
+ });
+ }
};
/**
+ * Modifier function for percent stacks. Blows up the stack to 100%.
+ */
+ Series.prototype.percentStacker = function(pointExtremes, stack, i) {
+ var totalFactor = stack.total ? 100 / stack.total : 0;
+ // Y bottom value
+ pointExtremes[0] = correctFloat(pointExtremes[0] * totalFactor);
+ // Y value
+ pointExtremes[1] = correctFloat(pointExtremes[1] * totalFactor);
+ this.stackedYData[i] = pointExtremes[1];
+ };
+
+ /**
* Get stack indicator, according to it's x-value, to determine points with the
* same x-value
*/
Series.prototype.getStackIndicator = function(stackIndicator, x, index, key) {
// Update stack indicator, when:
@@ -25961,11 +26722,11 @@
* Update point with new options (typically x/y data) and optionally redraw
* the series.
*
* @param {Object} options
* The point options. Point options are handled as described under
- * the `series<type>.data` item for each series type. For example
+ * the `series.type.data` item for each series type. For example
* for a line series, if options is a single number, the point will
* be given that number as the main y value. If it is an array, it
* will be interpreted as x and y values respectively. If it is an
* object, advanced options are applied.
* @param {Boolean} [redraw=true]
@@ -26319,14 +27080,16 @@
oldOptions = series.userOptions,
oldType = series.oldType || series.type,
newType = newOptions.type || oldOptions.type || chart.options.chart.type,
proto = seriesTypes[oldType].prototype,
n,
- preserve = [
+ preserveGroups = [
'group',
'markerGroup',
- 'dataLabelsGroup',
+ 'dataLabelsGroup'
+ ],
+ preserve = [
'navigatorSeries',
'baseSeries'
],
// Animation must be enabled when calling update before the initial
@@ -26344,15 +27107,23 @@
if (Object.keys && Object.keys(newOptions).toString() === 'data') {
return this.setData(newOptions.data, redraw);
}
// If we're changing type or zIndex, create new groups (#3380, #3404)
- if ((newType && newType !== oldType) || newOptions.zIndex !== undefined) {
+ // Also create new groups for navigator series.
+ if (
+ (newType && newType !== oldType) ||
+ newOptions.zIndex !== undefined
+ ) {
+ preserveGroups.length = 0;
+ }
+ if (series.options.isInternal) {
preserve.length = 0;
}
- // Make sure groups are not destroyed (#3094)
+ // Make sure preserved properties are not destroyed (#3094)
+ preserve = preserveGroups.concat(preserve);
each(preserve, function(prop) {
preserve[prop] = series[prop];
delete series[prop];
});
@@ -26508,16 +27279,77 @@
* Area series type.
* @constructor seriesTypes.area
* @extends {Series}
*/
/**
+ * The area series type.
* @extends {plotOptions.line}
+ * @product highcharts highstock
+ * @sample {highcharts} highcharts/demo/area-basic/
+ * Area chart
+ * @sample {highstock} stock/demo/area/
+ * Area chart
* @optionparent plotOptions.area
*/
seriesType('area', 'line', {
/**
+ * Fill color or gradient for the area. When `null`, the series' `color`
+ * is used with the series' `fillOpacity`.
+ *
+ * @type {Color}
+ * @see In styled mode, the fill color can be set with the `.highcharts-area` class name.
+ * @sample {highcharts} highcharts/plotoptions/area-fillcolor-default/ Null by default
+ * @sample {highcharts} highcharts/plotoptions/area-fillcolor-gradient/ Gradient
+ * @default null
+ * @product highcharts highstock
+ * @apioption plotOptions.area.fillColor
+ */
+
+ /**
+ * Fill opacity for the area. When you set an explicit `fillColor`,
+ * the `fillOpacity` is not applied. Instead, you should define the
+ * opacity in the `fillColor` with an rgba color definition. The `fillOpacity`
+ * setting, also the default setting, overrides the alpha component
+ * of the `color` setting.
+ *
+ * @type {Number}
+ * @see In styled mode, the fill opacity can be set with the `.highcharts-area` class name.
+ * @sample {highcharts} highcharts/plotoptions/area-fillopacity/ Automatic fill color and fill opacity of 0.1
+ * @default {highcharts} 0.75
+ * @default {highstock} .75
+ * @product highcharts highstock
+ * @apioption plotOptions.area.fillOpacity
+ */
+
+ /**
+ * A separate color for the graph line. By default the line takes the
+ * `color` of the series, but the lineColor setting allows setting a
+ * separate color for the line without altering the `fillColor`.
+ *
+ * @type {Color}
+ * @see In styled mode, the line stroke can be set with the `.highcharts-graph` class name.
+ * @sample {highcharts} highcharts/plotoptions/area-linecolor/ Dark gray line
+ * @default null
+ * @product highcharts highstock
+ * @apioption plotOptions.area.lineColor
+ */
+
+ /**
+ * A separate color for the negative part of the area.
+ *
+ * @type {Color}
+ * @see [negativeColor](#plotOptions.area.negativeColor). In styled mode, a negative
+ * color is set with the `.highcharts-negative` class name ([view live
+ * demo](http://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/highcharts/css/series-
+ * negative-color/)).
+ * @since 3.0
+ * @product highcharts
+ * @apioption plotOptions.area.negativeFillColor
+ */
+
+ /**
* When this is true, the series will not cause the Y axis to cross
* the zero plane (or [threshold](#plotOptions.series.threshold) option)
* unless the data actually crosses the plane.
*
* For example, if `softThreshold` is `false`, a series of 0, 1, 2,
@@ -26542,14 +27374,25 @@
* @default 0
* @since 2.0
* @product highcharts highstock
*/
threshold: 0
- // trackByArea: false,
- // lineColor: null, // overrides color, but lets fillColor be unaltered
- // fillOpacity: 0.75,
- // fillColor: null
+
+ /**
+ * Whether the whole area or just the line should respond to mouseover
+ * tooltips and other mouse or touch events.
+ *
+ * @type {Boolean}
+ * @sample {highcharts} highcharts/plotoptions/area-trackbyarea/ Display the tooltip when the area is hovered
+ * @sample {highstock} highcharts/plotoptions/area-trackbyarea/ Display the tooltip when the area is hovered
+ * @default false
+ * @since 1.1.6
+ * @product highcharts highstock
+ * @apioption plotOptions.area.trackByArea
+ */
+
+
}, /** @lends seriesTypes.area.prototype */ {
singleStacks: false,
/**
* Return an array of stacked points, where null and missing points are replaced by
* dummy points in order for gaps to be drawn correctly in stacks.
@@ -26674,11 +27517,10 @@
graphPath,
options = this.options,
stacking = options.stacking,
yAxis = this.yAxis,
topPath,
- //topPoints = [],
bottomPath,
bottomPoints = [],
graphPoints = [],
seriesIndex = this.index,
i,
@@ -26851,10 +27693,82 @@
},
drawLegendSymbol: LegendSymbolMixin.drawRectangle
});
+ /**
+ * A `area` series. If the [type](#series.area.type) option is not
+ * specified, it is inherited from [chart.type](#chart.type).
+ *
+ * For options that apply to multiple series, it is recommended to add
+ * them to the [plotOptions.series](#plotOptions.series) options structure.
+ * To apply to all series of this specific type, apply it to [plotOptions.
+ * area](#plotOptions.area).
+ *
+ * @type {Object}
+ * @extends series,plotOptions.area
+ * @excluding dataParser,dataURL
+ * @product highcharts highstock
+ * @apioption series.area
+ */
+
+ /**
+ * An array of data points for the series. For the `area` series type,
+ * points can be given in the following ways:
+ *
+ * 1. An array of numerical values. In this case, the numerical values
+ * will be interpreted as `y` options. The `x` values will be automatically
+ * calculated, either starting at 0 and incremented by 1, or from `pointStart`
+ * and `pointInterval` given in the series options. If the axis has
+ * categories, these will be used. Example:
+ *
+ * ```js
+ * data: [0, 5, 3, 5]
+ * ```
+ *
+ * 2. An array of arrays with 2 values. In this case, the values correspond
+ * to `x,y`. If the first value is a string, it is applied as the name
+ * of the point, and the `x` value is inferred.
+ *
+ * ```js
+ * data: [
+ * [0, 9],
+ * [1, 7],
+ * [2, 6]
+ * ]
+ * ```
+ *
+ * 3. An array of objects with named values. The objects are point
+ * configuration objects as seen below. If the total number of data
+ * points exceeds the series' [turboThreshold](#series.area.turboThreshold),
+ * this option is not available.
+ *
+ * ```js
+ * data: [{
+ * x: 1,
+ * y: 9,
+ * name: "Point2",
+ * color: "#00FF00"
+ * }, {
+ * x: 1,
+ * y: 6,
+ * name: "Point1",
+ * color: "#FF00FF"
+ * }]
+ * ```
+ *
+ * @type {Array<Object|Array|Number>}
+ * @extends series.line.data
+ * @sample {highcharts} highcharts/chart/reflow-true/ Numerical values
+ * @sample {highcharts} highcharts/series/data-array-of-arrays/ Arrays of numeric x and y
+ * @sample {highcharts} highcharts/series/data-array-of-arrays-datetime/ Arrays of datetime x and y
+ * @sample {highcharts} highcharts/series/data-array-of-name-value/ Arrays of point.name and y
+ * @sample {highcharts} highcharts/series/data-array-of-objects/ Config objects
+ * @product highcharts highstock
+ * @apioption series.area.data
+ */
+
}(Highcharts));
(function(H) {
/**
* (c) 2010-2017 Torstein Honsi
*
@@ -26862,20 +27776,37 @@
*/
var pick = H.pick,
seriesType = H.seriesType;
/**
+ * A spline series is a special type of line series, where the segments between
+ * the data points are smoothed.
+ *
+ * @sample {highcharts} highcharts/demo/spline-irregular-time/ Spline chart
+ * @sample {highstock} stock/demo/spline/ Spline chart
+ *
+ * @extends plotOptions.series
+ * @excluding step
+ * @product highcharts highstock
+ * @apioption plotOptions.spline
+ */
+
+ /**
* Spline series type.
* @constructor seriesTypes.spline
* @extends {Series}
*/
seriesType('spline', 'line', {}, /** @lends seriesTypes.spline.prototype */ {
/**
- * Get the spline segment from a given point's previous neighbour to the given point
+ * Get the spline segment from a given point's previous neighbour to the
+ * given point
*/
getPointSpline: function(points, point, i) {
- var smoothing = 1.5, // 1 means control points midway between points, 2 means 1/3 from the point, 3 is 1/4 etc
+ var
+ // 1 means control points midway between points, 2 means 1/3 from
+ // the point, 3 is 1/4 etc
+ smoothing = 1.5,
denom = smoothing + 1,
plotX = point.plotX,
plotY = point.plotY,
lastPoint = points[i - 1],
nextPoint = points[i + 1],
@@ -26903,11 +27834,12 @@
leftContX = (smoothing * plotX + lastX) / denom;
leftContY = (smoothing * plotY + lastY) / denom;
rightContX = (smoothing * plotX + nextX) / denom;
rightContY = (smoothing * plotY + nextY) / denom;
- // Have the two control points make a straight line through main point
+ // Have the two control points make a straight line through main
+ // point
if (rightContX !== leftContX) { // #5016, division by zero
correction = ((rightContY - leftContY) * (rightContX - plotX)) /
(rightContX - leftContX) + plotY - rightContY;
}
@@ -26916,11 +27848,12 @@
// to prevent false extremes, check that control points are between
// neighbouring points' y values
if (leftContY > lastY && leftContY > plotY) {
leftContY = Math.max(lastY, plotY);
- rightContY = 2 * plotY - leftContY; // mirror of left control point
+ // mirror of left control point
+ rightContY = 2 * plotY - leftContY;
} else if (leftContY < lastY && leftContY < plotY) {
leftContY = Math.min(lastY, plotY);
rightContY = 2 * plotY - leftContY;
}
if (rightContY > nextY && rightContY > plotY) {
@@ -26939,37 +27872,47 @@
}
// Visualize control points for debugging
/*
if (leftContX) {
- this.chart.renderer.circle(leftContX + this.chart.plotLeft, leftContY + this.chart.plotTop, 2)
+ this.chart.renderer.circle(
+ leftContX + this.chart.plotLeft,
+ leftContY + this.chart.plotTop,
+ 2
+ )
.attr({
stroke: 'red',
'stroke-width': 2,
fill: 'none',
zIndex: 9
})
.add();
- this.chart.renderer.path(['M', leftContX + this.chart.plotLeft, leftContY + this.chart.plotTop,
+ this.chart.renderer.path(['M', leftContX + this.chart.plotLeft,
+ leftContY + this.chart.plotTop,
'L', plotX + this.chart.plotLeft, plotY + this.chart.plotTop])
.attr({
stroke: 'red',
'stroke-width': 2,
zIndex: 9
})
.add();
}
if (rightContX) {
- this.chart.renderer.circle(rightContX + this.chart.plotLeft, rightContY + this.chart.plotTop, 2)
+ this.chart.renderer.circle(
+ rightContX + this.chart.plotLeft,
+ rightContY + this.chart.plotTop,
+ 2
+ )
.attr({
stroke: 'green',
'stroke-width': 2,
fill: 'none',
zIndex: 9
})
.add();
- this.chart.renderer.path(['M', rightContX + this.chart.plotLeft, rightContY + this.chart.plotTop,
+ this.chart.renderer.path(['M', rightContX + this.chart.plotLeft,
+ rightContY + this.chart.plotTop,
'L', plotX + this.chart.plotLeft, plotY + this.chart.plotTop])
.attr({
stroke: 'green',
'stroke-width': 2,
zIndex: 9
@@ -26984,15 +27927,93 @@
pick(leftContX, plotX),
pick(leftContY, plotY),
plotX,
plotY
];
- lastPoint.rightContX = lastPoint.rightContY = null; // reset for updating series later
+ // reset for updating series later
+ lastPoint.rightContX = lastPoint.rightContY = null;
return ret;
}
});
+ /**
+ * A `spline` series. If the [type](#series.spline.type) option is
+ * not specified, it is inherited from [chart.type](#chart.type).
+ *
+ * For options that apply to multiple series, it is recommended to add
+ * them to the [plotOptions.series](#plotOptions.series) options structure.
+ * To apply to all series of this specific type, apply it to [plotOptions.
+ * spline](#plotOptions.spline).
+ *
+ * @type {Object}
+ * @extends series,plotOptions.spline
+ * @excluding dataParser,dataURL
+ * @product highcharts highstock
+ * @apioption series.spline
+ */
+
+ /**
+ * An array of data points for the series. For the `spline` series type,
+ * points can be given in the following ways:
+ *
+ * 1. An array of numerical values. In this case, the numerical values
+ * will be interpreted as `y` options. The `x` values will be automatically
+ * calculated, either starting at 0 and incremented by 1, or from `pointStart`
+ * and `pointInterval` given in the series options. If the axis has
+ * categories, these will be used. Example:
+ *
+ * ```js
+ * data: [0, 5, 3, 5]
+ * ```
+ *
+ * 2. An array of arrays with 2 values. In this case, the values correspond
+ * to `x,y`. If the first value is a string, it is applied as the name
+ * of the point, and the `x` value is inferred.
+ *
+ * ```js
+ * data: [
+ * [0, 9],
+ * [1, 2],
+ * [2, 8]
+ * ]
+ * ```
+ *
+ * 3. An array of objects with named values. The objects are point
+ * configuration objects as seen below. If the total number of data
+ * points exceeds the series' [turboThreshold](#series.spline.turboThreshold),
+ * this option is not available.
+ *
+ * ```js
+ * data: [{
+ * x: 1,
+ * y: 9,
+ * name: "Point2",
+ * color: "#00FF00"
+ * }, {
+ * x: 1,
+ * y: 0,
+ * name: "Point1",
+ * color: "#FF00FF"
+ * }]
+ * ```
+ *
+ * @type {Array<Object|Array|Number>}
+ * @extends series.line.data
+ * @sample {highcharts} highcharts/chart/reflow-true/
+ * Numerical values
+ * @sample {highcharts} highcharts/series/data-array-of-arrays/
+ * Arrays of numeric x and y
+ * @sample {highcharts} highcharts/series/data-array-of-arrays-datetime/
+ * Arrays of datetime x and y
+ * @sample {highcharts} highcharts/series/data-array-of-name-value/
+ * Arrays of point.name and y
+ * @sample {highcharts} highcharts/series/data-array-of-objects/
+ * Config objects
+ * @product highcharts highstock
+ * @apioption series.spline.data
+ */
+
}(Highcharts));
(function(H) {
/**
* (c) 2010-2017 Torstein Honsi
*
@@ -27003,17 +28024,103 @@
LegendSymbolMixin = H.LegendSymbolMixin,
seriesType = H.seriesType;
/**
* AreaSplineSeries object
*/
+ /**
+ * The area spline series is an area series where the graph between the points
+ * is smoothed into a spline.
+ *
+ * @extends plotOptions.area
+ * @excluding step
+ * @sample {highcharts} highcharts/demo/areaspline/ Area spline chart
+ * @sample {highstock} stock/demo/areaspline/ Area spline chart
+ * @product highcharts highstock
+ * @apioption plotOptions.areaspline
+ */
seriesType('areaspline', 'spline', defaultPlotOptions.area, {
getStackPoints: areaProto.getStackPoints,
getGraphPath: areaProto.getGraphPath,
drawGraph: areaProto.drawGraph,
drawLegendSymbol: LegendSymbolMixin.drawRectangle
});
+ /**
+ * A `areaspline` series. If the [type](#series.areaspline.type) option
+ * is not specified, it is inherited from [chart.type](#chart.type).
+ *
+ *
+ * For options that apply to multiple series, it is recommended to add
+ * them to the [plotOptions.series](#plotOptions.series) options structure.
+ * To apply to all series of this specific type, apply it to [plotOptions.
+ * areaspline](#plotOptions.areaspline).
+ *
+ * @type {Object}
+ * @extends series,plotOptions.areaspline
+ * @excluding dataParser,dataURL
+ * @product highcharts highstock
+ * @apioption series.areaspline
+ */
+
+ /**
+ * An array of data points for the series. For the `areaspline` series
+ * type, points can be given in the following ways:
+ *
+ * 1. An array of numerical values. In this case, the numerical values
+ * will be interpreted as `y` options. The `x` values will be automatically
+ * calculated, either starting at 0 and incremented by 1, or from `pointStart`
+ * and `pointInterval` given in the series options. If the axis has
+ * categories, these will be used. Example:
+ *
+ * ```js
+ * data: [0, 5, 3, 5]
+ * ```
+ *
+ * 2. An array of arrays with 2 values. In this case, the values correspond
+ * to `x,y`. If the first value is a string, it is applied as the name
+ * of the point, and the `x` value is inferred.
+ *
+ * ```js
+ * data: [
+ * [0, 10],
+ * [1, 9],
+ * [2, 3]
+ * ]
+ * ```
+ *
+ * 3. An array of objects with named values. The objects are point
+ * configuration objects as seen below. If the total number of data
+ * points exceeds the series' [turboThreshold](#series.areaspline.turboThreshold),
+ * this option is not available.
+ *
+ * ```js
+ * data: [{
+ * x: 1,
+ * y: 4,
+ * name: "Point2",
+ * color: "#00FF00"
+ * }, {
+ * x: 1,
+ * y: 4,
+ * name: "Point1",
+ * color: "#FF00FF"
+ * }]
+ * ```
+ *
+ * @type {Array<Object|Array|Number>}
+ * @extends series.line.data
+ * @sample {highcharts} highcharts/chart/reflow-true/ Numerical values
+ * @sample {highcharts} highcharts/series/data-array-of-arrays/ Arrays of numeric x and y
+ * @sample {highcharts} highcharts/series/data-array-of-arrays-datetime/ Arrays of datetime x and y
+ * @sample {highcharts} highcharts/series/data-array-of-name-value/ Arrays of point.name and y
+ * @sample {highcharts} highcharts/series/data-array-of-objects/ Config objects
+ * @product highcharts highstock
+ * @apioption series.areaspline.data
+ */
+
+
+
}(Highcharts));
(function(H) {
/**
* (c) 2010-2017 Torstein Honsi
*
@@ -27037,82 +28144,184 @@
* @constructor seriesTypes.column
* @augments Series
*/
/**
+ * Column series display one column per value along an X axis.
+ *
+ * @sample {highcharts} highcharts/demo/column-basic/ Column chart
+ * @sample {highstock} stock/demo/column/ Column chart
+ *
* @extends {plotOptions.line}
+ * @product highcharts highstock
+ * @excluding connectNulls,dashStyle,gapSize,gapUnit,linecap,lineWidth,marker,
+ * connectEnds,step
* @optionparent plotOptions.column
- * @excluding connectNulls,dashStyle,linecap,lineWidth,marker,connectEnds,step
*/
seriesType('column', 'line', {
/**
* The corner radius of the border surrounding each column or bar.
*
* @type {Number}
- * @sample {highcharts} highcharts/plotoptions/column-borderradius/ Rounded columns
+ * @sample {highcharts} highcharts/plotoptions/column-borderradius/
+ * Rounded columns
* @default 0
* @product highcharts highstock
*/
borderRadius: 0,
- //colorByPoint: undefined,
/**
+ * The width of the border surrounding each column or bar.
+ *
+ * In styled mode, the stroke width can be set with the `.highcharts-point`
+ * rule.
+ *
+ * @type {Number}
+ * @sample {highcharts} highcharts/plotoptions/column-borderwidth/
+ * 2px black border
+ * @default 1
+ * @product highcharts highstock
+ * @apioption plotOptions.column.borderWidth
+ */
+
+ /**
+ * When using automatic point colors pulled from the `options.colors`
+ * collection, this option determines whether the chart should receive
+ * one color per series or one color per point.
+ *
+ * @type {Boolean}
+ * @see [series colors](#plotOptions.column.colors)
+ * @sample {highcharts} highcharts/plotoptions/column-colorbypoint-false/
+ * False by default
+ * @sample {highcharts} highcharts/plotoptions/column-colorbypoint-true/
+ * True
+ * @default false
+ * @since 2.0
+ * @product highcharts highstock
+ * @apioption plotOptions.column.colorByPoint
+ */
+
+ /**
+ * A series specific or series type specific color set to apply instead
+ * of the global [colors](#colors) when [colorByPoint](#plotOptions.
+ * column.colorByPoint) is true.
+ *
+ * @type {Array<Color>}
+ * @since 3.0
+ * @product highcharts highstock
+ * @apioption plotOptions.column.colors
+ */
+
+ /**
* When true, each column edge is rounded to its nearest pixel in order
* to render sharp on screen. In some cases, when there are a lot of
* densely packed columns, this leads to visible difference in column
* widths or distance between columns. In these cases, setting `crisp`
* to `false` may look better, even though each column is rendered
* blurry.
*
* @type {Boolean}
- * @sample {highcharts} highcharts/plotoptions/column-crisp-false/ Crisp is false
+ * @sample {highcharts} highcharts/plotoptions/column-crisp-false/
+ * Crisp is false
* @default true
* @since 5.0.10
* @product highcharts highstock
*/
crisp: true,
/**
* Padding between each value groups, in x axis units.
*
* @type {Number}
- * @sample {highcharts} highcharts/plotoptions/column-grouppadding-default/ 0.2 by default
- * @sample {highcharts} highcharts/plotoptions/column-grouppadding-none/ No group padding - all columns are evenly spaced
+ * @sample {highcharts} highcharts/plotoptions/column-grouppadding-default/
+ * 0.2 by default
+ * @sample {highcharts} highcharts/plotoptions/column-grouppadding-none/
+ * No group padding - all columns are evenly spaced
* @default 0.2
* @product highcharts highstock
*/
groupPadding: 0.2,
- //grouping: true,
/**
+ * Whether to group non-stacked columns or to let them render independent
+ * of each other. Non-grouped columns will be laid out individually
+ * and overlap each other.
+ *
+ * @type {Boolean}
+ * @sample {highcharts} highcharts/plotoptions/column-grouping-false/
+ * Grouping disabled
+ * @sample {highstock} highcharts/plotoptions/column-grouping-false/
+ * Grouping disabled
+ * @default true
+ * @since 2.3.0
+ * @product highcharts highstock
+ * @apioption plotOptions.column.grouping
*/
+
marker: null, // point options are specified in the base options
/**
+ * The maximum allowed pixel width for a column, translated to the height
+ * of a bar in a bar chart. This prevents the columns from becoming
+ * too wide when there is a small number of points in the chart.
+ *
+ * @type {Number}
+ * @see [pointWidth](#plotOptions.column.pointWidth)
+ * @sample {highcharts} highcharts/plotoptions/column-maxpointwidth-20/
+ * Limited to 50
+ * @sample {highstock} highcharts/plotoptions/column-maxpointwidth-20/
+ * Limited to 50
+ * @default null
+ * @since 4.1.8
+ * @product highcharts highstock
+ * @apioption plotOptions.column.maxPointWidth
+ */
+
+ /**
* Padding between each column or bar, in x axis units.
*
* @type {Number}
- * @sample {highcharts} highcharts/plotoptions/column-pointpadding-default/ 0.1 by default
- * @sample {highcharts} highcharts/plotoptions/column-pointpadding-025/ 0.25
- * @sample {highcharts} highcharts/plotoptions/column-pointpadding-none/ 0 for tightly packed columns
+ * @sample {highcharts} highcharts/plotoptions/column-pointpadding-default/
+ * 0.1 by default
+ * @sample {highcharts} highcharts/plotoptions/column-pointpadding-025/
+ * 0.25
+ * @sample {highcharts} highcharts/plotoptions/column-pointpadding-none/
+ * 0 for tightly packed columns
* @default 0.1
* @product highcharts highstock
*/
pointPadding: 0.1,
- //pointWidth: null,
/**
+ * A pixel value specifying a fixed width for each column or bar. When
+ * `null`, the width is calculated from the `pointPadding` and
+ * `groupPadding`.
+ *
+ * @type {Number}
+ * @see [maxPointWidth](#plotOptions.column.maxPointWidth)
+ * @sample {highcharts} highcharts/plotoptions/column-pointwidth-20/
+ * 20px wide columns regardless of chart width or the amount of data
+ * points
+ * @default null
+ * @since 1.2.5
+ * @product highcharts highstock
+ * @apioption plotOptions.column.pointWidth
+ */
+
+ /**
* The minimal height for a column or width for a bar. By default,
* 0 values are not shown. To visualize a 0 (or close to zero) point,
* set the minimal point length to a pixel value like 3\. In stacked
* column charts, minPointLength might not be respected for tightly
* packed values.
*
* @type {Number}
- * @sample {highcharts} highcharts/plotoptions/column-minpointlength/ Zero base value
- * @sample {highcharts} highcharts/plotoptions/column-minpointlength-pos-and-neg/ Positive and negative close to zero values
+ * @sample {highcharts} highcharts/plotoptions/column-minpointlength/
+ * Zero base value
+ * @sample {highcharts} highcharts/plotoptions/column-minpointlength-pos-and-neg/
+ * Positive and negative close to zero values
* @default 0
* @product highcharts highstock
*/
minPointLength: 0,
@@ -27150,81 +28359,71 @@
* @since 2.3
* @product highcharts highstock
*/
pointRange: null,
- /**
- */
states: {
/**
* @extends plotOptions.series.states.hover
- * @excluding lineWidth,lineWidthPlus,marker
+ * @excluding halo,lineWidth,lineWidthPlus,marker
* @product highcharts highstock
*/
hover: {
+ halo: false,
/**
+ * A specific border color for the hovered point. Defaults to
+ * inherit the normal state border color.
+ *
+ * @type {Color}
+ * @product highcharts
+ * @apioption plotOptions.column.states.hover.borderColor
*/
- halo: false,
+ /**
+ * A specific color for the hovered point.
+ *
+ * @type {Color}
+ * @default undefined
+ * @product highcharts
+ * @apioption plotOptions.column.states.hover.color
+ */
+
+
/**
* How much to brighten the point on interaction. Requires the main
* color to be defined in hex or rgb(a) format.
*
- * In [styled mode](http://www.highcharts.com/docs/chart-design-and-
- * style/style-by-css), the hover brightening is by default replaced
+ * In styled mode, the hover brightening is by default replaced
* with a fill-opacity set in the `.highcharts-point:hover` rule.
*
* @type {Number}
- * @sample {highcharts} highcharts/plotoptions/column-states-hover-brightness/ Brighten by 0.5
+ * @sample {highcharts} highcharts/plotoptions/column-states-hover-brightness/
+ * Brighten by 0.5
* @default 0.1
* @product highcharts highstock
*/
brightness: 0.1,
- /**
- */
shadow: false
},
- /**
- */
select: {
-
- /**
- */
color: '#cccccc',
-
- /**
- */
borderColor: '#000000',
-
- /**
- */
shadow: false
}
},
- /**
- */
dataLabels: {
-
- /**
- */
align: null, // auto
-
- /**
- */
verticalAlign: null, // auto
-
- /**
- */
y: null
},
/**
* When this is true, the series will not cause the Y axis to cross
@@ -27241,24 +28440,17 @@
* @since 4.1.9
* @product highcharts highstock
*/
softThreshold: false,
- /**
- */
- startFromThreshold: true, // false doesn't work well: http://jsfiddle.net/highcharts/hz8fopan/14/
+ // false doesn't work well: http://jsfiddle.net/highcharts/hz8fopan/14/
+ /** @ignore */
+ startFromThreshold: true,
- /**
- */
stickyTracking: false,
- /**
- */
tooltip: {
-
- /**
- */
distance: 6
},
/**
* The Y axis value to serve as the base for the columns, for distinguishing
@@ -27274,29 +28466,32 @@
/**
* The color of the border surrounding each column or bar.
*
- * In [styled mode](http://www.highcharts.com/docs/chart-design-and-
- * style/style-by-css), the border stroke can be set with the `.highcharts-
- * point` rule.
+ * In styled mode, the border stroke can be set with the `.highcharts-point`
+ * rule.
*
* @type {Color}
- * @sample {highcharts} highcharts/plotoptions/column-bordercolor/ Dark gray border
+ * @sample {highcharts} highcharts/plotoptions/column-bordercolor/
+ * Dark gray border
* @default #ffffff
* @product highcharts highstock
*/
borderColor: '#ffffff'
// borderWidth: 1
}, /** @lends seriesTypes.column.prototype */ {
cropShoulder: 0,
- directTouch: true, // When tooltip is not shared, this series (and derivatives) requires direct touch/hover. KD-tree does not apply.
+ // When tooltip is not shared, this series (and derivatives) requires direct
+ // touch/hover. KD-tree does not apply.
+ directTouch: true,
trackerGroups: ['group', 'dataLabelsGroup'],
- negStacks: true, // use separate negative stacks, unlike area stacks where a negative
- // point is substracted from previous (#1910)
+ // use separate negative stacks, unlike area stacks where a negative point
+ // is substracted from previous (#1910)
+ negStacks: true,
/**
* Initialize the series. Extends the basic Series.init method by
* marking other series of the same type as dirty.
*
@@ -27320,12 +28515,12 @@
});
}
},
/**
- * Return the width and x offset of the columns adjusted for grouping, groupPadding, pointPadding,
- * pointWidth etc.
+ * Return the width and x offset of the columns adjusted for grouping,
+ * groupPadding, pointPadding, pointWidth etc.
*/
getColumnMetrics: function() {
var series = this,
options = series.options,
@@ -27334,13 +28529,13 @@
reversedXAxis = xAxis.reversed,
stackKey,
stackGroups = {},
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
+ // 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,
@@ -27368,25 +28563,39 @@
}
});
}
var categoryWidth = Math.min(
- Math.abs(xAxis.transA) * (xAxis.ordinalSlope || options.pointRange || xAxis.closestPointRange || xAxis.tickInterval || 1), // #2610
+ Math.abs(xAxis.transA) * (
+ xAxis.ordinalSlope ||
+ options.pointRange ||
+ xAxis.closestPointRange ||
+ xAxis.tickInterval ||
+ 1
+ ), // #2610
xAxis.len // #1535
),
groupPadding = categoryWidth * options.groupPadding,
groupWidth = categoryWidth - 2 * groupPadding,
pointOffsetWidth = groupWidth / (columnCount || 1),
pointWidth = Math.min(
options.maxPointWidth || xAxis.len,
- pick(options.pointWidth, pointOffsetWidth * (1 - 2 * options.pointPadding))
+ pick(
+ options.pointWidth,
+ pointOffsetWidth * (1 - 2 * options.pointPadding)
+ )
),
pointPadding = (pointOffsetWidth - pointWidth) / 2,
- colIndex = (series.columnIndex || 0) + (reversedXAxis ? 1 : 0), // #1251, #3737
- pointXOffset = pointPadding + (groupPadding + colIndex *
- pointOffsetWidth - (categoryWidth / 2)) *
- (reversedXAxis ? -1 : 1);
+ // #1251, #3737
+ colIndex = (series.columnIndex || 0) + (reversedXAxis ? 1 : 0),
+ pointXOffset =
+ pointPadding +
+ (
+ groupPadding +
+ colIndex * pointOffsetWidth -
+ (categoryWidth / 2)
+ ) * (reversedXAxis ? -1 : 1);
// Save it for reading in linked series (Error bars particularly)
series.columnMetrics = {
width: pointWidth,
offset: pointXOffset
@@ -27409,12 +28618,12 @@
if (chart.inverted && chart.renderer.isVML) {
yCrisp += 1;
}
- // Horizontal. We need to first compute the exact right edge, then round it
- // and compute the width from there.
+ // Horizontal. We need to first compute the exact right edge, then round
+ // it and compute the width from there.
if (this.options.crisp) {
right = Math.round(x + w) + xCrisp;
x = Math.round(x) + xCrisp;
w = right - x;
}
@@ -27438,79 +28647,100 @@
height: h
};
},
/**
- * Translate each point to the plot area coordinate system and find shape positions
+ * Translate each point to the plot area coordinate system and find shape
+ * positions
*/
translate: function() {
var series = this,
chart = series.chart,
options = series.options,
- dense = series.dense = series.closestPointRange * series.xAxis.transA < 2,
+ dense = series.dense =
+ series.closestPointRange * series.xAxis.transA < 2,
borderWidth = series.borderWidth = pick(
options.borderWidth,
dense ? 0 : 1 // #3635
),
yAxis = series.yAxis,
threshold = options.threshold,
- translatedThreshold = series.translatedThreshold = yAxis.getThreshold(threshold),
+ translatedThreshold = series.translatedThreshold =
+ yAxis.getThreshold(threshold),
minPointLength = pick(options.minPointLength, 5),
metrics = series.getColumnMetrics(),
pointWidth = metrics.width,
- seriesBarW = series.barW = Math.max(pointWidth, 1 + 2 * borderWidth), // postprocessed for border width
+ // postprocessed for border width
+ seriesBarW = series.barW =
+ Math.max(pointWidth, 1 + 2 * borderWidth),
pointXOffset = series.pointXOffset = metrics.offset;
if (chart.inverted) {
translatedThreshold -= 0.5; // #3355
}
- // When the pointPadding is 0, we want the columns to be packed tightly, so we allow individual
- // columns to have individual sizes. When pointPadding is greater, we strive for equal-width
- // columns (#2694).
+ // When the pointPadding is 0, we want the columns to be packed tightly,
+ // so we allow individual columns to have individual sizes. When
+ // pointPadding is greater, we strive for equal-width columns (#2694).
if (options.pointPadding) {
seriesBarW = Math.ceil(seriesBarW);
}
Series.prototype.translate.apply(series);
// Record the new values
each(series.points, function(point) {
var yBottom = pick(point.yBottom, translatedThreshold),
safeDistance = 999 + Math.abs(yBottom),
- plotY = Math.min(Math.max(-safeDistance, point.plotY), yAxis.len + safeDistance), // Don't draw too far outside plot area (#1303, #2241, #4264)
+ plotY = Math.min(
+ Math.max(-safeDistance, point.plotY),
+ yAxis.len + safeDistance
+ ), // Don't draw too far outside plot area (#1303, #2241, #4264)
barX = point.plotX + pointXOffset,
barW = seriesBarW,
barY = Math.min(plotY, yBottom),
up,
barH = Math.max(plotY, yBottom) - barY;
// Handle options.minPointLength
- if (Math.abs(barH) < minPointLength) {
- if (minPointLength) {
- barH = minPointLength;
- up = (!yAxis.reversed && !point.negative) || (yAxis.reversed && point.negative);
- barY = Math.abs(barY - translatedThreshold) > minPointLength ? // stacked
- yBottom - minPointLength : // keep position
- translatedThreshold - (up ? minPointLength : 0); // #1485, #4051
+ if (minPointLength && Math.abs(barH) < minPointLength) {
+ barH = minPointLength;
+ up = (!yAxis.reversed && !point.negative) ||
+ (yAxis.reversed && point.negative);
+
+ // Reverse zeros if there's no positive value in the series
+ // in visible range (#7046)
+ if (point.y === 0 && series.dataMax <= 0) {
+ up = !up;
}
+
+ // If stacked...
+ barY = Math.abs(barY - translatedThreshold) > minPointLength ?
+ // ...keep position
+ yBottom - minPointLength :
+ // #1485, #4051
+ translatedThreshold - (up ? minPointLength : 0);
}
// Cache for access in polar
point.barX = barX;
point.pointWidth = pointWidth;
// Fix the tooltip on center of grouped columns (#1216, #424, #3648)
- point.tooltipPos = chart.inverted ? [yAxis.len + yAxis.pos - chart.plotLeft - plotY, series.xAxis.len - barX - barW / 2, barH] : [barX + barW / 2, plotY + yAxis.pos - chart.plotTop, barH];
+ point.tooltipPos = chart.inverted ? [
+ yAxis.len + yAxis.pos - chart.plotLeft - plotY,
+ series.xAxis.len - barX - barW / 2, barH
+ ] : [barX + barW / 2, plotY + yAxis.pos - chart.plotTop, barH];
// Register shape type and arguments to be used in drawPoints
point.shapeType = 'rect';
point.shapeArgs = series.crispCol.apply(
series,
point.isNull ?
- // #3169, drilldown from null must have a position to work from
- // #6585, dataLabel should be placed on xAxis, not floating in the middle of the chart
+ // #3169, drilldown from null must have a position to work
+ // from #6585, dataLabel should be placed on xAxis, not
+ // floating in the middle of the chart
[barX, translatedThreshold, barW, 0] : [barX, barY, barW, barH]
);
});
},
@@ -27525,11 +28755,13 @@
/**
* Columns have no graph
*/
drawGraph: function() {
- this.group[this.dense ? 'addClass' : 'removeClass']('highcharts-dense-data');
+ this.group[
+ this.dense ? 'addClass' : 'removeClass'
+ ]('highcharts-dense-data');
},
/**
* Get presentational attributes
@@ -27540,33 +28772,39 @@
ret,
p2o = this.pointAttrToOptions || {},
strokeOption = p2o.stroke || 'borderColor',
strokeWidthOption = p2o['stroke-width'] || 'borderWidth',
fill = (point && point.color) || this.color,
- stroke = point[strokeOption] || options[strokeOption] ||
+ stroke = (point && point[strokeOption]) || options[strokeOption] ||
this.color || fill, // set to fill when borderColor null
- strokeWidth = point[strokeWidthOption] ||
+ strokeWidth = (point && point[strokeWidthOption]) ||
options[strokeWidthOption] || this[strokeWidthOption] || 0,
dashstyle = options.dashStyle,
zone,
brightness;
// Handle zone colors
if (point && this.zones.length) {
zone = point.getZone();
- fill = point.options.color || (zone && zone.color) || this.color; // When zones are present, don't use point.color (#4267). Changed order (#6527)
+ // When zones are present, don't use point.color (#4267). Changed
+ // order (#6527)
+ fill = point.options.color || (zone && zone.color) || this.color;
}
// Select or hover states
if (state) {
stateOptions = merge(
options.states[state],
- point.options.states && point.options.states[state] || {} // #6401
+ // #6401
+ point.options.states && point.options.states[state] || {}
);
brightness = stateOptions.brightness;
fill = stateOptions.color ||
- (brightness !== undefined && color(fill).brighten(stateOptions.brightness).get()) ||
+ (
+ brightness !== undefined &&
+ color(fill).brighten(stateOptions.brightness).get()
+ ) ||
fill;
stroke = stateOptions[strokeOption] || stroke;
strokeWidth = stateOptions[strokeWidthOption] || strokeWidth;
dashstyle = stateOptions.dashStyle || dashstyle;
}
@@ -27584,13 +28822,13 @@
return ret;
},
/**
- * Draw the columns. For bars, the series.group is rotated, so the same coordinates
- * apply for columns and bars. This method is inherited by scatter series.
- *
+ * Draw the columns. For bars, the series.group is rotated, so the same
+ * coordinates apply for columns and bars. This method is inherited by
+ * scatter series.
*/
drawPoints: function() {
var series = this,
chart = this.chart,
options = series.options,
@@ -27605,16 +28843,19 @@
if (isNumber(plotY) && point.y !== null) {
shapeArgs = point.shapeArgs;
if (graphic) { // update
- graphic[chart.pointCount < animationLimit ? 'animate' : 'attr'](
+ graphic[
+ chart.pointCount < animationLimit ? 'animate' : 'attr'
+ ](
merge(shapeArgs)
);
} else {
- point.graphic = graphic = renderer[point.shapeType](shapeArgs)
+ point.graphic = graphic =
+ renderer[point.shapeType](shapeArgs)
.add(point.group || series.group);
}
// Border radius is not stylable (#6900)
if (options.borderRadius) {
@@ -27624,12 +28865,19 @@
}
// Presentational
graphic
- .attr(series.pointAttribs(point, point.selected && 'select'))
- .shadow(options.shadow, null, options.stacking && !options.borderRadius);
+ .attr(series.pointAttribs(
+ point,
+ point.selected && 'select'
+ ))
+ .shadow(
+ options.shadow,
+ null,
+ options.stacking && !options.borderRadius
+ );
graphic.addClass(point.getClassName(), true);
@@ -27652,29 +28900,35 @@
translatedThreshold;
if (svg) { // VML is too slow anyway
if (init) {
attr.scaleY = 0.001;
- translatedThreshold = Math.min(yAxis.pos + yAxis.len, Math.max(yAxis.pos, yAxis.toPixels(options.threshold)));
+ translatedThreshold = Math.min(
+ yAxis.pos + yAxis.len,
+ Math.max(yAxis.pos, yAxis.toPixels(options.threshold))
+ );
if (inverted) {
attr.translateX = translatedThreshold - yAxis.len;
} else {
attr.translateY = translatedThreshold;
}
series.group.attr(attr);
} else { // run the animation
attr[inverted ? 'translateX' : 'translateY'] = yAxis.pos;
- series.group.animate(attr, extend(animObject(series.options.animation), {
- // Do the scale synchronously to ensure smooth updating (#5030)
- step: function(val, fx) {
- series.group.attr({
- scaleY: Math.max(0.001, fx.pos) // #5250
- });
- }
- }));
+ series.group.animate(
+ attr,
+ extend(animObject(series.options.animation), {
+ // Do the scale synchronously to ensure smooth updating
+ // (#5030)
+ step: function(val, fx) {
+ series.group.attr({
+ scaleY: Math.max(0.001, fx.pos) // #5250
+ });
+ }
+ }));
// delete this function to allow it only once
series.animate = null;
}
}
@@ -27699,10 +28953,89 @@
Series.prototype.remove.apply(series, arguments);
}
});
+
+ /**
+ * A `column` series. If the [type](#series.column.type) option is
+ * not specified, it is inherited from [chart.type](#chart.type).
+ *
+ * For options that apply to multiple series, it is recommended to add
+ * them to the [plotOptions.series](#plotOptions.series) options structure.
+ * To apply to all series of this specific type, apply it to [plotOptions.
+ * column](#plotOptions.column).
+ *
+ * @type {Object}
+ * @extends series,plotOptions.column
+ * @excluding dataParser,dataURL
+ * @product highcharts highstock
+ * @apioption series.column
+ */
+
+ /**
+ * An array of data points for the series. For the `column` series type,
+ * points can be given in the following ways:
+ *
+ * 1. An array of numerical values. In this case, the numerical values
+ * will be interpreted as `y` options. The `x` values will be automatically
+ * calculated, either starting at 0 and incremented by 1, or from `pointStart`
+ * and `pointInterval` given in the series options. If the axis has
+ * categories, these will be used. Example:
+ *
+ * ```js
+ * data: [0, 5, 3, 5]
+ * ```
+ *
+ * 2. An array of arrays with 2 values. In this case, the values correspond
+ * to `x,y`. If the first value is a string, it is applied as the name
+ * of the point, and the `x` value is inferred.
+ *
+ * ```js
+ * data: [
+ * [0, 6],
+ * [1, 2],
+ * [2, 6]
+ * ]
+ * ```
+ *
+ * 3. An array of objects with named values. The objects are point
+ * configuration objects as seen below. If the total number of data
+ * points exceeds the series' [turboThreshold](#series.column.turboThreshold),
+ * this option is not available.
+ *
+ * ```js
+ * data: [{
+ * x: 1,
+ * y: 9,
+ * name: "Point2",
+ * color: "#00FF00"
+ * }, {
+ * x: 1,
+ * y: 6,
+ * name: "Point1",
+ * color: "#FF00FF"
+ * }]
+ * ```
+ *
+ * @type {Array<Object|Array|Number>}
+ * @extends series.line.data
+ * @excluding marker
+ * @sample {highcharts} highcharts/chart/reflow-true/ Numerical values
+ * @sample {highcharts} highcharts/series/data-array-of-arrays/
+ * Arrays of numeric x and y
+ * @sample {highcharts} highcharts/series/data-array-of-arrays-datetime/
+ * Arrays of datetime x and y
+ * @sample {highcharts} highcharts/series/data-array-of-name-value/
+ * Arrays of point.name and y
+ * @sample {highcharts} highcharts/series/data-array-of-objects/
+ * Config objects
+ * @product highcharts highstock
+ * @apioption series.column.data
+ */
+
+
}(Highcharts));
(function(H) {
/**
* (c) 2010-2017 Torstein Honsi
*
@@ -27713,63 +29046,173 @@
/**
* The Bar series class
*/
seriesType('bar', 'column', null, {
- /**
- */
inverted: true
});
/**
+ * A bar series is a special type of column series where the columns are
+ * horizontal.
+ *
+ * @sample highcharts/demo/bar-basic/ Bar chart
* @extends {plotOptions.column}
+ * @product highcharts
* @optionparent plotOptions.bar
*/
+
+ /**
+ * A `bar` series. If the [type](#series.bar.type) option is not specified,
+ * it is inherited from [chart.type](#chart.type).
+ *
+ * For options that apply to multiple series, it is recommended to add
+ * them to the [plotOptions.series](#plotOptions.series) options structure.
+ * To apply to all series of this specific type, apply it to [plotOptions.
+ * bar](#plotOptions.bar).
+ *
+ * @type {Object}
+ * @extends series,plotOptions.bar
+ * @excluding dataParser,dataURL
+ * @product highcharts
+ * @apioption series.bar
+ */
+
+ /**
+ * An array of data points for the series. For the `bar` series type,
+ * points can be given in the following ways:
+ *
+ * 1. An array of numerical values. In this case, the numerical values
+ * will be interpreted as `y` options. The `x` values will be automatically
+ * calculated, either starting at 0 and incremented by 1, or from `pointStart`
+ * and `pointInterval` given in the series options. If the axis has
+ * categories, these will be used. Example:
+ *
+ * ```js
+ * data: [0, 5, 3, 5]
+ * ```
+ *
+ * 2. An array of arrays with 2 values. In this case, the values correspond
+ * to `x,y`. If the first value is a string, it is applied as the name
+ * of the point, and the `x` value is inferred.
+ *
+ * ```js
+ * data: [
+ * [0, 5],
+ * [1, 10],
+ * [2, 3]
+ * ]
+ * ```
+ *
+ * 3. An array of objects with named values. The objects are point
+ * configuration objects as seen below. If the total number of data
+ * points exceeds the series' [turboThreshold](#series.bar.turboThreshold),
+ * this option is not available.
+ *
+ * ```js
+ * data: [{
+ * x: 1,
+ * y: 1,
+ * name: "Point2",
+ * color: "#00FF00"
+ * }, {
+ * x: 1,
+ * y: 10,
+ * name: "Point1",
+ * color: "#FF00FF"
+ * }]
+ * ```
+ *
+ * @type {Array<Object|Array|Number>}
+ * @extends series.column.data
+ * @sample {highcharts} highcharts/chart/reflow-true/ Numerical values
+ * @sample {highcharts} highcharts/series/data-array-of-arrays/ Arrays of numeric x and y
+ * @sample {highcharts} highcharts/series/data-array-of-arrays-datetime/ Arrays of datetime x and y
+ * @sample {highcharts} highcharts/series/data-array-of-name-value/ Arrays of point.name and y
+ * @sample {highcharts} highcharts/series/data-array-of-objects/ Config objects
+ * @product highcharts
+ * @apioption series.bar.data
+ */
+
+ /**
+ * Alignment of the data label relative to the data point.
+ *
+ * @type {String}
+ * @sample {highcharts} highcharts/plotoptions/bar-datalabels-align-inside-bar/
+ * Data labels inside the bar
+ * @default left
+ * @product highcharts
+ * @apioption plotOptions.bar.dataLabels.align
+ */
+
+ /**
+ * The x position of the data label relative to the data point.
+ *
+ * @type {Number}
+ * @sample {highcharts} highcharts/plotoptions/bar-datalabels-align-inside-bar/
+ * Data labels inside the bar
+ * @default 5
+ * @product highcharts
+ * @apioption plotOptions.bar.dataLabels.x
+ */
+
}(Highcharts));
(function(H) {
/**
* (c) 2010-2017 Torstein Honsi
*
* License: www.highcharts.com/license
*/
var Series = H.Series,
seriesType = H.seriesType;
- /**
- * The scatter series type
- */
/**
+ * A scatter plot uses cartesian coordinates to display values for two variables
+ * for a set of data.
+ *
+ * @sample {highcharts} highcharts/demo/scatter/ Scatter plot
+ *
* @extends {plotOptions.line}
+ * @product highcharts highstock
* @optionparent plotOptions.scatter
*/
seriesType('scatter', 'line', {
/**
* The width of the line connecting the data points.
*
* @type {Number}
- * @sample {highcharts} highcharts/plotoptions/scatter-linewidth-none/ 0 by default
- * @sample {highcharts} highcharts/plotoptions/scatter-linewidth-1/ 1px
+ * @sample {highcharts} highcharts/plotoptions/scatter-linewidth-none/
+ * 0 by default
+ * @sample {highcharts} highcharts/plotoptions/scatter-linewidth-1/
+ * 1px
* @default 0
* @product highcharts highstock
*/
lineWidth: 0,
- /**
- */
findNearestPointBy: 'xy',
-
- /**
- */
marker: {
-
- /**
- */
enabled: true // Overrides auto-enabling in line series (#3647)
},
/**
+ * Sticky tracking of mouse events. When true, the `mouseOut` event
+ * on a series isn't triggered until the mouse moves over another series,
+ * or out of the plot area. When false, the `mouseOut` event on a series
+ * is triggered when the mouse leaves the area around the series' graph
+ * or markers. This also implies the tooltip. When `stickyTracking`
+ * is false and `tooltip.shared` is false, the tooltip will be hidden
+ * when moving the mouse between series.
+ *
+ * @type {Boolean}
+ * @default false
+ * @product highcharts highstock
+ * @apioption plotOptions.scatter.stickyTracking
+ */
+
+ /**
* A configuration object for the tooltip rendering of each single
* series. Properties are inherited from <a class="internal">#tooltip</a>.
* Overridable properties are `headerFormat`, `pointFormat`, `yDecimals`,
* `xDateFormat`, `yPrefix` and `ySuffix`. Unlike other series, in
* a scatter plot the series.name by default shows in the headerFormat
@@ -27781,12 +29224,10 @@
headerFormat: '<span style="color:{point.color}">\u25CF</span> ' +
'<span style="font-size: 0.85em"> {series.name}</span><br/>',
- /**
- */
pointFormat: 'x: <b>{point.x}</b><br/>y: <b>{point.y}</b><br/>'
}
// Prototype members
}, {
@@ -27800,20 +29241,99 @@
Series.prototype.drawGraph.call(this);
}
}
});
+ /**
+ * A `scatter` series. If the [type](#series.scatter.type) option is
+ * not specified, it is inherited from [chart.type](#chart.type).
+ *
+ * For options that apply to multiple series, it is recommended to add
+ * them to the [plotOptions.series](#plotOptions.series) options structure.
+ * To apply to all series of this specific type, apply it to [plotOptions.
+ * scatter](#plotOptions.scatter).
+ *
+ * @type {Object}
+ * @extends series,plotOptions.scatter
+ * @excluding dataParser,dataURL,stack
+ * @product highcharts highstock
+ * @apioption series.scatter
+ */
+
+ /**
+ * An array of data points for the series. For the `scatter` series
+ * type, points can be given in the following ways:
+ *
+ * 1. An array of numerical values. In this case, the numerical values
+ * will be interpreted as `y` options. The `x` values will be automatically
+ * calculated, either starting at 0 and incremented by 1, or from `pointStart`
+ * and `pointInterval` given in the series options. If the axis has
+ * categories, these will be used. Example:
+ *
+ * ```js
+ * data: [0, 5, 3, 5]
+ * ```
+ *
+ * 2. An array of arrays with 2 values. In this case, the values correspond
+ * to `x,y`. If the first value is a string, it is applied as the name
+ * of the point, and the `x` value is inferred.
+ *
+ * ```js
+ * data: [
+ * [0, 0],
+ * [1, 8],
+ * [2, 9]
+ * ]
+ * ```
+ *
+ * 3. An array of objects with named values. The objects are point
+ * configuration objects as seen below. If the total number of data
+ * points exceeds the series' [turboThreshold](#series.scatter.turboThreshold),
+ * this option is not available.
+ *
+ * ```js
+ * data: [{
+ * x: 1,
+ * y: 2,
+ * name: "Point2",
+ * color: "#00FF00"
+ * }, {
+ * x: 1,
+ * y: 4,
+ * name: "Point1",
+ * color: "#FF00FF"
+ * }]
+ * ```
+ *
+ * @type {Array<Object|Array|Number>}
+ * @extends series.line.data
+ * @sample {highcharts} highcharts/chart/reflow-true/
+ * Numerical values
+ * @sample {highcharts} highcharts/series/data-array-of-arrays/
+ * Arrays of numeric x and y
+ * @sample {highcharts} highcharts/series/data-array-of-arrays-datetime/
+ * Arrays of datetime x and y
+ * @sample {highcharts} highcharts/series/data-array-of-name-value/
+ * Arrays of point.name and y
+ * @sample {highcharts} highcharts/series/data-array-of-objects/
+ * Config objects
+ * @product highcharts highstock
+ * @apioption series.scatter.data
+ */
+
+
}(Highcharts));
(function(H) {
/**
* (c) 2010-2017 Torstein Honsi
*
* License: www.highcharts.com/license
*/
- var pick = H.pick,
+ var deg2rad = H.deg2rad,
+ isNumber = H.isNumber,
+ pick = H.pick,
relativeLength = H.relativeLength;
-
H.CenteredSeriesMixin = {
/**
* Get the center of the pie based on the size and center options relative to the
* plot area. Borrowed by the polar and gauge series types.
*/
@@ -27846,10 +29366,37 @@
// innerSize cannot be larger than size (#3632)
if (positions[3] > positions[2]) {
positions[3] = positions[2];
}
return positions;
+ },
+ /**
+ * getStartAndEndRadians - Calculates start and end angles in radians.
+ * Used in series types such as pie and sunburst.
+ *
+ * @param {Number} start Start angle in degrees.
+ * @param {Number} end Start angle in degrees.
+ * @return {object} Returns an object containing start and end angles as
+ * radians.
+ */
+ getStartAndEndRadians: function getStartAndEndRadians(start, end) {
+ var startAngle = isNumber(start) ? start : 0, // must be a number
+ endAngle = (
+ (
+ isNumber(end) && // must be a number
+ end > startAngle && // must be larger than the start angle
+ // difference must be less than 360 degrees
+ (end - startAngle) < 360
+ ) ?
+ end :
+ startAngle + 360
+ ),
+ correction = -90;
+ return {
+ start: deg2rad * (startAngle + correction),
+ end: deg2rad * (endAngle + correction)
+ };
}
};
}(Highcharts));
(function(H) {
@@ -27861,10 +29408,11 @@
var addEvent = H.addEvent,
CenteredSeriesMixin = H.CenteredSeriesMixin,
defined = H.defined,
each = H.each,
extend = H.extend,
+ getStartAndEndRadians = CenteredSeriesMixin.getStartAndEndRadians,
inArray = H.inArray,
LegendSymbolMixin = H.LegendSymbolMixin,
noop = H.noop,
pick = H.pick,
Point = H.Point,
@@ -27879,11 +29427,22 @@
* @constructor seriesTypes.pie
* @augments Series
*/
/**
+ * A pie chart is a circular graphic which is divided into slices to illustrate
+ * numerical proportion.
+ *
+ * @sample highcharts/demo/pie-basic/ Pie chart
+ *
* @extends {plotOptions.line}
+ * @excluding animationLimit,boostThreshold,connectEnds,connectNulls,
+ * cropThreshold,dashStyle,findNearestPointBy,getExtremesFromAll,
+ * lineWidth,marker,negativeColor,pointInterval,pointIntervalUnit,
+ * pointPlacement,pointStart,softThreshold,stacking,step,threshold,
+ * turboThreshold,zoneAxis,zones
+ * @product highcharts
* @optionparent plotOptions.pie
*/
seriesType('pie', 'line', {
/**
@@ -27899,30 +29458,76 @@
* @default [null, null]
* @product highcharts
*/
center: [null, null],
- /**
- */
clip: false,
+ /** @ignore */
+ colorByPoint: true, // always true for pies
+
/**
+ * A series specific or series type specific color set to use instead
+ * of the global [colors](#colors).
+ *
+ * @type {Array<Color>}
+ * @sample {highcharts} highcharts/demo/pie-monochrome/ Set default colors for all pies
+ * @since 3.0
+ * @product highcharts
+ * @apioption plotOptions.pie.colors
*/
- colorByPoint: true, // always true for pies
/**
* @extends plotOptions.series.dataLabels
* @excluding align,allowOverlap,staggerLines,step
* @product highcharts
*/
dataLabels: {
- // align: null,
- // connectorWidth: 1,
- // connectorColor: point.color,
- // connectorPadding: 5,
+ /**
+ * The color of the line connecting the data label to the pie slice.
+ * The default color is the same as the point's color.
+ *
+ * In styled mode, the connector stroke is given in the
+ * `.highcharts-data-label-connector` class.
+ *
+ * @type {String}
+ * @sample {highcharts} highcharts/plotoptions/pie-datalabels-connectorcolor/ Blue connectors
+ * @sample {highcharts} highcharts/css/pie-point/ Styled connectors
+ * @default {point.color}
+ * @since 2.1
+ * @product highcharts
+ * @apioption plotOptions.pie.dataLabels.connectorColor
+ */
/**
+ * The distance from the data label to the connector.
+ *
+ * @type {Number}
+ * @sample {highcharts} highcharts/plotoptions/pie-datalabels-connectorpadding/ No padding
+ * @default 5
+ * @since 2.1
+ * @product highcharts
+ * @apioption plotOptions.pie.dataLabels.connectorPadding
+ */
+
+ /**
+ * The width of the line connecting the data label to the pie slice.
+ *
+ *
+ * In styled mode, the connector stroke width is given in the
+ * `.highcharts-data-label-connector` class.
+ *
+ * @type {Number}
+ * @sample {highcharts} highcharts/plotoptions/pie-datalabels-connectorwidth-disabled/ Disable the connector
+ * @sample {highcharts} highcharts/css/pie-point/ Styled connectors
+ * @default 1
+ * @since 2.1
+ * @product highcharts
+ * @apioption plotOptions.pie.dataLabels.connectorWidth
+ */
+
+ /**
* The distance of the data label from the pie's edge. Negative numbers
* put the data label on top of the pie slices. Connectors are only
* shown for data labels outside the pie.
*
* @type {Number}
@@ -27940,24 +29545,43 @@
* @since 2.1
* @product highcharts
*/
enabled: true,
- /**
- */
formatter: function() { // #2945
return this.point.isNull ? undefined : this.point.name;
},
- // softConnector: true,
/**
+ * Whether to render the connector as a soft arc or a line with sharp
+ * break.
+ *
+ * @type {Boolean}
+ * @sample {highcharts} highcharts/plotoptions/pie-datalabels-softconnector-true/ Soft
+ * @sample {highcharts} highcharts/plotoptions/pie-datalabels-softconnector-false/ Non soft
+ * @since 2.1.7
+ * @product highcharts
+ * @apioption plotOptions.pie.dataLabels.softConnector
*/
+
x: 0
// y: 0
},
/**
+ * The end angle of the pie in degrees where 0 is top and 90 is right.
+ * Defaults to `startAngle` plus 360.
+ *
+ * @type {Number}
+ * @sample {highcharts} highcharts/demo/pie-semi-circle/ Semi-circle donut
+ * @default null
+ * @since 1.3.6
+ * @product highcharts
+ * @apioption plotOptions.pie.endAngle
+ */
+
+ /**
* Equivalent to [chart.ignoreHiddenSeries](#chart.ignoreHiddenSeries),
* this option tells whether the series shall be redrawn as if the
* hidden point were `null`.
*
* The default value changed from `false` to `true` with Highcharts
@@ -27968,19 +29592,47 @@
* @default true
* @since 2.3.0
* @product highcharts
*/
ignoreHiddenPoint: true,
- //innerSize: 0,
/**
+ * The size of the inner diameter for the pie. A size greater than 0
+ * renders a donut chart. Can be a percentage or pixel value. Percentages
+ * are relative to the pie size. Pixel values are given as integers.
+ *
+ *
+ * Note: in Highcharts < 4.1.2, the percentage was relative to the plot
+ * area, not the pie size.
+ *
+ * @type {String|Number}
+ * @sample {highcharts} highcharts/plotoptions/pie-innersize-80px/ 80px inner size
+ * @sample {highcharts} highcharts/plotoptions/pie-innersize-50percent/ 50% of the plot area
+ * @sample {highcharts} highcharts/demo/3d-pie-donut/ 3D donut
+ * @default 0
+ * @since 2.0
+ * @product highcharts
+ * @apioption plotOptions.pie.innerSize
*/
+
+ /** @ignore */
legendType: 'point',
+ /** @ignore */
+ marker: null, // point options are specified in the base options
+
/**
+ * The minimum size for a pie in response to auto margins. The pie will
+ * try to shrink to make room for data labels in side the plot area,
+ * but only to this size.
+ *
+ * @type {Number}
+ * @default 80
+ * @since 3.0
+ * @product highcharts
+ * @apioption plotOptions.pie.minSize
*/
- marker: null, // point options are specified in the base options
/**
* The diameter of the pie relative to the plot area. Can be a percentage
* or pixel value. Pixel values are given as integers. The default
* behaviour (as of 3.0) is to scale to the plot area and give room
@@ -28016,43 +29668,46 @@
* @product highcharts
*/
slicedOffset: 10,
/**
+ * The start angle of the pie slices in degrees where 0 is top and 90
+ * right.
+ *
+ * @type {Number}
+ * @sample {highcharts} highcharts/plotoptions/pie-startangle-90/ Start from right
+ * @default 0
+ * @since 2.3.4
+ * @product highcharts
+ * @apioption plotOptions.pie.startAngle
+ */
+
+ /**
* Sticky tracking of mouse events. When true, the `mouseOut` event
* on a series isn't triggered until the mouse moves over another series,
* or out of the plot area. When false, the `mouseOut` event on a
* series is triggered when the mouse leaves the area around the series'
* graph or markers. This also implies the tooltip. When `stickyTracking`
* is false and `tooltip.shared` is false, the tooltip will be hidden
* when moving the mouse between series.
*
- * @type {Boolean}
- * @default false
* @product highcharts
*/
stickyTracking: false,
- /**
- */
tooltip: {
-
- /**
- */
followPointer: true
},
/**
* The color of the border surrounding each slice. When `null`, the
* border takes the same color as the slice fill. This can be used
* together with a `borderWidth` to fill drawing gaps created by antialiazing
* artefacts in borderless pies.
*
- * In [styled mode](http://www.highcharts.com/docs/chart-design-and-
- * style/style-by-css), the border stroke is given in the `.highcharts-
- * point` class.
+ * In styled mode, the border stroke is given in the `.highcharts-point` class.
*
* @type {Color}
* @sample {highcharts} highcharts/plotoptions/pie-bordercolor-black/ Black border
* @default #ffffff
* @product highcharts
@@ -28065,23 +29720,19 @@
* When setting the border width to 0, there may be small gaps between
* the slices due to SVG antialiasing artefacts. To work around this,
* keep the border width at 0.5 or 1, but set the `borderColor` to
* `null` instead.
*
- * In [styled mode](http://www.highcharts.com/docs/chart-design-and-
- * style/style-by-css), the border stroke width is given in the `.highcharts-
- * point` class.
+ * In styled mode, the border stroke width is given in the `.highcharts-point` class.
*
* @type {Number}
* @sample {highcharts} highcharts/plotoptions/pie-borderwidth/ 3px border
* @default 1
* @product highcharts
*/
borderWidth: 1,
- /**
- */
states: {
/**
* @extends plotOptions.series.states.hover
* @product highcharts
@@ -28090,23 +29741,20 @@
/**
* How much to brighten the point on interaction. Requires the main
* color to be defined in hex or rgb(a) format.
*
- * In [styled mode](http://www.highcharts.com/docs/chart-design-and-
- * style/style-by-css), the hover brightness is by default replaced
+ * In styled mode, the hover brightness is by default replaced
* by a fill-opacity given in the `.highcharts-point-hover` class.
*
* @type {Number}
* @sample {highcharts} highcharts/plotoptions/pie-states-hover-brightness/ Brightened by 0.5
* @default 0.1
* @product highcharts
*/
brightness: 0.1,
- /**
- */
shadow: false
}
}
@@ -28203,14 +29851,14 @@
connectorOffset = slicedOffset + (options.borderWidth || 0),
finalConnectorOffset,
start,
end,
angle,
- startAngle = options.startAngle || 0,
- startAngleRad = series.startAngleRad = Math.PI / 180 * (startAngle - 90),
- endAngleRad = series.endAngleRad = Math.PI / 180 * ((pick(options.endAngle, startAngle + 360)) - 90),
- circ = endAngleRad - startAngleRad, //2 * Math.PI,
+ radians = getStartAndEndRadians(options.startAngle, options.endAngle),
+ startAngleRad = series.startAngleRad = radians.start,
+ endAngleRad = series.endAngleRad = radians.end,
+ circ = endAngleRad - startAngleRad, // 2 * Math.PI,
points = series.points,
radiusX, // the x component of the radius vector for a given point
radiusY,
labelDistance = options.dataLabels.distance,
ignoreHiddenPoint = options.ignoreHiddenPoint,
@@ -28320,13 +29968,11 @@
drawPoints: function() {
var series = this,
chart = series.chart,
renderer = chart.renderer,
groupTranslation,
- //center,
graphic,
- //group,
pointAttr,
shapeArgs;
var shadow = series.options.shadow;
@@ -28336,12 +29982,12 @@
}
// draw the slices
each(series.points, function(point) {
+ graphic = point.graphic;
if (!point.isNull) {
- graphic = point.graphic;
shapeArgs = point.shapeArgs;
// If the point is sliced, use special translation, else use
// plot area traslation
@@ -28392,10 +30038,12 @@
}
graphic.addClass(point.getClassName());
+ } else if (graphic) {
+ point.graphic = graphic.destroy();
}
});
},
@@ -28558,10 +30206,123 @@
}
);
}
});
+ /**
+ * A `pie` series. If the [type](#series.pie.type) option is not specified,
+ * it is inherited from [chart.type](#chart.type).
+ *
+ * For options that apply to multiple series, it is recommended to add
+ * them to the [plotOptions.series](#plotOptions.series) options structure.
+ * To apply to all series of this specific type, apply it to [plotOptions.
+ * pie](#plotOptions.pie).
+ *
+ * @type {Object}
+ * @extends series,plotOptions.pie
+ * @excluding dataParser,dataURL,stack,xAxis,yAxis
+ * @product highcharts
+ * @apioption series.pie
+ */
+
+ /**
+ * An array of data points for the series. For the `pie` series type,
+ * points can be given in the following ways:
+ *
+ * 1. An array of numerical values. In this case, the numerical values
+ * will be interpreted as `y` options. Example:
+ *
+ * ```js
+ * data: [0, 5, 3, 5]
+ * ```
+ *
+ * 2. An array of objects with named values. The objects are point
+ * configuration objects as seen below. If the total number of data
+ * points exceeds the series' [turboThreshold](#series.pie.turboThreshold),
+ * this option is not available.
+ *
+ * ```js
+ * data: [{
+ * y: 1,
+ * name: "Point2",
+ * color: "#00FF00"
+ * }, {
+ * y: 7,
+ * name: "Point1",
+ * color: "#FF00FF"
+ * }]</pre>
+ *
+ * @type {Array<Object|Number>}
+ * @extends series.line.data
+ * @excluding marker,x
+ * @sample {highcharts} highcharts/chart/reflow-true/ Numerical values
+ * @sample {highcharts} highcharts/series/data-array-of-arrays/ Arrays of numeric x and y
+ * @sample {highcharts} highcharts/series/data-array-of-arrays-datetime/ Arrays of datetime x and y
+ * @sample {highcharts} highcharts/series/data-array-of-name-value/ Arrays of point.name and y
+ * @sample {highcharts} highcharts/series/data-array-of-objects/ Config objects
+ * @product highcharts
+ * @apioption series.pie.data
+ */
+
+ /**
+ * The sequential index of the data point in the legend.
+ *
+ * @type {Number}
+ * @product highcharts
+ * @apioption series.pie.data.legendIndex
+ */
+
+ /**
+ * Whether to display a slice offset from the center.
+ *
+ * @type {Boolean}
+ * @sample {highcharts} highcharts/point/sliced/ One sliced point
+ * @product highcharts
+ * @apioption series.pie.data.sliced
+ */
+
+ /**
+ * Fires when the checkbox next to the point name in the legend is clicked.
+ * One parameter, event, is passed to the function. The state of the
+ * checkbox is found by event.checked. The checked item is found by
+ * event.item. Return false to prevent the default action which is to
+ * toggle the select state of the series.
+ *
+ * @type {Function}
+ * @context Point
+ * @sample {highcharts} highcharts/plotoptions/series-events-checkboxclick/
+ * Alert checkbox status
+ * @since 1.2.0
+ * @product highcharts
+ * @apioption plotOptions.pie.events.checkboxClick
+ */
+
+ /**
+ * Not applicable to pies, as the legend item is per point. See point.
+ * events.
+ *
+ * @type {Function}
+ * @since 1.2.0
+ * @product highcharts
+ * @apioption plotOptions.pie.events.legendItemClick
+ */
+
+ /**
+ * Fires when the legend item belonging to the pie point (slice) is
+ * clicked. The `this` keyword refers to the point itself. One parameter,
+ * `event`, is passed to the function, containing common event information. The
+ * default action is to toggle the visibility of the point. This can be
+ * prevented by calling `event.preventDefault()`.
+ *
+ * @type {Function}
+ * @sample {highcharts} highcharts/plotoptions/pie-point-events-legenditemclick/
+ * Confirm toggle visibility
+ * @since 1.2.0
+ * @product highcharts
+ * @apioption plotOptions.pie.point.events.legendItemClick
+ */
+
}(Highcharts));
(function(H) {
/**
* (c) 2010-2017 Torstein Honsi
*
@@ -28580,16 +30341,17 @@
relativeLength = H.relativeLength,
Series = H.Series,
seriesTypes = H.seriesTypes,
stableSort = H.stableSort;
-
+ /* eslint max-len: ["warn", 80, 4] */
/**
- * Generatl distribution algorithm for distributing labels of differing size along a
- * confined length in two dimensions. The algorithm takes an array of objects containing
- * a size, a target and a rank. It will place the labels as close as possible to their
- * targets, skipping the lowest ranked labels if necessary.
+ * Generatl distribution algorithm for distributing labels of differing size
+ * along a confined length in two dimensions. The algorithm takes an array of
+ * objects containing a size, a target and a rank. It will place the labels as
+ * close as possible to their targets, skipping the lowest ranked labels if
+ * necessary.
*/
H.distribute = function(boxes, len) {
var i,
overlapping = true,
@@ -28601,11 +30363,12 @@
function sortByTarget(a, b) {
return a.target - b.target;
}
- // If the total size exceeds the len, remove those boxes with the lowest rank
+ // If the total size exceeds the len, remove those boxes with the lowest
+ // rank
i = boxes.length;
while (i--) {
total += boxes[i].size;
}
@@ -28640,21 +30403,29 @@
// Initial positions: target centered in box
i = boxes.length;
while (i--) {
box = boxes[i];
// Composite box, average of targets
- target = (Math.min.apply(0, box.targets) + Math.max.apply(0, box.targets)) / 2;
- box.pos = Math.min(Math.max(0, target - box.size / 2), len - box.size);
+ target = (Math.min.apply(0, box.targets) +
+ Math.max.apply(0, box.targets)) / 2;
+ box.pos = Math.min(
+ Math.max(0, target - box.size / 2),
+ len - box.size
+ );
}
// Detect overlap and join boxes
i = boxes.length;
overlapping = false;
while (i--) {
- if (i > 0 && boxes[i - 1].pos + boxes[i - 1].size > boxes[i].pos) { // Overlap
- boxes[i - 1].size += boxes[i].size; // Add this size to the previous box
- boxes[i - 1].targets = boxes[i - 1].targets.concat(boxes[i].targets);
+ // Overlap
+ if (i > 0 && boxes[i - 1].pos + boxes[i - 1].size > boxes[i].pos) {
+ // Add this size to the previous box
+ boxes[i - 1].size += boxes[i].size;
+ boxes[i - 1].targets = boxes[i - 1]
+ .targets
+ .concat(boxes[i].targets);
// Overlapping right, push left
if (boxes[i - 1].pos + boxes[i - 1].size > len) {
boxes[i - 1].pos = len - boxes[i - 1].size;
}
@@ -28662,11 +30433,12 @@
overlapping = true;
}
}
}
- // Now the composite boxes are placed, we need to put the original boxes within them
+ // Now the composite boxes are placed, we need to put the original boxes
+ // within them
i = 0;
each(boxes, function(box) {
var posInCompositeBox = 0;
each(box.targets, function() {
origBoxes[i].pos = box.pos + posInCompositeBox;
@@ -28719,11 +30491,13 @@
if (!hasRendered) {
addEvent(series, 'afterAnimate', function() {
if (series.visible) { // #2597, #3023, #3024
dataLabelsGroup.show(true);
}
- dataLabelsGroup[seriesOptions.animation ? 'animate' : 'attr']({
+ dataLabelsGroup[
+ seriesOptions.animation ? 'animate' : 'attr'
+ ]({
opacity: 1
}, {
duration: 200
});
});
@@ -28738,42 +30512,61 @@
labelConfig,
attr,
rotation,
connector = point.connector,
isNew = !dataLabel,
- style;
+ style,
+ formatString;
+
// Determine if each data label is enabled
// @note dataLabelAttribs (like pointAttribs) would eradicate
// the need for dlOptions, and simplify the section below.
- pointOptions = point.dlOptions || (point.options && point.options.dataLabels); // dlOptions is used in treemaps
- enabled = pick(pointOptions && pointOptions.enabled, generalOptions.enabled) && point.y !== null; // #2282, #4641
+ pointOptions = point.dlOptions || // dlOptions is used in treemaps
+ (point.options && point.options.dataLabels);
+ enabled = pick(
+ pointOptions && pointOptions.enabled,
+ generalOptions.enabled
+ ) && !point.isNull; // #2282, #4641, #7112
+
if (enabled) {
- // Create individual options structure that can be extended without
- // affecting others
+ // Create individual options structure that can be extended
+ // without affecting others
options = merge(generalOptions, pointOptions);
labelConfig = point.getLabelConfig();
- str = options.format ?
- format(options.format, labelConfig) :
+ formatString = (
+ options[point.formatPrefix + 'Format'] ||
+ options.format
+ );
+ str = defined(formatString) ?
+ format(formatString, labelConfig) :
options.formatter.call(labelConfig, options);
style = options.style;
rotation = options.rotation;
// Determine the color
- style.color = pick(options.color, style.color, series.color, '#000000');
+ style.color = pick(
+ options.color,
+ style.color,
+ series.color,
+ '#000000'
+ );
// Get automated contrast color
if (style.color === 'contrast') {
- point.contrastColor = renderer.getContrast(point.color || series.color);
- style.color = options.inside || pick(point.labelDistance, options.distance) < 0 ||
- !!seriesOptions.stacking ? point.contrastColor : '#000000';
+ point.contrastColor =
+ renderer.getContrast(point.color || series.color);
+ style.color = options.inside ||
+ pick(point.labelDistance, options.distance) < 0 ||
+ !!seriesOptions.stacking ?
+ point.contrastColor :
+ '#000000';
}
if (seriesOptions.cursor) {
style.cursor = seriesOptions.cursor;
}
attr = {
- //align: align,
fill: options.backgroundColor,
stroke: options.borderColor,
'stroke-width': options.borderWidth,
@@ -28799,11 +30592,13 @@
// Individual labels are disabled if the are explicitly disabled
// in the point options, or if they fall outside the plot area.
} else if (enabled && defined(str)) {
// create new label
if (!dataLabel) {
- dataLabel = point.dataLabel = renderer[rotation ? 'text' : 'label']( // labels don't support rotation
+ dataLabel = point.dataLabel = renderer[
+ rotation ? 'text' : 'label' // labels don't rotate
+ ](
str,
0, -9999,
options.shape,
null,
null,
@@ -28819,28 +30614,36 @@
} else {
attr.text = str;
}
dataLabel.attr(attr);
- // Styles must be applied before add in order to read text bounding box
+ // Styles must be applied before add in order to read text
+ // bounding box
dataLabel.css(style).shadow(options.shadow);
if (!dataLabel.added) {
dataLabel.add(dataLabelsGroup);
}
- // Now the data label is created and placed at 0,0, so we need to align it
+ // Now the data label is created and placed at 0,0, so we need
+ // to align it
series.alignDataLabel(point, dataLabel, options, null, isNew);
}
});
}
};
/**
* Align each individual data label
*/
- Series.prototype.alignDataLabel = function(point, dataLabel, options, alignTo, isNew) {
+ Series.prototype.alignDataLabel = function(
+ point,
+ dataLabel,
+ options,
+ alignTo,
+ isNew
+ ) {
var chart = this.chart,
inverted = chart.inverted,
plotX = pick(point.plotX, -9999),
plotY = pick(point.plotY, -9999),
bBox = dataLabel.getBBox(),
@@ -28849,20 +30652,23 @@
rotation = options.rotation,
normRotation,
negRotation,
align = options.align,
rotCorr, // rotation correction
- // Math.round for rounding errors (#2683), alignTo to allow column labels (#2700)
+ // Math.round for rounding errors (#2683), alignTo to allow column
+ // labels (#2700)
visible =
this.visible &&
(
point.series.forceDL ||
chart.isInsidePlot(plotX, Math.round(plotY), inverted) ||
(
alignTo && chart.isInsidePlot(
plotX,
- inverted ? alignTo.x + 1 : alignTo.y + alignTo.height - 1,
+ inverted ?
+ alignTo.x + 1 :
+ alignTo.y + alignTo.height - 1,
inverted
)
)
),
alignAttr, // the final position;
@@ -28888,21 +30694,26 @@
extend(options, {
width: bBox.width,
height: bBox.height
});
- // Allow a hook for changing alignment in the last moment, then do the alignment
+ // Allow a hook for changing alignment in the last moment, then do the
+ // alignment
if (rotation) {
justify = false; // Not supported for rotated text
rotCorr = chart.renderer.rotCorr(baseline, rotation); // #3723
alignAttr = {
x: alignTo.x + options.x + alignTo.width / 2 + rotCorr.x,
- y: alignTo.y + options.y + {
- top: 0,
- middle: 0.5,
- bottom: 1
- }[options.verticalAlign] * alignTo.height
+ y: (
+ alignTo.y +
+ options.y + {
+ top: 0,
+ middle: 0.5,
+ bottom: 1
+ }[options.verticalAlign] *
+ alignTo.height
+ )
};
dataLabel[isNew ? 'attr' : 'animate'](alignAttr)
.attr({ // #3003
align: align
});
@@ -28938,14 +30749,23 @@
isNew
);
// Now check that the data label is within the plot area
} else if (pick(options.crop, true)) {
- visible = chart.isInsidePlot(alignAttr.x, alignAttr.y) && chart.isInsidePlot(alignAttr.x + bBox.width, alignAttr.y + bBox.height);
+ visible =
+ chart.isInsidePlot(
+ alignAttr.x,
+ alignAttr.y
+ ) &&
+ chart.isInsidePlot(
+ alignAttr.x + bBox.width,
+ alignAttr.y + bBox.height
+ );
}
- // When we're using a shape, make it possible with a connector or an arrow pointing to thie point
+ // When we're using a shape, make it possible with a connector or an
+ // arrow pointing to thie point
if (options.shape && !rotation) {
dataLabel[isNew ? 'attr' : 'animate']({
anchorX: inverted ? chart.plotWidth - point.plotY : point.plotX,
anchorY: inverted ? chart.plotHeight - point.plotX : point.plotY
});
@@ -28961,14 +30781,21 @@
}
};
/**
- * If data labels fall partly outside the plot area, align them back in, in a way that
- * doesn't hide the point.
+ * If data labels fall partly outside the plot area, align them back in, in a
+ * way that doesn't hide the point.
*/
- Series.prototype.justifyDataLabel = function(dataLabel, options, alignAttr, bBox, alignTo, isNew) {
+ Series.prototype.justifyDataLabel = function(
+ dataLabel,
+ options,
+ alignAttr,
+ bBox,
+ alignTo,
+ isNew
+ ) {
var chart = this.chart,
align = options.align,
verticalAlign = options.verticalAlign,
off,
justified,
@@ -29046,11 +30873,12 @@
centerY = seriesCenter[1],
dataLabel,
dataLabelWidth,
labelPos,
labelHeight,
- halves = [ // divide the points into right and left halves for anti collision
+ // divide the points into right and left halves for anti collision
+ halves = [
[], // right
[] // left
],
x,
y,
@@ -29158,50 +30986,60 @@
positionsIndex = point.positionsIndex;
labelPos = point.labelPos;
dataLabel = point.dataLabel;
visibility = point.visible === false ? 'hidden' : 'inherit';
naturalY = labelPos[1];
+ y = naturalY;
if (positions && defined(positions[positionsIndex])) {
if (positions[positionsIndex].pos === undefined) {
visibility = 'hidden';
} else {
labelHeight = positions[positionsIndex].size;
y = point.top + positions[positionsIndex].pos;
}
-
- } else {
- y = naturalY;
}
// It is needed to delete point.positionIndex for
// dynamically added points etc.
delete point.positionIndex;
// get the x - use the natural x position for labels near the
- // top and bottom, to prevent the top and botton slice connectors
- // from touching each other on either side
+ // top and bottom, to prevent the top and botton slice
+ // connectors from touching each other on either side
if (options.justify) {
- x = seriesCenter[0] + (i ? -1 : 1) * (radius + point.labelDistance);
+ x = seriesCenter[0] +
+ (i ? -1 : 1) * (radius + point.labelDistance);
} else {
- x = series.getX(y < point.top + 2 || y > point.bottom - 2 ? naturalY : y, i, point);
+ x = series.getX(
+ y < point.top + 2 || y > point.bottom - 2 ?
+ naturalY :
+ y,
+ i,
+ point
+ );
}
// Record the placement and visibility
dataLabel._attr = {
visibility: visibility,
align: labelPos[6]
};
dataLabel._pos = {
- x: x + options.x +
+ x: (
+ x +
+ options.x +
({
left: connectorPadding,
right: -connectorPadding
- }[labelPos[6]] || 0),
- y: y + options.y - 10 // 10 is for the baseline (label vs text)
+ }[labelPos[6]] || 0)
+ ),
+
+ // 10 is for the baseline (label vs text)
+ y: y + options.y - 10
};
labelPos.x = x;
labelPos.y = y;
@@ -29245,13 +31083,16 @@
dataLabel.sideOverflow = sideOverflow;
}
} // for each point
}); // for each half
- // Do not apply the final placement and draw the connectors until we have verified
- // that labels are not spilling over.
- if (arrayMax(overflow) === 0 || this.verifyDataLabelOverflow(overflow)) {
+ // Do not apply the final placement and draw the connectors until we
+ // have verified that labels are not spilling over.
+ if (
+ arrayMax(overflow) === 0 ||
+ this.verifyDataLabelOverflow(overflow)
+ ) {
// Place the labels in the final position
this.placeDataLabels();
// Draw the connectors
@@ -29272,17 +31113,22 @@
isNew = !connector;
if (isNew) {
point.connector = connector = chart.renderer.path()
- .addClass('highcharts-data-label-connector highcharts-color-' + point.colorIndex)
+ .addClass('highcharts-data-label-connector ' +
+ ' highcharts-color-' + point.colorIndex)
.add(series.dataLabelsGroup);
connector.attr({
'stroke-width': connectorWidth,
- 'stroke': options.connectorColor || point.color || '#666666'
+ 'stroke': (
+ options.connectorColor ||
+ point.color ||
+ '#666666'
+ )
});
}
connector[isNew ? 'attr' : 'animate']({
d: series.connectorPath(point.labelPos)
@@ -29296,38 +31142,40 @@
}
}
};
/**
- * Extendable method for getting the path of the connector between the data label
- * and the pie slice.
+ * Extendable method for getting the path of the connector between the data
+ * label and the pie slice.
*/
seriesTypes.pie.prototype.connectorPath = function(labelPos) {
var x = labelPos.x,
y = labelPos.y;
return pick(this.options.dataLabels.softConnector, true) ? [
'M',
- x + (labelPos[6] === 'left' ? 5 : -5), y, // end of the string at the label
+ // end of the string at the label
+ x + (labelPos[6] === 'left' ? 5 : -5), y,
'C',
x, y, // first break, next to the label
2 * labelPos[2] - labelPos[4], 2 * labelPos[3] - labelPos[5],
labelPos[2], labelPos[3], // second break
'L',
labelPos[4], labelPos[5] // base
] : [
'M',
- x + (labelPos[6] === 'left' ? 5 : -5), y, // end of the string at the label
+ // end of the string at the label
+ x + (labelPos[6] === 'left' ? 5 : -5), y,
'L',
labelPos[2], labelPos[3], // second break
'L',
labelPos[4], labelPos[5] // base
];
};
/**
- * Perform the final placement of the data labels after we have verified that they
- * fall within the plot area.
+ * Perform the final placement of the data labels after we have verified
+ * that they fall within the plot area.
*/
seriesTypes.pie.prototype.placeDataLabels = function() {
each(this.points, function(point) {
var dataLabel = point.dataLabel,
_pos;
@@ -29360,13 +31208,13 @@
};
seriesTypes.pie.prototype.alignDataLabel = noop;
/**
- * Verify whether the data labels are allowed to draw, or we should run more translation and data
- * label positioning to keep them inside the plot area. Returns true when data labels are ready
- * to draw.
+ * Verify whether the data labels are allowed to draw, or we should run more
+ * translation and data label positioning to keep them inside the plot area.
+ * Returns true when data labels are ready to draw.
*/
seriesTypes.pie.prototype.verifyDataLabelOverflow = function(overflow) {
var center = this.center,
options = this.options,
@@ -29435,18 +31283,30 @@
}
if (seriesTypes.column) {
/**
- * Override the basic data label alignment by adjusting for the position of the column
+ * Override the basic data label alignment by adjusting for the position of
+ * the column
*/
- seriesTypes.column.prototype.alignDataLabel = function(point, dataLabel, options, alignTo, isNew) {
+ seriesTypes.column.prototype.alignDataLabel = function(
+ point,
+ dataLabel,
+ options,
+ alignTo,
+ isNew
+ ) {
var inverted = this.chart.inverted,
series = point.series,
- dlBox = point.dlBox || point.shapeArgs, // data label box for alignment
- below = pick(point.below, point.plotY > pick(this.translatedThreshold, series.yAxis.len)), // point.below is used in range series
- inside = pick(options.inside, !!this.options.stacking), // draw it inside the box?
+ // data label box for alignment
+ dlBox = point.dlBox || point.shapeArgs,
+ below = pick(
+ point.below, // range series
+ point.plotY > pick(this.translatedThreshold, series.yAxis.len)
+ ),
+ // draw it inside the box?
+ inside = pick(options.inside, !!this.options.stacking),
overshoot;
// Align to the column itself, or the top of it
if (dlBox) { // Area range uses this method but not alignTo
alignTo = merge(dlBox);
@@ -29480,22 +31340,29 @@
}
}
}
- // When alignment is undefined (typically columns and bars), display the individual
- // point below or above the point depending on the threshold
+ // When alignment is undefined (typically columns and bars), display the
+ // individual point below or above the point depending on the threshold
options.align = pick(
options.align, !inverted || inside ? 'center' : below ? 'right' : 'left'
);
options.verticalAlign = pick(
options.verticalAlign,
inverted || inside ? 'middle' : below ? 'top' : 'bottom'
);
// Call the parent method
- Series.prototype.alignDataLabel.call(this, point, dataLabel, options, alignTo, isNew);
+ Series.prototype.alignDataLabel.call(
+ this,
+ point,
+ dataLabel,
+ options,
+ alignTo,
+ isNew
+ );
// If label was justified and we have contrast, set it:
if (point.isLabelJustified && point.contrastColor) {
point.dataLabel.css({
color: point.contrastColor
@@ -29526,10 +31393,15 @@
// inside the columns.
Chart.prototype.callbacks.push(function(chart) {
function collectAndHide() {
var labels = [];
+ // Consider external label collectors
+ each(chart.labelCollectors || [], function(collector) {
+ labels = labels.concat(collector());
+ });
+
each(chart.yAxis || [], function(yAxis) {
if (
yAxis.options.stackLabels &&
!yAxis.options.stackLabels.allowOverlap
) {
@@ -29565,16 +31437,13 @@
}
});
chart.hideOverlappingLabels(labels);
}
- // Do it now ...
- collectAndHide();
+ // Do it on render and after each chart redraw
+ addEvent(chart, 'render', collectAndHide);
- // ... and after each chart redraw
- addEvent(chart, 'redraw', collectAndHide);
-
});
/**
* Hide overlapping labels. Labels are moved and faded in and out on zoom to
* provide a smooth visual imression.
@@ -29839,17 +31708,10 @@
trackerPath.splice(i, 0, 'L', trackerPath[i - 2] + snap, trackerPath[i - 1]);
}
}
}
- // handle single points
- /*for (i = 0; i < singlePoints.length; i++) {
- singlePoint = singlePoints[i];
- trackerPath.push(M, singlePoint.plotX - snap, singlePoint.plotY,
- L, singlePoint.plotX + snap, singlePoint.plotY);
- }*/
-
// draw the tracker
if (tracker) {
tracker.attr({
d: trackerPath
});
@@ -30369,19 +32231,11 @@
}
if (state) {
point.graphic.addClass('highcharts-point-' + state);
}
- /*attribs = radius ? { // new symbol attributes (#507, #612)
- x: plotX - radius,
- y: plotY - radius,
- width: 2 * radius,
- height: 2 * radius
- } : {};*/
-
- //attribs = merge(series.pointAttribs(point, state), attribs);
point.graphic.animate(
series.pointAttribs(point, state),
pick(
chart.options.chart.animation,
stateOptions.animation
@@ -30776,9 +32630,111 @@
inArray = H.inArray,
isArray = H.isArray,
isObject = H.isObject,
pick = H.pick,
splat = H.splat;
+
+
+ /**
+ * Allows setting a set of rules to apply for different screen or chart
+ * sizes. Each rule specifies additional chart options.
+ *
+ * @sample {highstock} stock/demo/responsive/ Stock chart
+ * @sample highcharts/responsive/axis/ Axis
+ * @sample highcharts/responsive/legend/ Legend
+ * @sample highcharts/responsive/classname/ Class name
+ * @since 5.0.0
+ * @apioption responsive
+ */
+
+ /**
+ * A set of rules for responsive settings. The rules are executed from
+ * the top down.
+ *
+ * @type {Array<Object>}
+ * @sample {highcharts} highcharts/responsive/axis/ Axis changes
+ * @sample {highstock} highcharts/responsive/axis/ Axis changes
+ * @sample {highmaps} highcharts/responsive/axis/ Axis changes
+ * @since 5.0.0
+ * @apioption responsive.rules
+ */
+
+ /**
+ * A full set of chart options to apply as overrides to the general
+ * chart options. The chart options are applied when the given rule
+ * is active.
+ *
+ * A special case is configuration objects that take arrays, for example
+ * [xAxis](#xAxis), [yAxis](#yAxis) or [series](#series). For these
+ * collections, an `id` option is used to map the new option set to
+ * an existing object. If an existing object of the same id is not found,
+ * the item of the same indexupdated. So for example, setting `chartOptions`
+ * with two series items without an `id`, will cause the existing chart's
+ * two series to be updated with respective options.
+ *
+ * @type {Object}
+ * @sample {highstock} stock/demo/responsive/ Stock chart
+ * @sample highcharts/responsive/axis/ Axis
+ * @sample highcharts/responsive/legend/ Legend
+ * @sample highcharts/responsive/classname/ Class name
+ * @since 5.0.0
+ * @apioption responsive.rules.chartOptions
+ */
+
+ /**
+ * Under which conditions the rule applies.
+ *
+ * @type {Object}
+ * @since 5.0.0
+ * @apioption responsive.rules.condition
+ */
+
+ /**
+ * A callback function to gain complete control on when the responsive
+ * rule applies. Return `true` if it applies. This opens for checking
+ * against other metrics than the chart size, or example the document
+ * size or other elements.
+ *
+ * @type {Function}
+ * @context Chart
+ * @since 5.0.0
+ * @apioption responsive.rules.condition.callback
+ */
+
+ /**
+ * The responsive rule applies if the chart height is less than this.
+ *
+ * @type {Number}
+ * @since 5.0.0
+ * @apioption responsive.rules.condition.maxHeight
+ */
+
+ /**
+ * The responsive rule applies if the chart width is less than this.
+ *
+ * @type {Number}
+ * @sample highcharts/responsive/axis/ Max width is 500
+ * @since 5.0.0
+ * @apioption responsive.rules.condition.maxWidth
+ */
+
+ /**
+ * The responsive rule applies if the chart height is greater than this.
+ *
+ * @type {Number}
+ * @default 0
+ * @since 5.0.0
+ * @apioption responsive.rules.condition.minHeight
+ */
+
+ /**
+ * The responsive rule applies if the chart width is greater than this.
+ *
+ * @type {Number}
+ * @default 0
+ * @since 5.0.0
+ * @apioption responsive.rules.condition.minWidth
+ */
/**
* Update the chart based on the current chart/document size and options for
* responsiveness.
*/