highcharts-rails 4.2.5 → 4.2.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.markdown +47 -0
- data/app/assets/javascripts/highcharts.js +261 -151
- data/app/assets/javascripts/highcharts/highcharts-3d.js +173 -184
- data/app/assets/javascripts/highcharts/highcharts-more.js +60 -13
- data/app/assets/javascripts/highcharts/modules/broken-axis.js +1 -1
- data/app/assets/javascripts/highcharts/modules/canvas-tools.js +1 -1
- data/app/assets/javascripts/highcharts/modules/data.js +11 -1
- data/app/assets/javascripts/highcharts/modules/drilldown.js +17 -10
- data/app/assets/javascripts/highcharts/modules/exporting.js +6 -9
- data/app/assets/javascripts/highcharts/modules/funnel.js +4 -4
- data/app/assets/javascripts/highcharts/modules/heatmap.js +1 -1
- data/app/assets/javascripts/highcharts/modules/no-data-to-display.js +1 -1
- data/app/assets/javascripts/highcharts/modules/offline-exporting.js +237 -201
- data/app/assets/javascripts/highcharts/modules/solid-gauge.js +1 -1
- data/app/assets/javascripts/highcharts/modules/treemap.js +16 -5
- data/lib/highcharts/version.rb +1 -1
- metadata +2 -2
@@ -2,7 +2,7 @@
|
|
2
2
|
// @compilation_level SIMPLE_OPTIMIZATIONS
|
3
3
|
|
4
4
|
/**
|
5
|
-
* @license Highcharts JS v4.2.
|
5
|
+
* @license Highcharts JS v4.2.6 (2016-08-02)
|
6
6
|
*
|
7
7
|
* 3D features for Highcharts JS
|
8
8
|
*
|
@@ -35,6 +35,41 @@
|
|
35
35
|
cos = Math.cos,
|
36
36
|
round = Math.round;
|
37
37
|
|
38
|
+
/**
|
39
|
+
* Apply 3-D rotation
|
40
|
+
* Euler Angles (XYZ): cosA = cos(Alfa|Roll), cosB = cos(Beta|Pitch), cosG = cos(Gamma|Yaw)
|
41
|
+
*
|
42
|
+
* Composite rotation:
|
43
|
+
* | cosB * cosG | cosB * sinG | -sinB |
|
44
|
+
* | sinA * sinB * cosG - cosA * sinG | sinA * sinB * sinG + cosA * cosG | sinA * cosB |
|
45
|
+
* | cosA * sinB * cosG + sinA * sinG | cosA * sinB * sinG - sinA * cosG | cosA * cosB |
|
46
|
+
*
|
47
|
+
* Now, Gamma/Yaw is not used (angle=0), so we assume cosG = 1 and sinG = 0, so we get:
|
48
|
+
* | cosB | 0 | - sinB |
|
49
|
+
* | sinA * sinB | cosA | sinA * cosB |
|
50
|
+
* | cosA * sinB | - sinA | cosA * cosB |
|
51
|
+
*
|
52
|
+
* But in browsers, y is reversed, so we get sinA => -sinA. The general result is:
|
53
|
+
* | cosB | 0 | - sinB | | x | | px |
|
54
|
+
* | - sinA * sinB | cosA | - sinA * cosB | x | y | = | py |
|
55
|
+
* | cosA * sinB | sinA | cosA * cosB | | z | | pz |
|
56
|
+
*/
|
57
|
+
function rotate3D(x, y, z, angles) {
|
58
|
+
return {
|
59
|
+
x: angles.cosB * x - angles.sinB * z,
|
60
|
+
y: -angles.sinA * angles.sinB * x + angles.cosA * y - angles.cosB * angles.sinA * z,
|
61
|
+
z: angles.cosA * angles.sinB * x + angles.sinA * y + angles.cosA * angles.cosB * z
|
62
|
+
};
|
63
|
+
}
|
64
|
+
|
65
|
+
function perspective3D(coordinate, origin, distance) {
|
66
|
+
var projection = ((distance > 0) && (distance < Number.POSITIVE_INFINITY)) ? distance / (coordinate.z + origin.z + distance) : 1;
|
67
|
+
return {
|
68
|
+
x: coordinate.x * projection,
|
69
|
+
y: coordinate.y * projection
|
70
|
+
};
|
71
|
+
}
|
72
|
+
|
38
73
|
/**
|
39
74
|
* Transforms a given array of points according to the angles in chart.options.
|
40
75
|
* Parameters:
|
@@ -44,97 +79,52 @@
|
|
44
79
|
* Returns:
|
45
80
|
* - an array of transformed points
|
46
81
|
*/
|
47
|
-
function
|
82
|
+
var perspective = Highcharts.perspective = function (points, chart, insidePlotArea) {
|
48
83
|
var options3d = chart.options.chart.options3d,
|
49
|
-
inverted = false,
|
50
|
-
origin,
|
51
|
-
scale = chart.scale3d || 1;
|
52
|
-
|
53
|
-
if (insidePlotArea) {
|
54
|
-
inverted = chart.inverted;
|
84
|
+
inverted = insidePlotArea ? chart.inverted : false,
|
55
85
|
origin = {
|
56
86
|
x: chart.plotWidth / 2,
|
57
87
|
y: chart.plotHeight / 2,
|
58
88
|
z: options3d.depth / 2,
|
59
89
|
vd: pick(options3d.depth, 1) * pick(options3d.viewDistance, 0)
|
90
|
+
},
|
91
|
+
scale = chart.scale3d || 1,
|
92
|
+
beta = deg2rad * options3d.beta * (inverted ? -1 : 1),
|
93
|
+
alpha = deg2rad * options3d.alpha * (inverted ? -1 : 1),
|
94
|
+
angles = {
|
95
|
+
cosA: cos(alpha),
|
96
|
+
cosB: cos(-beta),
|
97
|
+
sinA: sin(alpha),
|
98
|
+
sinB: sin(-beta)
|
60
99
|
};
|
61
|
-
} else {
|
62
|
-
origin = {
|
63
|
-
x: chart.plotLeft + (chart.plotWidth / 2),
|
64
|
-
y: chart.plotTop + (chart.plotHeight / 2),
|
65
|
-
z: options3d.depth / 2,
|
66
|
-
vd: pick(options3d.depth, 1) * pick(options3d.viewDistance, 0)
|
67
|
-
};
|
68
|
-
}
|
69
|
-
|
70
|
-
var result = [],
|
71
|
-
xe = origin.x,
|
72
|
-
ye = origin.y,
|
73
|
-
ze = origin.z,
|
74
|
-
vd = origin.vd,
|
75
|
-
angle1 = deg2rad * (inverted ? options3d.beta : -options3d.beta),
|
76
|
-
angle2 = deg2rad * (inverted ? -options3d.alpha : options3d.alpha),
|
77
|
-
s1 = sin(angle1),
|
78
|
-
c1 = cos(angle1),
|
79
|
-
s2 = sin(angle2),
|
80
|
-
c2 = cos(angle2);
|
81
100
|
|
82
|
-
|
101
|
+
if (!insidePlotArea) {
|
102
|
+
origin.x += chart.plotLeft;
|
103
|
+
origin.y += chart.plotTop;
|
104
|
+
}
|
83
105
|
|
84
106
|
// Transform each point
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
//
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
// Now, Gamma/Yaw is not used (angle=0), so we assume cosG = 1 and sinG = 0, so we get:
|
99
|
-
// | cosB | 0 | - sinB |
|
100
|
-
// | sinA * sinB | cosA | sinA * cosB |
|
101
|
-
// | cosA * sinB | - sinA | cosA * cosB |
|
102
|
-
//
|
103
|
-
// But in browsers, y is reversed, so we get sinA => -sinA. The general result is:
|
104
|
-
// | cosB | 0 | - sinB | | x | | px |
|
105
|
-
// | - sinA * sinB | cosA | - sinA * cosB | x | y | = | py |
|
106
|
-
// | cosA * sinB | sinA | cosA * cosB | | z | | pz |
|
107
|
-
//
|
108
|
-
// Result:
|
109
|
-
px = c1 * x - s1 * z;
|
110
|
-
py = -s1 * s2 * x + c2 * y - c1 * s2 * z;
|
111
|
-
pz = s1 * c2 * x + s2 * y + c1 * c2 * z;
|
112
|
-
|
113
|
-
|
114
|
-
// Apply perspective
|
115
|
-
if ((vd > 0) && (vd < Number.POSITIVE_INFINITY)) {
|
116
|
-
px = px * (vd / (pz + ze + vd));
|
117
|
-
py = py * (vd / (pz + ze + vd));
|
118
|
-
}
|
119
|
-
|
107
|
+
return Highcharts.map(points, function (point) {
|
108
|
+
var rotated = rotate3D(
|
109
|
+
(inverted ? point.y : point.x) - origin.x,
|
110
|
+
(inverted ? point.x : point.y) - origin.y,
|
111
|
+
(point.z || 0) - origin.z,
|
112
|
+
angles
|
113
|
+
),
|
114
|
+
coordinate = perspective3D(rotated, origin, origin.vd); // Apply perspective
|
115
|
+
|
116
|
+
// Apply translation
|
117
|
+
coordinate.x = coordinate.x * scale + origin.x;
|
118
|
+
coordinate.y = coordinate.y * scale + origin.y;
|
119
|
+
coordinate.z = rotated.z * scale + origin.z;
|
120
120
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
result.push({
|
128
|
-
x: (inverted ? py : px),
|
129
|
-
y: (inverted ? px : py),
|
130
|
-
z: pz
|
131
|
-
});
|
121
|
+
return {
|
122
|
+
x: (inverted ? coordinate.y : coordinate.x),
|
123
|
+
y: (inverted ? coordinate.x : coordinate.y),
|
124
|
+
z: coordinate.z
|
125
|
+
};
|
132
126
|
});
|
133
|
-
|
134
|
-
}
|
135
|
-
// Make function acessible to plugins
|
136
|
-
Highcharts.perspective = perspective;
|
137
|
-
/***
|
127
|
+
};/***
|
138
128
|
EXTENSION TO THE SVG-RENDERER TO ENABLE 3D SHAPES
|
139
129
|
***/
|
140
130
|
////// HELPER METHODS //////
|
@@ -480,7 +470,8 @@
|
|
480
470
|
wrap(wrapper, 'animate', function (proceed, params, animation, complete) {
|
481
471
|
var ca,
|
482
472
|
from = this.attribs,
|
483
|
-
to
|
473
|
+
to,
|
474
|
+
anim;
|
484
475
|
|
485
476
|
// Attribute-line properties connected to 3D. These shouldn't have been in the
|
486
477
|
// attribs collection in the first place.
|
@@ -490,15 +481,15 @@
|
|
490
481
|
delete params.alpha;
|
491
482
|
delete params.beta;
|
492
483
|
|
493
|
-
|
484
|
+
anim = animObject(pick(animation, this.renderer.globalAnimation));
|
494
485
|
|
495
|
-
if (
|
486
|
+
if (anim.duration) {
|
496
487
|
params = merge(params); // Don't mutate the original object
|
497
488
|
ca = suckOutCustom(params);
|
498
489
|
|
499
490
|
if (ca) {
|
500
491
|
to = ca;
|
501
|
-
|
492
|
+
anim.step = function (a, fx) {
|
502
493
|
function interpolate(key) {
|
503
494
|
return from[key] + (pick(to[key], from[key]) - from[key]) * fx.pos;
|
504
495
|
}
|
@@ -726,104 +717,103 @@
|
|
726
717
|
};
|
727
718
|
|
728
719
|
/**
|
729
|
-
*
|
720
|
+
* Calculate scale of the 3D view. That is required to
|
730
721
|
* fit chart's 3D projection into the actual plotting area. Reported as #4933.
|
722
|
+
* @notice This function should ideally take the plot values instead of a chart object,
|
723
|
+
* but since the chart object is needed for perspective it is not practical.
|
724
|
+
* Possible to make both getScale and perspective more logical and also immutable.
|
725
|
+
* @param {Object} chart Chart object
|
726
|
+
* @param {Number} chart.plotLeft
|
727
|
+
* @param {Number} chart.plotWidth
|
728
|
+
* @param {Number} chart.plotTop
|
729
|
+
* @param {Number} chart.plotHeight
|
730
|
+
* @param {Number} depth The depth of the chart
|
731
|
+
* @return {Number} The scale to fit the 3D chart into the plotting area.
|
731
732
|
*/
|
732
|
-
|
733
|
-
var
|
734
|
-
|
733
|
+
function getScale(chart, depth) {
|
734
|
+
var plotLeft = chart.plotLeft,
|
735
|
+
plotRight = chart.plotWidth + plotLeft,
|
736
|
+
plotTop = chart.plotTop,
|
737
|
+
plotBottom = chart.plotHeight + plotTop,
|
738
|
+
originX = plotLeft + chart.plotWidth / 2,
|
739
|
+
originY = plotTop + chart.plotHeight / 2,
|
735
740
|
bbox3d = {
|
736
741
|
minX: Number.MAX_VALUE,
|
737
742
|
maxX: -Number.MAX_VALUE,
|
738
743
|
minY: Number.MAX_VALUE,
|
739
744
|
maxY: -Number.MAX_VALUE
|
740
745
|
},
|
741
|
-
|
742
|
-
|
743
|
-
|
744
|
-
|
745
|
-
|
746
|
-
|
747
|
-
|
748
|
-
|
749
|
-
|
746
|
+
corners,
|
747
|
+
scale = 1;
|
748
|
+
|
749
|
+
// Top left corners:
|
750
|
+
corners = [{
|
751
|
+
x: plotLeft,
|
752
|
+
y: plotTop,
|
753
|
+
z: 0
|
754
|
+
}, {
|
755
|
+
x: plotLeft,
|
756
|
+
y: plotTop,
|
757
|
+
z: depth
|
758
|
+
}];
|
759
|
+
|
760
|
+
// Top right corners:
|
761
|
+
each([0, 1], function (i) {
|
762
|
+
corners.push({
|
763
|
+
x: plotRight,
|
764
|
+
y: corners[i].y,
|
765
|
+
z: corners[i].z
|
766
|
+
});
|
767
|
+
});
|
750
768
|
|
751
|
-
|
769
|
+
// All bottom corners:
|
770
|
+
each([0, 1, 2, 3], function (i) {
|
771
|
+
corners.push({
|
772
|
+
x: corners[i].x,
|
773
|
+
y: plotBottom,
|
774
|
+
z: corners[i].z
|
775
|
+
});
|
776
|
+
});
|
752
777
|
|
753
|
-
|
754
|
-
|
755
|
-
// Clear previous scale in case of updates:
|
756
|
-
chart.scale3d = 1;
|
757
|
-
|
758
|
-
// Top left corners:
|
759
|
-
corners = [{
|
760
|
-
x: plotLeft,
|
761
|
-
y: plotTop,
|
762
|
-
z: 0
|
763
|
-
}, {
|
764
|
-
x: plotLeft,
|
765
|
-
y: plotTop,
|
766
|
-
z: options3d.depth
|
767
|
-
}];
|
768
|
-
|
769
|
-
// Top right corners:
|
770
|
-
for (i = 0; i < 2; i++) {
|
771
|
-
corners.push({
|
772
|
-
x: plotRight,
|
773
|
-
y: corners[i].y,
|
774
|
-
z: corners[i].z
|
775
|
-
});
|
776
|
-
}
|
778
|
+
// Calculate 3D corners:
|
779
|
+
corners = perspective(corners, chart, false);
|
777
780
|
|
778
|
-
|
779
|
-
|
780
|
-
|
781
|
-
|
782
|
-
|
783
|
-
|
784
|
-
|
785
|
-
}
|
781
|
+
// Get bounding box of 3D element:
|
782
|
+
each(corners, function (corner) {
|
783
|
+
bbox3d.minX = Math.min(bbox3d.minX, corner.x);
|
784
|
+
bbox3d.maxX = Math.max(bbox3d.maxX, corner.x);
|
785
|
+
bbox3d.minY = Math.min(bbox3d.minY, corner.y);
|
786
|
+
bbox3d.maxY = Math.max(bbox3d.maxY, corner.y);
|
787
|
+
});
|
786
788
|
|
787
|
-
|
788
|
-
|
789
|
+
// Left edge:
|
790
|
+
if (plotLeft > bbox3d.minX) {
|
791
|
+
scale = Math.min(scale, 1 - Math.abs((plotLeft + originX) / (bbox3d.minX + originX)) % 1);
|
792
|
+
}
|
789
793
|
|
790
|
-
|
791
|
-
|
792
|
-
|
793
|
-
|
794
|
-
bbox3d.minY = Math.min(bbox3d.minY, corner.y);
|
795
|
-
bbox3d.maxY = Math.max(bbox3d.maxY, corner.y);
|
796
|
-
});
|
794
|
+
// Right edge:
|
795
|
+
if (plotRight < bbox3d.maxX) {
|
796
|
+
scale = Math.min(scale, (plotRight - originX) / (bbox3d.maxX - originX));
|
797
|
+
}
|
797
798
|
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
|
799
|
+
// Top edge:
|
800
|
+
if (plotTop > bbox3d.minY) {
|
801
|
+
if (bbox3d.minY < 0) {
|
802
|
+
scale = Math.min(scale, (plotTop + originY) / (-bbox3d.minY + plotTop + originY));
|
803
|
+
} else {
|
804
|
+
scale = Math.min(scale, 1 - (plotTop + originY) / (bbox3d.minY + originY) % 1);
|
805
|
+
}
|
806
|
+
}
|
802
807
|
|
803
|
-
|
804
|
-
|
805
|
-
|
806
|
-
|
808
|
+
// Bottom edge:
|
809
|
+
if (plotBottom < bbox3d.maxY) {
|
810
|
+
scale = Math.min(scale, Math.abs((plotBottom - originY) / (bbox3d.maxY - originY)));
|
811
|
+
}
|
807
812
|
|
808
|
-
|
809
|
-
|
810
|
-
if (bbox3d.minY < 0) {
|
811
|
-
scale = Math.min(scale, (plotTop + originY) / (-bbox3d.minY + plotTop + originY));
|
812
|
-
} else {
|
813
|
-
scale = Math.min(scale, 1 - (plotTop + originY) / (bbox3d.minY + originY) % 1);
|
814
|
-
}
|
815
|
-
}
|
813
|
+
return scale;
|
814
|
+
}
|
816
815
|
|
817
|
-
// Bottom edge:
|
818
|
-
if (plotBottom < bbox3d.maxY) {
|
819
|
-
scale = Math.min(scale, Math.abs((plotBottom - originY) / (bbox3d.maxY - originY)));
|
820
|
-
}
|
821
816
|
|
822
|
-
// Set scale, used later in perspective method():
|
823
|
-
chart.scale3d = scale;
|
824
|
-
}
|
825
|
-
}
|
826
|
-
});
|
827
817
|
|
828
818
|
Highcharts.wrap(Highcharts.Chart.prototype, 'isInsidePlot', function (proceed) {
|
829
819
|
return this.is3d() || proceed.apply(this, [].slice.call(arguments, 1));
|
@@ -863,12 +853,15 @@
|
|
863
853
|
});
|
864
854
|
|
865
855
|
Highcharts.wrap(Highcharts.Chart.prototype, 'setChartSize', function (proceed) {
|
866
|
-
|
856
|
+
var chart = this,
|
857
|
+
options3d = chart.options.chart.options3d;
|
867
858
|
|
868
|
-
|
869
|
-
|
870
|
-
|
871
|
-
|
859
|
+
proceed.apply(chart, [].slice.call(arguments, 1));
|
860
|
+
|
861
|
+
if (chart.is3d()) {
|
862
|
+
var inverted = chart.inverted,
|
863
|
+
clipBox = chart.clipBox,
|
864
|
+
margin = chart.margin,
|
872
865
|
x = inverted ? 'y' : 'x',
|
873
866
|
y = inverted ? 'x' : 'y',
|
874
867
|
w = inverted ? 'height' : 'width',
|
@@ -876,8 +869,14 @@
|
|
876
869
|
|
877
870
|
clipBox[x] = -(margin[3] || 0);
|
878
871
|
clipBox[y] = -(margin[0] || 0);
|
879
|
-
clipBox[w] =
|
880
|
-
clipBox[h] =
|
872
|
+
clipBox[w] = chart.chartWidth + (margin[3] || 0) + (margin[1] || 0);
|
873
|
+
clipBox[h] = chart.chartHeight + (margin[0] || 0) + (margin[2] || 0);
|
874
|
+
|
875
|
+
// Set scale, used later in perspective method():
|
876
|
+
chart.scale3d = 1; // @notice getScale uses perspective, so scale3d has to be reset.
|
877
|
+
if (options3d.fitToPlot === true) {
|
878
|
+
chart.scale3d = getScale(chart, options3d.depth);
|
879
|
+
}
|
881
880
|
}
|
882
881
|
});
|
883
882
|
|
@@ -1126,21 +1125,10 @@
|
|
1126
1125
|
var pos = proceed.apply(this, [].slice.call(arguments, 1));
|
1127
1126
|
|
1128
1127
|
// Do not do this if the chart is not 3D
|
1129
|
-
if (!this.axis.chart.is3d()) {
|
1130
|
-
return pos;
|
1131
|
-
}
|
1132
|
-
|
1133
|
-
var newPos = perspective([this.axis.swapZ({ x: pos.x, y: pos.y, z: 0 })], this.axis.chart, false)[0];
|
1134
|
-
newPos.x = newPos.x - (!this.axis.horiz && this.axis.opposite ? this.axis.transA : 0); //#3788
|
1135
|
-
newPos.old = pos;
|
1136
|
-
return newPos;
|
1137
|
-
});
|
1138
|
-
|
1139
|
-
Highcharts.wrap(Highcharts.Tick.prototype, 'handleOverflow', function (proceed, xy) {
|
1140
1128
|
if (this.axis.chart.is3d()) {
|
1141
|
-
|
1129
|
+
pos = perspective([this.axis.swapZ({ x: pos.x, y: pos.y, z: 0 })], this.axis.chart, false)[0];
|
1142
1130
|
}
|
1143
|
-
return
|
1131
|
+
return pos;
|
1144
1132
|
});
|
1145
1133
|
|
1146
1134
|
Highcharts.wrap(Highcharts.Axis.prototype, 'getTitlePosition', function (proceed) {
|
@@ -1738,6 +1726,7 @@
|
|
1738
1726
|
|
1739
1727
|
rawPoint.plotXold = rawPoint.plotX;
|
1740
1728
|
rawPoint.plotYold = rawPoint.plotY;
|
1729
|
+
rawPoint.plotZold = rawPoint.plotZ;
|
1741
1730
|
|
1742
1731
|
rawPoint.plotX = projectedPoint.x;
|
1743
1732
|
rawPoint.plotY = projectedPoint.y;
|