highcharts-rails 4.1.5 → 4.1.6
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 +47 -0
- data/Rakefile +0 -34
- data/app/assets/javascripts/highcharts.js +262 -241
- data/app/assets/javascripts/highcharts/adapters/standalone-framework.js +1 -1
- data/app/assets/javascripts/highcharts/highcharts-3d.js +258 -76
- data/app/assets/javascripts/highcharts/highcharts-more.js +19 -10
- data/app/assets/javascripts/highcharts/modules/broken-axis.js +8 -6
- data/app/assets/javascripts/highcharts/modules/canvas-tools.js +4 -4
- data/app/assets/javascripts/highcharts/modules/data.js +1 -1
- data/app/assets/javascripts/highcharts/modules/exporting.js +1 -1
- data/app/assets/javascripts/highcharts/modules/heatmap.js +22 -2
- data/app/assets/javascripts/highcharts/modules/no-data-to-display.js +1 -1
- data/app/assets/javascripts/highcharts/modules/solid-gauge.js +3 -3
- data/app/assets/javascripts/highcharts/modules/treemap.js +137 -132
- data/lib/highcharts/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 20d000bd52b08e8dd4a7376d96a3a9f76e41276a
|
4
|
+
data.tar.gz: ef3d6781527923bce73e358926c4befc2e85d4eb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2a94fc86214d938de0f8cab679f489978cc6ff272656dd7c2172f62dcf192b92ceea747f39e427519b11da95487807f6d3323ba3813b28107e15a9246846d4a3
|
7
|
+
data.tar.gz: e9c7523d2c44dba8d99512eaabc532b8c977b5a3d1633ca05449fa57c75b19c52b361a65ea8cf90972ab2c81acba8c9e5d4b74db3ae53c3b8b3b9d7c5e8e9c9f
|
data/CHANGELOG.markdown
CHANGED
@@ -1,3 +1,50 @@
|
|
1
|
+
# 4.1.6 / 2015-08-31
|
2
|
+
|
3
|
+
* Updated Highcharts to 4.1.6 (2015-06-12)
|
4
|
+
* Added new option, series.getExtremesFromAll, that tells the y axis to be scaled to the whole series range, not only the visible part.
|
5
|
+
* Added scaling support for Z axis on 3D charts.
|
6
|
+
* Added xAxis.title.x and xAxis.title.y options for positioning.
|
7
|
+
* Fixed #4160, 3D should be disabled for inverted charts
|
8
|
+
* Fixed #4160, 3D should be disabled for inverted charts.
|
9
|
+
* Fixed #1457, columnrange did not render with reversed Y axis.
|
10
|
+
* Fixed #182, browser hangs when updating chart from series mouseOut event.
|
11
|
+
* Fixed #2077, innerSize of pies was not correct when size was dynamic.
|
12
|
+
* Fixed #2088, crosshair shown on multiple axes.
|
13
|
+
* Fixed #3923, crash in Chrome when extending a dashed line to extreme length.
|
14
|
+
* Fixed #3974, duplicated data labels on Retina displays when text-shadow is applied.
|
15
|
+
* Fixed #3977, tooltip content sometimes displayed outside tooltip.
|
16
|
+
* Fixed #4069, slow updating of multiple pie slices.
|
17
|
+
* Fixed #4108, line wrap dataLabels in tree maps.
|
18
|
+
* Fixed #4116, cannot disable tooltip on polar chart.
|
19
|
+
* Fixed #4117, broken tooltips in pie charts when useHTML was enabled.
|
20
|
+
* Fixed #4124, treemap click on legend item returned error.
|
21
|
+
* Fixed #4128, tooltip only looked at X value for line series
|
22
|
+
* Fixed #4146, point marker stayed after updating point to null when connectNulls was true.
|
23
|
+
* Fixed #4161, a regression causing wrong position of tooltip in top row of heatmap.
|
24
|
+
* Fixed #4163, tooltip broken on pie in combo chart.
|
25
|
+
* Fixed #4166, resetting point state was coupled to tooltip, resulting in state not reset when the tooltip was empty.
|
26
|
+
* Fixed #4167, chart crashed on Y axis breaks in stock chart.
|
27
|
+
* Fixed #4177, X axis label ellipsis overlapped when in the middle of the axis.
|
28
|
+
* Fixed #4197, ignoreHiddenPoint didn't work.
|
29
|
+
* Fixed #4200, unresponsive tooltip on tight column chart with shared tooltip.
|
30
|
+
* Fixed #4201, redundant tick alignment to empty axes.
|
31
|
+
* Fixed #4203, radial gradient rendered wrong in 3D Pies
|
32
|
+
* Fixed #4208, click events did not bubble.
|
33
|
+
* Fixed #4210, touch scroll was trapped when zoomType enabled.
|
34
|
+
* Fixed #4217, tickInterval on linked axis did not follow that of parent.
|
35
|
+
* Fixed #4221, negative color and zones not working with logarithmic axis.
|
36
|
+
* Fixed #4223, tooltips showed year when data resolution was less than 1 millisecond.
|
37
|
+
* Fixed #4247, X zooming within an Y axis break resulted in empty chart.
|
38
|
+
* Fixed #4256, summary columns on waterfall, including data labels, extended below the plot area if an Y axis minimum was set.
|
39
|
+
* Fixed #4261, added namespace to drillToNode on click event in tree maps.
|
40
|
+
* Fixed #4264, column in stacked chart was mispositioned in some cases.
|
41
|
+
* Fixed issue with wrong data label being hidden on overlap in columns.
|
42
|
+
* Fixed issues with ellipsis on first and last label on X axis. Closes #3975.
|
43
|
+
* Export: Added missing treemaps.js, fixes #4092.
|
44
|
+
* Export: Added support for Map constructor.
|
45
|
+
* Export: Added treemaps for serverside rendering.
|
46
|
+
* Export: Enable loading of maps.js.
|
47
|
+
|
1
48
|
# 4.1.5 / 2015-04-13
|
2
49
|
|
3
50
|
* Updated Highcharts to 4.1.5
|
data/Rakefile
CHANGED
@@ -1,35 +1 @@
|
|
1
1
|
require 'bundler/gem_tasks'
|
2
|
-
|
3
|
-
desc "Update to the latest version of Highcharts"
|
4
|
-
task :update, :version do |t, args|
|
5
|
-
version = args[:version]
|
6
|
-
url = "http://code.highcharts.com/zips/Highcharts-#{version}.zip"
|
7
|
-
puts "Fetching #{url}"
|
8
|
-
`curl -# #{url} -o tmp/#{version}.zip`
|
9
|
-
`unzip tmp/#{version}.zip -d tmp/#{version}`
|
10
|
-
|
11
|
-
mappings = {
|
12
|
-
"highcharts.src.js" => "highcharts.js",
|
13
|
-
"highcharts-more.src.js" => "highcharts/highcharts-more.js",
|
14
|
-
"highcharts-3d.src.js" => "highcharts/highcharts-3d.js",
|
15
|
-
"standalone-framework.src.js" => "highcharts/adapters/standalone-framework.js",
|
16
|
-
"annotations.src.js" => "highcharts/modules/annotations.js",
|
17
|
-
"canvas-tools.src.js" => "highcharts/modules/canvas-tools.js",
|
18
|
-
"data.src.js" => "highcharts/modules/data.js",
|
19
|
-
"drilldown.src.js" => "highcharts/modules/drilldown.js",
|
20
|
-
"exporting.src.js" => "highcharts/modules/exporting.js",
|
21
|
-
"funnel.src.js" => "highcharts/modules/funnel.js",
|
22
|
-
"heatmap.src.js" => "highcharts/modules/heatmap.js",
|
23
|
-
"no-data-to-display.src.js" => "highcharts/modules/no-data-to-display.js",
|
24
|
-
"solid-gauge.src.js" => "highcharts/modules/solid-gauge.js",
|
25
|
-
"treemap.src.js" => "highcharts/modules/treemap.js",
|
26
|
-
"broken-axis.src.js" => "highcharts/modules/broken-axis.js",
|
27
|
-
}
|
28
|
-
dest = "app/assets/javascripts/"
|
29
|
-
Dir.glob("tmp/#{version}/js/**/*.src.js").each do |file|
|
30
|
-
name = File.basename(file)
|
31
|
-
FileUtils.cp file, "#{dest}#{mappings[name]}", verbose: true
|
32
|
-
end
|
33
|
-
FileUtils.cp Dir.glob("tmp/#{version}/js/themes/*.js"), "#{dest}highcharts/themes/", verbose: true
|
34
|
-
FileUtils.cp Dir.glob("tmp/#{version}/graphics/*.png"), "app/assets/images/highcharts", verbose: true
|
35
|
-
end
|
@@ -2,7 +2,7 @@
|
|
2
2
|
// @compilation_level SIMPLE_OPTIMIZATIONS
|
3
3
|
|
4
4
|
/**
|
5
|
-
* @license Highcharts JS v4.1.
|
5
|
+
* @license Highcharts JS v4.1.6 (2015-06-12)
|
6
6
|
*
|
7
7
|
* (c) 2009-2014 Torstein Honsi
|
8
8
|
*
|
@@ -56,7 +56,7 @@ var UNDEFINED,
|
|
56
56
|
charts = [],
|
57
57
|
chartCount = 0,
|
58
58
|
PRODUCT = 'Highcharts',
|
59
|
-
VERSION = '4.1.
|
59
|
+
VERSION = '4.1.6',
|
60
60
|
|
61
61
|
// some constants for frequently used strings
|
62
62
|
DIV = 'div',
|
@@ -368,6 +368,13 @@ function pad(number, length) {
|
|
368
368
|
return new Array((length || 2) + 1 - String(number).length).join(0) + number;
|
369
369
|
}
|
370
370
|
|
371
|
+
/**
|
372
|
+
* Return a length based on either the integer value, or a percentage of a base.
|
373
|
+
*/
|
374
|
+
function relativeLength (value, base) {
|
375
|
+
return (/%$/).test(value) ? base * parseFloat(value) / 100 : parseFloat(value);
|
376
|
+
}
|
377
|
+
|
371
378
|
/**
|
372
379
|
* Wrap a method with extended functionality, preserving the original function
|
373
380
|
* @param {Object} obj The context object that the method belongs to
|
@@ -1261,8 +1268,8 @@ defaultOptions = {
|
|
1261
1268
|
global: {
|
1262
1269
|
useUTC: true,
|
1263
1270
|
//timezoneOffset: 0,
|
1264
|
-
canvasToolsURL: 'http://code.highcharts.com/4.1.
|
1265
|
-
VMLRadialGradientURL: 'http://code.highcharts.com/4.1.
|
1271
|
+
canvasToolsURL: 'http://code.highcharts.com/4.1.6/modules/canvas-tools.js',
|
1272
|
+
VMLRadialGradientURL: 'http://code.highcharts.com/4.1.6/gfx/vml-radial-gradient.png'
|
1266
1273
|
},
|
1267
1274
|
chart: {
|
1268
1275
|
//animation: true,
|
@@ -1944,13 +1951,20 @@ SVGElement.prototype = {
|
|
1944
1951
|
var elem = this.element,
|
1945
1952
|
tspans,
|
1946
1953
|
hasContrast = textShadow.indexOf('contrast') !== -1,
|
1954
|
+
styles = {},
|
1947
1955
|
// IE10 and IE11 report textShadow in elem.style even though it doesn't work. Check
|
1948
1956
|
// this again with new IE release. In exports, the rendering is passed to PhantomJS.
|
1949
1957
|
supports = this.renderer.forExport || (elem.style.textShadow !== UNDEFINED && !isIE);
|
1950
1958
|
|
1951
1959
|
// When the text shadow is set to contrast, use dark stroke for light text and vice versa
|
1952
1960
|
if (hasContrast) {
|
1953
|
-
textShadow = textShadow.replace(/contrast/g, this.renderer.getContrast(elem.style.fill));
|
1961
|
+
styles.textShadow = textShadow = textShadow.replace(/contrast/g, this.renderer.getContrast(elem.style.fill));
|
1962
|
+
}
|
1963
|
+
|
1964
|
+
// Safari with retina displays as well as PhantomJS bug (#3974). Firefox does not tolerate this,
|
1965
|
+
// it removes the text shadows.
|
1966
|
+
if (isWebKit) {
|
1967
|
+
styles.textRendering = 'geometricPrecision';
|
1954
1968
|
}
|
1955
1969
|
|
1956
1970
|
/* Selective side-by-side testing in supported browser (http://jsfiddle.net/highcharts/73L1ptrh/)
|
@@ -1962,11 +1976,7 @@ SVGElement.prototype = {
|
|
1962
1976
|
|
1963
1977
|
// No reason to polyfill, we've got native support
|
1964
1978
|
if (supports) {
|
1965
|
-
|
1966
|
-
css(elem, {
|
1967
|
-
textShadow: textShadow
|
1968
|
-
});
|
1969
|
-
}
|
1979
|
+
css(elem, styles); // Apply altered textShadow or textRendering workaround
|
1970
1980
|
} else {
|
1971
1981
|
|
1972
1982
|
this.fakeTS = true; // Fake text shadow
|
@@ -3269,7 +3279,7 @@ SVGRenderer.prototype = {
|
|
3269
3279
|
wasTooLong = true;
|
3270
3280
|
}
|
3271
3281
|
wordStr = span.substring(0, wordStr.length + (tooLong ? -1 : 1) * mathCeil(cursor));
|
3272
|
-
words = [wordStr + '\u2026'];
|
3282
|
+
words = [wordStr + (width > 3 ? '\u2026' : '')];
|
3273
3283
|
tspan.removeChild(tspan.firstChild);
|
3274
3284
|
}
|
3275
3285
|
|
@@ -3365,7 +3375,7 @@ SVGRenderer.prototype = {
|
|
3365
3375
|
*/
|
3366
3376
|
getContrast: function (color) {
|
3367
3377
|
color = Color(color).rgba;
|
3368
|
-
return color[0] + color[1] + color[2] > 384 ? '#
|
3378
|
+
return color[0] + color[1] + color[2] > 384 ? '#000000' : '#FFFFFF';
|
3369
3379
|
},
|
3370
3380
|
|
3371
3381
|
/**
|
@@ -3889,11 +3899,8 @@ SVGRenderer.prototype = {
|
|
3889
3899
|
safeDistance = r + halfDistance,
|
3890
3900
|
anchorX = options && options.anchorX,
|
3891
3901
|
anchorY = options && options.anchorY,
|
3892
|
-
path
|
3893
|
-
normalizer = mathRound(options.strokeWidth || 0) % 2 / 2; // mathRound because strokeWidth can sometimes have roundoff errors;
|
3902
|
+
path;
|
3894
3903
|
|
3895
|
-
x += normalizer;
|
3896
|
-
y += normalizer;
|
3897
3904
|
path = [
|
3898
3905
|
'M', x + r, y,
|
3899
3906
|
'L', x + w - r, y, // top side
|
@@ -4121,8 +4128,8 @@ SVGRenderer.prototype = {
|
|
4121
4128
|
|
4122
4129
|
// create the border box if it is not already present
|
4123
4130
|
if (!box) {
|
4124
|
-
boxX = mathRound(-alignFactor * padding);
|
4125
|
-
boxY = baseline ? -baselineOffset : 0;
|
4131
|
+
boxX = mathRound(-alignFactor * padding) + crispAdjust;
|
4132
|
+
boxY = (baseline ? -baselineOffset : 0) + crispAdjust;
|
4126
4133
|
|
4127
4134
|
wrapper.box = box = shape ?
|
4128
4135
|
renderer.symbol(shape, boxX, boxY, wrapper.width, wrapper.height, deferredAttr) :
|
@@ -4162,11 +4169,7 @@ SVGRenderer.prototype = {
|
|
4162
4169
|
if (x !== text.x || y !== text.y) {
|
4163
4170
|
text.attr('x', x);
|
4164
4171
|
if (y !== UNDEFINED) {
|
4165
|
-
|
4166
|
-
// is a rendering bug in WebKit for Retina (Mac, iOS, PhantomJS) that
|
4167
|
-
// results in duplicated text when an y attribute is used in combination
|
4168
|
-
// with a CSS text-style.
|
4169
|
-
text.attr(text.element.nodeName === 'SPAN' ? 'y' : 'translateY', y);
|
4172
|
+
text.attr('y', y);
|
4170
4173
|
}
|
4171
4174
|
}
|
4172
4175
|
|
@@ -4263,7 +4266,7 @@ SVGRenderer.prototype = {
|
|
4263
4266
|
};
|
4264
4267
|
wrapper.anchorXSetter = function (value, key) {
|
4265
4268
|
anchorX = value;
|
4266
|
-
boxAttr(key, value
|
4269
|
+
boxAttr(key, mathRound(value) - crispAdjust - wrapperX);
|
4267
4270
|
};
|
4268
4271
|
wrapper.anchorYSetter = function (value, key) {
|
4269
4272
|
anchorY = value;
|
@@ -5896,6 +5899,8 @@ Tick.prototype = {
|
|
5896
5899
|
factor = { left: 0, center: 0.5, right: 1 }[axis.labelAlign],
|
5897
5900
|
labelWidth = label.getBBox().width,
|
5898
5901
|
slotWidth = axis.slotWidth,
|
5902
|
+
xCorrection = factor,
|
5903
|
+
goRight = 1,
|
5899
5904
|
leftPos,
|
5900
5905
|
rightPos,
|
5901
5906
|
textWidth;
|
@@ -5904,25 +5909,25 @@ Tick.prototype = {
|
|
5904
5909
|
// If it now overshoots the slotWidth, add ellipsis.
|
5905
5910
|
if (!rotation) {
|
5906
5911
|
leftPos = pxPos - factor * labelWidth;
|
5907
|
-
rightPos = pxPos + factor * labelWidth;
|
5912
|
+
rightPos = pxPos + (1 - factor) * labelWidth;
|
5908
5913
|
|
5909
5914
|
if (leftPos < leftBound) {
|
5910
|
-
slotWidth
|
5911
|
-
xy.x = leftBound;
|
5912
|
-
label.attr({ align: 'left' });
|
5915
|
+
slotWidth = xy.x + slotWidth * (1 - factor) - leftBound;
|
5913
5916
|
} else if (rightPos > rightBound) {
|
5914
|
-
slotWidth
|
5915
|
-
|
5916
|
-
label.attr({ align: 'right' });
|
5917
|
+
slotWidth = rightBound - xy.x + slotWidth * factor;
|
5918
|
+
goRight = -1;
|
5917
5919
|
}
|
5918
5920
|
|
5921
|
+
slotWidth = mathMin(axis.slotWidth, slotWidth); // #4177
|
5922
|
+
if (slotWidth < axis.slotWidth && axis.labelAlign === 'center') {
|
5923
|
+
xy.x += goRight * (axis.slotWidth - slotWidth - xCorrection * (axis.slotWidth - mathMin(labelWidth, slotWidth)));
|
5924
|
+
}
|
5919
5925
|
// If the label width exceeds the available space, set a text width to be
|
5920
5926
|
// picked up below. Also, if a width has been set before, we need to set a new
|
5921
5927
|
// one because the reported labelWidth will be limited by the box (#3938).
|
5922
5928
|
if (labelWidth > slotWidth || (axis.autoRotation && label.styles.width)) {
|
5923
5929
|
textWidth = slotWidth;
|
5924
5930
|
}
|
5925
|
-
|
5926
5931
|
|
5927
5932
|
// Add ellipsis to prevent rotated labels to be clipped against the edge of the chart
|
5928
5933
|
} else if (rotation < 0 && pxPos - factor * labelWidth < leftBound) {
|
@@ -6909,7 +6914,7 @@ Axis.prototype = {
|
|
6909
6914
|
*
|
6910
6915
|
*/
|
6911
6916
|
translate: function (val, backwards, cvsCoord, old, handleLog, pointPlacement) {
|
6912
|
-
var axis = this,
|
6917
|
+
var axis = this.linkedParent || this, // #1417
|
6913
6918
|
sign = 1,
|
6914
6919
|
cvsOffset = 0,
|
6915
6920
|
localA = old ? axis.oldTransA : axis.transA,
|
@@ -7371,7 +7376,7 @@ Axis.prototype = {
|
|
7371
7376
|
axis.tickInterval = 1;
|
7372
7377
|
} else if (isLinked && !tickIntervalOption &&
|
7373
7378
|
tickPixelIntervalOption === axis.linkedParent.options.tickPixelInterval) {
|
7374
|
-
axis.tickInterval = axis.linkedParent.tickInterval;
|
7379
|
+
axis.tickInterval = tickIntervalOption = axis.linkedParent.tickInterval;
|
7375
7380
|
} else {
|
7376
7381
|
axis.tickInterval = pick(
|
7377
7382
|
tickIntervalOption,
|
@@ -7416,20 +7421,18 @@ Axis.prototype = {
|
|
7416
7421
|
}
|
7417
7422
|
|
7418
7423
|
// for linear axes, get magnitude and normalize the interval
|
7419
|
-
if (!isDatetimeAxis && !isLog) {
|
7420
|
-
|
7421
|
-
axis.tickInterval
|
7422
|
-
|
7423
|
-
|
7424
|
-
|
7425
|
-
|
7426
|
-
|
7427
|
-
|
7428
|
-
|
7429
|
-
);
|
7430
|
-
}
|
7424
|
+
if (!isDatetimeAxis && !isLog && !tickIntervalOption) {
|
7425
|
+
axis.tickInterval = normalizeTickInterval(
|
7426
|
+
axis.tickInterval,
|
7427
|
+
null,
|
7428
|
+
getMagnitude(axis.tickInterval),
|
7429
|
+
// If the tick interval is between 0.5 and 5 and the axis max is in the order of
|
7430
|
+
// thousands, chances are we are dealing with years. Don't allow decimals. #3363.
|
7431
|
+
pick(options.allowDecimals, !(axis.tickInterval > 0.5 && axis.tickInterval < 5 && axis.max > 1000 && axis.max < 9999)),
|
7432
|
+
!!this.tickAmount
|
7433
|
+
);
|
7431
7434
|
}
|
7432
|
-
|
7435
|
+
|
7433
7436
|
// Prevent ticks from getting so close that we can't draw the labels
|
7434
7437
|
if (!this.tickAmount && this.len) { // Color axis with disabled legend has no length
|
7435
7438
|
axis.tickInterval = axis.unsquish();
|
@@ -7461,7 +7464,7 @@ Axis.prototype = {
|
|
7461
7464
|
this.tickInterval / 5 : options.minorTickInterval;
|
7462
7465
|
|
7463
7466
|
// Find the tick positions
|
7464
|
-
this.tickPositions = tickPositions =
|
7467
|
+
this.tickPositions = tickPositions = tickPositionsOption && tickPositionsOption.slice(); // Work on a copy (#1565)
|
7465
7468
|
if (!tickPositions) {
|
7466
7469
|
|
7467
7470
|
if (this.isDatetimeAxis) {
|
@@ -7563,7 +7566,9 @@ Axis.prototype = {
|
|
7563
7566
|
key = [horiz ? options.left : options.top, horiz ? options.width : options.height, options.pane].join(',');
|
7564
7567
|
|
7565
7568
|
if (others[key]) {
|
7566
|
-
|
7569
|
+
if (axis.series.length) {
|
7570
|
+
hasOther = true; // #4201
|
7571
|
+
}
|
7567
7572
|
} else {
|
7568
7573
|
others[key] = 1;
|
7569
7574
|
}
|
@@ -7939,8 +7944,9 @@ Axis.prototype = {
|
|
7939
7944
|
labelOptions = this.options.labels,
|
7940
7945
|
horiz = this.horiz,
|
7941
7946
|
margin = chart.margin,
|
7947
|
+
slotCount = this.categories ? tickPositions.length : tickPositions.length - 1,
|
7942
7948
|
slotWidth = this.slotWidth = (horiz && !labelOptions.step && !labelOptions.rotation &&
|
7943
|
-
((this.staggerLines || 1) * chart.plotWidth) /
|
7949
|
+
((this.staggerLines || 1) * chart.plotWidth) / slotCount) ||
|
7944
7950
|
(!horiz && ((margin[3] && (margin[3] - chart.spacing[3])) || chart.chartWidth * 0.33)), // #1580, #1931,
|
7945
7951
|
innerWidth = mathMax(1, mathRound(slotWidth - 2 * (labelOptions.padding || 5))),
|
7946
7952
|
attr = {},
|
@@ -8208,6 +8214,8 @@ Axis.prototype = {
|
|
8208
8214
|
margin = horiz ? axisLeft : axisTop,
|
8209
8215
|
opposite = this.opposite,
|
8210
8216
|
offset = this.offset,
|
8217
|
+
xOption = axisTitleOptions.x || 0,
|
8218
|
+
yOption = axisTitleOptions.y || 0,
|
8211
8219
|
fontSize = pInt(axisTitleOptions.style.fontSize || 12),
|
8212
8220
|
|
8213
8221
|
// the position in the length direction of the axis
|
@@ -8226,12 +8234,11 @@ Axis.prototype = {
|
|
8226
8234
|
|
8227
8235
|
return {
|
8228
8236
|
x: horiz ?
|
8229
|
-
alongAxis :
|
8230
|
-
offAxis + (opposite ? this.width : 0) + offset +
|
8231
|
-
(axisTitleOptions.x || 0), // x
|
8237
|
+
alongAxis + xOption :
|
8238
|
+
offAxis + (opposite ? this.width : 0) + offset + xOption,
|
8232
8239
|
y: horiz ?
|
8233
|
-
offAxis - (opposite ? this.height : 0) + offset :
|
8234
|
-
alongAxis +
|
8240
|
+
offAxis + yOption - (opposite ? this.height : 0) + offset :
|
8241
|
+
alongAxis + yOption
|
8235
8242
|
};
|
8236
8243
|
},
|
8237
8244
|
|
@@ -8511,7 +8518,9 @@ Axis.prototype = {
|
|
8511
8518
|
// Disabled in options
|
8512
8519
|
!this.crosshair ||
|
8513
8520
|
// Snap
|
8514
|
-
((defined(point) || !pick(this.crosshair.snap, true)) === false)
|
8521
|
+
((defined(point) || !pick(this.crosshair.snap, true)) === false) ||
|
8522
|
+
// Not on this axis (#4095, #2888)
|
8523
|
+
(point && point.series && point.series[this.coll] !== this)
|
8515
8524
|
) {
|
8516
8525
|
this.hideCrosshair();
|
8517
8526
|
|
@@ -9000,16 +9009,6 @@ Tooltip.prototype = {
|
|
9000
9009
|
tooltip.label.fadeOut();
|
9001
9010
|
tooltip.isHidden = true;
|
9002
9011
|
}, pick(delay, this.options.hideDelay, 500));
|
9003
|
-
|
9004
|
-
// hide previous hoverPoints and set new
|
9005
|
-
if (hoverPoints) {
|
9006
|
-
each(hoverPoints, function (point) {
|
9007
|
-
point.setState();
|
9008
|
-
});
|
9009
|
-
}
|
9010
|
-
|
9011
|
-
this.chart.hoverPoints = null;
|
9012
|
-
this.chart.hoverSeries = null;
|
9013
9012
|
}
|
9014
9013
|
},
|
9015
9014
|
|
@@ -9076,7 +9075,7 @@ Tooltip.prototype = {
|
|
9076
9075
|
var chart = this.chart,
|
9077
9076
|
distance = this.distance,
|
9078
9077
|
ret = {},
|
9079
|
-
h = point.h,
|
9078
|
+
h = point.h || 0, // #4117
|
9080
9079
|
swapped,
|
9081
9080
|
first = ['y', chart.chartHeight, boxHeight, point.plotY + chart.plotTop],
|
9082
9081
|
second = ['x', chart.chartWidth, boxWidth, point.plotX + chart.plotLeft],
|
@@ -9270,7 +9269,7 @@ Tooltip.prototype = {
|
|
9270
9269
|
plotY: y,
|
9271
9270
|
negative: point.negative,
|
9272
9271
|
ttBelow: point.ttBelow,
|
9273
|
-
h:
|
9272
|
+
h: anchor[2] || 0
|
9274
9273
|
});
|
9275
9274
|
|
9276
9275
|
this.isHidden = false;
|
@@ -9299,7 +9298,7 @@ Tooltip.prototype = {
|
|
9299
9298
|
// do the move
|
9300
9299
|
this.move(
|
9301
9300
|
mathRound(pos.x),
|
9302
|
-
mathRound(pos.y),
|
9301
|
+
mathRound(pos.y || 0), // can be undefined (#3977)
|
9303
9302
|
point.plotX + chart.plotLeft,
|
9304
9303
|
point.plotY + chart.plotTop
|
9305
9304
|
);
|
@@ -9322,7 +9321,7 @@ Tooltip.prototype = {
|
|
9322
9321
|
day: 3
|
9323
9322
|
},
|
9324
9323
|
date,
|
9325
|
-
lastN;
|
9324
|
+
lastN = 'millisecond'; // for sub-millisecond data, #4223
|
9326
9325
|
|
9327
9326
|
if (closestPointRange) {
|
9328
9327
|
date = dateFormat('%m-%d %H:%M:%S.%L', point.x);
|
@@ -9532,16 +9531,13 @@ Pointer.prototype = {
|
|
9532
9531
|
tooltip = chart.tooltip,
|
9533
9532
|
shared = tooltip ? tooltip.shared : false,
|
9534
9533
|
followPointer,
|
9535
|
-
//point,
|
9536
|
-
//points,
|
9537
9534
|
hoverPoint = chart.hoverPoint,
|
9538
9535
|
hoverSeries = chart.hoverSeries,
|
9539
9536
|
i,
|
9540
|
-
//j,
|
9541
9537
|
distance = chart.chartWidth,
|
9542
|
-
rdistance = chart.chartWidth,
|
9543
9538
|
anchor,
|
9544
9539
|
noSharedTooltip,
|
9540
|
+
directTouch,
|
9545
9541
|
kdpoints = [],
|
9546
9542
|
kdpoint,
|
9547
9543
|
kdpointT;
|
@@ -9557,7 +9553,7 @@ Pointer.prototype = {
|
|
9557
9553
|
}
|
9558
9554
|
|
9559
9555
|
// If it has a hoverPoint and that series requires direct touch (like columns),
|
9560
|
-
// use the hoverPoint (#3899). Otherwise, search the k-d tree.
|
9556
|
+
// use the hoverPoint (#3899). Otherwise, search the k-d tree.
|
9561
9557
|
if (!shared && hoverSeries && hoverSeries.directTouch && hoverPoint) {
|
9562
9558
|
kdpoint = hoverPoint;
|
9563
9559
|
|
@@ -9567,8 +9563,9 @@ Pointer.prototype = {
|
|
9567
9563
|
each(series, function (s) {
|
9568
9564
|
// Skip hidden series
|
9569
9565
|
noSharedTooltip = s.noSharedTooltip && shared;
|
9570
|
-
|
9571
|
-
|
9566
|
+
directTouch = !shared && s.directTouch;
|
9567
|
+
if (s.visible && !noSharedTooltip && !directTouch && pick(s.options.enableMouseTracking, true)) { // #3821
|
9568
|
+
kdpointT = s.searchPoint(e, !noSharedTooltip && s.kdDimensions === 1); // #3828
|
9572
9569
|
if (kdpointT) {
|
9573
9570
|
kdpoints.push(kdpointT);
|
9574
9571
|
}
|
@@ -9576,19 +9573,15 @@ Pointer.prototype = {
|
|
9576
9573
|
});
|
9577
9574
|
// Find absolute nearest point
|
9578
9575
|
each(kdpoints, function (p) {
|
9579
|
-
if (p &&
|
9580
|
-
|
9581
|
-
|
9582
|
-
distance = p.dist.distX;
|
9583
|
-
rdistance = p.dist.distR;
|
9584
|
-
kdpoint = p;
|
9585
|
-
}
|
9576
|
+
if (p && typeof p.dist === 'number' && p.dist < distance) {
|
9577
|
+
distance = p.dist;
|
9578
|
+
kdpoint = p;
|
9586
9579
|
}
|
9587
9580
|
});
|
9588
9581
|
}
|
9589
9582
|
|
9590
|
-
// Refresh tooltip for kdpoint if new hover point or tooltip was hidden // #3926
|
9591
|
-
if (kdpoint && (kdpoint !==
|
9583
|
+
// Refresh tooltip for kdpoint if new hover point or tooltip was hidden // #3926, #4200
|
9584
|
+
if (kdpoint && (kdpoint !== this.prevKDPoint || (tooltip && tooltip.isHidden))) {
|
9592
9585
|
// Draw tooltip if necessary
|
9593
9586
|
if (shared && !kdpoint.series.noSharedTooltip) {
|
9594
9587
|
i = kdpoints.length;
|
@@ -9615,6 +9608,7 @@ Pointer.prototype = {
|
|
9615
9608
|
}
|
9616
9609
|
kdpoint.onMouseOver(e);
|
9617
9610
|
}
|
9611
|
+
this.prevKDPoint = kdpoint;
|
9618
9612
|
|
9619
9613
|
// Update positions (regardless of kdpoint or hoverPoint)
|
9620
9614
|
} else {
|
@@ -9639,7 +9633,8 @@ Pointer.prototype = {
|
|
9639
9633
|
each(chart.axes, function (axis) {
|
9640
9634
|
axis.drawCrosshair(e, pick(kdpoint, hoverPoint));
|
9641
9635
|
});
|
9642
|
-
|
9636
|
+
|
9637
|
+
|
9643
9638
|
},
|
9644
9639
|
|
9645
9640
|
|
@@ -9654,8 +9649,9 @@ Pointer.prototype = {
|
|
9654
9649
|
chart = pointer.chart,
|
9655
9650
|
hoverSeries = chart.hoverSeries,
|
9656
9651
|
hoverPoint = chart.hoverPoint,
|
9652
|
+
hoverPoints = chart.hoverPoints,
|
9657
9653
|
tooltip = chart.tooltip,
|
9658
|
-
tooltipPoints = tooltip && tooltip.shared ?
|
9654
|
+
tooltipPoints = tooltip && tooltip.shared ? hoverPoints : hoverPoint;
|
9659
9655
|
|
9660
9656
|
// Narrow in allowMove
|
9661
9657
|
allowMove = allowMove && tooltip && tooltipPoints;
|
@@ -9671,7 +9667,7 @@ Pointer.prototype = {
|
|
9671
9667
|
hoverPoint.setState(hoverPoint.state, true);
|
9672
9668
|
each(chart.axes, function (axis) {
|
9673
9669
|
if (pick(axis.options.crosshair && axis.options.crosshair.snap, true)) {
|
9674
|
-
axis.drawCrosshair(null,
|
9670
|
+
axis.drawCrosshair(null, hoverPoint);
|
9675
9671
|
} else {
|
9676
9672
|
axis.hideCrosshair();
|
9677
9673
|
}
|
@@ -9686,6 +9682,12 @@ Pointer.prototype = {
|
|
9686
9682
|
hoverPoint.onMouseOut();
|
9687
9683
|
}
|
9688
9684
|
|
9685
|
+
if (hoverPoints) {
|
9686
|
+
each(hoverPoints, function (point) {
|
9687
|
+
point.setState();
|
9688
|
+
});
|
9689
|
+
}
|
9690
|
+
|
9689
9691
|
if (hoverSeries) {
|
9690
9692
|
hoverSeries.onMouseOut();
|
9691
9693
|
}
|
@@ -9704,7 +9706,7 @@ Pointer.prototype = {
|
|
9704
9706
|
axis.hideCrosshair();
|
9705
9707
|
});
|
9706
9708
|
|
9707
|
-
pointer.hoverX = null;
|
9709
|
+
pointer.hoverX = chart.hoverPoints = chart.hoverPoint = null;
|
9708
9710
|
|
9709
9711
|
}
|
9710
9712
|
},
|
@@ -10007,7 +10009,6 @@ Pointer.prototype = {
|
|
10007
10009
|
|
10008
10010
|
e = this.normalize(e);
|
10009
10011
|
e.originalEvent = e; // #3913
|
10010
|
-
e.cancelBubble = true; // IE specific
|
10011
10012
|
|
10012
10013
|
if (!chart.cancelClick) {
|
10013
10014
|
|
@@ -10208,8 +10209,14 @@ extend(Highcharts.Pointer.prototype, {
|
|
10208
10209
|
chart.runTrackerClick) || self.runChartClick),
|
10209
10210
|
clip = {};
|
10210
10211
|
|
10212
|
+
// Don't initiate panning until the user has pinched. This prevents us from
|
10213
|
+
// blocking page scrolling as users scroll down a long page (#4210).
|
10214
|
+
if (touchesLength > 1) {
|
10215
|
+
self.initiated = true;
|
10216
|
+
}
|
10217
|
+
|
10211
10218
|
// On touch devices, only proceed to trigger click if a handler is defined
|
10212
|
-
if (hasZoom && !fireClickEvent) {
|
10219
|
+
if (hasZoom && self.initiated && !fireClickEvent) {
|
10213
10220
|
e.preventDefault();
|
10214
10221
|
}
|
10215
10222
|
|
@@ -10271,7 +10278,10 @@ extend(Highcharts.Pointer.prototype, {
|
|
10271
10278
|
}
|
10272
10279
|
},
|
10273
10280
|
|
10274
|
-
|
10281
|
+
/**
|
10282
|
+
* General touch handler shared by touchstart and touchmove.
|
10283
|
+
*/
|
10284
|
+
touch: function (e, start) {
|
10275
10285
|
var chart = this.chart;
|
10276
10286
|
|
10277
10287
|
hoverChartIndex = chart.index;
|
@@ -10283,24 +10293,28 @@ extend(Highcharts.Pointer.prototype, {
|
|
10283
10293
|
if (chart.isInsidePlot(e.chartX - chart.plotLeft, e.chartY - chart.plotTop) && !chart.openMenu) {
|
10284
10294
|
|
10285
10295
|
// Run mouse events and display tooltip etc
|
10286
|
-
|
10296
|
+
if (start) {
|
10297
|
+
this.runPointActions(e);
|
10298
|
+
}
|
10287
10299
|
|
10288
10300
|
this.pinch(e);
|
10289
10301
|
|
10290
|
-
} else {
|
10302
|
+
} else if (start) {
|
10291
10303
|
// Hide the tooltip on touching outside the plot area (#1203)
|
10292
10304
|
this.reset();
|
10293
10305
|
}
|
10294
10306
|
|
10295
10307
|
} else if (e.touches.length === 2) {
|
10296
10308
|
this.pinch(e);
|
10297
|
-
}
|
10309
|
+
}
|
10310
|
+
},
|
10311
|
+
|
10312
|
+
onContainerTouchStart: function (e) {
|
10313
|
+
this.touch(e, true);
|
10298
10314
|
},
|
10299
10315
|
|
10300
10316
|
onContainerTouchMove: function (e) {
|
10301
|
-
|
10302
|
-
this.pinch(e);
|
10303
|
-
}
|
10317
|
+
this.touch(e);
|
10304
10318
|
},
|
10305
10319
|
|
10306
10320
|
onDocumentTouchEnd: function (e) {
|
@@ -10505,10 +10519,11 @@ Legend.prototype = {
|
|
10505
10519
|
legendItemPos = item._legendItemPos,
|
10506
10520
|
itemX = legendItemPos[0],
|
10507
10521
|
itemY = legendItemPos[1],
|
10508
|
-
checkbox = item.checkbox
|
10522
|
+
checkbox = item.checkbox,
|
10523
|
+
legendGroup = item.legendGroup;
|
10509
10524
|
|
10510
|
-
if (
|
10511
|
-
|
10525
|
+
if (legendGroup && legendGroup.element) {
|
10526
|
+
legendGroup.translate(
|
10512
10527
|
ltr ? itemX : legend.legendWidth - itemX - 2 * symbolPadding - 4,
|
10513
10528
|
itemY
|
10514
10529
|
);
|
@@ -10539,16 +10554,6 @@ Legend.prototype = {
|
|
10539
10554
|
}
|
10540
10555
|
},
|
10541
10556
|
|
10542
|
-
/**
|
10543
|
-
* Destroy all items.
|
10544
|
-
*/
|
10545
|
-
clearItems: function () {
|
10546
|
-
var legend = this;
|
10547
|
-
each(legend.getAllItems(), function (item) {
|
10548
|
-
legend.destroyItem(item);
|
10549
|
-
});
|
10550
|
-
},
|
10551
|
-
|
10552
10557
|
/**
|
10553
10558
|
* Destroys the legend.
|
10554
10559
|
*/
|
@@ -10617,6 +10622,16 @@ Legend.prototype = {
|
|
10617
10622
|
this.titleHeight = titleHeight;
|
10618
10623
|
},
|
10619
10624
|
|
10625
|
+
/**
|
10626
|
+
* Set the legend item text
|
10627
|
+
*/
|
10628
|
+
setText: function (item) {
|
10629
|
+
var options = this.options;
|
10630
|
+
item.legendItem.attr({
|
10631
|
+
text: options.labelFormat ? format(options.labelFormat, item) : options.labelFormatter.call(item)
|
10632
|
+
});
|
10633
|
+
},
|
10634
|
+
|
10620
10635
|
/**
|
10621
10636
|
* Render a single specific legend item
|
10622
10637
|
* @param {Object} item A series or point
|
@@ -10657,7 +10672,7 @@ Legend.prototype = {
|
|
10657
10672
|
|
10658
10673
|
// Generate the list item text and add it to the group
|
10659
10674
|
item.legendItem = li = renderer.text(
|
10660
|
-
|
10675
|
+
'',
|
10661
10676
|
ltr ? symbolWidth + symbolPadding : -symbolPadding,
|
10662
10677
|
legend.baseline || 0,
|
10663
10678
|
useHTML
|
@@ -10692,6 +10707,9 @@ Legend.prototype = {
|
|
10692
10707
|
}
|
10693
10708
|
}
|
10694
10709
|
|
10710
|
+
// Always update the text
|
10711
|
+
legend.setText(item);
|
10712
|
+
|
10695
10713
|
// calculate the positions for the next line
|
10696
10714
|
bBox = li.getBBox();
|
10697
10715
|
|
@@ -11402,10 +11420,13 @@ Chart.prototype = {
|
|
11402
11420
|
}
|
11403
11421
|
}
|
11404
11422
|
|
11405
|
-
//
|
11423
|
+
// Handle updated data in the series
|
11406
11424
|
each(series, function (serie) {
|
11407
|
-
if (serie.isDirty) {
|
11425
|
+
if (serie.isDirty) {
|
11408
11426
|
if (serie.options.legendType === 'point') {
|
11427
|
+
if (serie.updateTotals) {
|
11428
|
+
serie.updateTotals();
|
11429
|
+
}
|
11409
11430
|
redrawLegend = true;
|
11410
11431
|
}
|
11411
11432
|
}
|
@@ -12638,22 +12659,20 @@ var CenteredSeriesMixin = Highcharts.CenteredSeriesMixin = {
|
|
12638
12659
|
centerOption = options.center,
|
12639
12660
|
positions = [pick(centerOption[0], '50%'), pick(centerOption[1], '50%'), options.size || '100%', options.innerSize || 0],
|
12640
12661
|
smallestSize = mathMin(plotWidth, plotHeight),
|
12641
|
-
isPercent,
|
12642
12662
|
i,
|
12643
12663
|
value;
|
12644
12664
|
|
12645
12665
|
for (i = 0; i < 4; ++i) {
|
12646
12666
|
value = positions[i];
|
12647
|
-
|
12648
|
-
|
12649
|
-
|
12650
|
-
|
12651
|
-
|
12652
|
-
|
12653
|
-
|
12654
|
-
|
12655
|
-
|
12656
|
-
pInt(value)) + (handleSlicingRoom ? slicingRoom : 0);
|
12667
|
+
handleSlicingRoom = i < 2 || (i === 2 && /%$/.test(value));
|
12668
|
+
|
12669
|
+
// i == 0: centerX, relative to width
|
12670
|
+
// i == 1: centerY, relative to height
|
12671
|
+
// i == 2: size, relative to smallestSize
|
12672
|
+
// i == 3: innerSize, relative to size
|
12673
|
+
positions[i] = relativeLength(value, [plotWidth, plotHeight, smallestSize, positions[2]][i]) +
|
12674
|
+
(handleSlicingRoom ? slicingRoom : 0);
|
12675
|
+
|
12657
12676
|
}
|
12658
12677
|
return positions;
|
12659
12678
|
}
|
@@ -12728,7 +12747,7 @@ Point.prototype = {
|
|
12728
12747
|
optionsToObject: function (options) {
|
12729
12748
|
var ret = {},
|
12730
12749
|
series = this.series,
|
12731
|
-
keys = series.options.keys,
|
12750
|
+
keys = series.options.keys,
|
12732
12751
|
pointArrayMap = keys || series.pointArrayMap || ['y'],
|
12733
12752
|
valueCount = pointArrayMap.length,
|
12734
12753
|
firstItemType,
|
@@ -13591,8 +13610,8 @@ Series.prototype = {
|
|
13591
13610
|
// For points within the visible range, including the first point outside the
|
13592
13611
|
// visible range, consider y extremes
|
13593
13612
|
validValue = y !== null && y !== UNDEFINED && (!yAxis.isLog || (y.length || y > 0));
|
13594
|
-
withinRange = this.getExtremesFromAll || this.
|
13595
|
-
(xData[i - 1] || x) <= xMax);
|
13613
|
+
withinRange = this.getExtremesFromAll || this.options.getExtremesFromAll || this.cropped ||
|
13614
|
+
((xData[i + 1] || x) >= xMin && (xData[i - 1] || x) <= xMax);
|
13596
13615
|
|
13597
13616
|
if (validValue && withinRange) {
|
13598
13617
|
|
@@ -13634,6 +13653,7 @@ Series.prototype = {
|
|
13634
13653
|
pointPlacement = options.pointPlacement,
|
13635
13654
|
dynamicallyPlaced = pointPlacement === 'between' || isNumber(pointPlacement),
|
13636
13655
|
threshold = options.threshold,
|
13656
|
+
stackThreshold = options.startFromThreshold ? threshold : 0,
|
13637
13657
|
plotX,
|
13638
13658
|
plotY,
|
13639
13659
|
lastPlotX,
|
@@ -13645,7 +13665,7 @@ Series.prototype = {
|
|
13645
13665
|
xValue = point.x,
|
13646
13666
|
yValue = point.y,
|
13647
13667
|
yBottom = point.low,
|
13648
|
-
stack = stacking && yAxis.stacks[(series.negStacks && yValue < threshold ? '-' : '') + series.stackKey],
|
13668
|
+
stack = stacking && yAxis.stacks[(series.negStacks && yValue < (stackThreshold ? 0 : threshold) ? '-' : '') + series.stackKey],
|
13649
13669
|
pointStack,
|
13650
13670
|
stackValues;
|
13651
13671
|
|
@@ -13656,7 +13676,7 @@ Series.prototype = {
|
|
13656
13676
|
}
|
13657
13677
|
|
13658
13678
|
// Get the plotX translation
|
13659
|
-
point.plotX = plotX = xAxis.translate(xValue, 0, 0, 0, 1, pointPlacement, this.type === 'flags'); //
|
13679
|
+
point.plotX = plotX = mathMin(mathMax(-1e5, xAxis.translate(xValue, 0, 0, 0, 1, pointPlacement, this.type === 'flags')), 1e5); // #3923
|
13660
13680
|
|
13661
13681
|
|
13662
13682
|
// Calculate the bottom y value for stacked series
|
@@ -13667,7 +13687,7 @@ Series.prototype = {
|
|
13667
13687
|
yBottom = stackValues[0];
|
13668
13688
|
yValue = stackValues[1];
|
13669
13689
|
|
13670
|
-
if (yBottom ===
|
13690
|
+
if (yBottom === stackThreshold) {
|
13671
13691
|
yBottom = pick(threshold, yAxis.min);
|
13672
13692
|
}
|
13673
13693
|
if (yAxis.isLog && yBottom <= 0) { // #1200, #1232
|
@@ -14320,8 +14340,13 @@ Series.prototype = {
|
|
14320
14340
|
chartSizeMax = mathMax(chart.chartWidth, chart.chartHeight),
|
14321
14341
|
zoneAxis = this.zoneAxis || 'y',
|
14322
14342
|
axis = this[zoneAxis + 'Axis'],
|
14343
|
+
extremes,
|
14323
14344
|
reversed = axis.reversed,
|
14345
|
+
inverted = chart.inverted,
|
14324
14346
|
horiz = axis.horiz,
|
14347
|
+
pxRange,
|
14348
|
+
pxPosMin,
|
14349
|
+
pxPosMax,
|
14325
14350
|
ignoreZones = false;
|
14326
14351
|
|
14327
14352
|
if (zones.length && (graph || area)) {
|
@@ -14335,25 +14360,27 @@ Series.prototype = {
|
|
14335
14360
|
}
|
14336
14361
|
|
14337
14362
|
// Create the clips
|
14363
|
+
extremes = axis.getExtremes();
|
14338
14364
|
each(zones, function (threshold, i) {
|
14339
|
-
translatedFrom = pick(translatedTo, (reversed ? (horiz ? chart.plotWidth : 0) : (horiz ? 0 : axis.toPixels(axis.min))));
|
14340
|
-
translatedTo = mathRound(axis.toPixels(pick(threshold.value, axis.max), true));
|
14341
|
-
|
14342
|
-
if (axis.isXAxis) {
|
14343
|
-
translatedFrom = translatedFrom > translatedTo ? translatedTo : translatedFrom; //#4006 from should be less or equal then to
|
14344
|
-
} else {
|
14345
|
-
translatedFrom = translatedFrom < translatedTo ? translatedTo : translatedFrom; //#4006 from should be less or equal then to
|
14346
|
-
}
|
14347
14365
|
|
14366
|
+
translatedFrom = reversed ?
|
14367
|
+
(horiz ? chart.plotWidth : 0) :
|
14368
|
+
(horiz ? 0 : axis.toPixels(extremes.min));
|
14369
|
+
translatedFrom = mathMin(mathMax(pick(translatedTo, translatedFrom), 0), chartSizeMax);
|
14370
|
+
translatedTo = mathMin(mathMax(mathRound(axis.toPixels(pick(threshold.value, extremes.max), true)), 0), chartSizeMax);
|
14371
|
+
|
14348
14372
|
if (ignoreZones) {
|
14349
|
-
translatedFrom = translatedTo = axis.toPixels(
|
14373
|
+
translatedFrom = translatedTo = axis.toPixels(extremes.max);
|
14350
14374
|
}
|
14351
14375
|
|
14376
|
+
pxRange = Math.abs(translatedFrom - translatedTo);
|
14377
|
+
pxPosMin = mathMin(translatedFrom, translatedTo);
|
14378
|
+
pxPosMax = mathMax(translatedFrom, translatedTo);
|
14352
14379
|
if (axis.isXAxis) {
|
14353
14380
|
clipAttr = {
|
14354
|
-
x:
|
14381
|
+
x: inverted ? pxPosMax : pxPosMin,
|
14355
14382
|
y: 0,
|
14356
|
-
width:
|
14383
|
+
width: pxRange,
|
14357
14384
|
height: chartSizeMax
|
14358
14385
|
};
|
14359
14386
|
if (!horiz) {
|
@@ -14362,21 +14389,21 @@ Series.prototype = {
|
|
14362
14389
|
} else {
|
14363
14390
|
clipAttr = {
|
14364
14391
|
x: 0,
|
14365
|
-
y:
|
14392
|
+
y: inverted ? pxPosMax : pxPosMin,
|
14366
14393
|
width: chartSizeMax,
|
14367
|
-
height:
|
14368
|
-
};
|
14394
|
+
height: pxRange
|
14395
|
+
};
|
14369
14396
|
if (horiz) {
|
14370
14397
|
clipAttr.y = chart.plotWidth - clipAttr.y;
|
14371
14398
|
}
|
14372
|
-
}
|
14399
|
+
}
|
14373
14400
|
|
14374
14401
|
/// VML SUPPPORT
|
14375
14402
|
if (chart.inverted && renderer.isVML) {
|
14376
14403
|
if (axis.isXAxis) {
|
14377
14404
|
clipAttr = {
|
14378
14405
|
x: 0,
|
14379
|
-
y: reversed ?
|
14406
|
+
y: reversed ? pxPosMin : pxPosMax,
|
14380
14407
|
height: clipAttr.width,
|
14381
14408
|
width: chart.chartWidth
|
14382
14409
|
};
|
@@ -14405,7 +14432,7 @@ Series.prototype = {
|
|
14405
14432
|
}
|
14406
14433
|
}
|
14407
14434
|
// if this zone extends out of the axis, ignore the others
|
14408
|
-
ignoreZones = threshold.value >
|
14435
|
+
ignoreZones = threshold.value > extremes.max;
|
14409
14436
|
});
|
14410
14437
|
this.clips = clips;
|
14411
14438
|
}
|
@@ -14639,11 +14666,9 @@ Series.prototype = {
|
|
14639
14666
|
*/
|
14640
14667
|
|
14641
14668
|
kdDimensions: 1,
|
14642
|
-
kdTree: null,
|
14643
14669
|
kdAxisArray: ['clientX', 'plotY'],
|
14644
|
-
kdComparer: 'distX',
|
14645
14670
|
|
14646
|
-
searchPoint: function (e) {
|
14671
|
+
searchPoint: function (e, compareX) {
|
14647
14672
|
var series = this,
|
14648
14673
|
xAxis = series.xAxis,
|
14649
14674
|
yAxis = series.yAxis,
|
@@ -14652,7 +14677,7 @@ Series.prototype = {
|
|
14652
14677
|
return this.searchKDTree({
|
14653
14678
|
clientX: inverted ? xAxis.len - e.chartY + xAxis.pos : e.chartX - xAxis.pos,
|
14654
14679
|
plotY: inverted ? yAxis.len - e.chartX + yAxis.pos : e.chartY - yAxis.pos
|
14655
|
-
});
|
14680
|
+
}, compareX);
|
14656
14681
|
},
|
14657
14682
|
|
14658
14683
|
buildKDTree: function () {
|
@@ -14675,7 +14700,7 @@ Series.prototype = {
|
|
14675
14700
|
|
14676
14701
|
median = Math.floor(length / 2);
|
14677
14702
|
|
14678
|
-
// build and return
|
14703
|
+
// build and return nod
|
14679
14704
|
return {
|
14680
14705
|
point: points[median],
|
14681
14706
|
left: _kdtree(points.slice(0, median), depth + 1, dimensions),
|
@@ -14690,9 +14715,9 @@ Series.prototype = {
|
|
14690
14715
|
var points = grep(series.points, function (point) {
|
14691
14716
|
return point.y !== null;
|
14692
14717
|
});
|
14693
|
-
series.kdTree = _kdtree(points, dimensions, dimensions);
|
14694
|
-
}
|
14695
14718
|
|
14719
|
+
series.kdTree = _kdtree(points, dimensions, dimensions);
|
14720
|
+
}
|
14696
14721
|
delete series.kdTree;
|
14697
14722
|
|
14698
14723
|
if (series.options.kdSync) { // For testing tooltips, don't build async
|
@@ -14702,23 +14727,20 @@ Series.prototype = {
|
|
14702
14727
|
}
|
14703
14728
|
},
|
14704
14729
|
|
14705
|
-
searchKDTree: function (point) {
|
14730
|
+
searchKDTree: function (point, compareX) {
|
14706
14731
|
var series = this,
|
14707
|
-
kdComparer = this.kdComparer,
|
14708
14732
|
kdX = this.kdAxisArray[0],
|
14709
|
-
kdY = this.kdAxisArray[1]
|
14733
|
+
kdY = this.kdAxisArray[1],
|
14734
|
+
kdComparer = compareX ? 'distX' : 'dist';
|
14710
14735
|
|
14711
|
-
//
|
14712
|
-
function
|
14736
|
+
// Set the one and two dimensional distance on the point object
|
14737
|
+
function setDistance(p1, p2) {
|
14713
14738
|
var x = (defined(p1[kdX]) && defined(p2[kdX])) ? Math.pow(p1[kdX] - p2[kdX], 2) : null,
|
14714
14739
|
y = (defined(p1[kdY]) && defined(p2[kdY])) ? Math.pow(p1[kdY] - p2[kdY], 2) : null,
|
14715
14740
|
r = (x || 0) + (y || 0);
|
14716
|
-
|
14717
|
-
|
14718
|
-
|
14719
|
-
distY: defined(y) ? Math.sqrt(y) : Number.MAX_VALUE,
|
14720
|
-
distR: defined(r) ? Math.sqrt(r) : Number.MAX_VALUE
|
14721
|
-
};
|
14741
|
+
|
14742
|
+
p2.dist = defined(r) ? Math.sqrt(r) : Number.MAX_VALUE;
|
14743
|
+
p2.distX = defined(x) ? Math.sqrt(x) : Number.MAX_VALUE;
|
14722
14744
|
}
|
14723
14745
|
function _search(search, tree, depth, dimensions) {
|
14724
14746
|
var point = tree.point,
|
@@ -14729,27 +14751,28 @@ Series.prototype = {
|
|
14729
14751
|
ret = point,
|
14730
14752
|
nPoint1,
|
14731
14753
|
nPoint2;
|
14732
|
-
|
14754
|
+
|
14755
|
+
setDistance(search, point);
|
14733
14756
|
|
14734
14757
|
// Pick side based on distance to splitting point
|
14735
14758
|
tdist = search[axis] - point[axis];
|
14736
14759
|
sideA = tdist < 0 ? 'left' : 'right';
|
14760
|
+
sideB = tdist < 0 ? 'right' : 'left';
|
14737
14761
|
|
14738
14762
|
// End of tree
|
14739
14763
|
if (tree[sideA]) {
|
14740
14764
|
nPoint1 =_search(search, tree[sideA], depth + 1, dimensions);
|
14741
14765
|
|
14742
|
-
ret = (nPoint1
|
14743
|
-
|
14744
|
-
|
14745
|
-
|
14746
|
-
|
14747
|
-
|
14748
|
-
|
14749
|
-
ret = (nPoint2.dist[kdComparer] < ret.dist[kdComparer] ? nPoint2 : ret);
|
14750
|
-
}
|
14766
|
+
ret = (nPoint1[kdComparer] < ret[kdComparer] ? nPoint1 : point);
|
14767
|
+
}
|
14768
|
+
if (tree[sideB]) {
|
14769
|
+
// compare distance to current best to splitting point to decide wether to check side B or not
|
14770
|
+
if (Math.sqrt(tdist * tdist) < ret[kdComparer]) {
|
14771
|
+
nPoint2 = _search(search, tree[sideB], depth + 1, dimensions);
|
14772
|
+
ret = (nPoint2[kdComparer] < ret[kdComparer] ? nPoint2 : ret);
|
14751
14773
|
}
|
14752
14774
|
}
|
14775
|
+
|
14753
14776
|
return ret;
|
14754
14777
|
}
|
14755
14778
|
|
@@ -14947,6 +14970,7 @@ Series.prototype.setStackedPoints = function () {
|
|
14947
14970
|
yDataLength = yData.length,
|
14948
14971
|
seriesOptions = series.options,
|
14949
14972
|
threshold = seriesOptions.threshold,
|
14973
|
+
stackThreshold = seriesOptions.startFromThreshold ? threshold : 0,
|
14950
14974
|
stackOption = seriesOptions.stack,
|
14951
14975
|
stacking = seriesOptions.stacking,
|
14952
14976
|
stackKey = series.stackKey,
|
@@ -14972,7 +14996,7 @@ Series.prototype.setStackedPoints = function () {
|
|
14972
14996
|
|
14973
14997
|
// Read stacked values into a stack based on the x value,
|
14974
14998
|
// the sign of y and the stack key. Stacking is also handled for null values (#739)
|
14975
|
-
isNegative = negStacks && y < threshold;
|
14999
|
+
isNegative = negStacks && y < (stackThreshold ? 0 : threshold);
|
14976
15000
|
key = isNegative ? negKey : stackKey;
|
14977
15001
|
|
14978
15002
|
// Create empty object for this stack if it doesn't exist yet
|
@@ -14992,7 +15016,10 @@ Series.prototype.setStackedPoints = function () {
|
|
14992
15016
|
|
14993
15017
|
// If the StackItem doesn't exist, create it first
|
14994
15018
|
stack = stacks[key][x];
|
14995
|
-
stack.points[pointKey] = [stack.cum ||
|
15019
|
+
//stack.points[pointKey] = [stack.cum || stackThreshold];
|
15020
|
+
stack.points[pointKey] = [pick(stack.cum, stackThreshold)];
|
15021
|
+
|
15022
|
+
|
14996
15023
|
|
14997
15024
|
// Add value to the stack total
|
14998
15025
|
if (stacking === 'percent') {
|
@@ -15011,7 +15038,7 @@ Series.prototype.setStackedPoints = function () {
|
|
15011
15038
|
stack.total = correctFloat(stack.total + (y || 0));
|
15012
15039
|
}
|
15013
15040
|
|
15014
|
-
stack.cum = (stack.cum
|
15041
|
+
stack.cum = pick(stack.cum, stackThreshold) + (y || 0);
|
15015
15042
|
|
15016
15043
|
stack.points[pointKey].push(stack.cum);
|
15017
15044
|
stackedYData[i] = stack.cum;
|
@@ -15223,6 +15250,9 @@ extend(Point.prototype, {
|
|
15223
15250
|
point.applyOptions(options);
|
15224
15251
|
|
15225
15252
|
// Update visuals
|
15253
|
+
if (point.y === null && graphic) { // #4146
|
15254
|
+
point.graphic = graphic.destroy();
|
15255
|
+
}
|
15226
15256
|
if (isObject(options) && !isArray(options)) {
|
15227
15257
|
// Defer the actual redraw until getAttribs has been called (#3260)
|
15228
15258
|
point.redraw = function () {
|
@@ -15230,7 +15260,7 @@ extend(Point.prototype, {
|
|
15230
15260
|
if (options && options.marker && options.marker.symbol) {
|
15231
15261
|
point.graphic = graphic.destroy();
|
15232
15262
|
} else {
|
15233
|
-
graphic.attr(point.pointAttr[point.state || '']);
|
15263
|
+
graphic.attr(point.pointAttr[point.state || ''])[point.visible ? 'show' : 'hide'](true); // #2430
|
15234
15264
|
}
|
15235
15265
|
}
|
15236
15266
|
if (options && options.dataLabels && point.dataLabel) { // #2468
|
@@ -15255,9 +15285,8 @@ extend(Point.prototype, {
|
|
15255
15285
|
chart.isDirtyBox = true;
|
15256
15286
|
}
|
15257
15287
|
|
15258
|
-
if (
|
15259
|
-
|
15260
|
-
chart.legend.clearItems();
|
15288
|
+
if (seriesOptions.legendType === 'point') { // #1831, #1885
|
15289
|
+
chart.isDirtyLegend = true;
|
15261
15290
|
}
|
15262
15291
|
if (redraw) {
|
15263
15292
|
chart.redraw(animation);
|
@@ -15986,6 +16015,7 @@ defaultPlotOptions.column = merge(defaultSeriesOptions, {
|
|
15986
16015
|
verticalAlign: null, // auto
|
15987
16016
|
y: null
|
15988
16017
|
},
|
16018
|
+
startFromThreshold: true, // docs: http://jsfiddle.net/highcharts/hz8fopan/14/
|
15989
16019
|
stickyTracking: false,
|
15990
16020
|
tooltip: {
|
15991
16021
|
distance: 6
|
@@ -16137,7 +16167,8 @@ var ColumnSeries = extendClass(Series, {
|
|
16137
16167
|
// Record the new values
|
16138
16168
|
each(series.points, function (point) {
|
16139
16169
|
var yBottom = pick(point.yBottom, translatedThreshold),
|
16140
|
-
|
16170
|
+
safeDistance = 999 + mathAbs(yBottom),
|
16171
|
+
plotY = mathMin(mathMax(-safeDistance, point.plotY), yAxis.len + safeDistance), // Don't draw too far outside plot area (#1303, #2241, #4264)
|
16141
16172
|
barX = point.plotX + pointXOffset,
|
16142
16173
|
barW = seriesBarW,
|
16143
16174
|
barY = mathMin(plotY, yBottom),
|
@@ -16163,11 +16194,6 @@ var ColumnSeries = extendClass(Series, {
|
|
16163
16194
|
point.barX = barX;
|
16164
16195
|
point.pointWidth = pointWidth;
|
16165
16196
|
|
16166
|
-
// Fix the tooltip on center of grouped columns (#1216, #424, #3648)
|
16167
|
-
point.tooltipPos = chart.inverted ?
|
16168
|
-
[yAxis.len + yAxis.pos - chart.plotLeft - plotY, series.xAxis.len - barX - barW / 2] :
|
16169
|
-
[barX + barW / 2, plotY + yAxis.pos - chart.plotTop];
|
16170
|
-
|
16171
16197
|
// Round off to obtain crisp edges and avoid overlapping with neighbours (#2694)
|
16172
16198
|
right = mathRound(barX + barW) + xCrisp;
|
16173
16199
|
barX = mathRound(barX) + xCrisp;
|
@@ -16184,6 +16210,11 @@ var ColumnSeries = extendClass(Series, {
|
|
16184
16210
|
barH += 1;
|
16185
16211
|
}
|
16186
16212
|
|
16213
|
+
// Fix the tooltip on center of grouped columns (#1216, #424, #3648)
|
16214
|
+
point.tooltipPos = chart.inverted ?
|
16215
|
+
[yAxis.len + yAxis.pos - chart.plotLeft - plotY, series.xAxis.len - barX - barW / 2, barH] :
|
16216
|
+
[barX + barW / 2, plotY + yAxis.pos - chart.plotTop, barH];
|
16217
|
+
|
16187
16218
|
// Register shape type and arguments to be used in drawPoints
|
16188
16219
|
point.shapeType = 'rect';
|
16189
16220
|
point.shapeArgs = {
|
@@ -16192,7 +16223,6 @@ var ColumnSeries = extendClass(Series, {
|
|
16192
16223
|
width: barW,
|
16193
16224
|
height: barH
|
16194
16225
|
};
|
16195
|
-
|
16196
16226
|
});
|
16197
16227
|
|
16198
16228
|
},
|
@@ -16351,7 +16381,6 @@ var ScatterSeries = extendClass(Series, {
|
|
16351
16381
|
trackerGroups: ['group', 'markerGroup', 'dataLabelsGroup'],
|
16352
16382
|
takeOrdinalPosition: false, // #2342
|
16353
16383
|
kdDimensions: 2,
|
16354
|
-
kdComparer: 'distR',
|
16355
16384
|
drawGraph: function () {
|
16356
16385
|
if (this.options.lineWidth) {
|
16357
16386
|
Series.prototype.drawGraph.call(this);
|
@@ -16437,20 +16466,22 @@ var PiePoint = extendClass(Point, {
|
|
16437
16466
|
* @param {Boolean} vis Whether to show the slice or not. If undefined, the
|
16438
16467
|
* visibility is toggled
|
16439
16468
|
*/
|
16440
|
-
setVisible: function (vis,
|
16469
|
+
setVisible: function (vis, redraw) {
|
16441
16470
|
var point = this,
|
16442
16471
|
series = point.series,
|
16443
16472
|
chart = series.chart,
|
16444
|
-
|
16473
|
+
ignoreHiddenPoint = series.options.ignoreHiddenPoint;
|
16474
|
+
|
16475
|
+
redraw = pick(redraw, ignoreHiddenPoint);
|
16476
|
+
|
16477
|
+
if (vis !== point.visible) {
|
16445
16478
|
|
16446
|
-
// Only if the value has changed
|
16447
|
-
if (vis !== point.visible || force) {
|
16448
|
-
|
16449
16479
|
// If called without an argument, toggle visibility
|
16450
16480
|
point.visible = point.options.visible = vis = vis === UNDEFINED ? !point.visible : vis;
|
16451
16481
|
series.options.data[inArray(point, series.data)] = point.options; // update userOptions.data
|
16452
16482
|
|
16453
|
-
// Show and hide associated elements
|
16483
|
+
// Show and hide associated elements. This is performed regardless of redraw or not,
|
16484
|
+
// because chart.redraw only handles full series.
|
16454
16485
|
each(['graphic', 'dataLabel', 'connector', 'shadowGroup'], function (key) {
|
16455
16486
|
if (point[key]) {
|
16456
16487
|
point[key][vis ? 'show' : 'hide'](true);
|
@@ -16458,19 +16489,15 @@ var PiePoint = extendClass(Point, {
|
|
16458
16489
|
});
|
16459
16490
|
|
16460
16491
|
if (point.legendItem) {
|
16461
|
-
if (chart.hasRendered) {
|
16462
|
-
series.updateTotals();
|
16463
|
-
chart.legend.clearItems();
|
16464
|
-
if (!doRedraw) {
|
16465
|
-
chart.legend.render();
|
16466
|
-
}
|
16467
|
-
}
|
16468
16492
|
chart.legend.colorizeItem(point, vis);
|
16469
16493
|
}
|
16470
|
-
|
16494
|
+
|
16471
16495
|
// Handle ignore hidden slices
|
16472
|
-
if (
|
16496
|
+
if (ignoreHiddenPoint) {
|
16473
16497
|
series.isDirty = true;
|
16498
|
+
}
|
16499
|
+
|
16500
|
+
if (redraw) {
|
16474
16501
|
chart.redraw();
|
16475
16502
|
}
|
16476
16503
|
}
|
@@ -16529,6 +16556,7 @@ var PieSeries = {
|
|
16529
16556
|
isCartesian: false,
|
16530
16557
|
pointClass: PiePoint,
|
16531
16558
|
requireSorting: false,
|
16559
|
+
directTouch: true,
|
16532
16560
|
noSharedTooltip: true,
|
16533
16561
|
trackerGroups: ['group', 'dataLabelsGroup'],
|
16534
16562
|
axisTypes: [],
|
@@ -16597,24 +16625,14 @@ var PieSeries = {
|
|
16597
16625
|
updateTotals: function () {
|
16598
16626
|
var i,
|
16599
16627
|
total = 0,
|
16600
|
-
points,
|
16601
|
-
len,
|
16628
|
+
points = this.points,
|
16629
|
+
len = points.length,
|
16602
16630
|
point,
|
16603
16631
|
ignoreHiddenPoint = this.options.ignoreHiddenPoint;
|
16604
16632
|
|
16605
|
-
// Populate local vars
|
16606
|
-
points = this.points;
|
16607
|
-
len = points.length;
|
16608
|
-
|
16609
16633
|
// Get the total sum
|
16610
16634
|
for (i = 0; i < len; i++) {
|
16611
16635
|
point = points[i];
|
16612
|
-
|
16613
|
-
// Disallow negative values (#1530, #3623)
|
16614
|
-
if (point.y < 0) {
|
16615
|
-
point.y = null;
|
16616
|
-
}
|
16617
|
-
|
16618
16636
|
total += (ignoreHiddenPoint && !point.visible) ? 0 : point.y;
|
16619
16637
|
}
|
16620
16638
|
this.total = total;
|
@@ -16622,7 +16640,6 @@ var PieSeries = {
|
|
16622
16640
|
// Set each point's properties
|
16623
16641
|
for (i = 0; i < len; i++) {
|
16624
16642
|
point = points[i];
|
16625
|
-
//point.percentage = (total <= 0 || ignoreHiddenPoint && !point.visible) ? 0 : point.y / total * 100;
|
16626
16643
|
point.percentage = (total > 0 && (point.visible || !ignoreHiddenPoint)) ? point.y / total * 100 : 0;
|
16627
16644
|
point.total = total;
|
16628
16645
|
}
|
@@ -16762,7 +16779,8 @@ var PieSeries = {
|
|
16762
16779
|
//group,
|
16763
16780
|
shadow = series.options.shadow,
|
16764
16781
|
shadowGroup,
|
16765
|
-
shapeArgs
|
16782
|
+
shapeArgs,
|
16783
|
+
attr;
|
16766
16784
|
|
16767
16785
|
if (shadow && !series.shadowGroup) {
|
16768
16786
|
series.shadowGroup = renderer.g('shadow')
|
@@ -16771,9 +16789,6 @@ var PieSeries = {
|
|
16771
16789
|
|
16772
16790
|
// draw the slices
|
16773
16791
|
each(series.points, function (point) {
|
16774
|
-
|
16775
|
-
var visible = point.options.visible;
|
16776
|
-
|
16777
16792
|
graphic = point.graphic;
|
16778
16793
|
shapeArgs = point.shapeArgs;
|
16779
16794
|
shadowGroup = point.shadowGroup;
|
@@ -16797,27 +16812,24 @@ var PieSeries = {
|
|
16797
16812
|
|
16798
16813
|
// draw the slice
|
16799
16814
|
if (graphic) {
|
16800
|
-
graphic.animate(extend(shapeArgs, groupTranslation));
|
16815
|
+
graphic.animate(extend(shapeArgs, groupTranslation));
|
16801
16816
|
} else {
|
16817
|
+
attr = { 'stroke-linejoin': 'round' };
|
16818
|
+
if (!point.visible) {
|
16819
|
+
attr.visibility = 'hidden';
|
16820
|
+
}
|
16821
|
+
|
16802
16822
|
point.graphic = graphic = renderer[point.shapeType](shapeArgs)
|
16803
16823
|
.setRadialReference(series.center)
|
16804
16824
|
.attr(
|
16805
16825
|
point.pointAttr[point.selected ? SELECT_STATE : NORMAL_STATE]
|
16806
16826
|
)
|
16807
|
-
.attr(
|
16808
|
-
'stroke-linejoin': 'round'
|
16809
|
-
//zIndex: 1 // #2722 (reversed)
|
16810
|
-
})
|
16827
|
+
.attr(attr)
|
16811
16828
|
.attr(groupTranslation)
|
16812
16829
|
.add(series.group)
|
16813
16830
|
.shadow(shadow, shadowGroup);
|
16814
16831
|
}
|
16815
16832
|
|
16816
|
-
// Detect point specific visibility (#2430)
|
16817
|
-
if (visible !== undefined) {
|
16818
|
-
point.setVisible(visible, true);
|
16819
|
-
}
|
16820
|
-
|
16821
16833
|
});
|
16822
16834
|
|
16823
16835
|
},
|
@@ -17370,7 +17382,6 @@ if (seriesTypes.pie) {
|
|
17370
17382
|
|
17371
17383
|
// get the x - use the natural x position for first and last slot, to prevent the top
|
17372
17384
|
// and botton slice connectors from touching each other on either side
|
17373
|
-
// Problem: Should check that it makes sense - http://jsfiddle.net/highcharts/n1y6ngxz/
|
17374
17385
|
x = options.justify ?
|
17375
17386
|
seriesCenter[0] + (i ? -1 : 1) * (radius + distanceOption) :
|
17376
17387
|
series.getX(y === centerY - radius - distanceOption || y === centerY + radius + distanceOption ? naturalY : y, i);
|
@@ -17428,7 +17439,7 @@ if (seriesTypes.pie) {
|
|
17428
17439
|
labelPos = point.labelPos;
|
17429
17440
|
dataLabel = point.dataLabel;
|
17430
17441
|
|
17431
|
-
if (dataLabel && dataLabel._pos) {
|
17442
|
+
if (dataLabel && dataLabel._pos && point.visible) {
|
17432
17443
|
visibility = dataLabel._attr.visibility;
|
17433
17444
|
x = dataLabel.connX;
|
17434
17445
|
y = dataLabel.connY;
|
@@ -17479,7 +17490,7 @@ if (seriesTypes.pie) {
|
|
17479
17490
|
var dataLabel = point.dataLabel,
|
17480
17491
|
_pos;
|
17481
17492
|
|
17482
|
-
if (dataLabel) {
|
17493
|
+
if (dataLabel && point.visible) {
|
17483
17494
|
_pos = dataLabel._pos;
|
17484
17495
|
if (_pos) {
|
17485
17496
|
dataLabel.attr(dataLabel._attr);
|
@@ -17538,6 +17549,7 @@ if (seriesTypes.pie) {
|
|
17538
17549
|
// If the size must be decreased, we need to run translate and drawDataLabels again
|
17539
17550
|
if (newSize < center[2]) {
|
17540
17551
|
center[2] = newSize;
|
17552
|
+
center[3] = relativeLength(options.innerSize || 0, newSize);
|
17541
17553
|
this.translate(center);
|
17542
17554
|
each(this.points, function (point) {
|
17543
17555
|
if (point.dataLabel) {
|
@@ -17565,7 +17577,7 @@ if (seriesTypes.column) {
|
|
17565
17577
|
var inverted = this.chart.inverted,
|
17566
17578
|
series = point.series,
|
17567
17579
|
dlBox = point.dlBox || point.shapeArgs, // data label box for alignment
|
17568
|
-
below = point.below
|
17580
|
+
below = pick(point.below, point.plotY > pick(this.translatedThreshold, series.yAxis.len)), // point.below is used in range series
|
17569
17581
|
inside = pick(options.inside, !!this.options.stacking); // draw it inside the box?
|
17570
17582
|
|
17571
17583
|
// Align to the column itself, or the top of it
|
@@ -17613,7 +17625,7 @@ if (seriesTypes.column) {
|
|
17613
17625
|
|
17614
17626
|
|
17615
17627
|
/**
|
17616
|
-
* Highcharts JS v4.1.
|
17628
|
+
* Highcharts JS v4.1.6 (2015-06-12)
|
17617
17629
|
* Highcharts module to hide overlapping data labels. This module is included by default in Highmaps.
|
17618
17630
|
*
|
17619
17631
|
* (c) 2010-2014 Torstein Honsi
|
@@ -17625,6 +17637,7 @@ if (seriesTypes.column) {
|
|
17625
17637
|
(function (H) {
|
17626
17638
|
var Chart = H.Chart,
|
17627
17639
|
each = H.each,
|
17640
|
+
pick = H.pick,
|
17628
17641
|
addEvent = HighchartsAdapter.addEvent;
|
17629
17642
|
|
17630
17643
|
// Collect potensial overlapping data labels. Stack labels probably don't need to be
|
@@ -17638,7 +17651,7 @@ if (seriesTypes.column) {
|
|
17638
17651
|
if ((dlOptions.enabled || series._hasPointLabels) && !dlOptions.allowOverlap && series.visible) { // #3866
|
17639
17652
|
each(series.points, function (point) {
|
17640
17653
|
if (point.dataLabel) {
|
17641
|
-
point.dataLabel.labelrank = point.labelrank;
|
17654
|
+
point.dataLabel.labelrank = pick(point.labelrank, point.shapeArgs && point.shapeArgs.height); // #4118
|
17642
17655
|
labels.push(point.dataLabel);
|
17643
17656
|
}
|
17644
17657
|
});
|
@@ -17685,6 +17698,13 @@ if (seriesTypes.column) {
|
|
17685
17698
|
}
|
17686
17699
|
}
|
17687
17700
|
|
17701
|
+
// Prevent a situation in a gradually rising slope, that each label
|
17702
|
+
// will hide the previous one because the previous one always has
|
17703
|
+
// lower rank.
|
17704
|
+
labels.sort(function (a, b) {
|
17705
|
+
return b.labelrank - a.labelrank;
|
17706
|
+
});
|
17707
|
+
|
17688
17708
|
// Detect overlapping labels
|
17689
17709
|
for (i = 0; i < len; i++) {
|
17690
17710
|
label1 = labels[i];
|
@@ -18353,6 +18373,8 @@ extend(Series.prototype, {
|
|
18353
18373
|
tooltip = chart.tooltip,
|
18354
18374
|
hoverPoint = chart.hoverPoint;
|
18355
18375
|
|
18376
|
+
chart.hoverSeries = null; // #182, set to null before the mouseOut event fires
|
18377
|
+
|
18356
18378
|
// trigger mouse out on the point, which must be in this series
|
18357
18379
|
if (hoverPoint) {
|
18358
18380
|
hoverPoint.onMouseOut();
|
@@ -18371,7 +18393,6 @@ extend(Series.prototype, {
|
|
18371
18393
|
|
18372
18394
|
// set normal state
|
18373
18395
|
series.setState();
|
18374
|
-
chart.hoverSeries = null;
|
18375
18396
|
},
|
18376
18397
|
|
18377
18398
|
/**
|