highcharts-rails 5.0.6 → 5.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
|