highcharts-rails 3.0.1.5 → 3.0.2
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.
- data.tar.gz.asc +13 -13
- data/CHANGELOG.markdown +7 -1
- data/README.markdown +0 -48
- data/app/assets/javascripts/highcharts.js +134 -87
- data/app/assets/javascripts/highcharts/adapters/mootools.js +2 -2
- data/app/assets/javascripts/highcharts/adapters/prototype.js +3 -3
- data/app/assets/javascripts/highcharts/highcharts-more.js +2525 -50
- data/app/assets/javascripts/highcharts/modules/annotations.js +354 -0
- data/app/assets/javascripts/highcharts/modules/canvas-tools.js +1 -1
- data/app/assets/javascripts/highcharts/modules/exporting.js +12 -8
- data/highcharts-rails.gemspec +0 -1
- data/lib/highcharts/version.rb +1 -1
- metadata +3 -19
- metadata.gz.asc +13 -13
- data/lib/highcharts/export_endpoint.rb +0 -127
data.tar.gz.asc
CHANGED
@@ -2,17 +2,17 @@
|
|
2
2
|
Version: GnuPG/MacGPG2 v2.0.19 (Darwin)
|
3
3
|
Comment: GPGTools - http://gpgtools.org
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
=
|
5
|
+
iQIcBAABAgAGBQJRsdkzAAoJEH1ncb0Txu7XH/AP/1a0aFi65fj2/7kP2aW8Wh88
|
6
|
+
Eii6rsVmsDbUt480BskzXqFnksDOg2X8FwhX7ze0GwkHfADHbsoddf0WZ/NssLG6
|
7
|
+
O3C5AzX/695zPKxfGVd1IX6dmJCWroKqadz/HAJ7vNQRADhLlIpu97VRe79qRydQ
|
8
|
+
uV/zJnRcjSlOyGAukMw5KVvyUgpoWYOUPDB84coZJ7Nnw5RSNvJG7DduvLcABljJ
|
9
|
+
muMUG70To9Ei3KZOyGG39jBQXePuDrRaqUbgsofoypTQW6qFx91p3FCyH7eoUDTr
|
10
|
+
HU2zmBW3NAJXMlwPwtJO0y7OK8oFUXHpxX1rx99BVo3Xh/l+cLbPQuWV1zP2CEh4
|
11
|
+
JUry+JNpCIvVZtozhynCyxjQOWALW6hJ1cT2dfoKoz2ED2qOSJ0XG8SQac8bfel0
|
12
|
+
Tvico/ZWE+k6WQw/w60xmXQZEtlx6ovwHE4269bAH5zoAxef4F0PYqe/afZP3dDA
|
13
|
+
1XRrJpUbVffvtXeDz9kVY1aKu9gpFHgw1P1qqeCSdfqJSfXbrvzlmkkpfOwUGsVC
|
14
|
+
2DW6aXlVF1mCDCTNMZenlDUa4Vn3Tpdo5TjfFCsMRM3uUOE/Z37w7wyRzybTbPWa
|
15
|
+
+8S1Xmlgt77IZY1uuy1/Jts1i45Fn9gGvSqHmoNKqC5pXeWwOtKVkgRFlM1JP07e
|
16
|
+
VlXJlAfX7Bu5x5CxAB8r
|
17
|
+
=U2ji
|
18
18
|
-----END PGP SIGNATURE-----
|
data/CHANGELOG.markdown
CHANGED
@@ -1,4 +1,10 @@
|
|
1
|
-
# 3.0.
|
1
|
+
# 3.0.2 / 2013-06-07
|
2
|
+
|
3
|
+
* Updated Highcharts to 3.0.2
|
4
|
+
* Removed the Rack endpoint
|
5
|
+
(https://github.com/PerfectlyNormal/highcharts-rails/issues/9)
|
6
|
+
|
7
|
+
# 3.0.1.5 / 2013-05-08
|
2
8
|
|
3
9
|
* Add a Rack endpoint for exporting charts to image files
|
4
10
|
|
data/README.markdown
CHANGED
@@ -45,54 +45,6 @@ Or one of the themes
|
|
45
45
|
|
46
46
|
Other than that, refer to the [Highcharts documentation](http://docs.highcharts.com/#home)
|
47
47
|
|
48
|
-
## Export endpoint
|
49
|
-
|
50
|
-
This gem contains a Rack endpoint for converting the chart to a downloadable file.
|
51
|
-
It is not required by default, so to use it, `require
|
52
|
-
'highcharts/export_endpoint'`
|
53
|
-
|
54
|
-
The endpoint is basically a port of the [PHP version made available](https://github.com/highslide-software/highcharts.com/blob/master/exporting-server/php/php-batik/index.php).
|
55
|
-
It currently needs a lot of cleanup, but it is working fine for me. Your milage
|
56
|
-
may vary.
|
57
|
-
|
58
|
-
It uses [Apache Batik](http://xmlgraphics.apache.org/batik/) for the conversion, which must be
|
59
|
-
installed separately, as well as a Java Runtime Environment.
|
60
|
-
|
61
|
-
It expects to find a JRE in `/usr/bin/java`, and Batik in
|
62
|
-
`/usr/share/java/batik-rasterizer.jar`, but both paths are configurable.
|
63
|
-
|
64
|
-
Example usage in Rails:
|
65
|
-
|
66
|
-
# config/routes.rb
|
67
|
-
require 'highcharts/export_endpoint'
|
68
|
-
|
69
|
-
MyRailsApp::Application.routes.draw do
|
70
|
-
...
|
71
|
-
mount Highcharts::ExportEndpoint.new({
|
72
|
-
java_path: "/usr/bin/java",
|
73
|
-
batik: "/usr/share/java/batik-rasterizer.jar"
|
74
|
-
}), at: "highcharts-export"
|
75
|
-
...
|
76
|
-
end
|
77
|
-
|
78
|
-
# When rendering the chart
|
79
|
-
new Highcharts.Chart({
|
80
|
-
...
|
81
|
-
exporting: {
|
82
|
-
url: "/highcharts-export",
|
83
|
-
...
|
84
|
-
}
|
85
|
-
})
|
86
|
-
|
87
|
-
### Cocaine
|
88
|
-
|
89
|
-
The exporting endpoint uses [Cocaine](https://github.com/thoughtbot/cocaine) for
|
90
|
-
handling the command lines and arguments and so on.
|
91
|
-
|
92
|
-
I don't know a way to get optional dependencies in the gemspec, so for now
|
93
|
-
that gets added whether you want it or not. I'd like to get this fixed,
|
94
|
-
but would also like to avoid `begin; require 'cocaine'; rescue LoadError; ...; end` and similar hacks.
|
95
|
-
|
96
48
|
## Licensing
|
97
49
|
|
98
50
|
Highcharts, which makes up the majority of this gem, has [its own, separate licensing](http://shop.highsoft.com/highcharts.html).
|
@@ -2,7 +2,7 @@
|
|
2
2
|
// @compilation_level SIMPLE_OPTIMIZATIONS
|
3
3
|
|
4
4
|
/**
|
5
|
-
* @license Highcharts JS v3.0.
|
5
|
+
* @license Highcharts JS v3.0.2 (2013-06-05)
|
6
6
|
*
|
7
7
|
* (c) 2009-2013 Torstein Hønsi
|
8
8
|
*
|
@@ -10,7 +10,7 @@
|
|
10
10
|
*/
|
11
11
|
|
12
12
|
// JSLint options:
|
13
|
-
/*global Highcharts, document, window, navigator, setInterval, clearInterval, clearTimeout, setTimeout, location, jQuery, $, console */
|
13
|
+
/*global Highcharts, document, window, navigator, setInterval, clearInterval, clearTimeout, setTimeout, location, jQuery, $, console, each, grep */
|
14
14
|
|
15
15
|
(function () {
|
16
16
|
// encapsulated variables
|
@@ -55,7 +55,7 @@ var UNDEFINED,
|
|
55
55
|
noop = function () {},
|
56
56
|
charts = [],
|
57
57
|
PRODUCT = 'Highcharts',
|
58
|
-
VERSION = '3.0.
|
58
|
+
VERSION = '3.0.2',
|
59
59
|
|
60
60
|
// some constants for frequently used strings
|
61
61
|
DIV = 'div',
|
@@ -782,14 +782,7 @@ function getTimeTicks(normalizedInterval, min, max, startOfWeek) {
|
|
782
782
|
|
783
783
|
// else, the interval is fixed and we use simple addition
|
784
784
|
} else {
|
785
|
-
|
786
|
-
// mark new days if the time is dividable by day
|
787
|
-
if (interval <= timeUnits[HOUR] && time % timeUnits[DAY] === timezoneOffset) {
|
788
|
-
higherRanks[time] = DAY;
|
789
|
-
}
|
790
|
-
|
791
785
|
time += interval * count;
|
792
|
-
|
793
786
|
}
|
794
787
|
|
795
788
|
i++;
|
@@ -797,8 +790,17 @@ function getTimeTicks(normalizedInterval, min, max, startOfWeek) {
|
|
797
790
|
|
798
791
|
// push the last time
|
799
792
|
tickPositions.push(time);
|
793
|
+
|
794
|
+
|
795
|
+
// mark new days if the time is dividible by day (#1649, #1760)
|
796
|
+
each(grep(tickPositions, function (time) {
|
797
|
+
return interval <= timeUnits[HOUR] && time % timeUnits[DAY] === timezoneOffset;
|
798
|
+
}), function (time) {
|
799
|
+
higherRanks[time] = DAY;
|
800
|
+
});
|
800
801
|
}
|
801
802
|
|
803
|
+
|
802
804
|
// record information on the chosen unit - for dynamic label formatter
|
803
805
|
tickPositions.info = extend(normalizedInterval, {
|
804
806
|
higherRanks: higherRanks,
|
@@ -1094,7 +1096,8 @@ pathAnim = {
|
|
1094
1096
|
Step = Fx.step,
|
1095
1097
|
dSetter,
|
1096
1098
|
Tween = $.Tween,
|
1097
|
-
propHooks = Tween && Tween.propHooks
|
1099
|
+
propHooks = Tween && Tween.propHooks,
|
1100
|
+
opacityHook = $.cssHooks.opacity;
|
1098
1101
|
|
1099
1102
|
/*jslint unparam: true*//* allow unused param x in this function */
|
1100
1103
|
$.extend($.easing, {
|
@@ -1104,7 +1107,6 @@ pathAnim = {
|
|
1104
1107
|
});
|
1105
1108
|
/*jslint unparam: false*/
|
1106
1109
|
|
1107
|
-
|
1108
1110
|
// extend some methods to check for elem.attr, which means it is a Highcharts SVG object
|
1109
1111
|
$.each(['cur', '_default', 'width', 'height', 'opacity'], function (i, fn) {
|
1110
1112
|
var obj = Step,
|
@@ -1141,6 +1143,11 @@ pathAnim = {
|
|
1141
1143
|
};
|
1142
1144
|
}
|
1143
1145
|
});
|
1146
|
+
|
1147
|
+
// Extend the opacity getter, needed for fading opacity with IE9 and jQuery 1.10+
|
1148
|
+
wrap(opacityHook, 'get', function (proceed, elem, computed) {
|
1149
|
+
return elem.attr ? (elem.opacity || 0) : proceed.call(this, elem, computed);
|
1150
|
+
});
|
1144
1151
|
|
1145
1152
|
|
1146
1153
|
// Define the setter function for d (path definitions)
|
@@ -1396,15 +1403,15 @@ pathAnim = {
|
|
1396
1403
|
*/
|
1397
1404
|
animate: function (el, params, options) {
|
1398
1405
|
var $el = $(el);
|
1406
|
+
if (!el.style) {
|
1407
|
+
el.style = {}; // #1881
|
1408
|
+
}
|
1399
1409
|
if (params.d) {
|
1400
1410
|
el.toD = params.d; // keep the array form for paths, used in $.fx.step.d
|
1401
1411
|
params.d = 1; // because in jQuery, animating to an array has a different meaning
|
1402
1412
|
}
|
1403
1413
|
|
1404
1414
|
$el.stop();
|
1405
|
-
if (params.opacity !== UNDEFINED && el.attr) {
|
1406
|
-
params.opacity += 'px'; // force jQuery to use same logic as width and height
|
1407
|
-
}
|
1408
1415
|
$el.animate(params, options);
|
1409
1416
|
|
1410
1417
|
},
|
@@ -1487,8 +1494,8 @@ defaultOptions = {
|
|
1487
1494
|
},
|
1488
1495
|
global: {
|
1489
1496
|
useUTC: true,
|
1490
|
-
canvasToolsURL: 'http://code.highcharts.com/3.0.
|
1491
|
-
VMLRadialGradientURL: 'http://code.highcharts.com/3.0.
|
1497
|
+
canvasToolsURL: 'http://code.highcharts.com/3.0.2/modules/canvas-tools.js',
|
1498
|
+
VMLRadialGradientURL: 'http://code.highcharts.com/3.0.2/gfx/vml-radial-gradient.png'
|
1492
1499
|
},
|
1493
1500
|
chart: {
|
1494
1501
|
//animation: true,
|
@@ -1603,7 +1610,7 @@ defaultOptions = {
|
|
1603
1610
|
dataLabels: merge(defaultLabelOptions, {
|
1604
1611
|
enabled: false,
|
1605
1612
|
formatter: function () {
|
1606
|
-
return this.y;
|
1613
|
+
return numberFormat(this.y, -1);
|
1607
1614
|
},
|
1608
1615
|
verticalAlign: 'bottom', // above singular point
|
1609
1616
|
y: 0
|
@@ -2291,7 +2298,13 @@ SVGElement.prototype = {
|
|
2291
2298
|
});
|
2292
2299
|
|
2293
2300
|
wrapper.attr({
|
2294
|
-
d: wrapper.renderer.symbols[wrapper.symbolName](
|
2301
|
+
d: wrapper.renderer.symbols[wrapper.symbolName](
|
2302
|
+
wrapper.x,
|
2303
|
+
wrapper.y,
|
2304
|
+
wrapper.width,
|
2305
|
+
wrapper.height,
|
2306
|
+
wrapper
|
2307
|
+
)
|
2295
2308
|
});
|
2296
2309
|
},
|
2297
2310
|
|
@@ -2383,9 +2396,7 @@ SVGElement.prototype = {
|
|
2383
2396
|
for (n in styles) {
|
2384
2397
|
serializedCss += n.replace(/([A-Z])/g, hyphenate) + ':' + styles[n] + ';';
|
2385
2398
|
}
|
2386
|
-
|
2387
|
-
style: serializedCss
|
2388
|
-
});
|
2399
|
+
attr(elem, 'style', serializedCss); // #1881
|
2389
2400
|
}
|
2390
2401
|
|
2391
2402
|
|
@@ -2525,19 +2536,17 @@ SVGElement.prototype = {
|
|
2525
2536
|
shadows = wrapper.shadows;
|
2526
2537
|
|
2527
2538
|
// apply translate
|
2528
|
-
|
2529
|
-
|
2530
|
-
|
2531
|
-
|
2532
|
-
|
2533
|
-
|
2534
|
-
|
2535
|
-
|
2536
|
-
|
2537
|
-
marginTop: translateY + 1
|
2538
|
-
});
|
2539
|
+
css(elem, {
|
2540
|
+
marginLeft: translateX,
|
2541
|
+
marginTop: translateY
|
2542
|
+
});
|
2543
|
+
if (shadows) { // used in labels/tooltip
|
2544
|
+
each(shadows, function (shadow) {
|
2545
|
+
css(shadow, {
|
2546
|
+
marginLeft: translateX + 1,
|
2547
|
+
marginTop: translateY + 1
|
2539
2548
|
});
|
2540
|
-
}
|
2549
|
+
});
|
2541
2550
|
}
|
2542
2551
|
|
2543
2552
|
// apply inversion
|
@@ -2655,7 +2664,7 @@ SVGElement.prototype = {
|
|
2655
2664
|
scaleY = wrapper.scaleY,
|
2656
2665
|
inverted = wrapper.inverted,
|
2657
2666
|
rotation = wrapper.rotation,
|
2658
|
-
transform
|
2667
|
+
transform;
|
2659
2668
|
|
2660
2669
|
// flipping affects translate as adjustment for flipping around the group's axis
|
2661
2670
|
if (inverted) {
|
@@ -2663,10 +2672,9 @@ SVGElement.prototype = {
|
|
2663
2672
|
translateY += wrapper.attr('height');
|
2664
2673
|
}
|
2665
2674
|
|
2666
|
-
//
|
2667
|
-
|
2668
|
-
|
2669
|
-
}
|
2675
|
+
// Apply translate. Nearly all transformed elements have translation, so instead
|
2676
|
+
// of checking for translate = 0, do it always (#1767, #1846).
|
2677
|
+
transform = ['translate(' + translateX + ',' + translateY + ')'];
|
2670
2678
|
|
2671
2679
|
// apply rotation
|
2672
2680
|
if (inverted) {
|
@@ -4374,7 +4382,7 @@ SVGRenderer.prototype = {
|
|
4374
4382
|
if (styles) {
|
4375
4383
|
var textStyles = {};
|
4376
4384
|
styles = merge(styles); // create a copy to avoid altering the original object (#537)
|
4377
|
-
each(['fontSize', 'fontWeight', 'fontFamily', 'color', 'lineHeight', 'width'], function (prop) {
|
4385
|
+
each(['fontSize', 'fontWeight', 'fontFamily', 'color', 'lineHeight', 'width', 'textDecoration'], function (prop) {
|
4378
4386
|
if (styles[prop] !== UNDEFINED) {
|
4379
4387
|
textStyles[prop] = styles[prop];
|
4380
4388
|
delete styles[prop];
|
@@ -5303,12 +5311,14 @@ var VMLRendererExtension = { // inherit SVGRenderer
|
|
5303
5311
|
* @param {Number} r
|
5304
5312
|
*/
|
5305
5313
|
circle: function (x, y, r) {
|
5314
|
+
var circle = this.symbol('circle');
|
5306
5315
|
if (isObject(x)) {
|
5307
5316
|
r = x.r;
|
5308
5317
|
y = x.y;
|
5309
5318
|
x = x.x;
|
5310
5319
|
}
|
5311
|
-
|
5320
|
+
circle.isCircle = true; // Causes x and y to mean center (#1682)
|
5321
|
+
return circle.attr({ x: x, y: y, width: 2 * r, height: 2 * r });
|
5312
5322
|
},
|
5313
5323
|
|
5314
5324
|
/**
|
@@ -5450,8 +5460,14 @@ var VMLRendererExtension = { // inherit SVGRenderer
|
|
5450
5460
|
|
5451
5461
|
},
|
5452
5462
|
// Add circle symbol path. This performs significantly faster than v:oval.
|
5453
|
-
circle: function (x, y, w, h) {
|
5463
|
+
circle: function (x, y, w, h, wrapper) {
|
5464
|
+
// Center correction, #1682
|
5465
|
+
if (wrapper && wrapper.isCircle) {
|
5466
|
+
x -= w / 2;
|
5467
|
+
y -= h / 2;
|
5468
|
+
}
|
5454
5469
|
|
5470
|
+
// Return the path
|
5455
5471
|
return [
|
5456
5472
|
'wa', // clockwisearcto
|
5457
5473
|
x, // left
|
@@ -6244,7 +6260,10 @@ StackItem.prototype = {
|
|
6244
6260
|
*/
|
6245
6261
|
render: function (group) {
|
6246
6262
|
var options = this.options,
|
6247
|
-
|
6263
|
+
formatOption = options.format, // docs: added stackLabel.format option
|
6264
|
+
str = formatOption ?
|
6265
|
+
format(formatOption, this) :
|
6266
|
+
options.formatter.call(this); // format the text in the label
|
6248
6267
|
|
6249
6268
|
// Change the text to reflect the new total and set visibility to hidden in case the serie is hidden
|
6250
6269
|
if (this.label) {
|
@@ -6424,7 +6443,7 @@ Axis.prototype = {
|
|
6424
6443
|
//textAlign: dynamic,
|
6425
6444
|
//rotation: 0,
|
6426
6445
|
formatter: function () {
|
6427
|
-
return this.total;
|
6446
|
+
return numberFormat(this.total, -1);
|
6428
6447
|
},
|
6429
6448
|
style: defaultLabelOptions.style
|
6430
6449
|
}
|
@@ -6699,6 +6718,9 @@ Axis.prototype = {
|
|
6699
6718
|
erase(chart.axes, this);
|
6700
6719
|
erase(chart[key], this);
|
6701
6720
|
chart.options[key].splice(this.options.index, 1);
|
6721
|
+
each(chart[key], function (axis, i) { // Re-index, #1706
|
6722
|
+
axis.options.index = i;
|
6723
|
+
});
|
6702
6724
|
this.destroy();
|
6703
6725
|
chart.isDirtyBox = true;
|
6704
6726
|
|
@@ -7399,7 +7421,7 @@ Axis.prototype = {
|
|
7399
7421
|
}
|
7400
7422
|
|
7401
7423
|
// Record minPointOffset and pointRangePadding
|
7402
|
-
ordinalCorrection = axis.ordinalSlope ? axis.ordinalSlope / closestPointRange : 1; // #988
|
7424
|
+
ordinalCorrection = axis.ordinalSlope && closestPointRange ? axis.ordinalSlope / closestPointRange : 1; // #988, #1853
|
7403
7425
|
axis.minPointOffset = minPointOffset = minPointOffset * ordinalCorrection;
|
7404
7426
|
axis.pointRangePadding = pointRangePadding = pointRangePadding * ordinalCorrection;
|
7405
7427
|
|
@@ -8462,6 +8484,8 @@ Tooltip.prototype = {
|
|
8462
8484
|
if (this.label) {
|
8463
8485
|
this.label = this.label.destroy();
|
8464
8486
|
}
|
8487
|
+
clearTimeout(this.hideTimer);
|
8488
|
+
clearTimeout(this.tooltipTimeout);
|
8465
8489
|
},
|
8466
8490
|
|
8467
8491
|
/**
|
@@ -8511,7 +8535,8 @@ Tooltip.prototype = {
|
|
8511
8535
|
hide: function () {
|
8512
8536
|
var tooltip = this,
|
8513
8537
|
hoverPoints;
|
8514
|
-
|
8538
|
+
|
8539
|
+
clearTimeout(this.hideTimer); // disallow duplicate timers (#1728, #1766)
|
8515
8540
|
if (!this.isHidden) {
|
8516
8541
|
hoverPoints = this.chart.hoverPoints;
|
8517
8542
|
|
@@ -9076,7 +9101,7 @@ Pointer.prototype = {
|
|
9076
9101
|
|
9077
9102
|
// Scale each series
|
9078
9103
|
each(chart.series, function (series) {
|
9079
|
-
if (series.xAxis.zoomEnabled) {
|
9104
|
+
if (series.xAxis && series.xAxis.zoomEnabled) {
|
9080
9105
|
series.group.attr(attribs);
|
9081
9106
|
if (series.markerGroup) {
|
9082
9107
|
series.markerGroup.attr(attribs);
|
@@ -9179,7 +9204,7 @@ Pointer.prototype = {
|
|
9179
9204
|
var self = this,
|
9180
9205
|
chart = self.chart,
|
9181
9206
|
pinchDown = self.pinchDown,
|
9182
|
-
followTouchMove = chart.tooltip.options.followTouchMove,
|
9207
|
+
followTouchMove = chart.tooltip && chart.tooltip.options.followTouchMove,
|
9183
9208
|
touches = e.touches,
|
9184
9209
|
touchesLength = touches.length,
|
9185
9210
|
lastValidTouch = self.lastValidTouch,
|
@@ -9191,12 +9216,8 @@ Pointer.prototype = {
|
|
9191
9216
|
clip = {};
|
9192
9217
|
|
9193
9218
|
// On touch devices, only proceed to trigger click if a handler is defined
|
9194
|
-
if (e.type === 'touchstart'
|
9195
|
-
if (
|
9196
|
-
if (!chart.runTrackerClick || touchesLength > 1) {
|
9197
|
-
e.preventDefault();
|
9198
|
-
}
|
9199
|
-
} else if (!chart.runChartClick || touchesLength > 1) {
|
9219
|
+
if (e.type === 'touchstart') {
|
9220
|
+
if (followTouchMove || hasZoom) {
|
9200
9221
|
e.preventDefault();
|
9201
9222
|
}
|
9202
9223
|
}
|
@@ -9383,9 +9404,8 @@ Pointer.prototype = {
|
|
9383
9404
|
each(chart.axes, function (axis) {
|
9384
9405
|
if (axis.zoomEnabled) {
|
9385
9406
|
var horiz = axis.horiz,
|
9386
|
-
|
9387
|
-
|
9388
|
-
selectionMax = axis.toValue((horiz ? selectionLeft + selectionBox.width : selectionTop + selectionBox.height) - minPixelPadding);
|
9407
|
+
selectionMin = axis.toValue((horiz ? selectionLeft : selectionTop)),
|
9408
|
+
selectionMax = axis.toValue((horiz ? selectionLeft + selectionBox.width : selectionTop + selectionBox.height));
|
9389
9409
|
|
9390
9410
|
if (!isNaN(selectionMin) && !isNaN(selectionMax)) { // #859
|
9391
9411
|
selectionData[axis.xOrY + 'Axis'].push({
|
@@ -9420,7 +9440,7 @@ Pointer.prototype = {
|
|
9420
9440
|
// Reset all
|
9421
9441
|
if (chart) { // it may be destroyed on mouse up - #877
|
9422
9442
|
css(chart.container, { cursor: chart._cursor });
|
9423
|
-
chart.cancelClick = this.hasDragged; // #370
|
9443
|
+
chart.cancelClick = this.hasDragged > 10; // #370
|
9424
9444
|
chart.mouseIsDown = this.hasDragged = this.hasPinched = false;
|
9425
9445
|
this.pinchDown = [];
|
9426
9446
|
}
|
@@ -9488,8 +9508,8 @@ Pointer.prototype = {
|
|
9488
9508
|
this.drag(e);
|
9489
9509
|
}
|
9490
9510
|
|
9491
|
-
// Show the tooltip and run mouse over events (#977)
|
9492
|
-
if (chart.isInsidePlot(e.chartX - chart.plotLeft, e.chartY - chart.plotTop)) {
|
9511
|
+
// Show the tooltip and run mouse over events (#977)
|
9512
|
+
if (chart.isInsidePlot(e.chartX - chart.plotLeft, e.chartY - chart.plotTop) && !chart.openMenu) {
|
9493
9513
|
this.runPointActions(e);
|
9494
9514
|
}
|
9495
9515
|
},
|
@@ -9556,7 +9576,9 @@ Pointer.prototype = {
|
|
9556
9576
|
}));
|
9557
9577
|
|
9558
9578
|
// the point click event
|
9559
|
-
hoverPoint
|
9579
|
+
if (chart.hoverPoint) { // it may be destroyed (#1844)
|
9580
|
+
hoverPoint.firePointEvent('click', e);
|
9581
|
+
}
|
9560
9582
|
|
9561
9583
|
// When clicking outside a tracker, fire a chart event
|
9562
9584
|
} else {
|
@@ -10065,8 +10087,6 @@ Legend.prototype = {
|
|
10065
10087
|
.add(legendGroup);
|
10066
10088
|
legend.scrollGroup = renderer.g()
|
10067
10089
|
.add(legend.contentGroup);
|
10068
|
-
legend.clipRect = renderer.clipRect(0, 0, 9999, chart.chartHeight);
|
10069
|
-
legend.contentGroup.clip(legend.clipRect);
|
10070
10090
|
}
|
10071
10091
|
|
10072
10092
|
legend.renderTitle();
|
@@ -10210,12 +10230,17 @@ Legend.prototype = {
|
|
10210
10230
|
|
10211
10231
|
// Reset the legend height and adjust the clipping rectangle
|
10212
10232
|
if (legendHeight > spaceHeight && !options.useHTML) {
|
10213
|
-
|
10233
|
+
|
10214
10234
|
this.clipHeight = clipHeight = spaceHeight - 20 - this.titleHeight;
|
10215
10235
|
this.pageCount = pageCount = mathCeil(legendHeight / clipHeight);
|
10216
10236
|
this.currentPage = pick(this.currentPage, 1);
|
10217
10237
|
this.fullHeight = legendHeight;
|
10218
10238
|
|
10239
|
+
// Only apply clipping if needed. Clipping causes blurred legend in PDF export (#1787)
|
10240
|
+
if (!clipRect) {
|
10241
|
+
clipRect = legend.clipRect = renderer.clipRect(0, 0, 9999, 0);
|
10242
|
+
legend.contentGroup.clip(clipRect);
|
10243
|
+
}
|
10219
10244
|
clipRect.attr({
|
10220
10245
|
height: clipHeight
|
10221
10246
|
});
|
@@ -11112,7 +11137,8 @@ Chart.prototype = {
|
|
11112
11137
|
height: chartHeight + PX,
|
11113
11138
|
textAlign: 'left',
|
11114
11139
|
lineHeight: 'normal', // #427
|
11115
|
-
zIndex: 0 // #1072
|
11140
|
+
zIndex: 0, // #1072
|
11141
|
+
'-webkit-tap-highlight-color': 'rgba(0,0,0,0)'
|
11116
11142
|
}, optionsChart.style),
|
11117
11143
|
chart.renderToClone || renderTo
|
11118
11144
|
);
|
@@ -12117,7 +12143,7 @@ Point.prototype = {
|
|
12117
12143
|
// Insert options for valueDecimals, valuePrefix, and valueSuffix
|
12118
12144
|
var series = this.series,
|
12119
12145
|
seriesTooltipOptions = series.tooltipOptions,
|
12120
|
-
valueDecimals = pick(seriesTooltipOptions.valueDecimals,
|
12146
|
+
valueDecimals = pick(seriesTooltipOptions.valueDecimals, ''),
|
12121
12147
|
valuePrefix = seriesTooltipOptions.valuePrefix || '',
|
12122
12148
|
valueSuffix = seriesTooltipOptions.valueSuffix || '';
|
12123
12149
|
|
@@ -12518,7 +12544,7 @@ Series.prototype = {
|
|
12518
12544
|
|
12519
12545
|
// The series needs an X and an Y axis
|
12520
12546
|
if (!series[AXIS]) {
|
12521
|
-
error(
|
12547
|
+
error(18, true);
|
12522
12548
|
}
|
12523
12549
|
|
12524
12550
|
});
|
@@ -13129,13 +13155,18 @@ Series.prototype = {
|
|
13129
13155
|
dataLength = points.length,
|
13130
13156
|
hasModifyValue = !!series.modifyValue,
|
13131
13157
|
isBottomSeries,
|
13132
|
-
allStackSeries
|
13133
|
-
i
|
13158
|
+
allStackSeries,
|
13159
|
+
i,
|
13134
13160
|
placeBetween = options.pointPlacement === 'between',
|
13135
13161
|
threshold = options.threshold;
|
13136
13162
|
//nextSeriesDown;
|
13137
13163
|
|
13138
|
-
// Is it the last visible series?
|
13164
|
+
// Is it the last visible series? (#809, #1722).
|
13165
|
+
// TODO: After merging in the 'stacking' branch, this logic should probably be moved to Chart.getStacks
|
13166
|
+
allStackSeries = yAxis.series.sort(function (a, b) {
|
13167
|
+
return a.index - b.index;
|
13168
|
+
});
|
13169
|
+
i = allStackSeries.length;
|
13139
13170
|
while (i--) {
|
13140
13171
|
if (allStackSeries[i].visible) {
|
13141
13172
|
if (allStackSeries[i] === series) { // #809
|
@@ -13278,19 +13309,25 @@ Series.prototype = {
|
|
13278
13309
|
var series = this,
|
13279
13310
|
tooltipOptions = series.tooltipOptions,
|
13280
13311
|
xDateFormat = tooltipOptions.xDateFormat,
|
13312
|
+
dateTimeLabelFormats = tooltipOptions.dateTimeLabelFormats,
|
13281
13313
|
xAxis = series.xAxis,
|
13282
13314
|
isDateTime = xAxis && xAxis.options.type === 'datetime',
|
13283
13315
|
headerFormat = tooltipOptions.headerFormat,
|
13316
|
+
closestPointRange = xAxis && xAxis.closestPointRange,
|
13284
13317
|
n;
|
13285
13318
|
|
13286
13319
|
// Guess the best date format based on the closest point distance (#568)
|
13287
13320
|
if (isDateTime && !xDateFormat) {
|
13288
|
-
|
13289
|
-
|
13290
|
-
|
13291
|
-
|
13292
|
-
|
13293
|
-
|
13321
|
+
if (closestPointRange) {
|
13322
|
+
for (n in timeUnits) {
|
13323
|
+
if (timeUnits[n] >= closestPointRange) {
|
13324
|
+
xDateFormat = dateTimeLabelFormats[n];
|
13325
|
+
break;
|
13326
|
+
}
|
13327
|
+
}
|
13328
|
+
} else {
|
13329
|
+
xDateFormat = dateTimeLabelFormats.day;
|
13330
|
+
}
|
13294
13331
|
}
|
13295
13332
|
|
13296
13333
|
// Insert the header date format if any
|
@@ -13480,7 +13517,7 @@ Series.prototype = {
|
|
13480
13517
|
graphic = point.graphic;
|
13481
13518
|
pointMarkerOptions = point.marker || {};
|
13482
13519
|
enabled = (seriesMarkerOptions.enabled && pointMarkerOptions.enabled === UNDEFINED) || pointMarkerOptions.enabled;
|
13483
|
-
isInside = chart.isInsidePlot(plotX, plotY, chart.inverted);
|
13520
|
+
isInside = chart.isInsidePlot(mathRound(plotX), plotY, chart.inverted); // #1858
|
13484
13521
|
|
13485
13522
|
// only draw the point if y is defined
|
13486
13523
|
if (enabled && plotY !== UNDEFINED && !isNaN(plotY) && point.y !== null) {
|
@@ -13669,7 +13706,7 @@ Series.prototype = {
|
|
13669
13706
|
);
|
13670
13707
|
|
13671
13708
|
// Force the fill to negativeColor on markers
|
13672
|
-
if (point.negative && seriesOptions.marker) {
|
13709
|
+
if (point.negative && seriesOptions.marker && negativeColor) {
|
13673
13710
|
pointAttr[NORMAL_STATE].fill = pointAttr[HOVER_STATE].fill = pointAttr[SELECT_STATE].fill =
|
13674
13711
|
series.convertAttribs({ fillColor: negativeColor }).fill;
|
13675
13712
|
}
|
@@ -14110,6 +14147,8 @@ Series.prototype = {
|
|
14110
14147
|
translatedThreshold,
|
14111
14148
|
posAttr,
|
14112
14149
|
negAttr,
|
14150
|
+
graph = this.graph,
|
14151
|
+
area = this.area,
|
14113
14152
|
posClip = this.posClip,
|
14114
14153
|
negClip = this.negClip,
|
14115
14154
|
chartWidth = chart.chartWidth,
|
@@ -14118,7 +14157,7 @@ Series.prototype = {
|
|
14118
14157
|
above,
|
14119
14158
|
below;
|
14120
14159
|
|
14121
|
-
if (negativeColor &&
|
14160
|
+
if (negativeColor && (graph || area)) {
|
14122
14161
|
translatedThreshold = mathCeil(this.yAxis.len - this.yAxis.translate(options.threshold || 0));
|
14123
14162
|
above = {
|
14124
14163
|
x: 0,
|
@@ -14160,14 +14199,17 @@ Series.prototype = {
|
|
14160
14199
|
posClip.animate(posAttr);
|
14161
14200
|
negClip.animate(negAttr);
|
14162
14201
|
} else {
|
14163
|
-
this.posClip = posClip = renderer.clipRect(posAttr);
|
14164
|
-
this.graph.clip(posClip);
|
14165
14202
|
|
14203
|
+
this.posClip = posClip = renderer.clipRect(posAttr);
|
14166
14204
|
this.negClip = negClip = renderer.clipRect(negAttr);
|
14167
|
-
this.graphNeg.clip(negClip);
|
14168
14205
|
|
14169
|
-
if (
|
14170
|
-
|
14206
|
+
if (graph) {
|
14207
|
+
graph.clip(posClip);
|
14208
|
+
this.graphNeg.clip(negClip);
|
14209
|
+
}
|
14210
|
+
|
14211
|
+
if (area) {
|
14212
|
+
area.clip(posClip);
|
14171
14213
|
this.areaNeg.clip(negClip);
|
14172
14214
|
}
|
14173
14215
|
}
|
@@ -14180,6 +14222,11 @@ Series.prototype = {
|
|
14180
14222
|
invertGroups: function () {
|
14181
14223
|
var series = this,
|
14182
14224
|
chart = series.chart;
|
14225
|
+
|
14226
|
+
// Pie, go away (#1736)
|
14227
|
+
if (!series.xAxis) {
|
14228
|
+
return;
|
14229
|
+
}
|
14183
14230
|
|
14184
14231
|
// A fixed size is needed for inversion to work
|
14185
14232
|
function setInvert() {
|
@@ -14234,7 +14281,6 @@ Series.prototype = {
|
|
14234
14281
|
scaleX: 1, // #1623
|
14235
14282
|
scaleY: 1
|
14236
14283
|
});
|
14237
|
-
|
14238
14284
|
return group;
|
14239
14285
|
|
14240
14286
|
},
|
@@ -14281,8 +14327,8 @@ Series.prototype = {
|
|
14281
14327
|
// cache attributes for shapes
|
14282
14328
|
series.getAttribs();
|
14283
14329
|
|
14284
|
-
// SVGRenderer needs to know this before drawing elements (#1089)
|
14285
|
-
group.inverted = chart.inverted;
|
14330
|
+
// SVGRenderer needs to know this before drawing elements (#1089, #1795)
|
14331
|
+
group.inverted = series.isCartesian ? chart.inverted : false;
|
14286
14332
|
|
14287
14333
|
// draw the graph if any
|
14288
14334
|
if (series.drawGraph) {
|
@@ -16077,6 +16123,7 @@ var PieSeries = {
|
|
16077
16123
|
dataLabel = point.dataLabel;
|
16078
16124
|
|
16079
16125
|
if (dataLabel && dataLabel._pos) {
|
16126
|
+
visibility = dataLabel._attr.visibility;
|
16080
16127
|
x = dataLabel.connX;
|
16081
16128
|
y = dataLabel.connY;
|
16082
16129
|
connectorPath = softConnector ? [
|