highcharts-rails 4.2.5 → 4.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.markdown +47 -0
- data/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;
|