highcharts-rails 5.0.6 → 5.0.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.markdown +54 -0
- data/app/assets/javascripts/highcharts.js +542 -324
- data/app/assets/javascripts/highcharts/highcharts-3d.js +12 -2
- data/app/assets/javascripts/highcharts/highcharts-more.js +41 -47
- data/app/assets/javascripts/highcharts/modules/accessibility.js +20 -4
- data/app/assets/javascripts/highcharts/modules/annotations.js +1 -1
- data/app/assets/javascripts/highcharts/modules/boost.js +9 -3
- data/app/assets/javascripts/highcharts/modules/broken-axis.js +11 -13
- data/app/assets/javascripts/highcharts/modules/data.js +1 -1
- data/app/assets/javascripts/highcharts/modules/drilldown.js +28 -13
- data/app/assets/javascripts/highcharts/modules/exporting.js +1 -1
- data/app/assets/javascripts/highcharts/modules/funnel.js +1 -1
- data/app/assets/javascripts/highcharts/modules/grid-axis.js +1 -1
- data/app/assets/javascripts/highcharts/modules/heatmap.js +12 -7
- data/app/assets/javascripts/highcharts/modules/no-data-to-display.js +1 -1
- data/app/assets/javascripts/highcharts/modules/offline-exporting.js +71 -18
- data/app/assets/javascripts/highcharts/modules/overlapping-datalabels.js +1 -1
- data/app/assets/javascripts/highcharts/modules/series-label.js +1 -1
- data/app/assets/javascripts/highcharts/modules/solid-gauge.js +1 -1
- data/app/assets/javascripts/highcharts/modules/stock.js +6360 -0
- data/app/assets/javascripts/highcharts/modules/treemap.js +88 -90
- data/app/assets/javascripts/highcharts/modules/xrange-series.js +5 -1
- data/lib/highcharts/version.rb +1 -1
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 607c053da0b9fc8e51b7392df545aa6e5d297a34
|
4
|
+
data.tar.gz: 2e1f5f66fe81be42f4a96afdf21ca8ad5bc12697
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: abfc4475e26229dca060b337a77bf1564bfb55c66ed2d13ce8e2d156ec81811977117f3fe623a5c4bf147552a7653426c96e4e607be266ba8413e60e0af62e6c
|
7
|
+
data.tar.gz: a8be44f809d4987373a16f6a2383667f066ab4c9c82b6862922e5da10ba7955ca5c1e2a3bdc6482b32c7e9cf176e970dd5b6908810ff75b5e37977b283512885
|
data/CHANGELOG.markdown
CHANGED
@@ -1,3 +1,57 @@
|
|
1
|
+
# 5.0.7 / 2017-01-25
|
2
|
+
|
3
|
+
* Updated Highcharts to 5.0.7 (2017-01-17)
|
4
|
+
* Added Legend keyboard navigation to accessibility module.
|
5
|
+
* Added chart render and predraw events needed by the new Boost module.
|
6
|
+
* Added new option, global.timezone, as a convenient shortcut to timezones defined with moment.js.
|
7
|
+
* Added optional redraw to drillToNode, related to #6180.
|
8
|
+
* Added support for marker.symbol setting on bubble charts.
|
9
|
+
* Changed the Highcharts.addEvent function to return a callback to be used to remove the same event.
|
10
|
+
* Changed the Highcharts.error function to handle strings.
|
11
|
+
* Bug fixes
|
12
|
+
* Fixed compliance with Checkmarx security checker.
|
13
|
+
* Fixed #6108, issue with big data in offline exporting.
|
14
|
+
* Fixed #5672, X values in tooltip in Boost module was wrong.
|
15
|
+
* Fixed #5553, disabled trackByArea did not hide tooltip, when moving mouse out of the area shape.
|
16
|
+
* Fixed #5757, empty chart throws error with accessibility module.
|
17
|
+
* Fixed #5766, halo was not rendered for shared tooltip when density of points was high.
|
18
|
+
* Fixed #5818, render halo in a series group, not under all of the groups.
|
19
|
+
* Fixed #5819, crosshair width can now be set on category axes also.
|
20
|
+
* Fixed #5833, split tooltip tried to remove series tooltip again after destruction.
|
21
|
+
* Fixed #5835, exported SVG didn't validate, width and height attributes were set on group elements.
|
22
|
+
* Fixed #5837, could not style null points with CSS.
|
23
|
+
* Fixed #5855, split tooltip was not destroyed properly.
|
24
|
+
* Fixed #5862, wrong hover point, when tooltip was shared.
|
25
|
+
* Fixed #5866, treemap point.isNull was always true.
|
26
|
+
* Fixed #5868, dataLabels.softConnector was always set to true.
|
27
|
+
* Fixed #5873, bubbles were hidden in small charts when maxSize was percentage.
|
28
|
+
* Fixed #5884, optimizing addSeries.
|
29
|
+
* Fixed #6085, floating point errors on Y axis labels.
|
30
|
+
* Fixed #6088, rounding issue in tooltips.
|
31
|
+
* Fixed #6107, error with negative width in xrange study.
|
32
|
+
* Fixed #6112, issue and regression with swapping series indexes.
|
33
|
+
* Fixed #6113, long legend items were unresponsive due to heavy HTML parsing in SVG. Implemented caching.
|
34
|
+
* Fixed #6127, pie chart data label overlapped after drill up.
|
35
|
+
* Fixed #6128, tooltip caret was not drawn after updating from shared to non-shared.
|
36
|
+
* Fixed #6130, Chart.update didn't trigger responsive rules to be re-evaluated.
|
37
|
+
* Fixed #6138, reset colorCounter and symbolCounter when all series are removed.
|
38
|
+
* Fixed #6147, error in Chart.get when called between redraws.
|
39
|
+
* Fixed #6157, offline exporting was not working for Edge.
|
40
|
+
* Fixed #6158, duplicate ID of navigator series.
|
41
|
+
* Fixed #6171, drawDataLabels did not use updated options when data label already existed.
|
42
|
+
* Fixed #6173, no inline CSS should be allowed in styled mode.
|
43
|
+
* Fixed #6180, treemap crashed when the root node did not exist.
|
44
|
+
* Fixed #6184, polar arearange was misshaped when connectEnds was not set.
|
45
|
+
* Fixed #6196, dead clip path references.
|
46
|
+
* Fixed #6200, modified treemap setPointValues to only add crisping correction when needed.
|
47
|
+
* Fixed #6202, legend icons overflowed legend with large radius.
|
48
|
+
* Fixed #6207, when point X was given, point names did not show on category axis after hiding and showing series.
|
49
|
+
* Fixed #6208, error on responsive rules for plotOptions.series and series.xAxis.
|
50
|
+
* Fixed #6213, wrong text bounding box reported in Chrome for Windows, resulting in asymmetric label padding.
|
51
|
+
* Fixed #6217, container sizes below 20px height needed explicit chart height to be set.
|
52
|
+
* Fixed issue in offline exporting where libURL option was not picked up.
|
53
|
+
* Fixed issue with duplicate highcharts-negative class. Ref #6114.
|
54
|
+
|
1
55
|
# 5.0.6 / 2017-01-25
|
2
56
|
|
3
57
|
* Updated Highcharts to 5.0.6 (2016-12-07)
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/**
|
2
|
-
* @license Highcharts JS v5.0.
|
2
|
+
* @license Highcharts JS v5.0.7 (2017-01-17)
|
3
3
|
*
|
4
4
|
* (c) 2009-2016 Torstein Honsi
|
5
5
|
*
|
@@ -36,7 +36,7 @@
|
|
36
36
|
|
37
37
|
var Highcharts = win.Highcharts ? win.Highcharts.error(16, true) : {
|
38
38
|
product: 'Highcharts',
|
39
|
-
version: '5.0.
|
39
|
+
version: '5.0.7',
|
40
40
|
deg2rad: Math.PI * 2 / 360,
|
41
41
|
doc: doc,
|
42
42
|
hasBidiBug: hasBidiBug,
|
@@ -1165,8 +1165,11 @@
|
|
1165
1165
|
}
|
1166
1166
|
}
|
1167
1167
|
|
1168
|
-
//
|
1169
|
-
|
1168
|
+
// Multiply back to the correct magnitude. Correct floats to appropriate
|
1169
|
+
// precision (#6085).
|
1170
|
+
retInterval = H.correctFloat(
|
1171
|
+
retInterval * magnitude, -Math.round(Math.log(0.001) / Math.LN10)
|
1172
|
+
);
|
1170
1173
|
|
1171
1174
|
return retInterval;
|
1172
1175
|
};
|
@@ -1370,7 +1373,8 @@
|
|
1370
1373
|
* @function #numberFormat
|
1371
1374
|
* @memberOf Highcharts
|
1372
1375
|
* @param {Number} number - The input number to format.
|
1373
|
-
* @param {Number} decimals - The amount of decimals.
|
1376
|
+
* @param {Number} decimals - The amount of decimals. A value of -1 preserves
|
1377
|
+
* the amount in the input number.
|
1374
1378
|
* @param {String} [decimalPoint] - The decimal point, defaults to the one given
|
1375
1379
|
* in the lang options.
|
1376
1380
|
* @param {String} [thousandsSep] - The thousands separator, defaults to the one
|
@@ -1378,17 +1382,15 @@
|
|
1378
1382
|
* @returns {String} The formatted number.
|
1379
1383
|
*/
|
1380
1384
|
H.numberFormat = function(number, decimals, decimalPoint, thousandsSep) {
|
1381
|
-
|
1382
1385
|
number = +number || 0;
|
1383
1386
|
decimals = +decimals;
|
1384
1387
|
|
1385
1388
|
var lang = H.defaultOptions.lang,
|
1386
1389
|
origDec = (number.toString().split('.')[1] || '').length,
|
1387
|
-
decimalComponent,
|
1388
1390
|
strinteger,
|
1389
1391
|
thousands,
|
1390
|
-
|
1391
|
-
|
1392
|
+
ret,
|
1393
|
+
roundedNumber;
|
1392
1394
|
|
1393
1395
|
if (decimals === -1) {
|
1394
1396
|
// Preserve decimals. Not huge numbers (#3793).
|
@@ -1397,8 +1399,14 @@
|
|
1397
1399
|
decimals = 2;
|
1398
1400
|
}
|
1399
1401
|
|
1402
|
+
// Add another decimal to avoid rounding errors of float numbers. (#4573)
|
1403
|
+
// Then use toFixed to handle rounding.
|
1404
|
+
roundedNumber = (
|
1405
|
+
Math.abs(number) + Math.pow(10, -Math.max(decimals, origDec) - 1)
|
1406
|
+
).toFixed(decimals);
|
1407
|
+
|
1400
1408
|
// A string containing the positive integer component of the number
|
1401
|
-
strinteger = String(H.pInt(
|
1409
|
+
strinteger = String(H.pInt(roundedNumber));
|
1402
1410
|
|
1403
1411
|
// Leftover after grouping into thousands. Can be 0, 1 or 3.
|
1404
1412
|
thousands = strinteger.length > 3 ? strinteger.length % 3 : 0;
|
@@ -1421,11 +1429,8 @@
|
|
1421
1429
|
|
1422
1430
|
// Add the decimal point and the decimal component
|
1423
1431
|
if (decimals) {
|
1424
|
-
// Get the decimal component
|
1425
|
-
|
1426
|
-
decimalComponent = Math.abs(absNumber - strinteger +
|
1427
|
-
Math.pow(10, -Math.max(decimals, origDec) - 1));
|
1428
|
-
ret += decimalPoint + decimalComponent.toFixed(decimals).slice(2);
|
1432
|
+
// Get the decimal component
|
1433
|
+
ret += decimalPoint + roundedNumber.slice(-decimals);
|
1429
1434
|
}
|
1430
1435
|
|
1431
1436
|
return ret;
|
@@ -2280,6 +2285,7 @@
|
|
2280
2285
|
erase = H.erase,
|
2281
2286
|
grep = H.grep,
|
2282
2287
|
hasTouch = H.hasTouch,
|
2288
|
+
inArray = H.inArray,
|
2283
2289
|
isArray = H.isArray,
|
2284
2290
|
isFirefox = H.isFirefox,
|
2285
2291
|
isMS = H.isMS,
|
@@ -2948,7 +2954,12 @@
|
|
2948
2954
|
n,
|
2949
2955
|
serializedCss = '',
|
2950
2956
|
hyphenate,
|
2951
|
-
hasNew = !oldStyles
|
2957
|
+
hasNew = !oldStyles,
|
2958
|
+
// These CSS properties are interpreted internally by the SVG
|
2959
|
+
// renderer, but are not supported by SVG and should not be added to
|
2960
|
+
// the DOM. In styled mode, no CSS should find its way to the DOM
|
2961
|
+
// whatsoever (#6173).
|
2962
|
+
svgPseudoProps = ['textOverflow', 'width'];
|
2952
2963
|
|
2953
2964
|
// convert legacy
|
2954
2965
|
if (styles && styles.color) {
|
@@ -2992,9 +3003,15 @@
|
|
2992
3003
|
return '-' + b.toLowerCase();
|
2993
3004
|
};
|
2994
3005
|
for (n in styles) {
|
2995
|
-
|
3006
|
+
if (inArray(n, svgPseudoProps) === -1) {
|
3007
|
+
serializedCss +=
|
3008
|
+
n.replace(/([A-Z])/g, hyphenate) + ':' +
|
3009
|
+
styles[n] + ';';
|
3010
|
+
}
|
3011
|
+
}
|
3012
|
+
if (serializedCss) {
|
3013
|
+
attr(elem, 'style', serializedCss); // #1881
|
2996
3014
|
}
|
2997
|
-
attr(elem, 'style', serializedCss); // #1881
|
2998
3015
|
}
|
2999
3016
|
|
3000
3017
|
|
@@ -3138,8 +3155,8 @@
|
|
3138
3155
|
|
3139
3156
|
// flipping affects translate as adjustment for flipping around the group's axis
|
3140
3157
|
if (inverted) {
|
3141
|
-
translateX += wrapper.
|
3142
|
-
translateY += wrapper.
|
3158
|
+
translateX += wrapper.width;
|
3159
|
+
translateY += wrapper.height;
|
3143
3160
|
}
|
3144
3161
|
|
3145
3162
|
// Apply translate. Nearly all transformed elements have translation, so instead
|
@@ -3326,8 +3343,8 @@
|
|
3326
3343
|
'',
|
3327
3344
|
rotation || 0,
|
3328
3345
|
fontSize,
|
3329
|
-
|
3330
|
-
|
3346
|
+
styles && styles.width,
|
3347
|
+
styles && styles.textOverflow // #5968
|
3331
3348
|
]
|
3332
3349
|
.join(',');
|
3333
3350
|
|
@@ -3360,9 +3377,9 @@
|
|
3360
3377
|
bBox = element.getBBox ?
|
3361
3378
|
// SVG: use extend because IE9 is not allowed to change width and height in case
|
3362
3379
|
// of rotation (below)
|
3363
|
-
extend({}, element.getBBox()) :
|
3364
|
-
|
3365
|
-
|
3380
|
+
extend({}, element.getBBox()) : {
|
3381
|
+
|
3382
|
+
// Legacy IE in export mode
|
3366
3383
|
width: element.offsetWidth,
|
3367
3384
|
height: element.offsetHeight
|
3368
3385
|
};
|
@@ -3396,8 +3413,19 @@
|
|
3396
3413
|
width = bBox.width;
|
3397
3414
|
height = bBox.height;
|
3398
3415
|
|
3399
|
-
// Workaround for wrong bounding box in
|
3400
|
-
|
3416
|
+
// Workaround for wrong bounding box in IE, Edge and Chrome on
|
3417
|
+
// Windows. With Highcharts' default font, IE and Edge report
|
3418
|
+
// a box height of 16.899 and Chrome rounds it to 17. If this
|
3419
|
+
// stands uncorrected, it results in more padding added below
|
3420
|
+
// the text than above when adding a label border or background.
|
3421
|
+
// Also vertical positioning is affected.
|
3422
|
+
// http://jsfiddle.net/highcharts/em37nvuj/
|
3423
|
+
// (#1101, #1505, #1669, #2568, #6213).
|
3424
|
+
if (
|
3425
|
+
styles &&
|
3426
|
+
styles.fontSize === '11px' &&
|
3427
|
+
Math.round(height) === 17
|
3428
|
+
) {
|
3401
3429
|
bBox.height = height = 14;
|
3402
3430
|
}
|
3403
3431
|
|
@@ -3990,13 +4018,14 @@
|
|
3990
4018
|
this.url = (isFirefox || isWebKit) && doc.getElementsByTagName('base').length ?
|
3991
4019
|
win.location.href
|
3992
4020
|
.replace(/#.*?$/, '') // remove the hash
|
4021
|
+
.replace(/<[^>]*>/g, '') // wing cut HTML
|
3993
4022
|
.replace(/([\('\)])/g, '\\$1') // escape parantheses and quotes
|
3994
4023
|
.replace(/ /g, '%20') : // replace spaces (needed for Safari only)
|
3995
4024
|
'';
|
3996
4025
|
|
3997
4026
|
// Add description
|
3998
4027
|
desc = this.createElement('desc').add();
|
3999
|
-
desc.element.appendChild(doc.createTextNode('Created with Highcharts 5.0.
|
4028
|
+
desc.element.appendChild(doc.createTextNode('Created with Highcharts 5.0.7'));
|
4000
4029
|
|
4001
4030
|
|
4002
4031
|
renderer.defs = this.createElement('defs').add();
|
@@ -4169,6 +4198,9 @@
|
|
4169
4198
|
textLineHeight = textStyles && textStyles.lineHeight,
|
4170
4199
|
textOutline = textStyles && textStyles.textOutline,
|
4171
4200
|
ellipsis = textStyles && textStyles.textOverflow === 'ellipsis',
|
4201
|
+
noWrap = textStyles && textStyles.whiteSpace === 'nowrap',
|
4202
|
+
fontSize = textStyles && textStyles.fontSize,
|
4203
|
+
textCache,
|
4172
4204
|
i = childNodes.length,
|
4173
4205
|
tempParent = width && !wrapper.added && this.box,
|
4174
4206
|
getLineHeight = function(tspan) {
|
@@ -4176,7 +4208,7 @@
|
|
4176
4208
|
|
4177
4209
|
fontSizeStyle = /(px|em)$/.test(tspan && tspan.style.fontSize) ?
|
4178
4210
|
tspan.style.fontSize :
|
4179
|
-
(
|
4211
|
+
(fontSize || renderer.style.fontSize || 12);
|
4180
4212
|
|
4181
4213
|
|
4182
4214
|
return textLineHeight ?
|
@@ -4191,6 +4223,22 @@
|
|
4191
4223
|
return inputStr.replace(/</g, '<').replace(/>/g, '>');
|
4192
4224
|
};
|
4193
4225
|
|
4226
|
+
// The buildText code is quite heavy, so if we're not changing something
|
4227
|
+
// that affects the text, skip it (#6113).
|
4228
|
+
textCache = [
|
4229
|
+
textStr,
|
4230
|
+
ellipsis,
|
4231
|
+
noWrap,
|
4232
|
+
textLineHeight,
|
4233
|
+
textOutline,
|
4234
|
+
fontSize,
|
4235
|
+
width
|
4236
|
+
].join(',');
|
4237
|
+
if (textCache === wrapper.textCache) {
|
4238
|
+
return;
|
4239
|
+
}
|
4240
|
+
wrapper.textCache = textCache;
|
4241
|
+
|
4194
4242
|
/// remove old text
|
4195
4243
|
while (i--) {
|
4196
4244
|
textNode.removeChild(childNodes[i]);
|
@@ -4310,7 +4358,6 @@
|
|
4310
4358
|
// Check width and apply soft breaks or ellipsis
|
4311
4359
|
if (width) {
|
4312
4360
|
var words = span.replace(/([^\^])-/g, '$1- ').split(' '), // #1273
|
4313
|
-
noWrap = textStyles.whiteSpace === 'nowrap',
|
4314
4361
|
hasWhiteSpace = spans.length > 1 || lineNo || (words.length > 1 && !noWrap),
|
4315
4362
|
tooLong,
|
4316
4363
|
actualWidth,
|
@@ -4442,6 +4489,15 @@
|
|
4442
4489
|
*/
|
4443
4490
|
getContrast: function(rgba) {
|
4444
4491
|
rgba = color(rgba).rgba;
|
4492
|
+
|
4493
|
+
// The threshold may be discussed. Here's a proposal for adding
|
4494
|
+
// different weight to the color channels (#6216)
|
4495
|
+
/*
|
4496
|
+
rgba[0] *= 1; // red
|
4497
|
+
rgba[1] *= 1.2; // green
|
4498
|
+
rgba[2] *= 0.7; // blue
|
4499
|
+
*/
|
4500
|
+
|
4445
4501
|
return rgba[0] + rgba[1] + rgba[2] > 2 * 255 ? '#000000' : '#FFFFFF';
|
4446
4502
|
},
|
4447
4503
|
|
@@ -4859,7 +4915,7 @@
|
|
4859
4915
|
symbolFn = this.symbols[symbol],
|
4860
4916
|
|
4861
4917
|
// check if there's a path defined for this symbol
|
4862
|
-
path = defined(x) && symbolFn &&
|
4918
|
+
path = defined(x) && symbolFn && this.symbols[symbol](
|
4863
4919
|
Math.round(x),
|
4864
4920
|
Math.round(y),
|
4865
4921
|
width,
|
@@ -5023,13 +5079,12 @@
|
|
5023
5079
|
*/
|
5024
5080
|
symbols: {
|
5025
5081
|
'circle': function(x, y, w, h) {
|
5026
|
-
|
5027
|
-
return
|
5028
|
-
|
5029
|
-
|
5030
|
-
|
5031
|
-
|
5032
|
-
];
|
5082
|
+
// Return a full arc
|
5083
|
+
return this.arc(x + w / 2, y + h / 2, w / 2, h / 2, {
|
5084
|
+
start: 0,
|
5085
|
+
end: Math.PI * 2,
|
5086
|
+
open: false
|
5087
|
+
});
|
5033
5088
|
},
|
5034
5089
|
|
5035
5090
|
'square': function(x, y, w, h) {
|
@@ -5070,7 +5125,8 @@
|
|
5070
5125
|
},
|
5071
5126
|
'arc': function(x, y, w, h, options) {
|
5072
5127
|
var start = options.start,
|
5073
|
-
|
5128
|
+
rx = options.r || w,
|
5129
|
+
ry = options.r || h || w,
|
5074
5130
|
end = options.end - 0.001, // to prevent cos and sin of start and end from becoming equal on 360 arcs (related: #1561)
|
5075
5131
|
innerRadius = options.innerR,
|
5076
5132
|
open = options.open,
|
@@ -5078,34 +5134,41 @@
|
|
5078
5134
|
sinStart = Math.sin(start),
|
5079
5135
|
cosEnd = Math.cos(end),
|
5080
5136
|
sinEnd = Math.sin(end),
|
5081
|
-
longArc = options.end - start < Math.PI ? 0 : 1
|
5137
|
+
longArc = options.end - start < Math.PI ? 0 : 1,
|
5138
|
+
arc;
|
5082
5139
|
|
5083
|
-
|
5140
|
+
arc = [
|
5084
5141
|
'M',
|
5085
|
-
x +
|
5086
|
-
y +
|
5142
|
+
x + rx * cosStart,
|
5143
|
+
y + ry * sinStart,
|
5087
5144
|
'A', // arcTo
|
5088
|
-
|
5089
|
-
|
5145
|
+
rx, // x radius
|
5146
|
+
ry, // y radius
|
5090
5147
|
0, // slanting
|
5091
5148
|
longArc, // long or short arc
|
5092
5149
|
1, // clockwise
|
5093
|
-
x +
|
5094
|
-
y +
|
5095
|
-
open ? 'M' : 'L',
|
5096
|
-
x + innerRadius * cosEnd,
|
5097
|
-
y + innerRadius * sinEnd,
|
5098
|
-
'A', // arcTo
|
5099
|
-
innerRadius, // x radius
|
5100
|
-
innerRadius, // y radius
|
5101
|
-
0, // slanting
|
5102
|
-
longArc, // long or short arc
|
5103
|
-
0, // clockwise
|
5104
|
-
x + innerRadius * cosStart,
|
5105
|
-
y + innerRadius * sinStart,
|
5106
|
-
|
5107
|
-
open ? '' : 'Z' // close
|
5150
|
+
x + rx * cosEnd,
|
5151
|
+
y + ry * sinEnd
|
5108
5152
|
];
|
5153
|
+
|
5154
|
+
if (defined(innerRadius)) {
|
5155
|
+
arc.push(
|
5156
|
+
open ? 'M' : 'L',
|
5157
|
+
x + innerRadius * cosEnd,
|
5158
|
+
y + innerRadius * sinEnd,
|
5159
|
+
'A', // arcTo
|
5160
|
+
innerRadius, // x radius
|
5161
|
+
innerRadius, // y radius
|
5162
|
+
0, // slanting
|
5163
|
+
longArc, // long or short arc
|
5164
|
+
0, // clockwise
|
5165
|
+
x + innerRadius * cosStart,
|
5166
|
+
y + innerRadius * sinStart
|
5167
|
+
);
|
5168
|
+
}
|
5169
|
+
|
5170
|
+
arc.push(open ? '' : 'Z'); // close
|
5171
|
+
return arc;
|
5109
5172
|
},
|
5110
5173
|
|
5111
5174
|
/**
|
@@ -7241,11 +7304,18 @@
|
|
7241
7304
|
symbols: ['circle', 'diamond', 'square', 'triangle', 'triangle-down'],
|
7242
7305
|
lang: {
|
7243
7306
|
loading: 'Loading...',
|
7244
|
-
months: [
|
7307
|
+
months: [
|
7308
|
+
'January', 'February', 'March', 'April', 'May', 'June', 'July',
|
7245
7309
|
'August', 'September', 'October', 'November', 'December'
|
7246
7310
|
],
|
7247
|
-
shortMonths: [
|
7248
|
-
|
7311
|
+
shortMonths: [
|
7312
|
+
'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul',
|
7313
|
+
'Aug', 'Sep', 'Oct', 'Nov', 'Dec'
|
7314
|
+
],
|
7315
|
+
weekdays: [
|
7316
|
+
'Sunday', 'Monday', 'Tuesday', 'Wednesday',
|
7317
|
+
'Thursday', 'Friday', 'Saturday'
|
7318
|
+
],
|
7249
7319
|
// invalidDate: '',
|
7250
7320
|
decimalPoint: '.',
|
7251
7321
|
numericSymbols: ['k', 'M', 'G', 'T', 'P', 'E'], // SI prefixes used in axis labels
|
@@ -7257,7 +7327,7 @@
|
|
7257
7327
|
useUTC: true,
|
7258
7328
|
//timezoneOffset: 0,
|
7259
7329
|
|
7260
|
-
VMLRadialGradientURL: 'http://code.highcharts.com/5.0.
|
7330
|
+
VMLRadialGradientURL: 'http://code.highcharts.com/5.0.7/gfx/vml-radial-gradient.png'
|
7261
7331
|
|
7262
7332
|
},
|
7263
7333
|
chart: {
|
@@ -7493,6 +7563,37 @@
|
|
7493
7563
|
|
7494
7564
|
|
7495
7565
|
|
7566
|
+
/**
|
7567
|
+
* Sets the getTimezoneOffset function. If the timezone option is set, a default
|
7568
|
+
* getTimezoneOffset function with that timezone is returned. If not, the
|
7569
|
+
* specified getTimezoneOffset function is returned. If neither are specified,
|
7570
|
+
* undefined is returned.
|
7571
|
+
* @return {function} a getTimezoneOffset function or undefined
|
7572
|
+
*/
|
7573
|
+
function getTimezoneOffsetOption() {
|
7574
|
+
var globalOptions = H.defaultOptions.global,
|
7575
|
+
moment = win.moment;
|
7576
|
+
|
7577
|
+
if (globalOptions.timezone) {
|
7578
|
+
if (!moment) {
|
7579
|
+
// getTimezoneOffset-function stays undefined because it depends on
|
7580
|
+
// Moment.js
|
7581
|
+
H.error(25);
|
7582
|
+
|
7583
|
+
} else {
|
7584
|
+
return function(timestamp) {
|
7585
|
+
return -moment.tz(
|
7586
|
+
timestamp,
|
7587
|
+
globalOptions.timezone
|
7588
|
+
).utcOffset();
|
7589
|
+
};
|
7590
|
+
}
|
7591
|
+
}
|
7592
|
+
|
7593
|
+
// If not timezone is set, look for the getTimezoneOffset callback
|
7594
|
+
return globalOptions.useUTC && globalOptions.getTimezoneOffset;
|
7595
|
+
}
|
7596
|
+
|
7496
7597
|
/**
|
7497
7598
|
* Set the time methods globally based on the useUTC option. Time method can be
|
7498
7599
|
* either local time or UTC (default). It is called internally on initiating
|
@@ -7509,7 +7610,7 @@
|
|
7509
7610
|
|
7510
7611
|
H.Date = Date = globalOptions.Date || win.Date; // Allow using a different Date class
|
7511
7612
|
Date.hcTimezoneOffset = useUTC && globalOptions.timezoneOffset;
|
7512
|
-
Date.hcGetTimezoneOffset =
|
7613
|
+
Date.hcGetTimezoneOffset = getTimezoneOffsetOption();
|
7513
7614
|
Date.hcMakeTime = function(year, month, date, hours, minutes, seconds) {
|
7514
7615
|
var d;
|
7515
7616
|
if (useUTC) {
|
@@ -7686,6 +7787,7 @@
|
|
7686
7787
|
return;
|
7687
7788
|
}
|
7688
7789
|
|
7790
|
+
|
7689
7791
|
// common for lines and bands
|
7690
7792
|
if (isNew && path && path.length) {
|
7691
7793
|
svgElem.attr({
|
@@ -9246,7 +9348,7 @@
|
|
9246
9348
|
|
9247
9349
|
each(series.points, function(point, i) {
|
9248
9350
|
var x;
|
9249
|
-
if (point.options
|
9351
|
+
if (point.options) {
|
9250
9352
|
x = axis.nameToX(point);
|
9251
9353
|
if (x !== point.x) {
|
9252
9354
|
point.x = x;
|
@@ -9606,11 +9708,9 @@
|
|
9606
9708
|
|
9607
9709
|
}
|
9608
9710
|
|
9711
|
+
// reset min/max or remove extremes based on start/end on tick
|
9712
|
+
this.trimTicks(tickPositions, startOnTick, endOnTick);
|
9609
9713
|
if (!this.isLinked) {
|
9610
|
-
|
9611
|
-
// reset min/max or remove extremes based on start/end on tick
|
9612
|
-
this.trimTicks(tickPositions, startOnTick, endOnTick);
|
9613
|
-
|
9614
9714
|
// When there is only one point, or all points have the same value on this axis, then min
|
9615
9715
|
// and max are equal and tickPositions.length is 0 or 1. In this case, add some padding
|
9616
9716
|
// in order to center the point, but leave it with one tick. #1337.
|
@@ -9621,7 +9721,6 @@
|
|
9621
9721
|
this.max += 0.5;
|
9622
9722
|
}
|
9623
9723
|
this.single = single;
|
9624
|
-
|
9625
9724
|
if (!tickPositionsOption && !tickPositioner) {
|
9626
9725
|
this.adjustTickAmount();
|
9627
9726
|
}
|
@@ -9636,25 +9735,27 @@
|
|
9636
9735
|
roundedMax = tickPositions[tickPositions.length - 1],
|
9637
9736
|
minPointOffset = this.minPointOffset || 0;
|
9638
9737
|
|
9639
|
-
if (
|
9640
|
-
|
9641
|
-
|
9642
|
-
|
9643
|
-
tickPositions
|
9738
|
+
if (!this.isLinked) {
|
9739
|
+
if (startOnTick) {
|
9740
|
+
this.min = roundedMin;
|
9741
|
+
} else {
|
9742
|
+
while (this.min - minPointOffset > tickPositions[0]) {
|
9743
|
+
tickPositions.shift();
|
9744
|
+
}
|
9644
9745
|
}
|
9645
|
-
}
|
9646
9746
|
|
9647
|
-
|
9648
|
-
|
9649
|
-
|
9650
|
-
|
9651
|
-
|
9747
|
+
if (endOnTick) {
|
9748
|
+
this.max = roundedMax;
|
9749
|
+
} else {
|
9750
|
+
while (this.max + minPointOffset < tickPositions[tickPositions.length - 1]) {
|
9751
|
+
tickPositions.pop();
|
9752
|
+
}
|
9652
9753
|
}
|
9653
|
-
}
|
9654
9754
|
|
9655
|
-
|
9656
|
-
|
9657
|
-
|
9755
|
+
// If no tick are left, set one tick in the middle (#3195)
|
9756
|
+
if (tickPositions.length === 0 && defined(roundedMin)) {
|
9757
|
+
tickPositions.push((roundedMax + roundedMin) / 2);
|
9758
|
+
}
|
9658
9759
|
}
|
9659
9760
|
},
|
9660
9761
|
|
@@ -9921,13 +10022,12 @@
|
|
9921
10022
|
setAxisSize: function() {
|
9922
10023
|
var chart = this.chart,
|
9923
10024
|
options = this.options,
|
9924
|
-
|
9925
|
-
offsetRight = options.offsetRight || 0,
|
10025
|
+
offsets = options.offsets || [0, 0, 0, 0], // top / right / bottom / left
|
9926
10026
|
horiz = this.horiz,
|
9927
|
-
width = pick(options.width, chart.plotWidth -
|
9928
|
-
height = pick(options.height, chart.plotHeight),
|
9929
|
-
top = pick(options.top, chart.plotTop),
|
9930
|
-
left = pick(options.left, chart.plotLeft +
|
10027
|
+
width = pick(options.width, chart.plotWidth - offsets[3] + offsets[1]),
|
10028
|
+
height = pick(options.height, chart.plotHeight - offsets[0] + offsets[2]),
|
10029
|
+
top = pick(options.top, chart.plotTop + offsets[0]),
|
10030
|
+
left = pick(options.left, chart.plotLeft + offsets[3]),
|
9931
10031
|
percentRegex = /%$/;
|
9932
10032
|
|
9933
10033
|
// Check for percentage based input values. Rounding fixes problems with
|
@@ -10113,9 +10213,15 @@
|
|
10113
10213
|
slotCount = Math.max(this.tickPositions.length - (this.categories ? 0 : 1), 1),
|
10114
10214
|
marginLeft = chart.margin[3];
|
10115
10215
|
|
10116
|
-
return (
|
10117
|
-
|
10118
|
-
(
|
10216
|
+
return (
|
10217
|
+
horiz &&
|
10218
|
+
(labelOptions.step || 0) < 2 &&
|
10219
|
+
!labelOptions.rotation && // #4415
|
10220
|
+
((this.staggerLines || 1) * this.len) / slotCount
|
10221
|
+
) || (!horiz && (
|
10222
|
+
(marginLeft && (marginLeft - chart.spacing[3])) ||
|
10223
|
+
chart.chartWidth * 0.33
|
10224
|
+
)); // #1580, #1931
|
10119
10225
|
|
10120
10226
|
},
|
10121
10227
|
|
@@ -10296,6 +10402,21 @@
|
|
10296
10402
|
axis.axisTitle[display ? 'show' : 'hide'](true);
|
10297
10403
|
},
|
10298
10404
|
|
10405
|
+
/**
|
10406
|
+
* Generates a tick for initial positioning.
|
10407
|
+
* @param {number} pos - The tick position in axis values.
|
10408
|
+
* @param {number} i - The index of the tick in axis.tickPositions.
|
10409
|
+
*/
|
10410
|
+
generateTick: function(pos) {
|
10411
|
+
var ticks = this.ticks;
|
10412
|
+
|
10413
|
+
if (!ticks[pos]) {
|
10414
|
+
ticks[pos] = new Tick(this, pos);
|
10415
|
+
} else {
|
10416
|
+
ticks[pos].addLabel(); // update labels depending on tick interval
|
10417
|
+
}
|
10418
|
+
},
|
10419
|
+
|
10299
10420
|
/**
|
10300
10421
|
* Render the tick labels to a preliminary position to get their sizes
|
10301
10422
|
*/
|
@@ -10360,12 +10481,9 @@
|
|
10360
10481
|
if (hasData || axis.isLinked) {
|
10361
10482
|
|
10362
10483
|
// Generate ticks
|
10363
|
-
each(tickPositions, function(pos) {
|
10364
|
-
|
10365
|
-
|
10366
|
-
} else {
|
10367
|
-
ticks[pos].addLabel(); // update labels depending on tick interval
|
10368
|
-
}
|
10484
|
+
each(tickPositions, function(pos, i) {
|
10485
|
+
// i is not used here, but may be used in overrides
|
10486
|
+
axis.generateTick(pos, i);
|
10369
10487
|
});
|
10370
10488
|
|
10371
10489
|
axis.renderUnsquish();
|
@@ -10539,6 +10657,54 @@
|
|
10539
10657
|
};
|
10540
10658
|
},
|
10541
10659
|
|
10660
|
+
/**
|
10661
|
+
* Render a minor tick into the given position. If a minor tick already
|
10662
|
+
* exists in this position, move it.
|
10663
|
+
* @param {number} pos - The position in axis values.
|
10664
|
+
*/
|
10665
|
+
renderMinorTick: function(pos) {
|
10666
|
+
var slideInTicks = this.chart.hasRendered && isNumber(this.oldMin),
|
10667
|
+
minorTicks = this.minorTicks;
|
10668
|
+
|
10669
|
+
if (!minorTicks[pos]) {
|
10670
|
+
minorTicks[pos] = new Tick(this, pos, 'minor');
|
10671
|
+
}
|
10672
|
+
|
10673
|
+
// Render new ticks in old position
|
10674
|
+
if (slideInTicks && minorTicks[pos].isNew) {
|
10675
|
+
minorTicks[pos].render(null, true);
|
10676
|
+
}
|
10677
|
+
|
10678
|
+
minorTicks[pos].render(null, false, 1);
|
10679
|
+
},
|
10680
|
+
|
10681
|
+
/**
|
10682
|
+
* Render a major tick into the given position. If a tick already exists
|
10683
|
+
* in this position, move it.
|
10684
|
+
* @param {number} pos - The position in axis values
|
10685
|
+
* @param {number} i - The tick index
|
10686
|
+
*/
|
10687
|
+
renderTick: function(pos, i) {
|
10688
|
+
var isLinked = this.isLinked,
|
10689
|
+
ticks = this.ticks,
|
10690
|
+
slideInTicks = this.chart.hasRendered && isNumber(this.oldMin);
|
10691
|
+
|
10692
|
+
// Linked axes need an extra check to find out if
|
10693
|
+
if (!isLinked || (pos >= this.min && pos <= this.max)) {
|
10694
|
+
|
10695
|
+
if (!ticks[pos]) {
|
10696
|
+
ticks[pos] = new Tick(this, pos);
|
10697
|
+
}
|
10698
|
+
|
10699
|
+
// render new ticks in old position
|
10700
|
+
if (slideInTicks && ticks[pos].isNew) {
|
10701
|
+
ticks[pos].render(i, true, 0.1);
|
10702
|
+
}
|
10703
|
+
|
10704
|
+
ticks[pos].render(i);
|
10705
|
+
}
|
10706
|
+
},
|
10707
|
+
|
10542
10708
|
/**
|
10543
10709
|
* Render the axis
|
10544
10710
|
*/
|
@@ -10559,8 +10725,6 @@
|
|
10559
10725
|
alternateGridColor = options.alternateGridColor,
|
10560
10726
|
tickmarkOffset = axis.tickmarkOffset,
|
10561
10727
|
axisLine = axis.axisLine,
|
10562
|
-
hasRendered = chart.hasRendered,
|
10563
|
-
slideInTicks = hasRendered && isNumber(axis.oldMin),
|
10564
10728
|
showAxis = axis.showAxis,
|
10565
10729
|
animation = animObject(renderer.globalAnimation),
|
10566
10730
|
from,
|
@@ -10585,16 +10749,7 @@
|
|
10585
10749
|
// minor ticks
|
10586
10750
|
if (axis.minorTickInterval && !axis.categories) {
|
10587
10751
|
each(axis.getMinorTickPositions(), function(pos) {
|
10588
|
-
|
10589
|
-
minorTicks[pos] = new Tick(axis, pos, 'minor');
|
10590
|
-
}
|
10591
|
-
|
10592
|
-
// render new ticks in old position
|
10593
|
-
if (slideInTicks && minorTicks[pos].isNew) {
|
10594
|
-
minorTicks[pos].render(null, true);
|
10595
|
-
}
|
10596
|
-
|
10597
|
-
minorTicks[pos].render(null, false, 1);
|
10752
|
+
axis.renderMinorTick(pos);
|
10598
10753
|
});
|
10599
10754
|
}
|
10600
10755
|
|
@@ -10602,22 +10757,7 @@
|
|
10602
10757
|
// we can get the position of the neighbour label. #808.
|
10603
10758
|
if (tickPositions.length) { // #1300
|
10604
10759
|
each(tickPositions, function(pos, i) {
|
10605
|
-
|
10606
|
-
// linked axes need an extra check to find out if
|
10607
|
-
if (!isLinked || (pos >= axis.min && pos <= axis.max)) {
|
10608
|
-
|
10609
|
-
if (!ticks[pos]) {
|
10610
|
-
ticks[pos] = new Tick(axis, pos);
|
10611
|
-
}
|
10612
|
-
|
10613
|
-
// render new ticks in old position
|
10614
|
-
if (slideInTicks && ticks[pos].isNew) {
|
10615
|
-
ticks[pos].render(i, true, 0.1);
|
10616
|
-
}
|
10617
|
-
|
10618
|
-
ticks[pos].render(i);
|
10619
|
-
}
|
10620
|
-
|
10760
|
+
axis.renderTick(pos, i);
|
10621
10761
|
});
|
10622
10762
|
// In a categorized axis, the tick marks are displayed between labels. So
|
10623
10763
|
// we need to add a tick mark and grid line at the left edge of the X axis.
|
@@ -11058,10 +11198,17 @@
|
|
11058
11198
|
|
11059
11199
|
|
11060
11200
|
// Handle higher ranks. Mark new days if the time is on midnight
|
11061
|
-
// (#950, #1649, #1760, #3349)
|
11062
|
-
|
11201
|
+
// (#950, #1649, #1760, #3349). Use a reasonable dropout threshold to
|
11202
|
+
// prevent looping over dense data grouping (#6156).
|
11203
|
+
if (interval <= timeUnits.hour && tickPositions.length < 10000) {
|
11063
11204
|
each(tickPositions, function(time) {
|
11064
|
-
if (
|
11205
|
+
if (
|
11206
|
+
// Speed optimization, no need to run dateFormat unless
|
11207
|
+
// we're on a full or half hour
|
11208
|
+
time % 1800000 === 0 &&
|
11209
|
+
// Check for local or global midnight
|
11210
|
+
dateFormat('%H%M%S%L', time) === '000000000'
|
11211
|
+
) {
|
11065
11212
|
higherRanks[time] = 'day';
|
11066
11213
|
}
|
11067
11214
|
});
|
@@ -11730,13 +11877,13 @@
|
|
11730
11877
|
y: point[0].y
|
11731
11878
|
};
|
11732
11879
|
textConfig.points = pointConfig;
|
11733
|
-
this.len = pointConfig.length;
|
11734
11880
|
point = point[0];
|
11735
11881
|
|
11736
11882
|
// single point tooltip
|
11737
11883
|
} else {
|
11738
11884
|
textConfig = point.getLabelConfig();
|
11739
11885
|
}
|
11886
|
+
this.len = pointConfig.length; // #6128
|
11740
11887
|
text = formatter.call(textConfig, tooltip);
|
11741
11888
|
|
11742
11889
|
// register the current series
|
@@ -11803,8 +11950,8 @@
|
|
11803
11950
|
headerHeight,
|
11804
11951
|
tooltipLabel = this.getLabel();
|
11805
11952
|
|
11806
|
-
// Create the individual labels
|
11807
|
-
each(labels.slice(0,
|
11953
|
+
// Create the individual labels for header and points, ignore footer
|
11954
|
+
each(labels.slice(0, points.length + 1), function(str, i) {
|
11808
11955
|
var point = points[i - 1] ||
|
11809
11956
|
// Item 0 is the header. Instead of this, we could also use the crosshair label
|
11810
11957
|
{
|
@@ -11927,12 +12074,17 @@
|
|
11927
12074
|
},
|
11928
12075
|
|
11929
12076
|
/**
|
11930
|
-
* Get the
|
12077
|
+
* Get the optimal date format for a point, based on a range.
|
12078
|
+
* @param {number} range - The time range
|
12079
|
+
* @param {number|Date} date - The date of the point in question
|
12080
|
+
* @param {number} startOfWeek - An integer representing the first day of
|
12081
|
+
* the week, where 0 is Sunday
|
12082
|
+
* @param {Object} dateTimeLabelFormats - A map of time units to formats
|
12083
|
+
* @return {string} - the optimal date format for a point
|
11931
12084
|
*/
|
11932
|
-
|
11933
|
-
var
|
11934
|
-
|
11935
|
-
closestPointRange = xAxis && xAxis.closestPointRange,
|
12085
|
+
getDateFormat: function(range, date, startOfWeek, dateTimeLabelFormats) {
|
12086
|
+
var dateStr = dateFormat('%m-%d %H:%M:%S.%L', date),
|
12087
|
+
format,
|
11936
12088
|
n,
|
11937
12089
|
blank = '01-01 00:00:00.000',
|
11938
12090
|
strpos = {
|
@@ -11942,41 +12094,56 @@
|
|
11942
12094
|
hour: 6,
|
11943
12095
|
day: 3
|
11944
12096
|
},
|
11945
|
-
date,
|
11946
12097
|
lastN = 'millisecond'; // for sub-millisecond data, #4223
|
12098
|
+
for (n in timeUnits) {
|
11947
12099
|
|
11948
|
-
|
11949
|
-
|
11950
|
-
|
11951
|
-
|
11952
|
-
|
11953
|
-
|
11954
|
-
date.substr(6) === blank.substr(6)) {
|
11955
|
-
n = 'week';
|
11956
|
-
break;
|
11957
|
-
}
|
11958
|
-
|
11959
|
-
// The first format that is too great for the range
|
11960
|
-
if (timeUnits[n] > closestPointRange) {
|
11961
|
-
n = lastN;
|
11962
|
-
break;
|
11963
|
-
}
|
12100
|
+
// If the range is exactly one week and we're looking at a Sunday/Monday, go for the week format
|
12101
|
+
if (range === timeUnits.week && +dateFormat('%w', date) === startOfWeek &&
|
12102
|
+
dateStr.substr(6) === blank.substr(6)) {
|
12103
|
+
n = 'week';
|
12104
|
+
break;
|
12105
|
+
}
|
11964
12106
|
|
11965
|
-
|
11966
|
-
|
11967
|
-
|
11968
|
-
|
11969
|
-
|
12107
|
+
// The first format that is too great for the range
|
12108
|
+
if (timeUnits[n] > range) {
|
12109
|
+
n = lastN;
|
12110
|
+
break;
|
12111
|
+
}
|
11970
12112
|
|
11971
|
-
|
11972
|
-
|
11973
|
-
|
11974
|
-
|
12113
|
+
// If the point is placed every day at 23:59, we need to show
|
12114
|
+
// the minutes as well. #2637.
|
12115
|
+
if (strpos[n] && dateStr.substr(strpos[n]) !== blank.substr(strpos[n])) {
|
12116
|
+
break;
|
11975
12117
|
}
|
11976
12118
|
|
11977
|
-
|
11978
|
-
|
12119
|
+
// Weeks are outside the hierarchy, only apply them on Mondays/Sundays like in the first condition
|
12120
|
+
if (n !== 'week') {
|
12121
|
+
lastN = n;
|
11979
12122
|
}
|
12123
|
+
}
|
12124
|
+
|
12125
|
+
if (n) {
|
12126
|
+
format = dateTimeLabelFormats[n];
|
12127
|
+
}
|
12128
|
+
|
12129
|
+
return format;
|
12130
|
+
},
|
12131
|
+
|
12132
|
+
/**
|
12133
|
+
* Get the best X date format based on the closest point range on the axis.
|
12134
|
+
*/
|
12135
|
+
getXDateFormat: function(point, options, xAxis) {
|
12136
|
+
var xDateFormat,
|
12137
|
+
dateTimeLabelFormats = options.dateTimeLabelFormats,
|
12138
|
+
closestPointRange = xAxis && xAxis.closestPointRange;
|
12139
|
+
|
12140
|
+
if (closestPointRange) {
|
12141
|
+
xDateFormat = this.getDateFormat(
|
12142
|
+
closestPointRange,
|
12143
|
+
point.x,
|
12144
|
+
xAxis.options.startOfWeek,
|
12145
|
+
dateTimeLabelFormats
|
12146
|
+
);
|
11980
12147
|
} else {
|
11981
12148
|
xDateFormat = dateTimeLabelFormats.day;
|
11982
12149
|
}
|
@@ -12236,7 +12403,8 @@
|
|
12236
12403
|
kdpoints.sort(function(p1, p2) {
|
12237
12404
|
var isCloserX = p1.distX - p2.distX,
|
12238
12405
|
isCloser = p1.dist - p2.dist,
|
12239
|
-
isAbove = p2.series.group
|
12406
|
+
isAbove = (p2.series.group && p2.series.group.zIndex) -
|
12407
|
+
(p1.series.group && p1.series.group.zIndex);
|
12240
12408
|
|
12241
12409
|
// We have two points which are not in the same place on xAxis and shared tooltip:
|
12242
12410
|
if (isCloserX !== 0 && shared) { // #5721
|
@@ -13562,6 +13730,7 @@
|
|
13562
13730
|
}
|
13563
13731
|
|
13564
13732
|
// Draw the legend symbol inside the group box
|
13733
|
+
legend.symbolHeight = options.symbolHeight || legend.fontMetrics.f;
|
13565
13734
|
series.drawLegendSymbol(legend, item);
|
13566
13735
|
|
13567
13736
|
if (legend.setItemEvents) {
|
@@ -14039,7 +14208,7 @@
|
|
14039
14208
|
*/
|
14040
14209
|
drawRectangle: function(legend, item) {
|
14041
14210
|
var options = legend.options,
|
14042
|
-
symbolHeight =
|
14211
|
+
symbolHeight = legend.symbolHeight,
|
14043
14212
|
square = options.squareSymbol,
|
14044
14213
|
symbolWidth = square ? symbolHeight : legend.symbolWidth;
|
14045
14214
|
|
@@ -14070,6 +14239,8 @@
|
|
14070
14239
|
radius,
|
14071
14240
|
legendSymbol,
|
14072
14241
|
symbolWidth = legend.symbolWidth,
|
14242
|
+
symbolHeight = legend.symbolHeight,
|
14243
|
+
generalRadius = symbolHeight / 2,
|
14073
14244
|
renderer = this.chart.renderer,
|
14074
14245
|
legendItemGroup = this.legendGroup,
|
14075
14246
|
verticalCenter = legend.baseline - Math.round(legend.fontMetrics.b * 0.3),
|
@@ -14099,7 +14270,22 @@
|
|
14099
14270
|
|
14100
14271
|
// Draw the marker
|
14101
14272
|
if (markerOptions && markerOptions.enabled !== false) {
|
14102
|
-
|
14273
|
+
|
14274
|
+
// Do not allow the marker to be larger than the symbolHeight
|
14275
|
+
radius = Math.min(
|
14276
|
+
pick(markerOptions.radius, generalRadius),
|
14277
|
+
generalRadius
|
14278
|
+
);
|
14279
|
+
|
14280
|
+
// Restrict symbol markers size
|
14281
|
+
if (this.symbol.indexOf('url') === 0) {
|
14282
|
+
markerOptions = merge(markerOptions, {
|
14283
|
+
width: symbolHeight,
|
14284
|
+
height: symbolHeight
|
14285
|
+
});
|
14286
|
+
radius = 0;
|
14287
|
+
}
|
14288
|
+
|
14103
14289
|
this.legendSymbol = legendSymbol = renderer.symbol(
|
14104
14290
|
this.symbol,
|
14105
14291
|
(symbolWidth / 2) - radius,
|
@@ -14325,6 +14511,26 @@
|
|
14325
14511
|
return series;
|
14326
14512
|
},
|
14327
14513
|
|
14514
|
+
/**
|
14515
|
+
* Order all series above a given index. When series are added and ordered
|
14516
|
+
* by configuration, only the last series is handled (#248, #1123, #2456,
|
14517
|
+
* #6112). This function is called on series initialization and destroy.
|
14518
|
+
*
|
14519
|
+
* @param {number} fromIndex - If this is given, only the series above this
|
14520
|
+
* index are handled.
|
14521
|
+
*/
|
14522
|
+
orderSeries: function(fromIndex) {
|
14523
|
+
var series = this.series,
|
14524
|
+
i = fromIndex || 0;
|
14525
|
+
for (; i < series.length; i++) {
|
14526
|
+
if (series[i]) {
|
14527
|
+
series[i].index = i;
|
14528
|
+
series[i].name = series[i].name ||
|
14529
|
+
'Series ' + (series[i].index + 1);
|
14530
|
+
}
|
14531
|
+
}
|
14532
|
+
},
|
14533
|
+
|
14328
14534
|
/**
|
14329
14535
|
* Check whether a given point is within the plot area
|
14330
14536
|
*
|
@@ -14366,6 +14572,11 @@
|
|
14366
14572
|
isHiddenChart = renderer.isHidden(),
|
14367
14573
|
afterRedraw = [];
|
14368
14574
|
|
14575
|
+
// Handle responsive rules, not only on resize (#6130)
|
14576
|
+
if (chart.setResponsive) {
|
14577
|
+
chart.setResponsive(false);
|
14578
|
+
}
|
14579
|
+
|
14369
14580
|
H.setAnimation(animation, chart);
|
14370
14581
|
|
14371
14582
|
if (isHiddenChart) {
|
@@ -14468,12 +14679,18 @@
|
|
14468
14679
|
chart.drawChartBox();
|
14469
14680
|
}
|
14470
14681
|
|
14682
|
+
// Fire an event before redrawing series, used by the boost module to
|
14683
|
+
// clear previous series renderings.
|
14684
|
+
fireEvent(chart, 'predraw');
|
14471
14685
|
|
14472
14686
|
// redraw affected series
|
14473
14687
|
each(series, function(serie) {
|
14474
14688
|
if ((isDirtyBox || serie.isDirty) && serie.visible) {
|
14475
14689
|
serie.redraw();
|
14476
14690
|
}
|
14691
|
+
// Set it here, otherwise we will have unlimited 'updatedData' calls
|
14692
|
+
// for a hidden series after setData(). Fixes #6012
|
14693
|
+
serie.isDirtyData = false;
|
14477
14694
|
});
|
14478
14695
|
|
14479
14696
|
// move tooltip or reset
|
@@ -14484,8 +14701,9 @@
|
|
14484
14701
|
// redraw if canvas
|
14485
14702
|
renderer.draw();
|
14486
14703
|
|
14487
|
-
//
|
14704
|
+
// Fire the events
|
14488
14705
|
fireEvent(chart, 'redraw');
|
14706
|
+
fireEvent(chart, 'render');
|
14489
14707
|
|
14490
14708
|
if (isHiddenChart) {
|
14491
14709
|
chart.cloneRenderTo(true);
|
@@ -14508,7 +14726,7 @@
|
|
14508
14726
|
i;
|
14509
14727
|
|
14510
14728
|
function itemById(item) {
|
14511
|
-
return item.id === id || item.options.id === id;
|
14729
|
+
return item.id === id || (item.options && item.options.id === id);
|
14512
14730
|
}
|
14513
14731
|
|
14514
14732
|
ret =
|
@@ -14724,10 +14942,14 @@
|
|
14724
14942
|
chart.containerHeight = getStyle(renderTo, 'height');
|
14725
14943
|
}
|
14726
14944
|
|
14727
|
-
chart.chartWidth = Math.max(
|
14728
|
-
|
14729
|
-
|
14730
|
-
|
14945
|
+
chart.chartWidth = Math.max( // #1393
|
14946
|
+
0,
|
14947
|
+
widthOption || chart.containerWidth || 600 // #1460
|
14948
|
+
);
|
14949
|
+
chart.chartHeight = Math.max(
|
14950
|
+
0,
|
14951
|
+
heightOption || chart.containerHeight || 400
|
14952
|
+
);
|
14731
14953
|
},
|
14732
14954
|
|
14733
14955
|
/**
|
@@ -14907,8 +15129,8 @@
|
|
14907
15129
|
}
|
14908
15130
|
|
14909
15131
|
// adjust for scroller
|
14910
|
-
if (chart.
|
14911
|
-
chart.
|
15132
|
+
if (chart.extraMargin) {
|
15133
|
+
chart[chart.extraMargin.type] = (chart[chart.extraMargin.type] || 0) + chart.extraMargin.value;
|
14912
15134
|
}
|
14913
15135
|
if (chart.extraTopMargin) {
|
14914
15136
|
chart.plotTop += chart.extraTopMargin;
|
@@ -15048,9 +15270,6 @@
|
|
15048
15270
|
chart.layOutTitles(); // #2857
|
15049
15271
|
chart.getMargins();
|
15050
15272
|
|
15051
|
-
if (chart.setResponsive) {
|
15052
|
-
chart.setResponsive(false);
|
15053
|
-
}
|
15054
15273
|
chart.redraw(animation);
|
15055
15274
|
|
15056
15275
|
|
@@ -15570,9 +15789,11 @@
|
|
15570
15789
|
}
|
15571
15790
|
|
15572
15791
|
// ==== Destroy chart properties:
|
15573
|
-
each([
|
15574
|
-
'
|
15575
|
-
'
|
15792
|
+
each([
|
15793
|
+
'title', 'subtitle', 'chartBackground', 'plotBackground',
|
15794
|
+
'plotBGImage', 'plotBorder', 'seriesGroup', 'clipRect', 'credits',
|
15795
|
+
'pointer', 'rangeSelector', 'legend', 'resetZoomButton', 'tooltip',
|
15796
|
+
'renderer'
|
15576
15797
|
], function(name) {
|
15577
15798
|
var prop = chart[name];
|
15578
15799
|
|
@@ -15666,9 +15887,6 @@
|
|
15666
15887
|
|
15667
15888
|
chart.render();
|
15668
15889
|
|
15669
|
-
// add canvas
|
15670
|
-
chart.renderer.draw();
|
15671
|
-
|
15672
15890
|
// Fire the load event if there are no external images
|
15673
15891
|
if (!chart.renderer.imgCount && chart.onload) {
|
15674
15892
|
chart.onload();
|
@@ -15692,6 +15910,8 @@
|
|
15692
15910
|
}, this);
|
15693
15911
|
|
15694
15912
|
fireEvent(this, 'load');
|
15913
|
+
fireEvent(this, 'render');
|
15914
|
+
|
15695
15915
|
|
15696
15916
|
// Set up auto resize, check for not destroyed (#6068)
|
15697
15917
|
if (defined(this.index) && this.options.chart.reflow !== false) {
|
@@ -15892,9 +16112,11 @@
|
|
15892
16112
|
(this.selected ? ' highcharts-point-select' : '') +
|
15893
16113
|
(this.negative ? ' highcharts-negative' : '') +
|
15894
16114
|
(this.isNull ? ' highcharts-null-point' : '') +
|
15895
|
-
(this.colorIndex !== undefined ? ' highcharts-color-' +
|
16115
|
+
(this.colorIndex !== undefined ? ' highcharts-color-' +
|
16116
|
+
this.colorIndex : '') +
|
15896
16117
|
(this.options.className ? ' ' + this.options.className : '') +
|
15897
|
-
(this.zone && this.zone.className ? ' ' +
|
16118
|
+
(this.zone && this.zone.className ? ' ' +
|
16119
|
+
this.zone.className.replace('highcharts-negative', '') : '');
|
15898
16120
|
},
|
15899
16121
|
|
15900
16122
|
/**
|
@@ -15984,6 +16206,7 @@
|
|
15984
16206
|
x: this.category,
|
15985
16207
|
y: this.y,
|
15986
16208
|
color: this.color,
|
16209
|
+
colorIndex: this.colorIndex,
|
15987
16210
|
key: this.name || this.category,
|
15988
16211
|
series: this.series,
|
15989
16212
|
point: this,
|
@@ -16235,8 +16458,7 @@
|
|
16235
16458
|
eventType,
|
16236
16459
|
events,
|
16237
16460
|
chartSeries = chart.series,
|
16238
|
-
lastSeries
|
16239
|
-
i;
|
16461
|
+
lastSeries;
|
16240
16462
|
|
16241
16463
|
series.chart = chart;
|
16242
16464
|
series.options = options = series.setOptions(options); // merge with plotOptions
|
@@ -16287,14 +16509,8 @@
|
|
16287
16509
|
}
|
16288
16510
|
series._i = pick(lastSeries && lastSeries._i, -1) + 1;
|
16289
16511
|
|
16290
|
-
// Insert the series and
|
16291
|
-
|
16292
|
-
// inserted last. #248, #1123, #2456
|
16293
|
-
for (i = this.insert(chartSeries); i < chartSeries.length; i++) {
|
16294
|
-
chartSeries[i].index = i;
|
16295
|
-
chartSeries[i].name = chartSeries[i].name ||
|
16296
|
-
'Series ' + (chartSeries[i].index + 1);
|
16297
|
-
}
|
16512
|
+
// Insert the series and re-order all series above the insertion point.
|
16513
|
+
chart.orderSeries(this.insert(chartSeries));
|
16298
16514
|
},
|
16299
16515
|
|
16300
16516
|
/**
|
@@ -16502,10 +16718,14 @@
|
|
16502
16718
|
|
16503
16719
|
getCyclic: function(prop, value, defaults) {
|
16504
16720
|
var i,
|
16721
|
+
chart = this.chart,
|
16505
16722
|
userOptions = this.userOptions,
|
16506
16723
|
indexName = prop + 'Index',
|
16507
16724
|
counterName = prop + 'Counter',
|
16508
|
-
len = defaults ? defaults.length : pick(
|
16725
|
+
len = defaults ? defaults.length : pick(
|
16726
|
+
chart.options.chart[prop + 'Count'],
|
16727
|
+
chart[prop + 'Count']
|
16728
|
+
),
|
16509
16729
|
setting;
|
16510
16730
|
|
16511
16731
|
if (!value) {
|
@@ -16514,8 +16734,12 @@
|
|
16514
16734
|
if (defined(setting)) { // after Series.update()
|
16515
16735
|
i = setting;
|
16516
16736
|
} else {
|
16517
|
-
|
16518
|
-
|
16737
|
+
// #6138
|
16738
|
+
if (!chart.series.length) {
|
16739
|
+
chart[counterName] = 0;
|
16740
|
+
}
|
16741
|
+
userOptions['_' + indexName] = i = chart[counterName] % len;
|
16742
|
+
chart[counterName] += 1;
|
16519
16743
|
}
|
16520
16744
|
if (defaults) {
|
16521
16745
|
value = defaults[i];
|
@@ -17128,6 +17352,7 @@
|
|
17128
17352
|
chart[sharedClipKey] = chart[sharedClipKey].destroy();
|
17129
17353
|
}
|
17130
17354
|
if (chart[sharedClipKey + 'm']) {
|
17355
|
+
this.markerGroup.clip();
|
17131
17356
|
chart[sharedClipKey + 'm'] = chart[sharedClipKey + 'm'].destroy();
|
17132
17357
|
}
|
17133
17358
|
}
|
@@ -17211,8 +17436,7 @@
|
|
17211
17436
|
|
17212
17437
|
if (seriesMarkerOptions.enabled !== false || series._hasPointMarkers) {
|
17213
17438
|
|
17214
|
-
i = points.length;
|
17215
|
-
while (i--) {
|
17439
|
+
for (i = 0; i < points.length; i++) {
|
17216
17440
|
point = points[i];
|
17217
17441
|
plotY = point.plotY;
|
17218
17442
|
graphic = point.graphic;
|
@@ -17273,8 +17497,7 @@
|
|
17273
17497
|
markerAttribs: function(point, state) {
|
17274
17498
|
var seriesMarkerOptions = this.options.marker,
|
17275
17499
|
seriesStateOptions,
|
17276
|
-
|
17277
|
-
pointMarkerOptions = (pointOptions && pointOptions.marker) || {},
|
17500
|
+
pointMarkerOptions = point.marker || {},
|
17278
17501
|
pointStateOptions,
|
17279
17502
|
radius = pick(
|
17280
17503
|
pointMarkerOptions.radius,
|
@@ -17426,6 +17649,7 @@
|
|
17426
17649
|
chart.hoverSeries = null;
|
17427
17650
|
}
|
17428
17651
|
erase(chart.series, series);
|
17652
|
+
chart.orderSeries();
|
17429
17653
|
|
17430
17654
|
// clear all members
|
17431
17655
|
for (prop in series) {
|
@@ -17756,14 +17980,11 @@
|
|
17756
17980
|
remover;
|
17757
17981
|
|
17758
17982
|
function setInvert() {
|
17759
|
-
var size = {
|
17760
|
-
width: series.yAxis.len,
|
17761
|
-
height: series.xAxis.len
|
17762
|
-
};
|
17763
|
-
|
17764
17983
|
each(['group', 'markerGroup'], function(groupName) {
|
17765
17984
|
if (series[groupName]) {
|
17766
|
-
series[groupName].
|
17985
|
+
series[groupName].width = series.yAxis.len;
|
17986
|
+
series[groupName].height = series.xAxis.len;
|
17987
|
+
series[groupName].invert(inverted);
|
17767
17988
|
}
|
17768
17989
|
});
|
17769
17990
|
}
|
@@ -17923,7 +18144,7 @@
|
|
17923
18144
|
}, animDuration);
|
17924
18145
|
}
|
17925
18146
|
|
17926
|
-
series.isDirty =
|
18147
|
+
series.isDirty = false; // means data is in accordance with what you see
|
17927
18148
|
// (See #322) series.isDirty = series.isDirtyData = false; // means data is in accordance with what you see
|
17928
18149
|
series.hasRendered = true;
|
17929
18150
|
},
|
@@ -17980,7 +18201,17 @@
|
|
17980
18201
|
}, compareX);
|
17981
18202
|
},
|
17982
18203
|
|
18204
|
+
/**
|
18205
|
+
* Build the k-d-tree that is used by mouse and touch interaction to get the
|
18206
|
+
* closest point. Line-like series typically have a one-dimensional tree
|
18207
|
+
* where points are searched along the X axis, while scatter-like series
|
18208
|
+
* typically search in two dimensions, X and Y.
|
18209
|
+
*/
|
17983
18210
|
buildKDTree: function() {
|
18211
|
+
|
18212
|
+
// Prevent multiple k-d-trees from being built simultaneously (#6235)
|
18213
|
+
this.buildingKdTree = true;
|
18214
|
+
|
17984
18215
|
var series = this,
|
17985
18216
|
dimensions = series.kdDimensions;
|
17986
18217
|
|
@@ -18021,6 +18252,7 @@
|
|
18021
18252
|
dimensions,
|
18022
18253
|
dimensions
|
18023
18254
|
);
|
18255
|
+
series.buildingKdTree = false;
|
18024
18256
|
}
|
18025
18257
|
delete series.kdTree;
|
18026
18258
|
|
@@ -18078,7 +18310,7 @@
|
|
18078
18310
|
return ret;
|
18079
18311
|
}
|
18080
18312
|
|
18081
|
-
if (!this.kdTree) {
|
18313
|
+
if (!this.kdTree && !this.buildingKdTree) {
|
18082
18314
|
this.buildKDTree();
|
18083
18315
|
}
|
18084
18316
|
|
@@ -18857,13 +19089,20 @@
|
|
18857
19089
|
merge(true, this.options.plotOptions, options.plotOptions);
|
18858
19090
|
}
|
18859
19091
|
|
18860
|
-
// Setters for collections. For axes and series, each item is referred
|
18861
|
-
// id is not found, it defaults to the
|
18862
|
-
//
|
19092
|
+
// Setters for collections. For axes and series, each item is referred
|
19093
|
+
// by an id. If the id is not found, it defaults to the corresponding
|
19094
|
+
// item in the collection, so setting one series without an id, will
|
19095
|
+
// update the first series in the chart. Setting two series without
|
19096
|
+
// an id will update the first and the second respectively (#6019)
|
19097
|
+
// // docs: New behaviour for unidentified items, add it to docs for
|
19098
|
+
// chart.update and responsive.
|
18863
19099
|
each(['xAxis', 'yAxis', 'series'], function(coll) {
|
18864
19100
|
if (options[coll]) {
|
18865
|
-
each(splat(options[coll]), function(newOptions) {
|
18866
|
-
var item = (
|
19101
|
+
each(splat(options[coll]), function(newOptions, i) {
|
19102
|
+
var item = (
|
19103
|
+
defined(newOptions.id) &&
|
19104
|
+
this.get(newOptions.id)
|
19105
|
+
) || this[coll][i];
|
18867
19106
|
if (item && item.coll === coll) {
|
18868
19107
|
item.update(newOptions, false);
|
18869
19108
|
}
|
@@ -19010,7 +19249,8 @@
|
|
19010
19249
|
seriesOptions = series.options,
|
19011
19250
|
data = series.data,
|
19012
19251
|
chart = series.chart,
|
19013
|
-
|
19252
|
+
xAxis = series.xAxis,
|
19253
|
+
names = xAxis && xAxis.hasNames && xAxis.names,
|
19014
19254
|
dataOptions = seriesOptions.data,
|
19015
19255
|
point,
|
19016
19256
|
isInTheMiddle,
|
@@ -19924,7 +20164,7 @@
|
|
19924
20164
|
),
|
19925
20165
|
groupPadding = categoryWidth * options.groupPadding,
|
19926
20166
|
groupWidth = categoryWidth - 2 * groupPadding,
|
19927
|
-
pointOffsetWidth = groupWidth / columnCount,
|
20167
|
+
pointOffsetWidth = groupWidth / (columnCount || 1),
|
19928
20168
|
pointWidth = Math.min(
|
19929
20169
|
options.maxPointWidth || xAxis.len,
|
19930
20170
|
pick(options.pointWidth, pointOffsetWidth * (1 - 2 * options.pointPadding))
|
@@ -20276,7 +20516,10 @@
|
|
20276
20516
|
enabled: true // Overrides auto-enabling in line series (#3647)
|
20277
20517
|
},
|
20278
20518
|
tooltip: {
|
20279
|
-
|
20519
|
+
|
20520
|
+
headerFormat: '<span style="color:{point.color}">\u25CF</span> ' +
|
20521
|
+
'<span style="font-size: 0.85em"> {series.name}</span><br/>',
|
20522
|
+
|
20280
20523
|
pointFormat: 'x: <b>{point.x}</b><br/>y: <b>{point.y}</b><br/>'
|
20281
20524
|
}
|
20282
20525
|
|
@@ -20969,7 +21212,6 @@
|
|
20969
21212
|
* Draw the data labels
|
20970
21213
|
*/
|
20971
21214
|
Series.prototype.drawDataLabels = function() {
|
20972
|
-
|
20973
21215
|
var series = this,
|
20974
21216
|
seriesOptions = series.options,
|
20975
21217
|
options = seriesOptions.dataLabels,
|
@@ -21018,7 +21260,6 @@
|
|
21018
21260
|
// Make the labels for each point
|
21019
21261
|
generalOptions = options;
|
21020
21262
|
each(points, function(point) {
|
21021
|
-
|
21022
21263
|
var enabled,
|
21023
21264
|
dataLabel = point.dataLabel,
|
21024
21265
|
labelConfig,
|
@@ -21026,130 +21267,97 @@
|
|
21026
21267
|
name,
|
21027
21268
|
rotation,
|
21028
21269
|
connector = point.connector,
|
21029
|
-
isNew =
|
21030
|
-
style
|
21031
|
-
moreStyle = {};
|
21032
|
-
|
21270
|
+
isNew = !dataLabel,
|
21271
|
+
style;
|
21033
21272
|
// Determine if each data label is enabled
|
21273
|
+
// @note dataLabelAttribs (like pointAttribs) would eradicate
|
21274
|
+
// the need for dlOptions, and simplify the section below.
|
21034
21275
|
pointOptions = point.dlOptions || (point.options && point.options.dataLabels); // dlOptions is used in treemaps
|
21035
21276
|
enabled = pick(pointOptions && pointOptions.enabled, generalOptions.enabled) && point.y !== null; // #2282, #4641
|
21036
|
-
|
21037
|
-
|
21038
|
-
// If the point is outside the plot area, destroy it. #678, #820
|
21039
|
-
if (dataLabel && !enabled) {
|
21040
|
-
point.dataLabel = dataLabel.destroy();
|
21041
|
-
|
21042
|
-
// Individual labels are disabled if the are explicitly disabled
|
21043
|
-
// in the point options, or if they fall outside the plot area.
|
21044
|
-
} else if (enabled) {
|
21045
|
-
|
21277
|
+
if (enabled) {
|
21046
21278
|
// Create individual options structure that can be extended without
|
21047
21279
|
// affecting others
|
21048
21280
|
options = merge(generalOptions, pointOptions);
|
21049
|
-
style = options.style;
|
21050
|
-
|
21051
|
-
rotation = options.rotation;
|
21052
|
-
|
21053
|
-
// Get the string
|
21054
21281
|
labelConfig = point.getLabelConfig();
|
21055
21282
|
str = options.format ?
|
21056
21283
|
format(options.format, labelConfig) :
|
21057
21284
|
options.formatter.call(labelConfig, options);
|
21058
|
-
|
21285
|
+
style = options.style;
|
21286
|
+
rotation = options.rotation;
|
21059
21287
|
|
21060
21288
|
// Determine the color
|
21061
21289
|
style.color = pick(options.color, style.color, series.color, '#000000');
|
21290
|
+
// Get automated contrast color
|
21291
|
+
if (style.color === 'contrast') {
|
21292
|
+
style.color = options.inside || options.distance < 0 || !!seriesOptions.stacking ?
|
21293
|
+
renderer.getContrast(point.color || series.color) :
|
21294
|
+
'#000000';
|
21295
|
+
}
|
21296
|
+
if (seriesOptions.cursor) {
|
21297
|
+
style.cursor = seriesOptions.cursor;
|
21298
|
+
}
|
21062
21299
|
|
21063
21300
|
|
21064
|
-
|
21065
|
-
|
21066
|
-
|
21067
|
-
if (defined(str)) {
|
21068
|
-
dataLabel
|
21069
|
-
.attr({
|
21070
|
-
text: str
|
21071
|
-
});
|
21072
|
-
isNew = false;
|
21073
|
-
|
21074
|
-
} else { // #1437 - the label is shown conditionally
|
21075
|
-
point.dataLabel = dataLabel = dataLabel.destroy();
|
21076
|
-
if (connector) {
|
21077
|
-
point.connector = connector.destroy();
|
21078
|
-
}
|
21079
|
-
}
|
21080
|
-
|
21081
|
-
// create new label
|
21082
|
-
} else if (defined(str)) {
|
21083
|
-
attr = {
|
21084
|
-
//align: align,
|
21085
|
-
|
21086
|
-
fill: options.backgroundColor,
|
21087
|
-
stroke: options.borderColor,
|
21088
|
-
'stroke-width': options.borderWidth,
|
21089
|
-
|
21090
|
-
r: options.borderRadius || 0,
|
21091
|
-
rotation: rotation,
|
21092
|
-
padding: options.padding,
|
21093
|
-
zIndex: 1
|
21094
|
-
};
|
21095
|
-
|
21096
|
-
|
21097
|
-
// Get automated contrast color
|
21098
|
-
if (style.color === 'contrast') {
|
21099
|
-
moreStyle.color = options.inside || options.distance < 0 || !!seriesOptions.stacking ?
|
21100
|
-
renderer.getContrast(point.color || series.color) :
|
21101
|
-
'#000000';
|
21102
|
-
}
|
21103
|
-
|
21104
|
-
if (seriesOptions.cursor) {
|
21105
|
-
moreStyle.cursor = seriesOptions.cursor;
|
21106
|
-
}
|
21301
|
+
attr = {
|
21302
|
+
//align: align,
|
21107
21303
|
|
21304
|
+
fill: options.backgroundColor,
|
21305
|
+
stroke: options.borderColor,
|
21306
|
+
'stroke-width': options.borderWidth,
|
21108
21307
|
|
21308
|
+
r: options.borderRadius || 0,
|
21309
|
+
rotation: rotation,
|
21310
|
+
padding: options.padding,
|
21311
|
+
zIndex: 1
|
21312
|
+
};
|
21109
21313
|
|
21110
|
-
|
21111
|
-
|
21112
|
-
|
21113
|
-
|
21114
|
-
}
|
21314
|
+
// Remove unused attributes (#947)
|
21315
|
+
for (name in attr) {
|
21316
|
+
if (attr[name] === undefined) {
|
21317
|
+
delete attr[name];
|
21115
21318
|
}
|
21116
|
-
|
21319
|
+
}
|
21320
|
+
}
|
21321
|
+
// If the point is outside the plot area, destroy it. #678, #820
|
21322
|
+
if (dataLabel && (!enabled || !defined(str))) {
|
21323
|
+
point.dataLabel = dataLabel = dataLabel.destroy();
|
21324
|
+
if (connector) {
|
21325
|
+
point.connector = connector.destroy();
|
21326
|
+
}
|
21327
|
+
// Individual labels are disabled if the are explicitly disabled
|
21328
|
+
// in the point options, or if they fall outside the plot area.
|
21329
|
+
} else if (enabled && defined(str)) {
|
21330
|
+
// create new label
|
21331
|
+
if (!dataLabel) {
|
21117
21332
|
dataLabel = point.dataLabel = renderer[rotation ? 'text' : 'label']( // labels don't support rotation
|
21118
|
-
|
21119
|
-
|
21120
|
-
|
21121
|
-
|
21122
|
-
|
21123
|
-
|
21124
|
-
|
21125
|
-
|
21126
|
-
|
21127
|
-
.attr(attr);
|
21128
|
-
|
21333
|
+
str,
|
21334
|
+
0, -9999,
|
21335
|
+
options.shape,
|
21336
|
+
null,
|
21337
|
+
null,
|
21338
|
+
options.useHTML,
|
21339
|
+
null,
|
21340
|
+
'data-label'
|
21341
|
+
);
|
21129
21342
|
dataLabel.addClass(
|
21130
21343
|
'highcharts-data-label-color-' + point.colorIndex +
|
21131
21344
|
' ' + (options.className || '') +
|
21132
21345
|
(options.useHTML ? 'highcharts-tracker' : '') // #3398
|
21133
21346
|
);
|
21347
|
+
} else {
|
21348
|
+
attr.text = str;
|
21349
|
+
}
|
21350
|
+
dataLabel.attr(attr);
|
21134
21351
|
|
21135
|
-
|
21136
|
-
|
21137
|
-
dataLabel.css(extend(style, moreStyle));
|
21352
|
+
// Styles must be applied before add in order to read text bounding box
|
21353
|
+
dataLabel.css(style).shadow(options.shadow);
|
21138
21354
|
|
21139
21355
|
|
21356
|
+
if (!dataLabel.added) {
|
21140
21357
|
dataLabel.add(dataLabelsGroup);
|
21141
|
-
|
21142
|
-
|
21143
|
-
dataLabel.shadow(options.shadow);
|
21144
|
-
|
21145
|
-
|
21146
|
-
|
21147
|
-
}
|
21148
|
-
|
21149
|
-
if (dataLabel) {
|
21150
|
-
// Now the data label is created and placed at 0,0, so we need to align it
|
21151
|
-
series.alignDataLabel(point, dataLabel, options, null, isNew);
|
21152
21358
|
}
|
21359
|
+
// Now the data label is created and placed at 0,0, so we need to align it
|
21360
|
+
series.alignDataLabel(point, dataLabel, options, null, isNew);
|
21153
21361
|
}
|
21154
21362
|
});
|
21155
21363
|
}
|
@@ -22918,27 +23126,37 @@
|
|
22918
23126
|
* Recurse over a set of options and its current values,
|
22919
23127
|
* and store the current values in the ret object.
|
22920
23128
|
*/
|
22921
|
-
function getCurrent(options, curr, ret) {
|
23129
|
+
function getCurrent(options, curr, ret, depth) {
|
22922
23130
|
var key, i;
|
22923
23131
|
for (key in options) {
|
22924
|
-
if (inArray(key, ['series', 'xAxis', 'yAxis']) > -1) {
|
23132
|
+
if (!depth && inArray(key, ['series', 'xAxis', 'yAxis']) > -1) {
|
22925
23133
|
options[key] = splat(options[key]);
|
22926
23134
|
|
22927
23135
|
ret[key] = [];
|
22928
23136
|
for (i = 0; i < options[key].length; i++) {
|
22929
23137
|
ret[key][i] = {};
|
22930
|
-
getCurrent(
|
23138
|
+
getCurrent(
|
23139
|
+
options[key][i],
|
23140
|
+
curr[key][i],
|
23141
|
+
ret[key][i],
|
23142
|
+
depth + 1
|
23143
|
+
);
|
22931
23144
|
}
|
22932
23145
|
} else if (isObject(options[key])) {
|
22933
23146
|
ret[key] = {};
|
22934
|
-
getCurrent(
|
23147
|
+
getCurrent(
|
23148
|
+
options[key],
|
23149
|
+
curr[key] || {},
|
23150
|
+
ret[key],
|
23151
|
+
depth + 1
|
23152
|
+
);
|
22935
23153
|
} else {
|
22936
23154
|
ret[key] = curr[key] || null;
|
22937
23155
|
}
|
22938
23156
|
}
|
22939
23157
|
}
|
22940
23158
|
|
22941
|
-
getCurrent(options, this.options, ret);
|
23159
|
+
getCurrent(options, this.options, ret, 0);
|
22942
23160
|
return ret;
|
22943
23161
|
};
|
22944
23162
|
|