highcharts-rails 2.3.0 → 2.3.2
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 +231 -200
- data/vendor/assets/javascripts/highcharts/adapters/mootools.js +6 -6
- data/vendor/assets/javascripts/highcharts/adapters/prototype.js +8 -8
- data/vendor/assets/javascripts/highcharts/highcharts-more.js +23 -22
- data/vendor/assets/javascripts/highcharts/modules/canvas-tools.js +472 -472
- data/vendor/assets/javascripts/highcharts/modules/exporting.js +3 -3
- 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.2 (2012-08-31)
|
6
6
|
*
|
7
7
|
* (c) 2009-2011 Torstein Hønsi
|
8
8
|
*
|
@@ -32,7 +32,8 @@ var UNDEFINED,
|
|
32
32
|
|
33
33
|
// some variables
|
34
34
|
userAgent = navigator.userAgent,
|
35
|
-
|
35
|
+
isOpera = win.opera,
|
36
|
+
isIE = /msie/i.test(userAgent) && !isOpera,
|
36
37
|
docMode8 = doc.documentMode === 8,
|
37
38
|
isWebKit = /AppleWebKit/.test(userAgent),
|
38
39
|
isFirefox = /Firefox/.test(userAgent),
|
@@ -1070,6 +1071,25 @@ pathAnim = {
|
|
1070
1071
|
Step.d = dSetter;
|
1071
1072
|
}
|
1072
1073
|
|
1074
|
+
/**
|
1075
|
+
* Utility for iterating over an array. Parameters are reversed compared to jQuery.
|
1076
|
+
* @param {Array} arr
|
1077
|
+
* @param {Function} fn
|
1078
|
+
*/
|
1079
|
+
this.each = Array.prototype.forEach ?
|
1080
|
+
function (arr, fn) { // modern browsers
|
1081
|
+
return Array.prototype.forEach.call(arr, fn);
|
1082
|
+
|
1083
|
+
} :
|
1084
|
+
function (arr, fn) { // legacy
|
1085
|
+
var i = 0,
|
1086
|
+
len = arr.length;
|
1087
|
+
for (; i < len; i++) {
|
1088
|
+
if (fn.call(arr[i], arr[i], i, arr) === false) {
|
1089
|
+
return i;
|
1090
|
+
}
|
1091
|
+
}
|
1092
|
+
};
|
1073
1093
|
|
1074
1094
|
// Register Highcharts as a jQuery plugin
|
1075
1095
|
// TODO: MooTools and prototype as well?
|
@@ -1102,21 +1122,6 @@ pathAnim = {
|
|
1102
1122
|
return $(elem)[method]();
|
1103
1123
|
},
|
1104
1124
|
|
1105
|
-
/**
|
1106
|
-
* Utility for iterating over an array. Parameters are reversed compared to jQuery.
|
1107
|
-
* @param {Array} arr
|
1108
|
-
* @param {Function} fn
|
1109
|
-
*/
|
1110
|
-
each: function (arr, fn) {
|
1111
|
-
var i = 0,
|
1112
|
-
len = arr.length;
|
1113
|
-
for (; i < len; i++) {
|
1114
|
-
if (fn.call(arr[i], arr[i], i, arr) === false) {
|
1115
|
-
return i;
|
1116
|
-
}
|
1117
|
-
}
|
1118
|
-
},
|
1119
|
-
|
1120
1125
|
/**
|
1121
1126
|
* Filter an array
|
1122
1127
|
*/
|
@@ -1288,12 +1293,18 @@ pathAnim = {
|
|
1288
1293
|
|
1289
1294
|
// check for a custom HighchartsAdapter defined prior to this file
|
1290
1295
|
var globalAdapter = win.HighchartsAdapter,
|
1291
|
-
adapter = globalAdapter || {}
|
1296
|
+
adapter = globalAdapter || {};
|
1297
|
+
|
1298
|
+
// Initialize the adapter
|
1299
|
+
if (globalAdapter) {
|
1300
|
+
globalAdapter.init.call(globalAdapter, pathAnim);
|
1301
|
+
}
|
1302
|
+
|
1292
1303
|
|
1293
1304
|
// Utility functions. If the HighchartsAdapter is not defined, adapter is an empty object
|
1294
1305
|
// and all the utility functions will be null. In that case they are populated by the
|
1295
1306
|
// default adapters below.
|
1296
|
-
|
1307
|
+
var adapterRun = adapter.adapterRun,
|
1297
1308
|
getScript = adapter.getScript,
|
1298
1309
|
inArray = adapter.inArray,
|
1299
1310
|
each = adapter.each,
|
@@ -1308,15 +1319,6 @@ var globalAdapter = win.HighchartsAdapter,
|
|
1308
1319
|
animate = adapter.animate,
|
1309
1320
|
stop = adapter.stop;
|
1310
1321
|
|
1311
|
-
/*
|
1312
|
-
* Define the adapter for frameworks. If an external adapter is not defined,
|
1313
|
-
* Highcharts reverts to the built-in jQuery adapter.
|
1314
|
-
*/
|
1315
|
-
if (globalAdapter && globalAdapter.init) {
|
1316
|
-
// Initialize the adapter with the pathAnim object that takes care
|
1317
|
-
// of path animations.
|
1318
|
-
globalAdapter.init(pathAnim);
|
1319
|
-
}
|
1320
1322
|
|
1321
1323
|
|
1322
1324
|
/* ****************************************************************************
|
@@ -1358,8 +1360,8 @@ defaultOptions = {
|
|
1358
1360
|
},
|
1359
1361
|
global: {
|
1360
1362
|
useUTC: true,
|
1361
|
-
canvasToolsURL: 'http://code.highcharts.com/2.3.
|
1362
|
-
VMLRadialGradientURL: 'http://code.highcharts.com/2.3.
|
1363
|
+
canvasToolsURL: 'http://code.highcharts.com/2.3.2/modules/canvas-tools.js',
|
1364
|
+
VMLRadialGradientURL: 'http://code.highcharts.com/2.3.2/gfx/vml-radial-gradient.png'
|
1363
1365
|
},
|
1364
1366
|
chart: {
|
1365
1367
|
//animation: true,
|
@@ -2061,7 +2063,10 @@ SVGElement.prototype = {
|
|
2061
2063
|
|
2062
2064
|
|
2063
2065
|
if (key === 'text') {
|
2064
|
-
//
|
2066
|
+
// Delete bBox memo when the text changes
|
2067
|
+
if (value !== wrapper.textStr) {
|
2068
|
+
delete wrapper.bBox;
|
2069
|
+
}
|
2065
2070
|
wrapper.textStr = value;
|
2066
2071
|
if (wrapper.added) {
|
2067
2072
|
renderer.buildText(wrapper);
|
@@ -2168,7 +2173,7 @@ SVGElement.prototype = {
|
|
2168
2173
|
|
2169
2174
|
// store object
|
2170
2175
|
elemWrapper.styles = styles;
|
2171
|
-
|
2176
|
+
|
2172
2177
|
// serialize and set style attribute
|
2173
2178
|
if (isIE && !hasSVG) { // legacy IE doesn't support setting style attribute
|
2174
2179
|
if (textWidth) {
|
@@ -2276,13 +2281,13 @@ SVGElement.prototype = {
|
|
2276
2281
|
* @return {Object} A hash containing values for x, y, width and height
|
2277
2282
|
*/
|
2278
2283
|
|
2279
|
-
htmlGetBBox: function (
|
2284
|
+
htmlGetBBox: function () {
|
2280
2285
|
var wrapper = this,
|
2281
2286
|
element = wrapper.element,
|
2282
2287
|
bBox = wrapper.bBox;
|
2283
2288
|
|
2284
2289
|
// faking getBBox in exported SVG in legacy IE
|
2285
|
-
if (!bBox
|
2290
|
+
if (!bBox) {
|
2286
2291
|
// faking getBBox in exported SVG in legacy IE (is this a duplicate of the fix for #1079?)
|
2287
2292
|
if (element.nodeName === 'text') {
|
2288
2293
|
element.style.position = ABSOLUTE;
|
@@ -2357,25 +2362,34 @@ SVGElement.prototype = {
|
|
2357
2362
|
textWidth = pInt(wrapper.textWidth),
|
2358
2363
|
xCorr = wrapper.xCorr || 0,
|
2359
2364
|
yCorr = wrapper.yCorr || 0,
|
2360
|
-
currentTextTransform = [rotation, align, elem.innerHTML, wrapper.textWidth].join(',')
|
2365
|
+
currentTextTransform = [rotation, align, elem.innerHTML, wrapper.textWidth].join(','),
|
2366
|
+
rotationStyle = {},
|
2367
|
+
prefix;
|
2361
2368
|
|
2362
2369
|
if (currentTextTransform !== wrapper.cTT) { // do the calculations and DOM access only if properties changed
|
2363
2370
|
|
2364
2371
|
if (defined(rotation)) {
|
2365
|
-
|
2366
|
-
|
2367
|
-
|
2368
|
-
|
2369
|
-
|
2370
|
-
|
2371
|
-
|
2372
|
-
|
2373
|
-
|
2374
|
-
|
2375
|
-
|
2376
|
-
|
2377
|
-
|
2378
|
-
|
2372
|
+
|
2373
|
+
if (renderer.isSVG) { // #916
|
2374
|
+
prefix = isIE ? '-ms' : isWebKit ? '-webkit' : isFirefox ? '-moz' : isOpera ? '-o' : '';
|
2375
|
+
rotationStyle[prefix + '-transform'] = rotationStyle.transform = 'rotate(' + rotation + 'deg)';
|
2376
|
+
|
2377
|
+
} else {
|
2378
|
+
radians = rotation * deg2rad; // deg to rad
|
2379
|
+
costheta = mathCos(radians);
|
2380
|
+
sintheta = mathSin(radians);
|
2381
|
+
|
2382
|
+
// Adjust for alignment and rotation. Rotation of useHTML content is not yet implemented
|
2383
|
+
// but it can probably be implemented for Firefox 3.5+ on user request. FF3.5+
|
2384
|
+
// has support for CSS3 transform. The getBBox method also needs to be updated
|
2385
|
+
// to compensate for the rotation, like it currently does for SVG.
|
2386
|
+
// Test case: http://highcharts.com/tests/?file=text-rotation
|
2387
|
+
rotationStyle.filter = rotation ? ['progid:DXImageTransform.Microsoft.Matrix(M11=', costheta,
|
2388
|
+
', M12=', -sintheta, ', M21=', sintheta, ', M22=', costheta,
|
2389
|
+
', sizingMethod=\'auto expand\')'].join('') : NONE;
|
2390
|
+
}
|
2391
|
+
|
2392
|
+
css(elem, rotationStyle);
|
2379
2393
|
}
|
2380
2394
|
|
2381
2395
|
width = pick(wrapper.elemWidth, elem.offsetWidth);
|
@@ -2531,50 +2545,61 @@ SVGElement.prototype = {
|
|
2531
2545
|
/**
|
2532
2546
|
* Get the bounding box (width, height, x and y) for the element
|
2533
2547
|
*/
|
2534
|
-
getBBox: function (
|
2548
|
+
getBBox: function () {
|
2535
2549
|
var wrapper = this,
|
2536
|
-
bBox,
|
2550
|
+
bBox = wrapper.bBox,
|
2551
|
+
renderer = wrapper.renderer,
|
2537
2552
|
width,
|
2538
2553
|
height,
|
2539
2554
|
rotation = wrapper.rotation,
|
2540
2555
|
element = wrapper.element,
|
2541
2556
|
rad = rotation * deg2rad;
|
2542
2557
|
|
2543
|
-
|
2544
|
-
|
2545
|
-
|
2558
|
+
if (!bBox) {
|
2559
|
+
// SVG elements
|
2560
|
+
if (element.namespaceURI === SVG_NS || renderer.forExport) {
|
2561
|
+
try { // Fails in Firefox if the container has display: none.
|
2562
|
+
|
2563
|
+
bBox = element.getBBox ?
|
2564
|
+
// SVG: use extend because IE9 is not allowed to change width and height in case
|
2565
|
+
// of rotation (below)
|
2566
|
+
extend({}, element.getBBox()) :
|
2567
|
+
// Canvas renderer and legacy IE in export mode
|
2568
|
+
{
|
2569
|
+
width: element.offsetWidth,
|
2570
|
+
height: element.offsetHeight
|
2571
|
+
};
|
2572
|
+
} catch (e) {}
|
2573
|
+
|
2574
|
+
// If the bBox is not set, the try-catch block above failed. The other condition
|
2575
|
+
// is for Opera that returns a width of -Infinity on hidden elements.
|
2576
|
+
if (!bBox || bBox.width < 0) {
|
2577
|
+
bBox = { width: 0, height: 0 };
|
2578
|
+
}
|
2579
|
+
|
2580
|
+
|
2581
|
+
// VML Renderer or useHTML within SVG
|
2582
|
+
} else {
|
2583
|
+
|
2584
|
+
bBox = wrapper.htmlGetBBox();
|
2546
2585
|
|
2547
|
-
bBox = element.getBBox ?
|
2548
|
-
// SVG: use extend because IE9 is not allowed to change width and height in case
|
2549
|
-
// of rotation (below)
|
2550
|
-
extend({}, element.getBBox()) :
|
2551
|
-
// Canvas renderer and legacy IE in export mode
|
2552
|
-
{
|
2553
|
-
width: element.offsetWidth,
|
2554
|
-
height: element.offsetHeight
|
2555
|
-
};
|
2556
|
-
} catch (e) {}
|
2557
|
-
|
2558
|
-
// If the bBox is not set, the try-catch block above failed. The other condition
|
2559
|
-
// is for Opera that returns a width of -Infinity on hidden elements.
|
2560
|
-
if (!bBox || bBox.width < 0) {
|
2561
|
-
bBox = { width: 0, height: 0 };
|
2562
2586
|
}
|
2563
2587
|
|
2564
|
-
|
2565
|
-
|
2566
|
-
|
2567
|
-
|
2568
|
-
|
2569
|
-
|
2570
|
-
|
2588
|
+
// True SVG elements as well as HTML elements in modern browsers using the .useHTML option
|
2589
|
+
// need to compensated for rotation
|
2590
|
+
if (renderer.isSVG) {
|
2591
|
+
width = bBox.width;
|
2592
|
+
height = bBox.height;
|
2593
|
+
|
2594
|
+
// Adjust for rotated text
|
2595
|
+
if (rotation) {
|
2596
|
+
bBox.width = mathAbs(height * mathSin(rad)) + mathAbs(width * mathCos(rad));
|
2597
|
+
bBox.height = mathAbs(height * mathCos(rad)) + mathAbs(width * mathSin(rad));
|
2598
|
+
}
|
2571
2599
|
}
|
2572
|
-
|
2573
|
-
|
2574
|
-
} else {
|
2575
|
-
bBox = wrapper.htmlGetBBox(refresh);
|
2600
|
+
|
2601
|
+
wrapper.bBox = bBox;
|
2576
2602
|
}
|
2577
|
-
|
2578
2603
|
return bBox;
|
2579
2604
|
},
|
2580
2605
|
|
@@ -3054,6 +3079,7 @@ SVGRenderer.prototype = {
|
|
3054
3079
|
rest = [];
|
3055
3080
|
|
3056
3081
|
while (words.length || rest.length) {
|
3082
|
+
delete wrapper.bBox; // delete cache
|
3057
3083
|
actualWidth = wrapper.getBBox().width;
|
3058
3084
|
tooLong = actualWidth > width;
|
3059
3085
|
if (!tooLong || words.length === 1) { // new line needed
|
@@ -3748,6 +3774,9 @@ SVGRenderer.prototype = {
|
|
3748
3774
|
|
3749
3775
|
// Text setter
|
3750
3776
|
attrSetters.text = function (value) {
|
3777
|
+
if (value !== element.innerHTML) {
|
3778
|
+
delete this.bBox;
|
3779
|
+
}
|
3751
3780
|
element.innerHTML = value;
|
3752
3781
|
return false;
|
3753
3782
|
};
|
@@ -3916,7 +3945,7 @@ SVGRenderer.prototype = {
|
|
3916
3945
|
style = text.element.style;
|
3917
3946
|
|
3918
3947
|
bBox = (width === undefined || height === undefined || wrapper.styles.textAlign) &&
|
3919
|
-
text.getBBox(
|
3948
|
+
text.getBBox();
|
3920
3949
|
wrapper.width = (width || bBox.width || 0) + 2 * padding;
|
3921
3950
|
wrapper.height = (height || bBox.height || 0) + 2 * padding;
|
3922
3951
|
|
@@ -4213,11 +4242,6 @@ var VMLElement = {
|
|
4213
4242
|
renderer.invertChild(element, parentNode);
|
4214
4243
|
}
|
4215
4244
|
|
4216
|
-
// issue #140 workaround - related to #61 and #74
|
4217
|
-
if (docMode8 && parentNode.gVis === HIDDEN) {
|
4218
|
-
css(element, { visibility: HIDDEN });
|
4219
|
-
}
|
4220
|
-
|
4221
4245
|
// append it
|
4222
4246
|
parentNode.appendChild(element);
|
4223
4247
|
|
@@ -4233,26 +4257,6 @@ var VMLElement = {
|
|
4233
4257
|
return wrapper;
|
4234
4258
|
},
|
4235
4259
|
|
4236
|
-
/**
|
4237
|
-
* In IE8 documentMode 8, we need to recursively set the visibility down in the DOM
|
4238
|
-
* tree for nested groups. Related to #61, #586.
|
4239
|
-
*/
|
4240
|
-
toggleChildren: function (element, visibility) {
|
4241
|
-
var childNodes = element.childNodes,
|
4242
|
-
i = childNodes.length;
|
4243
|
-
|
4244
|
-
while (i--) {
|
4245
|
-
|
4246
|
-
// apply the visibility
|
4247
|
-
css(childNodes[i], { visibility: visibility });
|
4248
|
-
|
4249
|
-
// we have a nested group, apply it to its children again
|
4250
|
-
if (childNodes[i].nodeName === 'DIV') {
|
4251
|
-
this.toggleChildren(childNodes[i], visibility);
|
4252
|
-
}
|
4253
|
-
}
|
4254
|
-
},
|
4255
|
-
|
4256
4260
|
/**
|
4257
4261
|
* VML always uses htmlUpdateTransform
|
4258
4262
|
*/
|
@@ -4356,24 +4360,33 @@ var VMLElement = {
|
|
4356
4360
|
}
|
4357
4361
|
skipAttr = true;
|
4358
4362
|
|
4359
|
-
//
|
4360
|
-
} else if (key === '
|
4361
|
-
|
4362
|
-
//
|
4363
|
-
if (
|
4364
|
-
|
4365
|
-
|
4366
|
-
|
4367
|
-
value = null;
|
4363
|
+
// handle visibility
|
4364
|
+
} else if (key === 'visibility') {
|
4365
|
+
|
4366
|
+
// let the shadow follow the main element
|
4367
|
+
if (shadows) {
|
4368
|
+
i = shadows.length;
|
4369
|
+
while (i--) {
|
4370
|
+
shadows[i].style[key] = value;
|
4368
4371
|
}
|
4369
4372
|
}
|
4373
|
+
|
4374
|
+
// Instead of toggling the visibility CSS property, move the div out of the viewport.
|
4375
|
+
// This works around #61 and #586
|
4376
|
+
if (nodeName === 'DIV') {
|
4377
|
+
value = value === HIDDEN ? '-999em' : 0;
|
4378
|
+
key = 'top';
|
4379
|
+
}
|
4380
|
+
|
4381
|
+
elemStyle[key] = value;
|
4382
|
+
skipAttr = true;
|
4383
|
+
|
4384
|
+
// directly mapped to css
|
4385
|
+
} else if (key === 'zIndex') {
|
4370
4386
|
|
4371
4387
|
if (value) {
|
4372
4388
|
elemStyle[key] = value;
|
4373
4389
|
}
|
4374
|
-
|
4375
|
-
|
4376
|
-
|
4377
4390
|
skipAttr = true;
|
4378
4391
|
|
4379
4392
|
// width and height
|
@@ -4463,16 +4476,6 @@ var VMLElement = {
|
|
4463
4476
|
skipAttr = true;
|
4464
4477
|
}
|
4465
4478
|
|
4466
|
-
// let the shadow follow the main element
|
4467
|
-
if (shadows && key === 'visibility') {
|
4468
|
-
i = shadows.length;
|
4469
|
-
while (i--) {
|
4470
|
-
shadows[i].style[key] = value;
|
4471
|
-
}
|
4472
|
-
}
|
4473
|
-
|
4474
|
-
|
4475
|
-
|
4476
4479
|
if (!skipAttr) {
|
4477
4480
|
if (docMode8) { // IE8 setAttribute bug
|
4478
4481
|
element[key] = value;
|
@@ -4496,7 +4499,8 @@ var VMLElement = {
|
|
4496
4499
|
var wrapper = this,
|
4497
4500
|
clipMembers,
|
4498
4501
|
element = wrapper.element,
|
4499
|
-
parentNode = element.parentNode
|
4502
|
+
parentNode = element.parentNode,
|
4503
|
+
cssRet;
|
4500
4504
|
|
4501
4505
|
if (clipRect) {
|
4502
4506
|
clipMembers = clipRect.members;
|
@@ -4508,12 +4512,17 @@ var VMLElement = {
|
|
4508
4512
|
if (parentNode && parentNode.className === 'highcharts-tracker' && !docMode8) {
|
4509
4513
|
css(element, { visibility: HIDDEN });
|
4510
4514
|
}
|
4515
|
+
cssRet = clipRect.getCSS(wrapper);
|
4511
4516
|
|
4512
|
-
} else
|
4513
|
-
wrapper.destroyClip
|
4517
|
+
} else {
|
4518
|
+
if (wrapper.destroyClip) {
|
4519
|
+
wrapper.destroyClip();
|
4520
|
+
}
|
4521
|
+
cssRet = { clip: docMode8 ? 'inherit' : 'rect(auto)' }; // #1214
|
4514
4522
|
}
|
4515
4523
|
|
4516
|
-
return wrapper.css(
|
4524
|
+
return wrapper.css(cssRet);
|
4525
|
+
|
4517
4526
|
},
|
4518
4527
|
|
4519
4528
|
/**
|
@@ -4529,8 +4538,7 @@ var VMLElement = {
|
|
4529
4538
|
safeRemoveChild: function (element) {
|
4530
4539
|
// discardElement will detach the node from its parent before attaching it
|
4531
4540
|
// to the garbage bin. Therefore it is important that the node is attached and have parent.
|
4532
|
-
|
4533
|
-
if (parentNode) {
|
4541
|
+
if (element.parentNode) {
|
4534
4542
|
discardElement(element);
|
4535
4543
|
}
|
4536
4544
|
},
|
@@ -4539,13 +4547,11 @@ var VMLElement = {
|
|
4539
4547
|
* Extend element.destroy by removing it from the clip members array
|
4540
4548
|
*/
|
4541
4549
|
destroy: function () {
|
4542
|
-
|
4543
|
-
|
4544
|
-
if (wrapper.destroyClip) {
|
4545
|
-
wrapper.destroyClip();
|
4550
|
+
if (this.destroyClip) {
|
4551
|
+
this.destroyClip();
|
4546
4552
|
}
|
4547
4553
|
|
4548
|
-
return SVGElement.prototype.destroy.apply(
|
4554
|
+
return SVGElement.prototype.destroy.apply(this);
|
4549
4555
|
},
|
4550
4556
|
|
4551
4557
|
/**
|
@@ -5442,7 +5448,7 @@ Tick.prototype = {
|
|
5442
5448
|
var label = this.label,
|
5443
5449
|
axis = this.axis;
|
5444
5450
|
return label ?
|
5445
|
-
((this.labelBBox = label.getBBox(
|
5451
|
+
((this.labelBBox = label.getBBox()))[axis.horiz ? 'height' : 'width'] :
|
5446
5452
|
0;
|
5447
5453
|
},
|
5448
5454
|
|
@@ -5616,7 +5622,7 @@ Tick.prototype = {
|
|
5616
5622
|
step = labelOptions.step,
|
5617
5623
|
attribs,
|
5618
5624
|
show = true,
|
5619
|
-
tickmarkOffset =
|
5625
|
+
tickmarkOffset = axis.tickmarkOffset,
|
5620
5626
|
xy = tick.getPosition(horiz, pos, tickmarkOffset, old),
|
5621
5627
|
x = xy.x,
|
5622
5628
|
y = xy.y,
|
@@ -6259,6 +6265,8 @@ Axis.prototype = {
|
|
6259
6265
|
// Tick intervals
|
6260
6266
|
//axis.tickInterval = UNDEFINED;
|
6261
6267
|
//axis.minorTickInterval = UNDEFINED;
|
6268
|
+
|
6269
|
+
axis.tickmarkOffset = (options.categories && options.tickmarkPlacement === 'between') ? 0.5 : 0;
|
6262
6270
|
|
6263
6271
|
// Major ticks
|
6264
6272
|
axis.ticks = {};
|
@@ -7336,6 +7344,15 @@ Axis.prototype = {
|
|
7336
7344
|
});
|
7337
7345
|
},
|
7338
7346
|
|
7347
|
+
/**
|
7348
|
+
* Overridable method for zooming chart. Pulled out in a separate method to allow overriding
|
7349
|
+
* in stock charts.
|
7350
|
+
*/
|
7351
|
+
zoom: function (newMin, newMax) {
|
7352
|
+
this.setExtremes(newMin, newMax, false, UNDEFINED, { trigger: 'zoom' });
|
7353
|
+
return true;
|
7354
|
+
},
|
7355
|
+
|
7339
7356
|
/**
|
7340
7357
|
* Update the axis metrics
|
7341
7358
|
*/
|
@@ -7540,6 +7557,8 @@ Axis.prototype = {
|
|
7540
7557
|
horiz = this.horiz,
|
7541
7558
|
lineLeft = this.left + (opposite ? this.width : 0) + offset,
|
7542
7559
|
lineTop = chart.chartHeight - this.bottom - (opposite ? this.height : 0) + offset;
|
7560
|
+
|
7561
|
+
this.lineTop = lineTop; // used by flag series
|
7543
7562
|
|
7544
7563
|
return chart.renderer.crispLine([
|
7545
7564
|
M,
|
@@ -7617,6 +7636,7 @@ Axis.prototype = {
|
|
7617
7636
|
alternateBands = axis.alternateBands,
|
7618
7637
|
stackLabelOptions = options.stackLabels,
|
7619
7638
|
alternateGridColor = options.alternateGridColor,
|
7639
|
+
tickmarkOffset = axis.tickmarkOffset,
|
7620
7640
|
lineWidth = options.lineWidth,
|
7621
7641
|
linePath,
|
7622
7642
|
hasRendered = chart.hasRendered,
|
@@ -7679,8 +7699,8 @@ Axis.prototype = {
|
|
7679
7699
|
if (!alternateBands[pos]) {
|
7680
7700
|
alternateBands[pos] = new PlotLineOrBand(axis);
|
7681
7701
|
}
|
7682
|
-
from = pos;
|
7683
|
-
to = tickPositions[i + 1] !== UNDEFINED ? tickPositions[i + 1] : axis.max;
|
7702
|
+
from = pos + tickmarkOffset; // #949
|
7703
|
+
to = tickPositions[i + 1] !== UNDEFINED ? tickPositions[i + 1] + tickmarkOffset : axis.max;
|
7684
7704
|
alternateBands[pos].options = {
|
7685
7705
|
from: isLog ? lin2log(from) : from,
|
7686
7706
|
to: isLog ? lin2log(to) : to,
|
@@ -9302,7 +9322,7 @@ Legend.prototype = {
|
|
9302
9322
|
|
9303
9323
|
// sort by legendIndex
|
9304
9324
|
stableSort(allItems, function (a, b) {
|
9305
|
-
return (a.options.legendIndex || 0) - (b.options.legendIndex || 0);
|
9325
|
+
return ((a.options && a.options.legendIndex) || 0) - ((b.options && b.options.legendIndex) || 0);
|
9306
9326
|
});
|
9307
9327
|
|
9308
9328
|
// reversed legend
|
@@ -10008,22 +10028,12 @@ Chart.prototype = {
|
|
10008
10028
|
*/
|
10009
10029
|
zoom: function (event) {
|
10010
10030
|
var chart = this,
|
10011
|
-
|
10012
|
-
|
10013
|
-
// add button to reset selection
|
10014
|
-
var hasZoomed;
|
10015
|
-
|
10016
|
-
if (chart.resetZoomEnabled !== false && !chart.resetZoomButton) { // hook for Stock charts etc.
|
10017
|
-
chart.showResetZoom();
|
10018
|
-
}
|
10031
|
+
hasZoomed;
|
10019
10032
|
|
10020
10033
|
// if zoom is called with no arguments, reset the axes
|
10021
10034
|
if (!event || event.resetSelection) {
|
10022
10035
|
each(chart.axes, function (axis) {
|
10023
|
-
|
10024
|
-
axis.setExtremes(null, null, false, UNDEFINED, { trigger: 'zoomout' });
|
10025
|
-
hasZoomed = true;
|
10026
|
-
}
|
10036
|
+
hasZoomed = axis.zoom();
|
10027
10037
|
});
|
10028
10038
|
} else { // else, zoom in on all axes
|
10029
10039
|
each(event.xAxis.concat(event.yAxis), function (axisData) {
|
@@ -10031,16 +10041,21 @@ Chart.prototype = {
|
|
10031
10041
|
|
10032
10042
|
// don't zoom more than minRange
|
10033
10043
|
if (chart.tracker[axis.isXAxis ? 'zoomX' : 'zoomY']) {
|
10034
|
-
axis.
|
10035
|
-
hasZoomed = true;
|
10044
|
+
hasZoomed = axis.zoom(axisData.min, axisData.max);
|
10036
10045
|
}
|
10037
10046
|
});
|
10038
10047
|
}
|
10048
|
+
|
10049
|
+
// Show the Reset zoom button
|
10050
|
+
if (!chart.resetZoomButton) {
|
10051
|
+
chart.showResetZoom();
|
10052
|
+
}
|
10053
|
+
|
10039
10054
|
|
10040
10055
|
// Redraw
|
10041
10056
|
if (hasZoomed) {
|
10042
10057
|
chart.redraw(
|
10043
|
-
pick(
|
10058
|
+
pick(chart.options.chart.animation, chart.pointCount < 100) // animation
|
10044
10059
|
);
|
10045
10060
|
}
|
10046
10061
|
},
|
@@ -10771,8 +10786,8 @@ Chart.prototype = {
|
|
10771
10786
|
|
10772
10787
|
// Labels
|
10773
10788
|
if (labels.items) {
|
10774
|
-
each(labels.items, function () {
|
10775
|
-
var style = extend(labels.style,
|
10789
|
+
each(labels.items, function (label) {
|
10790
|
+
var style = extend(labels.style, label.style),
|
10776
10791
|
x = pInt(style.left) + chart.plotLeft,
|
10777
10792
|
y = pInt(style.top) + chart.plotTop + 12;
|
10778
10793
|
|
@@ -10781,7 +10796,7 @@ Chart.prototype = {
|
|
10781
10796
|
delete style.top;
|
10782
10797
|
|
10783
10798
|
renderer.text(
|
10784
|
-
|
10799
|
+
label.html,
|
10785
10800
|
x,
|
10786
10801
|
y
|
10787
10802
|
)
|
@@ -11064,10 +11079,7 @@ Point.prototype = {
|
|
11064
11079
|
|
11065
11080
|
if (series.options.colorByPoint) {
|
11066
11081
|
defaultColors = series.chart.options.colors;
|
11067
|
-
|
11068
|
-
point.options = {};
|
11069
|
-
}
|
11070
|
-
point.color = point.options.color = point.color || defaultColors[counters.color++];
|
11082
|
+
point.color = point.color || defaultColors[counters.color++];
|
11071
11083
|
|
11072
11084
|
// loop back to zero
|
11073
11085
|
counters.wrapColor(defaultColors.length);
|
@@ -11643,7 +11655,7 @@ Series.prototype = {
|
|
11643
11655
|
chart.series.push(series);
|
11644
11656
|
|
11645
11657
|
// Sort series according to index option (#248, #1123)
|
11646
|
-
chart.series
|
11658
|
+
stableSort(chart.series, function (a, b) {
|
11647
11659
|
return (a.options.index || 0) - (b.options.index || 0);
|
11648
11660
|
});
|
11649
11661
|
each(chart.series, function (series, i) {
|
@@ -12286,7 +12298,7 @@ Series.prototype = {
|
|
12286
12298
|
yValue = yBottom + yValue;
|
12287
12299
|
|
12288
12300
|
if (isBottomSeries) {
|
12289
|
-
yBottom = pick(options.threshold, yAxis.min);
|
12301
|
+
yBottom = pick(options.threshold, yAxis.isLog ? null : yAxis.min); // #1200
|
12290
12302
|
}
|
12291
12303
|
|
12292
12304
|
if (stacking === 'percent') {
|
@@ -12541,18 +12553,13 @@ Series.prototype = {
|
|
12541
12553
|
afterAnimate: function () {
|
12542
12554
|
var chart = this.chart,
|
12543
12555
|
sharedClipKey = this.sharedClipKey,
|
12544
|
-
group = this.group
|
12545
|
-
trackerGroup = this.trackerGroup;
|
12556
|
+
group = this.group;
|
12546
12557
|
|
12547
12558
|
if (group && this.options.clip !== false) {
|
12548
12559
|
group.clip(chart.clipRect);
|
12549
12560
|
this.markerGroup.clip(); // no clip
|
12550
12561
|
}
|
12551
12562
|
|
12552
|
-
if (trackerGroup) {
|
12553
|
-
trackerGroup.clip(chart.clipRect);
|
12554
|
-
}
|
12555
|
-
|
12556
12563
|
// Remove the shared clipping rectancgle when all series are shown
|
12557
12564
|
setTimeout(function () {
|
12558
12565
|
if (sharedClipKey && chart[sharedClipKey]) {
|
@@ -12725,8 +12732,8 @@ Series.prototype = {
|
|
12725
12732
|
if (normalOptions && normalOptions.enabled === false) {
|
12726
12733
|
normalOptions.radius = 0;
|
12727
12734
|
}
|
12728
|
-
hasPointSpecificOptions =
|
12729
|
-
|
12735
|
+
hasPointSpecificOptions = series.options.colorByPoint; // #868
|
12736
|
+
|
12730
12737
|
// check if the point has specific visual options
|
12731
12738
|
if (point.options) {
|
12732
12739
|
for (key in pointAttrToOptions) {
|
@@ -12741,22 +12748,25 @@ Series.prototype = {
|
|
12741
12748
|
// a specific marker config object is defined for the individual point:
|
12742
12749
|
// create it's own attribute collection
|
12743
12750
|
if (hasPointSpecificOptions) {
|
12744
|
-
|
12751
|
+
normalOptions = normalOptions || {};
|
12745
12752
|
pointAttr = [];
|
12746
12753
|
stateOptions = normalOptions.states || {}; // reassign for individual point
|
12747
12754
|
pointStateOptionsHover = stateOptions[HOVER_STATE] = stateOptions[HOVER_STATE] || {};
|
12748
12755
|
|
12749
|
-
//
|
12756
|
+
// Handle colors for column and pies
|
12750
12757
|
if (!series.options.marker) { // column, bar, point
|
12758
|
+
// if no hover color is given, brighten the normal color
|
12751
12759
|
pointStateOptionsHover.color =
|
12752
|
-
Color(pointStateOptionsHover.color || point.
|
12760
|
+
Color(pointStateOptionsHover.color || point.color)
|
12753
12761
|
.brighten(pointStateOptionsHover.brightness ||
|
12754
12762
|
stateOptionsHover.brightness).get();
|
12755
12763
|
|
12756
12764
|
}
|
12757
12765
|
|
12758
12766
|
// normal point state inherits series wide normal state
|
12759
|
-
pointAttr[NORMAL_STATE] = series.convertAttribs(
|
12767
|
+
pointAttr[NORMAL_STATE] = series.convertAttribs(extend({
|
12768
|
+
color: point.color // #868
|
12769
|
+
}, normalOptions), seriesPointAttr[NORMAL_STATE]);
|
12760
12770
|
|
12761
12771
|
// inherit from point normal and series hover
|
12762
12772
|
pointAttr[HOVER_STATE] = series.convertAttribs(
|
@@ -12885,9 +12895,7 @@ Series.prototype = {
|
|
12885
12895
|
yIsNull = options.y === null,
|
12886
12896
|
fontMetrics = renderer.fontMetrics(options.style.fontSize), // height and baseline
|
12887
12897
|
fontLineHeight = fontMetrics.h,
|
12888
|
-
fontBaseline = fontMetrics.b
|
12889
|
-
dataLabel,
|
12890
|
-
enabled;
|
12898
|
+
fontBaseline = fontMetrics.b;
|
12891
12899
|
|
12892
12900
|
if (isBarLike) {
|
12893
12901
|
var defaultYs = {
|
@@ -12931,7 +12939,11 @@ Series.prototype = {
|
|
12931
12939
|
generalOptions = options;
|
12932
12940
|
each(points, function (point) {
|
12933
12941
|
|
12934
|
-
|
12942
|
+
var plotX,
|
12943
|
+
plotY,
|
12944
|
+
individualYDelta,
|
12945
|
+
enabled,
|
12946
|
+
dataLabel = point.dataLabel;
|
12935
12947
|
|
12936
12948
|
// Merge in individual options from point
|
12937
12949
|
options = generalOptions; // reset changes from previous points
|
@@ -12943,24 +12955,30 @@ Series.prototype = {
|
|
12943
12955
|
|
12944
12956
|
// Get the positions
|
12945
12957
|
if (enabled) {
|
12946
|
-
|
12947
|
-
|
12958
|
+
plotX = (point.barX && point.barX + point.barW / 2) || pick(point.plotX, -999);
|
12959
|
+
plotY = pick(point.plotY, -999);
|
12948
12960
|
|
12949
|
-
|
12950
|
-
|
12951
|
-
|
12952
|
-
|
12953
|
-
|
12954
|
-
|
12955
|
-
|
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;
|
12956
12968
|
|
12957
12969
|
x = (inverted ? chart.plotWidth - plotY : plotX) + options.x;
|
12958
12970
|
y = mathRound((inverted ? chart.plotHeight - plotX : plotY) + individualYDelta);
|
12959
12971
|
|
12960
12972
|
}
|
12961
12973
|
|
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
|
+
|
12962
12980
|
// If the point is outside the plot area, destroy it. #678, #820
|
12963
|
-
if (dataLabel &&
|
12981
|
+
if (dataLabel && !enabled) {
|
12964
12982
|
point.dataLabel = dataLabel.destroy();
|
12965
12983
|
|
12966
12984
|
// Individual labels are disabled if the are explicitly disabled
|
@@ -13286,6 +13304,9 @@ Series.prototype = {
|
|
13286
13304
|
// Initial clipping, must be defined after inverting groups for VML
|
13287
13305
|
if (options.clip !== false && !series.sharedClipKey && !hasRendered) {
|
13288
13306
|
group.clip(chart.clipRect);
|
13307
|
+
if (this.trackerGroup) {
|
13308
|
+
this.trackerGroup.clip(chart.clipRect);
|
13309
|
+
}
|
13289
13310
|
}
|
13290
13311
|
|
13291
13312
|
// Run the animation
|
@@ -14368,7 +14389,8 @@ var PiePoint = extendClass(Point, {
|
|
14368
14389
|
*/
|
14369
14390
|
setVisible: function (vis) {
|
14370
14391
|
var point = this,
|
14371
|
-
|
14392
|
+
series = point.series,
|
14393
|
+
chart = series.chart,
|
14372
14394
|
tracker = point.tracker,
|
14373
14395
|
dataLabel = point.dataLabel,
|
14374
14396
|
connector = point.connector,
|
@@ -14396,6 +14418,12 @@ var PiePoint = extendClass(Point, {
|
|
14396
14418
|
if (point.legendItem) {
|
14397
14419
|
chart.legend.colorizeItem(point, vis);
|
14398
14420
|
}
|
14421
|
+
|
14422
|
+
// Handle ignore hidden slices
|
14423
|
+
if (!series.isDirty && series.options.ignoreHiddenPoint) {
|
14424
|
+
series.isDirty = true;
|
14425
|
+
chart.redraw();
|
14426
|
+
}
|
14399
14427
|
},
|
14400
14428
|
|
14401
14429
|
/**
|
@@ -14549,7 +14577,8 @@ var PieSeries = {
|
|
14549
14577
|
fraction,
|
14550
14578
|
radiusX, // the x component of the radius vector for a given point
|
14551
14579
|
radiusY,
|
14552
|
-
labelDistance = options.dataLabels.distance
|
14580
|
+
labelDistance = options.dataLabels.distance,
|
14581
|
+
ignoreHiddenPoint = options.ignoreHiddenPoint;
|
14553
14582
|
|
14554
14583
|
// get positions - either an integer or a percentage string must be given
|
14555
14584
|
series.center = positions = series.getCenter();
|
@@ -14566,14 +14595,16 @@ var PieSeries = {
|
|
14566
14595
|
|
14567
14596
|
// get the total sum
|
14568
14597
|
each(points, function (point) {
|
14569
|
-
total += point.y;
|
14598
|
+
total += (ignoreHiddenPoint && !point.visible) ? 0 : point.y;
|
14570
14599
|
});
|
14571
14600
|
|
14572
14601
|
each(points, function (point) {
|
14573
14602
|
// set start and end angle
|
14574
14603
|
fraction = total ? point.y / total : 0;
|
14575
14604
|
start = mathRound(cumulative * circ * precision) / precision;
|
14576
|
-
|
14605
|
+
if (!ignoreHiddenPoint || point.visible) {
|
14606
|
+
cumulative += fraction;
|
14607
|
+
}
|
14577
14608
|
end = mathRound(cumulative * circ * precision) / precision;
|
14578
14609
|
|
14579
14610
|
// set the shape
|
@@ -15030,6 +15061,6 @@ extend(Highcharts, {
|
|
15030
15061
|
canvas: useCanVG,
|
15031
15062
|
vml: !hasSVG && !useCanVG,
|
15032
15063
|
product: 'Highcharts',
|
15033
|
-
version: '2.3.
|
15064
|
+
version: '2.3.2'
|
15034
15065
|
});
|
15035
15066
|
}());
|