highcharts-rails 2.3.2 → 2.3.3
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.markdown +4 -0
- data/lib/highcharts/version.rb +1 -1
- data/vendor/assets/javascripts/highcharts.js +352 -307
- data/vendor/assets/javascripts/highcharts/adapters/mootools.js +1 -1
- data/vendor/assets/javascripts/highcharts/adapters/prototype.js +1 -1
- data/vendor/assets/javascripts/highcharts/highcharts-more.js +27 -26
- data/vendor/assets/javascripts/highcharts/modules/canvas-tools.js +1 -1
- data/vendor/assets/javascripts/highcharts/modules/exporting.js +1 -1
- metadata +2 -2
data/CHANGELOG.markdown
CHANGED
data/lib/highcharts/version.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
// @compilation_level SIMPLE_OPTIMIZATIONS
|
3
3
|
|
4
4
|
/**
|
5
|
-
* @license Highcharts JS v2.3.
|
5
|
+
* @license Highcharts JS v2.3.3 (2012-10-04)
|
6
6
|
*
|
7
7
|
* (c) 2009-2011 Torstein Hønsi
|
8
8
|
*
|
@@ -1258,8 +1258,10 @@ pathAnim = {
|
|
1258
1258
|
var ret = e.originalEvent || e;
|
1259
1259
|
|
1260
1260
|
// computed by jQuery, needed by IE8
|
1261
|
-
ret.pageX
|
1262
|
-
|
1261
|
+
if (ret.pageX === UNDEFINED) { // #1236
|
1262
|
+
ret.pageX = e.pageX;
|
1263
|
+
ret.pageY = e.pageY;
|
1264
|
+
}
|
1263
1265
|
|
1264
1266
|
return ret;
|
1265
1267
|
},
|
@@ -1360,8 +1362,8 @@ defaultOptions = {
|
|
1360
1362
|
},
|
1361
1363
|
global: {
|
1362
1364
|
useUTC: true,
|
1363
|
-
canvasToolsURL: 'http://code.highcharts.com/2.3.
|
1364
|
-
VMLRadialGradientURL: 'http://code.highcharts.com/2.3.
|
1365
|
+
canvasToolsURL: 'http://code.highcharts.com/2.3.3/modules/canvas-tools.js',
|
1366
|
+
VMLRadialGradientURL: 'http://code.highcharts.com/2.3.3/gfx/vml-radial-gradient.png'
|
1365
1367
|
},
|
1366
1368
|
chart: {
|
1367
1369
|
//animation: true,
|
@@ -1475,10 +1477,11 @@ defaultOptions = {
|
|
1475
1477
|
},
|
1476
1478
|
dataLabels: merge(defaultLabelOptions, {
|
1477
1479
|
enabled: false,
|
1478
|
-
y: -6,
|
1479
1480
|
formatter: function () {
|
1480
1481
|
return this.y;
|
1481
|
-
}
|
1482
|
+
},
|
1483
|
+
verticalAlign: 'bottom', // above singular point
|
1484
|
+
y: 0
|
1482
1485
|
// backgroundColor: undefined,
|
1483
1486
|
// borderColor: undefined,
|
1484
1487
|
// borderRadius: undefined,
|
@@ -1867,7 +1870,7 @@ SVGElement.prototype = {
|
|
1867
1870
|
i,
|
1868
1871
|
child,
|
1869
1872
|
element = wrapper.element,
|
1870
|
-
nodeName = element.nodeName,
|
1873
|
+
nodeName = element.nodeName.toLowerCase(), // Android2 requires lower for "text"
|
1871
1874
|
renderer = wrapper.renderer,
|
1872
1875
|
skipAttr,
|
1873
1876
|
titleNode,
|
@@ -2154,7 +2157,7 @@ SVGElement.prototype = {
|
|
2154
2157
|
/*jslint unparam: true*//* allow unused param a in the regexp function below */
|
2155
2158
|
var elemWrapper = this,
|
2156
2159
|
elem = elemWrapper.element,
|
2157
|
-
textWidth = styles && styles.width && elem.nodeName === 'text',
|
2160
|
+
textWidth = styles && styles.width && elem.nodeName.toLowerCase() === 'text',
|
2158
2161
|
n,
|
2159
2162
|
serializedCss = '',
|
2160
2163
|
hyphenate = function (a, b) { return '-' + b.toLowerCase(); };
|
@@ -2174,6 +2177,12 @@ SVGElement.prototype = {
|
|
2174
2177
|
// store object
|
2175
2178
|
elemWrapper.styles = styles;
|
2176
2179
|
|
2180
|
+
|
2181
|
+
// Don't handle line wrap on canvas
|
2182
|
+
if (useCanVG && textWidth) {
|
2183
|
+
delete styles.width;
|
2184
|
+
}
|
2185
|
+
|
2177
2186
|
// serialize and set style attribute
|
2178
2187
|
if (isIE && !hasSVG) { // legacy IE doesn't support setting style attribute
|
2179
2188
|
if (textWidth) {
|
@@ -2364,15 +2373,15 @@ SVGElement.prototype = {
|
|
2364
2373
|
yCorr = wrapper.yCorr || 0,
|
2365
2374
|
currentTextTransform = [rotation, align, elem.innerHTML, wrapper.textWidth].join(','),
|
2366
2375
|
rotationStyle = {},
|
2367
|
-
|
2376
|
+
cssTransformKey;
|
2368
2377
|
|
2369
2378
|
if (currentTextTransform !== wrapper.cTT) { // do the calculations and DOM access only if properties changed
|
2370
2379
|
|
2371
2380
|
if (defined(rotation)) {
|
2372
2381
|
|
2373
2382
|
if (renderer.isSVG) { // #916
|
2374
|
-
|
2375
|
-
rotationStyle[
|
2383
|
+
cssTransformKey = isIE ? '-ms-transform' : isWebKit ? '-webkit-transform' : isFirefox ? 'MozTransform' : isOpera ? '-o-transform' : '';
|
2384
|
+
rotationStyle[cssTransformKey] = rotationStyle.transform = 'rotate(' + rotation + 'deg)';
|
2376
2385
|
|
2377
2386
|
} else {
|
2378
2387
|
radians = rotation * deg2rad; // deg to rad
|
@@ -2388,7 +2397,6 @@ SVGElement.prototype = {
|
|
2388
2397
|
', M12=', -sintheta, ', M21=', sintheta, ', M22=', costheta,
|
2389
2398
|
', sizingMethod=\'auto expand\')'].join('') : NONE;
|
2390
2399
|
}
|
2391
|
-
|
2392
2400
|
css(elem, rotationStyle);
|
2393
2401
|
}
|
2394
2402
|
|
@@ -2519,7 +2527,7 @@ SVGElement.prototype = {
|
|
2519
2527
|
|
2520
2528
|
|
2521
2529
|
// align
|
2522
|
-
if (
|
2530
|
+
if (align === 'right' || align === 'center') {
|
2523
2531
|
x += (box.width - (alignOptions.width || 0)) /
|
2524
2532
|
{ right: 1, center: 2 }[align];
|
2525
2533
|
}
|
@@ -2527,7 +2535,7 @@ SVGElement.prototype = {
|
|
2527
2535
|
|
2528
2536
|
|
2529
2537
|
// vertical align
|
2530
|
-
if (
|
2538
|
+
if (vAlign === 'bottom' || vAlign === 'middle') {
|
2531
2539
|
y += (box.height - (alignOptions.height || 0)) /
|
2532
2540
|
({ bottom: 1, middle: 2 }[vAlign] || 1);
|
2533
2541
|
|
@@ -2553,6 +2561,7 @@ SVGElement.prototype = {
|
|
2553
2561
|
height,
|
2554
2562
|
rotation = wrapper.rotation,
|
2555
2563
|
element = wrapper.element,
|
2564
|
+
styles = wrapper.styles,
|
2556
2565
|
rad = rotation * deg2rad;
|
2557
2566
|
|
2558
2567
|
if (!bBox) {
|
@@ -2598,6 +2607,11 @@ SVGElement.prototype = {
|
|
2598
2607
|
}
|
2599
2608
|
}
|
2600
2609
|
|
2610
|
+
// Workaround for wrong bounding box in IE9 and IE10 (#1101)
|
2611
|
+
if (isIE && styles && styles.fontSize === '11px' && height === 22.700000762939453) {
|
2612
|
+
bBox.height = 14;
|
2613
|
+
}
|
2614
|
+
|
2601
2615
|
wrapper.bBox = bBox;
|
2602
2616
|
}
|
2603
2617
|
return bBox;
|
@@ -2704,7 +2718,6 @@ SVGElement.prototype = {
|
|
2704
2718
|
var wrapper = this,
|
2705
2719
|
element = wrapper.element || {},
|
2706
2720
|
shadows = wrapper.shadows,
|
2707
|
-
box = wrapper.box,
|
2708
2721
|
key,
|
2709
2722
|
i;
|
2710
2723
|
|
@@ -2734,11 +2747,6 @@ SVGElement.prototype = {
|
|
2734
2747
|
});
|
2735
2748
|
}
|
2736
2749
|
|
2737
|
-
// destroy label box
|
2738
|
-
if (box) {
|
2739
|
-
box.destroy();
|
2740
|
-
}
|
2741
|
-
|
2742
2750
|
// remove from alignObjects
|
2743
2751
|
erase(wrapper.renderer.alignedObjects, wrapper);
|
2744
2752
|
|
@@ -2784,7 +2792,7 @@ SVGElement.prototype = {
|
|
2784
2792
|
shadowElementOpacity = (shadowOptions.opacity || 0.15) / shadowWidth;
|
2785
2793
|
transform = this.parentInverted ?
|
2786
2794
|
'(-1,-1)' :
|
2787
|
-
'(' + (shadowOptions.offsetX
|
2795
|
+
'(' + pick(shadowOptions.offsetX, 1) + ', ' + pick(shadowOptions.offsetY, 1) + ')';
|
2788
2796
|
for (i = 1; i <= shadowWidth; i++) {
|
2789
2797
|
shadow = element.cloneNode(0);
|
2790
2798
|
strokeWidth = (shadowWidth * 2) + 1 - (2 * i);
|
@@ -2965,13 +2973,13 @@ SVGRenderer.prototype = {
|
|
2965
2973
|
hrefRegex = /href="([^"]+)"/,
|
2966
2974
|
parentX = attr(textNode, 'x'),
|
2967
2975
|
textStyles = wrapper.styles,
|
2968
|
-
width = textStyles && pInt(textStyles.width),
|
2976
|
+
width = textStyles && textStyles.width && pInt(textStyles.width),
|
2969
2977
|
textLineHeight = textStyles && textStyles.lineHeight,
|
2970
2978
|
lastLine,
|
2971
2979
|
GET_COMPUTED_STYLE = 'getComputedStyle',
|
2972
2980
|
i = childNodes.length,
|
2973
2981
|
linePositions = [];
|
2974
|
-
|
2982
|
+
|
2975
2983
|
// Needed in IE9 because it doesn't report tspan's offsetHeight (#893)
|
2976
2984
|
function getLineHeightByBBox(lineNo) {
|
2977
2985
|
linePositions[lineNo] = textNode.getBBox ?
|
@@ -3004,13 +3012,11 @@ SVGRenderer.prototype = {
|
|
3004
3012
|
each(spans, function (span) {
|
3005
3013
|
if (span !== '' || spans.length === 1) {
|
3006
3014
|
var attributes = {},
|
3007
|
-
tspan = doc.createElementNS(SVG_NS, 'tspan')
|
3015
|
+
tspan = doc.createElementNS(SVG_NS, 'tspan'),
|
3016
|
+
spanStyle; // #390
|
3008
3017
|
if (styleRegex.test(span)) {
|
3009
|
-
|
3010
|
-
|
3011
|
-
'style',
|
3012
|
-
span.match(styleRegex)[1].replace(/(;| |^)color([ :])/, '$1fill$2')
|
3013
|
-
);
|
3018
|
+
spanStyle = span.match(styleRegex)[1].replace(/(;| |^)color([ :])/, '$1fill$2');
|
3019
|
+
attr(tspan, 'style', spanStyle);
|
3014
3020
|
}
|
3015
3021
|
if (hrefRegex.test(span)) {
|
3016
3022
|
attr(tspan, 'onclick', 'location.href=\"' + span.match(hrefRegex)[1] + '\"');
|
@@ -3073,7 +3079,7 @@ SVGRenderer.prototype = {
|
|
3073
3079
|
|
3074
3080
|
// check width and apply soft breaks
|
3075
3081
|
if (width) {
|
3076
|
-
var words = span.replace(
|
3082
|
+
var words = span.replace(/([^\^])-/g, '$1- ').split(' '), // #1273
|
3077
3083
|
tooLong,
|
3078
3084
|
actualWidth,
|
3079
3085
|
rest = [];
|
@@ -3091,6 +3097,9 @@ SVGRenderer.prototype = {
|
|
3091
3097
|
dy: textLineHeight || 16,
|
3092
3098
|
x: parentX
|
3093
3099
|
});
|
3100
|
+
if (spanStyle) { // #390
|
3101
|
+
attr(tspan, 'style', spanStyle);
|
3102
|
+
}
|
3094
3103
|
textNode.appendChild(tspan);
|
3095
3104
|
|
3096
3105
|
if (actualWidth > width) { // a single word is pressing it out
|
@@ -3724,6 +3733,7 @@ SVGRenderer.prototype = {
|
|
3724
3733
|
// declare variables
|
3725
3734
|
var renderer = this,
|
3726
3735
|
defaultChartStyle = defaultOptions.chart.style,
|
3736
|
+
fakeSVG = useCanVG || (!hasSVG && renderer.forExport),
|
3727
3737
|
wrapper;
|
3728
3738
|
|
3729
3739
|
if (useHTML && !renderer.forExport) {
|
@@ -3745,7 +3755,7 @@ SVGRenderer.prototype = {
|
|
3745
3755
|
});
|
3746
3756
|
|
3747
3757
|
// Prevent wrapping from creating false offsetWidths in export in legacy IE (#1079, #1063)
|
3748
|
-
if (
|
3758
|
+
if (fakeSVG) {
|
3749
3759
|
wrapper.css({
|
3750
3760
|
position: ABSOLUTE
|
3751
3761
|
});
|
@@ -4152,9 +4162,11 @@ SVGRenderer.prototype = {
|
|
4152
4162
|
removeEvent(wrapper.element, 'mouseleave');
|
4153
4163
|
|
4154
4164
|
if (text) {
|
4155
|
-
// Destroy the text element
|
4156
4165
|
text = text.destroy();
|
4157
4166
|
}
|
4167
|
+
if (box) {
|
4168
|
+
box = box.destroy();
|
4169
|
+
}
|
4158
4170
|
// Call base implementation to destroy the rest
|
4159
4171
|
SVGElement.prototype.destroy.call(wrapper);
|
4160
4172
|
}
|
@@ -4642,8 +4654,8 @@ var VMLElement = {
|
|
4642
4654
|
|
4643
4655
|
shadow = createElement(renderer.prepVML(markup),
|
4644
4656
|
null, {
|
4645
|
-
left: pInt(elemStyle.left) + (shadowOptions.offsetX
|
4646
|
-
top: pInt(elemStyle.top) + (shadowOptions.offsetY
|
4657
|
+
left: pInt(elemStyle.left) + pick(shadowOptions.offsetX, 1),
|
4658
|
+
top: pInt(elemStyle.top) + pick(shadowOptions.offsetY, 1)
|
4647
4659
|
}
|
4648
4660
|
);
|
4649
4661
|
if (cutOff) {
|
@@ -5062,9 +5074,9 @@ var VMLRendererExtension = { // inherit SVGRenderer
|
|
5062
5074
|
.attr({ src: src });
|
5063
5075
|
|
5064
5076
|
if (arguments.length > 1) {
|
5065
|
-
obj.
|
5066
|
-
|
5067
|
-
|
5077
|
+
obj.attr({
|
5078
|
+
x: x,
|
5079
|
+
y: y,
|
5068
5080
|
width: width,
|
5069
5081
|
height: height
|
5070
5082
|
});
|
@@ -5289,7 +5301,8 @@ if (useCanVG) {
|
|
5289
5301
|
* together with the canvg library.
|
5290
5302
|
*/
|
5291
5303
|
CanVGRenderer = function () {
|
5292
|
-
//
|
5304
|
+
// Override the global SVG namespace to fake SVG/HTML that accepts CSS
|
5305
|
+
SVG_NS = 'http://www.w3.org/1999/xhtml';
|
5293
5306
|
};
|
5294
5307
|
|
5295
5308
|
/**
|
@@ -5908,7 +5921,8 @@ PlotLineOrBand.prototype = {
|
|
5908
5921
|
/**
|
5909
5922
|
* The class for stack items
|
5910
5923
|
*/
|
5911
|
-
function StackItem(axis, options, isNegative, x, stackOption) {
|
5924
|
+
function StackItem(axis, options, isNegative, x, stackOption, stacking) {
|
5925
|
+
|
5912
5926
|
var inverted = axis.chart.inverted;
|
5913
5927
|
|
5914
5928
|
this.axis = axis;
|
@@ -5922,8 +5936,9 @@ function StackItem(axis, options, isNegative, x, stackOption) {
|
|
5922
5936
|
// Save the x value to be able to position the label later
|
5923
5937
|
this.x = x;
|
5924
5938
|
|
5925
|
-
// Save the stack option on the series configuration object
|
5939
|
+
// Save the stack option on the series configuration object, and whether to treat it as percent
|
5926
5940
|
this.stack = stackOption;
|
5941
|
+
this.percent = stacking === 'percent';
|
5927
5942
|
|
5928
5943
|
// The align options and text align varies on whether the stack is negative and
|
5929
5944
|
// if the chart is inverted or not.
|
@@ -5966,9 +5981,11 @@ StackItem.prototype = {
|
|
5966
5981
|
this.label =
|
5967
5982
|
this.axis.chart.renderer.text(str, 0, 0) // dummy positions, actual position updated with setOffset method in columnseries
|
5968
5983
|
.css(this.options.style) // apply style
|
5969
|
-
.attr({
|
5984
|
+
.attr({
|
5985
|
+
align: this.textAlign, // fix the text-anchor
|
5970
5986
|
rotation: this.options.rotation, // rotation
|
5971
|
-
visibility: HIDDEN
|
5987
|
+
visibility: HIDDEN // hidden until setOffset is called
|
5988
|
+
})
|
5972
5989
|
.add(group); // add to the labels-group
|
5973
5990
|
}
|
5974
5991
|
},
|
@@ -5982,24 +5999,31 @@ StackItem.prototype = {
|
|
5982
5999
|
chart = axis.chart,
|
5983
6000
|
inverted = chart.inverted,
|
5984
6001
|
neg = this.isNegative, // special treatment is needed for negative stacks
|
5985
|
-
y = axis.translate(this.total, 0, 0, 0, 1),
|
6002
|
+
y = axis.translate(this.percent ? 100 : this.total, 0, 0, 0, 1), // stack value translated mapped to chart coordinates
|
5986
6003
|
yZero = axis.translate(0), // stack origin
|
5987
6004
|
h = mathAbs(y - yZero), // stack height
|
5988
6005
|
x = chart.xAxis[0].translate(this.x) + xOffset, // stack x position
|
5989
6006
|
plotHeight = chart.plotHeight,
|
5990
6007
|
stackBox = { // this is the box for the complete stack
|
5991
|
-
|
5992
|
-
|
5993
|
-
|
5994
|
-
|
5995
|
-
}
|
5996
|
-
|
5997
|
-
|
5998
|
-
this.label
|
5999
|
-
.align(this.alignOptions, null, stackBox) // align the label to the box
|
6000
|
-
.attr({visibility: VISIBLE}); // set visibility
|
6001
|
-
}
|
6008
|
+
x: inverted ? (neg ? y : y - h) : x,
|
6009
|
+
y: inverted ? plotHeight - x - xWidth : (neg ? (plotHeight - y - h) : plotHeight - y),
|
6010
|
+
width: inverted ? h : xWidth,
|
6011
|
+
height: inverted ? xWidth : h
|
6012
|
+
},
|
6013
|
+
label = this.label,
|
6014
|
+
alignAttr;
|
6002
6015
|
|
6016
|
+
if (label) {
|
6017
|
+
label.align(this.alignOptions, null, stackBox); // align the label to the box
|
6018
|
+
|
6019
|
+
// Set visibility (#678)
|
6020
|
+
alignAttr = label.alignAttr;
|
6021
|
+
label.attr({
|
6022
|
+
visibility: this.options.crop === false || chart.isInsidePlot(alignAttr.x, alignAttr.y) ?
|
6023
|
+
(hasSVG ? 'inherit' : VISIBLE) :
|
6024
|
+
HIDDEN
|
6025
|
+
});
|
6026
|
+
}
|
6003
6027
|
}
|
6004
6028
|
};
|
6005
6029
|
/**
|
@@ -6511,44 +6535,41 @@ Axis.prototype = {
|
|
6511
6535
|
for (i = 0; i < yDataLength; i++) {
|
6512
6536
|
x = xData[i];
|
6513
6537
|
y = yData[i];
|
6514
|
-
|
6515
|
-
|
6516
|
-
|
6517
|
-
|
6518
|
-
|
6519
|
-
|
6520
|
-
|
6521
|
-
|
6522
|
-
|
6523
|
-
|
6524
|
-
|
6525
|
-
|
6526
|
-
|
6527
|
-
|
6528
|
-
|
6529
|
-
|
6530
|
-
|
6531
|
-
|
6532
|
-
|
6533
|
-
// If the StackItem is there, just update the values,
|
6534
|
-
// if not, create one first
|
6535
|
-
if (!stacks[key][x]) {
|
6536
|
-
stacks[key][x] = new StackItem(axis, axis.options.stackLabels, isNegative, x, stackOption);
|
6537
|
-
}
|
6538
|
-
stacks[key][x].setTotal(y);
|
6538
|
+
|
6539
|
+
// Read stacked values into a stack based on the x value,
|
6540
|
+
// the sign of y and the stack key. Stacking is also handled for null values (#739)
|
6541
|
+
if (stacking) {
|
6542
|
+
isNegative = y < threshold;
|
6543
|
+
pointStack = isNegative ? negPointStack : posPointStack;
|
6544
|
+
key = isNegative ? negKey : stackKey;
|
6545
|
+
|
6546
|
+
y = pointStack[x] =
|
6547
|
+
defined(pointStack[x]) ?
|
6548
|
+
correctFloat(pointStack[x] + y) :
|
6549
|
+
y;
|
6550
|
+
|
6551
|
+
|
6552
|
+
// add the series
|
6553
|
+
if (!stacks[key]) {
|
6554
|
+
stacks[key] = {};
|
6555
|
+
}
|
6539
6556
|
|
6557
|
+
// If the StackItem is there, just update the values,
|
6558
|
+
// if not, create one first
|
6559
|
+
if (!stacks[key][x]) {
|
6560
|
+
stacks[key][x] = new StackItem(axis, axis.options.stackLabels, isNegative, x, stackOption, stacking);
|
6561
|
+
}
|
6562
|
+
stacks[key][x].setTotal(y);
|
6563
|
+
}
|
6564
|
+
|
6565
|
+
// Handle non null values
|
6566
|
+
if (y !== null && y !== UNDEFINED) {
|
6540
6567
|
|
6541
6568
|
// general hook, used for Highstock compare values feature
|
6542
|
-
|
6569
|
+
if (hasModifyValue) {
|
6543
6570
|
y = series.modifyValue(y);
|
6544
6571
|
}
|
6545
6572
|
|
6546
|
-
// get the smallest distance between points
|
6547
|
-
/*if (i) {
|
6548
|
-
distance = mathAbs(xData[i] - xData[i - 1]);
|
6549
|
-
pointRange = pointRange === UNDEFINED ? distance : mathMin(distance, pointRange);
|
6550
|
-
}*/
|
6551
|
-
|
6552
6573
|
// for points within the visible range, including the first point outside the
|
6553
6574
|
// visible range, consider y extremes
|
6554
6575
|
if (cropped || ((xData[i + 1] || x) >= xExtremes.min && (xData[i - 1] || x) <= xExtremes.max)) {
|
@@ -6962,12 +6983,15 @@ Axis.prototype = {
|
|
6962
6983
|
closestPointRange,
|
6963
6984
|
minPointOffset = 0,
|
6964
6985
|
pointRangePadding = 0,
|
6986
|
+
linkedParent = axis.linkedParent,
|
6965
6987
|
transA = axis.transA;
|
6966
6988
|
|
6967
6989
|
// adjust translation for padding
|
6968
6990
|
if (axis.isXAxis) {
|
6969
|
-
if (
|
6970
|
-
minPointOffset =
|
6991
|
+
if (linkedParent) {
|
6992
|
+
minPointOffset = linkedParent.minPointOffset;
|
6993
|
+
pointRangePadding = linkedParent.pointRangePadding;
|
6994
|
+
|
6971
6995
|
} else {
|
6972
6996
|
each(axis.series, function (series) {
|
6973
6997
|
var seriesPointRange = series.pointRange,
|
@@ -7000,8 +7024,9 @@ Axis.prototype = {
|
|
7000
7024
|
});
|
7001
7025
|
}
|
7002
7026
|
|
7003
|
-
// Record
|
7027
|
+
// Record minPointOffset and pointRangePadding
|
7004
7028
|
axis.minPointOffset = minPointOffset;
|
7029
|
+
axis.pointRangePadding = pointRangePadding;
|
7005
7030
|
|
7006
7031
|
// pointRange means the width reserved for each point, like in a column chart
|
7007
7032
|
axis.pointRange = pointRange;
|
@@ -7941,9 +7966,6 @@ function Tooltip(chart, options) {
|
|
7941
7966
|
// Current values of x and y when animating
|
7942
7967
|
this.now = { x: 0, y: 0 };
|
7943
7968
|
|
7944
|
-
// The tooltipTick function, initialized to nothing
|
7945
|
-
//this.tooltipTick = UNDEFINED;
|
7946
|
-
|
7947
7969
|
// The tooltip is initially hidden
|
7948
7970
|
this.isHidden = true;
|
7949
7971
|
|
@@ -8011,13 +8033,21 @@ Tooltip.prototype = {
|
|
8011
8033
|
// move to the intermediate value
|
8012
8034
|
tooltip.label.attr(now);
|
8013
8035
|
|
8036
|
+
|
8014
8037
|
// run on next tick of the mouse tracker
|
8015
8038
|
if (animate && (mathAbs(x - now.x) > 1 || mathAbs(y - now.y) > 1)) {
|
8016
|
-
|
8017
|
-
|
8018
|
-
|
8019
|
-
|
8020
|
-
|
8039
|
+
|
8040
|
+
// never allow two timeouts
|
8041
|
+
clearTimeout(this.tooltipTimeout);
|
8042
|
+
|
8043
|
+
// set the fixed interval ticking for the smooth tooltip
|
8044
|
+
this.tooltipTimeout = setTimeout(function () {
|
8045
|
+
// The interval function may still be running during destroy, so check that the chart is really there before calling.
|
8046
|
+
if (tooltip) {
|
8047
|
+
tooltip.move(x, y, anchorX, anchorY);
|
8048
|
+
}
|
8049
|
+
}, 32);
|
8050
|
+
|
8021
8051
|
}
|
8022
8052
|
},
|
8023
8053
|
|
@@ -8114,7 +8144,7 @@ Tooltip.prototype = {
|
|
8114
8144
|
|
8115
8145
|
// It is too far to the left, adjust it
|
8116
8146
|
if (x < 7) {
|
8117
|
-
x = plotLeft + pointX + distance;
|
8147
|
+
x = plotLeft + mathMax(pointX, 0) + distance;
|
8118
8148
|
}
|
8119
8149
|
|
8120
8150
|
// Test to see if the tooltip is too far to the right,
|
@@ -8140,7 +8170,6 @@ Tooltip.prototype = {
|
|
8140
8170
|
if (y + boxHeight > plotTop + plotHeight) {
|
8141
8171
|
y = mathMax(plotTop, plotTop + plotHeight - boxHeight - distance); // below
|
8142
8172
|
}
|
8143
|
-
|
8144
8173
|
|
8145
8174
|
return {x: x, y: y};
|
8146
8175
|
},
|
@@ -8320,15 +8349,6 @@ Tooltip.prototype = {
|
|
8320
8349
|
y: y + chart.plotTop,
|
8321
8350
|
borderColor: borderColor
|
8322
8351
|
});
|
8323
|
-
},
|
8324
|
-
|
8325
|
-
/**
|
8326
|
-
* Runs the tooltip animation one tick.
|
8327
|
-
*/
|
8328
|
-
tick: function () {
|
8329
|
-
if (this.tooltipTick) {
|
8330
|
-
this.tooltipTick();
|
8331
|
-
}
|
8332
8352
|
}
|
8333
8353
|
};
|
8334
8354
|
/**
|
@@ -8350,7 +8370,7 @@ function MouseTracker(chart, options) {
|
|
8350
8370
|
this.chart = chart;
|
8351
8371
|
|
8352
8372
|
// The interval id
|
8353
|
-
//this.
|
8373
|
+
//this.tooltipTimeout = UNDEFINED;
|
8354
8374
|
|
8355
8375
|
// The cached x hover position
|
8356
8376
|
//this.hoverX = UNDEFINED;
|
@@ -8907,7 +8927,7 @@ MouseTracker.prototype = {
|
|
8907
8927
|
container.onclick = container.onmousedown = container.onmousemove = container.ontouchstart = container.ontouchend = container.ontouchmove = null;
|
8908
8928
|
|
8909
8929
|
// memory and CPU leak
|
8910
|
-
clearInterval(this.
|
8930
|
+
clearInterval(this.tooltipTimeout);
|
8911
8931
|
},
|
8912
8932
|
|
8913
8933
|
// Run MouseTracker
|
@@ -8920,14 +8940,6 @@ MouseTracker.prototype = {
|
|
8920
8940
|
|
8921
8941
|
if (options.enabled) {
|
8922
8942
|
chart.tooltip = new Tooltip(chart, options);
|
8923
|
-
|
8924
|
-
// set the fixed interval ticking for the smooth tooltip
|
8925
|
-
this.tooltipInterval = setInterval(function () {
|
8926
|
-
// The interval function may still be running during destroy, so check that the chart is really there before calling.
|
8927
|
-
if (chart && chart.tooltip) {
|
8928
|
-
chart.tooltip.tick();
|
8929
|
-
}
|
8930
|
-
}, 32);
|
8931
8943
|
}
|
8932
8944
|
|
8933
8945
|
this.setDOMEvents();
|
@@ -9012,19 +9024,37 @@ Legend.prototype = {
|
|
9012
9024
|
legendSymbol = item.legendSymbol,
|
9013
9025
|
hiddenColor = legend.itemHiddenStyle.color,
|
9014
9026
|
textColor = visible ? options.itemStyle.color : hiddenColor,
|
9015
|
-
symbolColor = visible ? item.color : hiddenColor
|
9027
|
+
symbolColor = visible ? item.color : hiddenColor,
|
9028
|
+
markerOptions = item.options && item.options.marker,
|
9029
|
+
symbolAttr = {
|
9030
|
+
stroke: symbolColor,
|
9031
|
+
fill: symbolColor
|
9032
|
+
},
|
9033
|
+
key,
|
9034
|
+
val;
|
9016
9035
|
|
9036
|
+
|
9017
9037
|
if (legendItem) {
|
9018
9038
|
legendItem.css({ fill: textColor });
|
9019
9039
|
}
|
9020
9040
|
if (legendLine) {
|
9021
9041
|
legendLine.attr({ stroke: symbolColor });
|
9022
9042
|
}
|
9043
|
+
|
9023
9044
|
if (legendSymbol) {
|
9024
|
-
|
9025
|
-
|
9026
|
-
|
9027
|
-
|
9045
|
+
|
9046
|
+
// Apply marker options
|
9047
|
+
if (markerOptions) {
|
9048
|
+
markerOptions = item.convertAttribs(markerOptions);
|
9049
|
+
for (key in markerOptions) {
|
9050
|
+
val = markerOptions[key];
|
9051
|
+
if (val !== UNDEFINED) {
|
9052
|
+
symbolAttr[key] = val;
|
9053
|
+
}
|
9054
|
+
}
|
9055
|
+
}
|
9056
|
+
|
9057
|
+
legendSymbol.attr(symbolAttr);
|
9028
9058
|
}
|
9029
9059
|
},
|
9030
9060
|
|
@@ -9714,7 +9744,8 @@ Chart.prototype = {
|
|
9714
9744
|
i = seriesLength,
|
9715
9745
|
serie,
|
9716
9746
|
renderer = chart.renderer,
|
9717
|
-
isHiddenChart = renderer.isHidden()
|
9747
|
+
isHiddenChart = renderer.isHidden(),
|
9748
|
+
afterRedraw = [];
|
9718
9749
|
|
9719
9750
|
setAnimation(animation, chart);
|
9720
9751
|
|
@@ -9778,7 +9809,9 @@ Chart.prototype = {
|
|
9778
9809
|
// Fire 'afterSetExtremes' only if extremes are set
|
9779
9810
|
if (axis.isDirtyExtremes) { // #821
|
9780
9811
|
axis.isDirtyExtremes = false;
|
9781
|
-
|
9812
|
+
afterRedraw.push(function () { // prevent a recursive call to chart.redraw() (#1119)
|
9813
|
+
fireEvent(axis, 'afterSetExtremes', axis.getExtremes()); // #747, #751
|
9814
|
+
});
|
9782
9815
|
}
|
9783
9816
|
|
9784
9817
|
if (axis.isDirty || isDirtyBox || hasStackedSeries) {
|
@@ -9819,6 +9852,11 @@ Chart.prototype = {
|
|
9819
9852
|
if (isHiddenChart) {
|
9820
9853
|
chart.cloneRenderTo(true);
|
9821
9854
|
}
|
9855
|
+
|
9856
|
+
// Fire callbacks that are put on hold until after the redraw
|
9857
|
+
each(afterRedraw, function (callback) {
|
9858
|
+
callback.call();
|
9859
|
+
});
|
9822
9860
|
},
|
9823
9861
|
|
9824
9862
|
|
@@ -10379,9 +10417,9 @@ Chart.prototype = {
|
|
10379
10417
|
initReflow: function () {
|
10380
10418
|
var chart = this,
|
10381
10419
|
optionsChart = chart.options.chart,
|
10382
|
-
renderTo = chart.renderTo
|
10383
|
-
|
10384
|
-
|
10420
|
+
renderTo = chart.renderTo,
|
10421
|
+
reflowTimeout;
|
10422
|
+
|
10385
10423
|
function reflow(e) {
|
10386
10424
|
var width = optionsChart.width || adapterRun(renderTo, 'width'),
|
10387
10425
|
height = optionsChart.height || adapterRun(renderTo, 'height'),
|
@@ -10393,8 +10431,10 @@ Chart.prototype = {
|
|
10393
10431
|
|
10394
10432
|
if (width !== chart.containerWidth || height !== chart.containerHeight) {
|
10395
10433
|
clearTimeout(reflowTimeout);
|
10396
|
-
reflowTimeout = setTimeout(function () {
|
10397
|
-
chart.
|
10434
|
+
chart.reflowTimeout = reflowTimeout = setTimeout(function () {
|
10435
|
+
if (chart.container) { // It may have been destroyed in the meantime (#1257)
|
10436
|
+
chart.resize(width, height, false);
|
10437
|
+
}
|
10398
10438
|
}, 100);
|
10399
10439
|
}
|
10400
10440
|
chart.containerWidth = width;
|
@@ -10483,7 +10523,7 @@ Chart.prototype = {
|
|
10483
10523
|
}
|
10484
10524
|
|
10485
10525
|
// Move resize button (#1115)
|
10486
|
-
if (resetZoomButton) {
|
10526
|
+
if (resetZoomButton && resetZoomButton.align) {
|
10487
10527
|
resetZoomButton.align(null, null, chart[resetZoomButton.alignTo]);
|
10488
10528
|
}
|
10489
10529
|
|
@@ -10841,18 +10881,10 @@ Chart.prototype = {
|
|
10841
10881
|
var chart = this,
|
10842
10882
|
axes = chart.axes,
|
10843
10883
|
series = chart.series,
|
10844
|
-
container = chart.container
|
10845
|
-
|
10846
|
-
var i,
|
10884
|
+
container = chart.container,
|
10885
|
+
i,
|
10847
10886
|
parentNode = container && container.parentNode;
|
10848
10887
|
|
10849
|
-
// If the chart is destroyed already, do nothing.
|
10850
|
-
// This will happen if if a script invokes chart.destroy and
|
10851
|
-
// then it will be called again on win.unload
|
10852
|
-
if (chart === null) {
|
10853
|
-
return;
|
10854
|
-
}
|
10855
|
-
|
10856
10888
|
// fire the chart.destoy event
|
10857
10889
|
fireEvent(chart, 'destroy');
|
10858
10890
|
|
@@ -10876,7 +10908,7 @@ Chart.prototype = {
|
|
10876
10908
|
each(['title', 'subtitle', 'chartBackground', 'plotBackground', 'plotBGImage', 'plotBorder', 'seriesGroup', 'clipRect', 'credits', 'tracker', 'scroller', 'rangeSelector', 'legend', 'resetZoomButton', 'tooltip', 'renderer'], function (name) {
|
10877
10909
|
var prop = chart[name];
|
10878
10910
|
|
10879
|
-
if (prop) {
|
10911
|
+
if (prop && prop.destroy) {
|
10880
10912
|
chart[name] = prop.destroy();
|
10881
10913
|
}
|
10882
10914
|
});
|
@@ -10889,8 +10921,6 @@ Chart.prototype = {
|
|
10889
10921
|
discardElement(container);
|
10890
10922
|
}
|
10891
10923
|
|
10892
|
-
// IE6 leak
|
10893
|
-
container = null;
|
10894
10924
|
}
|
10895
10925
|
|
10896
10926
|
// clean it all up
|
@@ -10898,8 +10928,6 @@ Chart.prototype = {
|
|
10898
10928
|
delete chart[i];
|
10899
10929
|
}
|
10900
10930
|
|
10901
|
-
chart.options = null;
|
10902
|
-
chart = null;
|
10903
10931
|
},
|
10904
10932
|
|
10905
10933
|
/**
|
@@ -11297,7 +11325,7 @@ Point.prototype = {
|
|
11297
11325
|
parts,
|
11298
11326
|
prop,
|
11299
11327
|
i,
|
11300
|
-
cfg = {
|
11328
|
+
cfg = {
|
11301
11329
|
y: 0, // 0: use 'value' for repOptionKey
|
11302
11330
|
open: 0,
|
11303
11331
|
high: 0,
|
@@ -11875,7 +11903,6 @@ Series.prototype = {
|
|
11875
11903
|
2 * radius,
|
11876
11904
|
2 * radius
|
11877
11905
|
)
|
11878
|
-
.attr(this.pointAttr[NORMAL_STATE])
|
11879
11906
|
.add(legendItemGroup);
|
11880
11907
|
}
|
11881
11908
|
},
|
@@ -12298,7 +12325,11 @@ Series.prototype = {
|
|
12298
12325
|
yValue = yBottom + yValue;
|
12299
12326
|
|
12300
12327
|
if (isBottomSeries) {
|
12301
|
-
yBottom = pick(options.threshold, yAxis.
|
12328
|
+
yBottom = pick(options.threshold, yAxis.min);
|
12329
|
+
}
|
12330
|
+
|
12331
|
+
if (yAxis.isLog && yBottom <= 0) { // #1200, #1232
|
12332
|
+
yBottom = null;
|
12302
12333
|
}
|
12303
12334
|
|
12304
12335
|
if (stacking === 'percent') {
|
@@ -12417,7 +12448,7 @@ Series.prototype = {
|
|
12417
12448
|
}
|
12418
12449
|
|
12419
12450
|
return tooltipOptions.headerFormat
|
12420
|
-
.replace('{point.key}', isDateTime ? dateFormat(xDateFormat, key) : key)
|
12451
|
+
.replace('{point.key}', isDateTime && isNumber(key) ? dateFormat(xDateFormat, key) : key)
|
12421
12452
|
.replace('{series.name}', series.name)
|
12422
12453
|
.replace('{series.color}', series.color);
|
12423
12454
|
},
|
@@ -12636,6 +12667,9 @@ Series.prototype = {
|
|
12636
12667
|
.attr(pointAttr)
|
12637
12668
|
.add(markerGroup);
|
12638
12669
|
}
|
12670
|
+
|
12671
|
+
} else if (graphic) {
|
12672
|
+
point.graphic = graphic.destroy(); // #1269
|
12639
12673
|
}
|
12640
12674
|
}
|
12641
12675
|
}
|
@@ -12875,59 +12909,21 @@ Series.prototype = {
|
|
12875
12909
|
|
12876
12910
|
var series = this,
|
12877
12911
|
seriesOptions = series.options,
|
12878
|
-
options = seriesOptions.dataLabels
|
12912
|
+
options = seriesOptions.dataLabels,
|
12913
|
+
points = series.points,
|
12914
|
+
pointOptions,
|
12915
|
+
generalOptions,
|
12916
|
+
str,
|
12917
|
+
dataLabelsGroup;
|
12879
12918
|
|
12880
12919
|
if (options.enabled || series._hasPointLabels) {
|
12881
|
-
|
12882
|
-
|
12883
|
-
|
12884
|
-
|
12885
|
-
generalOptions,
|
12886
|
-
str,
|
12887
|
-
dataLabelsGroup,
|
12888
|
-
chart = series.chart,
|
12889
|
-
renderer = chart.renderer,
|
12890
|
-
inverted = chart.inverted,
|
12891
|
-
seriesType = series.type,
|
12892
|
-
stacking = seriesOptions.stacking,
|
12893
|
-
isBarLike = seriesType === 'column' || seriesType === 'bar',
|
12894
|
-
vAlignIsNull = options.verticalAlign === null,
|
12895
|
-
yIsNull = options.y === null,
|
12896
|
-
fontMetrics = renderer.fontMetrics(options.style.fontSize), // height and baseline
|
12897
|
-
fontLineHeight = fontMetrics.h,
|
12898
|
-
fontBaseline = fontMetrics.b;
|
12899
|
-
|
12900
|
-
if (isBarLike) {
|
12901
|
-
var defaultYs = {
|
12902
|
-
top: fontBaseline,
|
12903
|
-
middle: fontBaseline - fontLineHeight / 2,
|
12904
|
-
bottom: -fontLineHeight + fontBaseline
|
12905
|
-
};
|
12906
|
-
if (stacking) {
|
12907
|
-
// In stacked series the default label placement is inside the bars
|
12908
|
-
if (vAlignIsNull) {
|
12909
|
-
options = merge(options, {verticalAlign: 'middle'});
|
12910
|
-
}
|
12911
|
-
|
12912
|
-
// If no y delta is specified, try to create a good default
|
12913
|
-
if (yIsNull) {
|
12914
|
-
options = merge(options, { y: defaultYs[options.verticalAlign]});
|
12915
|
-
}
|
12916
|
-
} else {
|
12917
|
-
// In non stacked series the default label placement is on top of the bars
|
12918
|
-
if (vAlignIsNull) {
|
12919
|
-
options = merge(options, {verticalAlign: 'top'});
|
12920
|
-
|
12921
|
-
// If no y delta is specified, try to create a good default (like default bar)
|
12922
|
-
} else if (yIsNull) {
|
12923
|
-
options = merge(options, { y: defaultYs[options.verticalAlign]});
|
12924
|
-
}
|
12925
|
-
|
12926
|
-
}
|
12920
|
+
|
12921
|
+
// Process default alignment of data labels for columns
|
12922
|
+
if (series.dlProcessOptions) {
|
12923
|
+
series.dlProcessOptions(options);
|
12927
12924
|
}
|
12928
12925
|
|
12929
|
-
|
12930
|
-
// create a separate group for the data labels to avoid rotation
|
12926
|
+
// Create a separate group for the data labels to avoid rotation
|
12931
12927
|
dataLabelsGroup = series.plotGroup(
|
12932
12928
|
'dataLabelsGroup',
|
12933
12929
|
'data-labels',
|
@@ -12935,47 +12931,21 @@ Series.prototype = {
|
|
12935
12931
|
6
|
12936
12932
|
);
|
12937
12933
|
|
12938
|
-
//
|
12934
|
+
// Make the labels for each point
|
12939
12935
|
generalOptions = options;
|
12940
12936
|
each(points, function (point) {
|
12941
12937
|
|
12942
|
-
var
|
12943
|
-
|
12944
|
-
|
12945
|
-
|
12946
|
-
|
12947
|
-
|
12948
|
-
// Merge in individual options from point
|
12949
|
-
options = generalOptions; // reset changes from previous points
|
12950
|
-
pointOptions = point.options;
|
12951
|
-
if (pointOptions && pointOptions.dataLabels) {
|
12952
|
-
options = merge(options, pointOptions.dataLabels);
|
12953
|
-
}
|
12954
|
-
enabled = options.enabled;
|
12938
|
+
var enabled,
|
12939
|
+
dataLabel = point.dataLabel,
|
12940
|
+
attr,
|
12941
|
+
name,
|
12942
|
+
rotation,
|
12943
|
+
isNew = true;
|
12955
12944
|
|
12956
|
-
//
|
12957
|
-
|
12958
|
-
|
12959
|
-
plotY = pick(point.plotY, -999);
|
12960
|
-
|
12961
|
-
// if options.y is null, which happens by default on column charts, set the position
|
12962
|
-
// above or below the column depending on the threshold
|
12963
|
-
individualYDelta = options.y === null ?
|
12964
|
-
(point.y >= seriesOptions.threshold ?
|
12965
|
-
-fontLineHeight + fontBaseline : // below the threshold
|
12966
|
-
fontBaseline) : // above the threshold
|
12967
|
-
options.y;
|
12968
|
-
|
12969
|
-
x = (inverted ? chart.plotWidth - plotY : plotX) + options.x;
|
12970
|
-
y = mathRound((inverted ? chart.plotHeight - plotX : plotY) + individualYDelta);
|
12971
|
-
|
12972
|
-
}
|
12945
|
+
// Determine if each data label is enabled
|
12946
|
+
pointOptions = point.options && point.options.dataLabels;
|
12947
|
+
enabled = generalOptions.enabled || (pointOptions && pointOptions.enabled);
|
12973
12948
|
|
12974
|
-
// Check if the individual label must be disabled due to either falling
|
12975
|
-
// ouside the plot area, or the enabled option being switched off
|
12976
|
-
if (series.isCartesian && !chart.isInsidePlot(x - options.x, y)) {
|
12977
|
-
enabled = false;
|
12978
|
-
}
|
12979
12949
|
|
12980
12950
|
// If the point is outside the plot area, destroy it. #678, #820
|
12981
12951
|
if (dataLabel && !enabled) {
|
@@ -12985,23 +12955,15 @@ Series.prototype = {
|
|
12985
12955
|
// in the point options, or if they fall outside the plot area.
|
12986
12956
|
} else if (enabled) {
|
12987
12957
|
|
12988
|
-
|
12989
|
-
|
12990
|
-
|
12958
|
+
rotation = options.rotation;
|
12959
|
+
|
12960
|
+
// Create individual options structure that can be extended without
|
12961
|
+
// affecting others
|
12962
|
+
options = merge(generalOptions, pointOptions);
|
12991
12963
|
|
12992
12964
|
// Get the string
|
12993
12965
|
str = options.formatter.call(point.getLabelConfig(), options);
|
12994
12966
|
|
12995
|
-
// in columns, align the string to the column
|
12996
|
-
if (seriesType === 'column') {
|
12997
|
-
x += { left: -1, right: 1 }[align] * point.barW / 2 || 0;
|
12998
|
-
}
|
12999
|
-
|
13000
|
-
if (!stacking && inverted && point.y < 0) {
|
13001
|
-
align = 'right';
|
13002
|
-
x -= 10;
|
13003
|
-
}
|
13004
|
-
|
13005
12967
|
// Determine the color
|
13006
12968
|
options.style.color = pick(options.color, options.style.color, series.color, 'black');
|
13007
12969
|
|
@@ -13012,19 +12974,17 @@ Series.prototype = {
|
|
13012
12974
|
dataLabel
|
13013
12975
|
.attr({
|
13014
12976
|
text: str
|
13015
|
-
}).animate({
|
13016
|
-
x: x,
|
13017
|
-
y: y
|
13018
12977
|
});
|
12978
|
+
isNew = false;
|
13019
12979
|
// create new label
|
13020
12980
|
} else if (defined(str)) {
|
13021
12981
|
attr = {
|
13022
|
-
align: align,
|
12982
|
+
//align: align,
|
13023
12983
|
fill: options.backgroundColor,
|
13024
12984
|
stroke: options.borderColor,
|
13025
12985
|
'stroke-width': options.borderWidth,
|
13026
12986
|
r: options.borderRadius || 0,
|
13027
|
-
rotation:
|
12987
|
+
rotation: rotation,
|
13028
12988
|
padding: options.padding,
|
13029
12989
|
zIndex: 1
|
13030
12990
|
};
|
@@ -13035,43 +12995,78 @@ Series.prototype = {
|
|
13035
12995
|
}
|
13036
12996
|
}
|
13037
12997
|
|
13038
|
-
dataLabel = point.dataLabel = renderer[
|
12998
|
+
dataLabel = point.dataLabel = series.chart.renderer[rotation ? 'text' : 'label']( // labels don't support rotation
|
13039
12999
|
str,
|
13040
|
-
|
13041
|
-
|
13000
|
+
0,
|
13001
|
+
-999,
|
13042
13002
|
null,
|
13043
13003
|
null,
|
13044
13004
|
null,
|
13045
|
-
options.useHTML
|
13046
|
-
true // baseline for backwards compat
|
13005
|
+
options.useHTML
|
13047
13006
|
)
|
13048
13007
|
.attr(attr)
|
13049
13008
|
.css(options.style)
|
13050
13009
|
.add(dataLabelsGroup)
|
13051
13010
|
.shadow(options.shadow);
|
13011
|
+
|
13052
13012
|
}
|
13053
|
-
|
13054
|
-
if (isBarLike && seriesOptions.stacking && dataLabel) {
|
13055
|
-
var barX = point.barX,
|
13056
|
-
barY = point.barY,
|
13057
|
-
barW = point.barW,
|
13058
|
-
barH = point.barH;
|
13059
|
-
|
13060
|
-
dataLabel.align(options, null,
|
13061
|
-
{
|
13062
|
-
x: inverted ? chart.plotWidth - barY - barH : barX,
|
13063
|
-
y: inverted ? chart.plotHeight - barX - barW : barY,
|
13064
|
-
width: inverted ? barH : barW,
|
13065
|
-
height: inverted ? barW : barH
|
13066
|
-
});
|
13067
|
-
}
|
13068
|
-
|
13069
13013
|
|
13014
|
+
// Now the data label is created and placed at 0,0, so we need to align it
|
13015
|
+
if (dataLabel) {
|
13016
|
+
series.alignDataLabel(point, dataLabel, options, null, isNew);
|
13017
|
+
}
|
13070
13018
|
}
|
13071
13019
|
});
|
13072
13020
|
}
|
13073
13021
|
},
|
13074
13022
|
|
13023
|
+
/**
|
13024
|
+
* Align each individual data label
|
13025
|
+
*/
|
13026
|
+
alignDataLabel: function (point, dataLabel, options, alignTo, isNew) {
|
13027
|
+
var chart = this.chart,
|
13028
|
+
inverted = chart.inverted,
|
13029
|
+
plotX = pick(point.plotX, -999),
|
13030
|
+
plotY = pick(point.plotY, -999),
|
13031
|
+
bBox = dataLabel.getBBox(),
|
13032
|
+
alignAttr; // the final position;
|
13033
|
+
|
13034
|
+
// The alignment box is a singular point
|
13035
|
+
alignTo = extend({
|
13036
|
+
x: inverted ? chart.plotWidth - plotY : plotX,
|
13037
|
+
y: mathRound(inverted ? chart.plotHeight - plotX : plotY),
|
13038
|
+
width: 0,
|
13039
|
+
height: 0
|
13040
|
+
}, alignTo);
|
13041
|
+
|
13042
|
+
// Add the text size for alignment calculation
|
13043
|
+
extend(options, {
|
13044
|
+
width: bBox.width,
|
13045
|
+
height: bBox.height
|
13046
|
+
});
|
13047
|
+
|
13048
|
+
// Allow a hook for changing alignment in the last moment, then do the alignment
|
13049
|
+
if (options.rotation) { // Fancy box alignment isn't supported for rotated text
|
13050
|
+
alignAttr = {
|
13051
|
+
align: options.align,
|
13052
|
+
x: alignTo.x + options.x + alignTo.width / 2,
|
13053
|
+
y: alignTo.y + options.y + alignTo.height / 2
|
13054
|
+
};
|
13055
|
+
dataLabel[isNew ? 'attr' : 'animate'](alignAttr);
|
13056
|
+
} else {
|
13057
|
+
dataLabel.align(options, null, alignTo);
|
13058
|
+
alignAttr = dataLabel.alignAttr;
|
13059
|
+
}
|
13060
|
+
|
13061
|
+
// Show or hide based on the final aligned position
|
13062
|
+
dataLabel.attr({
|
13063
|
+
visibility: options.crop === false || chart.isInsidePlot(alignAttr.x, alignAttr.y) || chart.isInsidePlot(plotX, plotY, inverted) ?
|
13064
|
+
(hasSVG ? 'inherit' : VISIBLE) :
|
13065
|
+
HIDDEN
|
13066
|
+
});
|
13067
|
+
|
13068
|
+
},
|
13069
|
+
|
13075
13070
|
/**
|
13076
13071
|
* Return the graph path of a segment
|
13077
13072
|
*/
|
@@ -13270,8 +13265,6 @@ Series.prototype = {
|
|
13270
13265
|
chartSeriesGroup
|
13271
13266
|
);
|
13272
13267
|
|
13273
|
-
series.drawDataLabels();
|
13274
|
-
|
13275
13268
|
// initiate the animation
|
13276
13269
|
if (doAnimation) {
|
13277
13270
|
series.animate(true);
|
@@ -13290,6 +13283,10 @@ Series.prototype = {
|
|
13290
13283
|
|
13291
13284
|
// draw the points
|
13292
13285
|
series.drawPoints();
|
13286
|
+
|
13287
|
+
// draw the data labels
|
13288
|
+
series.drawDataLabels();
|
13289
|
+
|
13293
13290
|
|
13294
13291
|
// draw the mouse tracking area
|
13295
13292
|
if (series.options.enableMouseTracking !== false) {
|
@@ -13880,8 +13877,9 @@ defaultPlotOptions.column = merge(defaultSeriesOptions, {
|
|
13880
13877
|
}
|
13881
13878
|
},
|
13882
13879
|
dataLabels: {
|
13883
|
-
|
13884
|
-
verticalAlign: null
|
13880
|
+
align: null, // auto
|
13881
|
+
verticalAlign: null, // auto
|
13882
|
+
y: null
|
13885
13883
|
},
|
13886
13884
|
threshold: 0
|
13887
13885
|
});
|
@@ -13981,7 +13979,7 @@ var ColumnSeries = extendClass(Series, {
|
|
13981
13979
|
pointOffsetWidth - (categoryWidth / 2)) *
|
13982
13980
|
(reversedXAxis ? -1 : 1),
|
13983
13981
|
threshold = options.threshold,
|
13984
|
-
translatedThreshold = series.yAxis.getThreshold(threshold),
|
13982
|
+
translatedThreshold = series.translatedThreshold = series.yAxis.getThreshold(threshold),
|
13985
13983
|
minPointLength = pick(options.minPointLength, 5);
|
13986
13984
|
|
13987
13985
|
// record the new values
|
@@ -14010,13 +14008,8 @@ var ColumnSeries = extendClass(Series, {
|
|
14010
14008
|
}
|
14011
14009
|
}
|
14012
14010
|
|
14013
|
-
|
14014
|
-
|
14015
|
-
barY: barY,
|
14016
|
-
barW: barW,
|
14017
|
-
barH: barH,
|
14018
|
-
pointWidth: pointWidth
|
14019
|
-
});
|
14011
|
+
point.barX = barX;
|
14012
|
+
point.pointWidth = pointWidth;
|
14020
14013
|
|
14021
14014
|
// create shape type and shape args that are reused in drawPoints and drawTracker
|
14022
14015
|
point.shapeType = 'rect';
|
@@ -14058,15 +14051,14 @@ var ColumnSeries = extendClass(Series, {
|
|
14058
14051
|
var series = this,
|
14059
14052
|
options = series.options,
|
14060
14053
|
renderer = series.chart.renderer,
|
14061
|
-
graphic,
|
14062
14054
|
shapeArgs;
|
14063
14055
|
|
14064
14056
|
|
14065
14057
|
// draw the columns
|
14066
14058
|
each(series.points, function (point) {
|
14067
|
-
var plotY = point.plotY
|
14068
|
-
if (plotY !== UNDEFINED && !isNaN(plotY) && point.y !== null) {
|
14059
|
+
var plotY = point.plotY,
|
14069
14060
|
graphic = point.graphic;
|
14061
|
+
if (plotY !== UNDEFINED && !isNaN(plotY) && point.y !== null) {
|
14070
14062
|
shapeArgs = point.shapeArgs;
|
14071
14063
|
if (graphic) { // update
|
14072
14064
|
stop(graphic);
|
@@ -14079,6 +14071,8 @@ var ColumnSeries = extendClass(Series, {
|
|
14079
14071
|
.shadow(options.shadow, null, options.stacking && !options.borderRadius);
|
14080
14072
|
}
|
14081
14073
|
|
14074
|
+
} else if (graphic) {
|
14075
|
+
point.graphic = graphic.destroy(); // #1269
|
14082
14076
|
}
|
14083
14077
|
});
|
14084
14078
|
},
|
@@ -14141,6 +14135,54 @@ var ColumnSeries = extendClass(Series, {
|
|
14141
14135
|
}
|
14142
14136
|
});
|
14143
14137
|
},
|
14138
|
+
|
14139
|
+
/**
|
14140
|
+
* Override the basic data label alignment by adjusting for the position of the column
|
14141
|
+
*/
|
14142
|
+
alignDataLabel: function (point, dataLabel, options, alignTo, isNew) {
|
14143
|
+
var chart = this.chart,
|
14144
|
+
inverted = chart.inverted,
|
14145
|
+
below = point.below || (point.plotY > (this.translatedThreshold || chart.plotSizeY)),
|
14146
|
+
inside = (this.options.stacking || options.inside); // draw it inside the box?
|
14147
|
+
|
14148
|
+
// Align to the column itself, or the top of it
|
14149
|
+
if (point.shapeArgs) { // Area range uses this method but not alignTo
|
14150
|
+
alignTo = merge(point.shapeArgs);
|
14151
|
+
if (inverted) {
|
14152
|
+
alignTo = {
|
14153
|
+
x: chart.plotWidth - alignTo.y - alignTo.height,
|
14154
|
+
y: chart.plotHeight - alignTo.x - alignTo.width,
|
14155
|
+
width: alignTo.height,
|
14156
|
+
height: alignTo.width
|
14157
|
+
};
|
14158
|
+
}
|
14159
|
+
|
14160
|
+
// Compute the alignment box
|
14161
|
+
if (!inside) {
|
14162
|
+
if (inverted) {
|
14163
|
+
alignTo.x += below ? 0 : alignTo.width;
|
14164
|
+
alignTo.width = 0;
|
14165
|
+
} else {
|
14166
|
+
alignTo.y += below ? alignTo.height : 0;
|
14167
|
+
alignTo.height = 0;
|
14168
|
+
}
|
14169
|
+
}
|
14170
|
+
}
|
14171
|
+
|
14172
|
+
// When alignment is undefined (typically columns and bars), display the individual
|
14173
|
+
// point below or above the point depending on the threshold
|
14174
|
+
options.align = pick(
|
14175
|
+
options.align,
|
14176
|
+
!inverted || inside ? 'center' : below ? 'right' : 'left'
|
14177
|
+
);
|
14178
|
+
options.verticalAlign = pick(
|
14179
|
+
options.verticalAlign,
|
14180
|
+
inverted || inside ? 'middle' : below ? 'top' : 'bottom'
|
14181
|
+
);
|
14182
|
+
|
14183
|
+
// Call the parent method
|
14184
|
+
Series.prototype.alignDataLabel.call(this, point, dataLabel, options, alignTo, isNew);
|
14185
|
+
},
|
14144
14186
|
|
14145
14187
|
|
14146
14188
|
/**
|
@@ -14214,14 +14256,7 @@ seriesTypes.column = ColumnSeries;
|
|
14214
14256
|
/**
|
14215
14257
|
* Set the default options for bar
|
14216
14258
|
*/
|
14217
|
-
defaultPlotOptions.bar = merge(defaultPlotOptions.column
|
14218
|
-
dataLabels: {
|
14219
|
-
align: 'left',
|
14220
|
-
x: 5,
|
14221
|
-
y: null,
|
14222
|
-
verticalAlign: 'middle'
|
14223
|
-
}
|
14224
|
-
});
|
14259
|
+
defaultPlotOptions.bar = merge(defaultPlotOptions.column);
|
14225
14260
|
/**
|
14226
14261
|
* The Bar series class
|
14227
14262
|
*/
|
@@ -14334,9 +14369,9 @@ defaultPlotOptions.pie = merge(defaultSeriesOptions, {
|
|
14334
14369
|
enabled: true,
|
14335
14370
|
formatter: function () {
|
14336
14371
|
return this.point.name;
|
14337
|
-
}
|
14372
|
+
}
|
14338
14373
|
// softConnector: true,
|
14339
|
-
y:
|
14374
|
+
//y: 0
|
14340
14375
|
},
|
14341
14376
|
//innerSize: 0,
|
14342
14377
|
legendType: 'point',
|
@@ -14578,7 +14613,10 @@ var PieSeries = {
|
|
14578
14613
|
radiusX, // the x component of the radius vector for a given point
|
14579
14614
|
radiusY,
|
14580
14615
|
labelDistance = options.dataLabels.distance,
|
14581
|
-
ignoreHiddenPoint = options.ignoreHiddenPoint
|
14616
|
+
ignoreHiddenPoint = options.ignoreHiddenPoint,
|
14617
|
+
i,
|
14618
|
+
len = points.length,
|
14619
|
+
point;
|
14582
14620
|
|
14583
14621
|
// get positions - either an integer or a percentage string must be given
|
14584
14622
|
series.center = positions = series.getCenter();
|
@@ -14594,11 +14632,16 @@ var PieSeries = {
|
|
14594
14632
|
};
|
14595
14633
|
|
14596
14634
|
// get the total sum
|
14597
|
-
|
14635
|
+
for (i = 0; i < len; i++) {
|
14636
|
+
point = points[i];
|
14598
14637
|
total += (ignoreHiddenPoint && !point.visible) ? 0 : point.y;
|
14599
|
-
}
|
14638
|
+
}
|
14600
14639
|
|
14601
|
-
each
|
14640
|
+
// Calculate the geometry for each point
|
14641
|
+
for (i = 0; i < len; i++) {
|
14642
|
+
|
14643
|
+
point = points[i];
|
14644
|
+
|
14602
14645
|
// set start and end angle
|
14603
14646
|
fraction = total ? point.y / total : 0;
|
14604
14647
|
start = mathRound(cumulative * circ * precision) / precision;
|
@@ -14651,7 +14694,7 @@ var PieSeries = {
|
|
14651
14694
|
point.percentage = fraction * 100;
|
14652
14695
|
point.total = total;
|
14653
14696
|
|
14654
|
-
}
|
14697
|
+
}
|
14655
14698
|
|
14656
14699
|
|
14657
14700
|
this.setTooltipPoints();
|
@@ -14952,7 +14995,7 @@ var PieSeries = {
|
|
14952
14995
|
})[dataLabel.moved ? 'animate' : 'attr']({
|
14953
14996
|
x: x + options.x +
|
14954
14997
|
({ left: connectorPadding, right: -connectorPadding }[labelPos[6]] || 0),
|
14955
|
-
y: y + options.y
|
14998
|
+
y: y + options.y - 10 // 10 is for the baseline (label vs text)
|
14956
14999
|
});
|
14957
15000
|
dataLabel.moved = true;
|
14958
15001
|
|
@@ -14996,6 +15039,8 @@ var PieSeries = {
|
|
14996
15039
|
}
|
14997
15040
|
}
|
14998
15041
|
},
|
15042
|
+
|
15043
|
+
alignDataLabel: noop,
|
14999
15044
|
|
15000
15045
|
/**
|
15001
15046
|
* Draw point specific tracker objects. Inherit directly from column series.
|
@@ -15061,6 +15106,6 @@ extend(Highcharts, {
|
|
15061
15106
|
canvas: useCanVG,
|
15062
15107
|
vml: !hasSVG && !useCanVG,
|
15063
15108
|
product: 'Highcharts',
|
15064
|
-
version: '2.3.
|
15109
|
+
version: '2.3.3'
|
15065
15110
|
});
|
15066
15111
|
}());
|