highcharts-rails 4.2.7 → 5.0.0

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.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.markdown +34 -0
  3. data/Gemfile +4 -0
  4. data/Rakefile +53 -32
  5. data/app/assets/javascripts/highcharts.js +18775 -17176
  6. data/app/assets/javascripts/highcharts/highcharts-3d.js +1849 -1563
  7. data/app/assets/javascripts/highcharts/highcharts-more.js +2162 -1988
  8. data/app/assets/javascripts/highcharts/modules/accessibility.js +1005 -0
  9. data/app/assets/javascripts/highcharts/modules/annotations.js +408 -401
  10. data/app/assets/javascripts/highcharts/modules/boost.js +561 -546
  11. data/app/assets/javascripts/highcharts/modules/broken-axis.js +330 -324
  12. data/app/assets/javascripts/highcharts/modules/data.js +973 -965
  13. data/app/assets/javascripts/highcharts/modules/drilldown.js +783 -723
  14. data/app/assets/javascripts/highcharts/modules/exporting.js +864 -785
  15. data/app/assets/javascripts/highcharts/modules/funnel.js +290 -306
  16. data/app/assets/javascripts/highcharts/modules/heatmap.js +701 -645
  17. data/app/assets/javascripts/highcharts/modules/no-data-to-display.js +150 -132
  18. data/app/assets/javascripts/highcharts/modules/offline-exporting.js +414 -355
  19. data/app/assets/javascripts/highcharts/modules/overlapping-datalabels.js +164 -0
  20. data/app/assets/javascripts/highcharts/modules/series-label.js +473 -448
  21. data/app/assets/javascripts/highcharts/modules/solid-gauge.js +279 -271
  22. data/app/assets/javascripts/highcharts/modules/treemap.js +921 -886
  23. data/app/assets/javascripts/highcharts/themes/dark-blue.js +307 -244
  24. data/app/assets/javascripts/highcharts/themes/dark-green.js +303 -244
  25. data/app/assets/javascripts/highcharts/themes/dark-unica.js +231 -201
  26. data/app/assets/javascripts/highcharts/themes/gray.js +314 -245
  27. data/app/assets/javascripts/highcharts/themes/grid-light.js +91 -66
  28. data/app/assets/javascripts/highcharts/themes/grid.js +124 -96
  29. data/app/assets/javascripts/highcharts/themes/sand-signika.js +119 -94
  30. data/app/assets/javascripts/highcharts/themes/skies.js +108 -85
  31. data/lib/highcharts/version.rb +1 -1
  32. metadata +13 -14
  33. data/app/assets/javascripts/highcharts/adapters/standalone-framework.js +0 -1
  34. data/app/assets/javascripts/highcharts/modules/canvas-tools.js +0 -3115
  35. data/app/assets/javascripts/highcharts/modules/map.js +0 -2117
@@ -1,1807 +1,2093 @@
1
- // ==ClosureCompiler==
2
- // @compilation_level SIMPLE_OPTIMIZATIONS
3
-
4
1
  /**
5
- * @license Highcharts JS v4.2.7 (2016-09-21)
2
+ * @license Highcharts JS v5.0.0 (2016-09-29)
6
3
  *
7
4
  * 3D features for Highcharts JS
8
5
  *
9
6
  * @license: www.highcharts.com/license
10
7
  */
11
-
12
- (function (factory) {
8
+ (function(factory) {
13
9
  if (typeof module === 'object' && module.exports) {
14
10
  module.exports = factory;
15
11
  } else {
16
12
  factory(Highcharts);
17
13
  }
18
- }(function (Highcharts) {
19
- /**
20
- Shorthands for often used function
21
- */
22
- var animObject = Highcharts.animObject,
23
- each = Highcharts.each,
24
- extend = Highcharts.extend,
25
- inArray = Highcharts.inArray,
26
- merge = Highcharts.merge,
27
- pick = Highcharts.pick,
28
- wrap = Highcharts.wrap;
29
- /**
30
- * Mathematical Functionility
31
- */
32
- var PI = Math.PI,
33
- deg2rad = (PI / 180), // degrees to radians
34
- sin = Math.sin,
35
- cos = Math.cos,
36
- round = Math.round;
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
-
73
- /**
74
- * Transforms a given array of points according to the angles in chart.options.
75
- * Parameters:
76
- * - points: the array of points
77
- * - chart: the chart
78
- * - insidePlotArea: wether to verifiy the points are inside the plotArea
79
- * Returns:
80
- * - an array of transformed points
81
- */
82
- var perspective = Highcharts.perspective = function (points, chart, insidePlotArea) {
83
- var options3d = chart.options.chart.options3d,
84
- inverted = insidePlotArea ? chart.inverted : false,
85
- origin = {
86
- x: chart.plotWidth / 2,
87
- y: chart.plotHeight / 2,
88
- z: options3d.depth / 2,
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)
14
+ }(function(Highcharts) {
15
+ (function(H) {
16
+ /**
17
+ * (c) 2010-2016 Torstein Honsi
18
+ *
19
+ * License: www.highcharts.com/license
20
+ */
21
+ 'use strict';
22
+ /**
23
+ * Mathematical Functionility
24
+ */
25
+ var deg2rad = H.deg2rad,
26
+ pick = H.pick;
27
+ /**
28
+ * Apply 3-D rotation
29
+ * Euler Angles (XYZ): cosA = cos(Alfa|Roll), cosB = cos(Beta|Pitch), cosG = cos(Gamma|Yaw)
30
+ *
31
+ * Composite rotation:
32
+ * | cosB * cosG | cosB * sinG | -sinB |
33
+ * | sinA * sinB * cosG - cosA * sinG | sinA * sinB * sinG + cosA * cosG | sinA * cosB |
34
+ * | cosA * sinB * cosG + sinA * sinG | cosA * sinB * sinG - sinA * cosG | cosA * cosB |
35
+ *
36
+ * Now, Gamma/Yaw is not used (angle=0), so we assume cosG = 1 and sinG = 0, so we get:
37
+ * | cosB | 0 | - sinB |
38
+ * | sinA * sinB | cosA | sinA * cosB |
39
+ * | cosA * sinB | - sinA | cosA * cosB |
40
+ *
41
+ * But in browsers, y is reversed, so we get sinA => -sinA. The general result is:
42
+ * | cosB | 0 | - sinB | | x | | px |
43
+ * | - sinA * sinB | cosA | - sinA * cosB | x | y | = | py |
44
+ * | cosA * sinB | sinA | cosA * cosB | | z | | pz |
45
+ */
46
+ function rotate3D(x, y, z, angles) {
47
+ return {
48
+ x: angles.cosB * x - angles.sinB * z,
49
+ y: -angles.sinA * angles.sinB * x + angles.cosA * y - angles.cosB * angles.sinA * z,
50
+ z: angles.cosA * angles.sinB * x + angles.sinA * y + angles.cosA * angles.cosB * z
99
51
  };
100
-
101
- if (!insidePlotArea) {
102
- origin.x += chart.plotLeft;
103
- origin.y += chart.plotTop;
104
52
  }
105
53
 
106
- // Transform each point
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
-
54
+ function perspective3D(coordinate, origin, distance) {
55
+ var projection = ((distance > 0) && (distance < Number.POSITIVE_INFINITY)) ? distance / (coordinate.z + origin.z + distance) : 1;
121
56
  return {
122
- x: (inverted ? coordinate.y : coordinate.x),
123
- y: (inverted ? coordinate.x : coordinate.y),
124
- z: coordinate.z
57
+ x: coordinate.x * projection,
58
+ y: coordinate.y * projection
125
59
  };
126
- });
127
- };/***
128
- EXTENSION TO THE SVG-RENDERER TO ENABLE 3D SHAPES
129
- ***/
130
- ////// HELPER METHODS //////
60
+ }
61
+
62
+ /**
63
+ * Transforms a given array of points according to the angles in chart.options.
64
+ * Parameters:
65
+ * - points: the array of points
66
+ * - chart: the chart
67
+ * - insidePlotArea: wether to verifiy the points are inside the plotArea
68
+ * Returns:
69
+ * - an array of transformed points
70
+ */
71
+ H.perspective = function(points, chart, insidePlotArea) {
72
+ var options3d = chart.options.chart.options3d,
73
+ inverted = insidePlotArea ? chart.inverted : false,
74
+ origin = {
75
+ x: chart.plotWidth / 2,
76
+ y: chart.plotHeight / 2,
77
+ z: options3d.depth / 2,
78
+ vd: pick(options3d.depth, 1) * pick(options3d.viewDistance, 0)
79
+ },
80
+ scale = chart.scale3d || 1,
81
+ beta = deg2rad * options3d.beta * (inverted ? -1 : 1),
82
+ alpha = deg2rad * options3d.alpha * (inverted ? -1 : 1),
83
+ angles = {
84
+ cosA: Math.cos(alpha),
85
+ cosB: Math.cos(-beta),
86
+ sinA: Math.sin(alpha),
87
+ sinB: Math.sin(-beta)
88
+ };
131
89
 
132
- var dFactor = (4 * (Math.sqrt(2) - 1) / 3) / (PI / 2);
90
+ if (!insidePlotArea) {
91
+ origin.x += chart.plotLeft;
92
+ origin.y += chart.plotTop;
93
+ }
133
94
 
134
- function defined(obj) {
135
- return obj !== undefined && obj !== null;
136
- }
95
+ // Transform each point
96
+ return H.map(points, function(point) {
97
+ var rotated = rotate3D(
98
+ (inverted ? point.y : point.x) - origin.x,
99
+ (inverted ? point.x : point.y) - origin.y,
100
+ (point.z || 0) - origin.z,
101
+ angles
102
+ ),
103
+ coordinate = perspective3D(rotated, origin, origin.vd); // Apply perspective
104
+
105
+ // Apply translation
106
+ coordinate.x = coordinate.x * scale + origin.x;
107
+ coordinate.y = coordinate.y * scale + origin.y;
108
+ coordinate.z = rotated.z * scale + origin.z;
109
+
110
+ return {
111
+ x: (inverted ? coordinate.y : coordinate.x),
112
+ y: (inverted ? coordinate.x : coordinate.y),
113
+ z: coordinate.z
114
+ };
115
+ });
116
+ };
137
117
 
138
- //Shoelace algorithm -- http://en.wikipedia.org/wiki/Shoelace_formula
139
- function shapeArea(vertexes) {
140
- var area = 0,
141
- i,
142
- j;
143
- for (i = 0; i < vertexes.length; i++) {
144
- j = (i + 1) % vertexes.length;
145
- area += vertexes[i].x * vertexes[j].y - vertexes[j].x * vertexes[i].y;
118
+ }(Highcharts));
119
+ (function(H) {
120
+ /**
121
+ * (c) 2010-2016 Torstein Honsi
122
+ *
123
+ * License: www.highcharts.com/license
124
+ */
125
+ 'use strict';
126
+ var cos = Math.cos,
127
+ PI = Math.PI,
128
+ sin = Math.sin;
129
+
130
+
131
+ var animObject = H.animObject,
132
+ charts = H.charts,
133
+ color = H.color,
134
+ defined = H.defined,
135
+ deg2rad = H.deg2rad,
136
+ each = H.each,
137
+ extend = H.extend,
138
+ inArray = H.inArray,
139
+ map = H.map,
140
+ merge = H.merge,
141
+ perspective = H.perspective,
142
+ pick = H.pick,
143
+ SVGElement = H.SVGElement,
144
+ SVGRenderer = H.SVGRenderer,
145
+ wrap = H.wrap;
146
+ /***
147
+ EXTENSION TO THE SVG-RENDERER TO ENABLE 3D SHAPES
148
+ ***/
149
+ ////// HELPER METHODS //////
150
+
151
+ var dFactor = (4 * (Math.sqrt(2) - 1) / 3) / (PI / 2);
152
+
153
+
154
+ //Shoelace algorithm -- http://en.wikipedia.org/wiki/Shoelace_formula
155
+ function shapeArea(vertexes) {
156
+ var area = 0,
157
+ i,
158
+ j;
159
+ for (i = 0; i < vertexes.length; i++) {
160
+ j = (i + 1) % vertexes.length;
161
+ area += vertexes[i].x * vertexes[j].y - vertexes[j].x * vertexes[i].y;
162
+ }
163
+ return area / 2;
146
164
  }
147
- return area / 2;
148
- }
149
165
 
150
- function averageZ(vertexes) {
151
- var z = 0,
152
- i;
153
- for (i = 0; i < vertexes.length; i++) {
154
- z += vertexes[i].z;
166
+ function averageZ(vertexes) {
167
+ var z = 0,
168
+ i;
169
+ for (i = 0; i < vertexes.length; i++) {
170
+ z += vertexes[i].z;
171
+ }
172
+ return vertexes.length ? z / vertexes.length : 0;
155
173
  }
156
- return vertexes.length ? z / vertexes.length : 0;
157
- }
158
174
 
159
- /** Method to construct a curved path
160
- * Can 'wrap' around more then 180 degrees
161
- */
162
- function curveTo(cx, cy, rx, ry, start, end, dx, dy) {
163
- var result = [];
164
- if ((end > start) && (end - start > PI / 2 + 0.0001)) {
165
- result = result.concat(curveTo(cx, cy, rx, ry, start, start + (PI / 2), dx, dy));
166
- result = result.concat(curveTo(cx, cy, rx, ry, start + (PI / 2), end, dx, dy));
167
- } else if ((end < start) && (start - end > PI / 2 + 0.0001)) {
168
- result = result.concat(curveTo(cx, cy, rx, ry, start, start - (PI / 2), dx, dy));
169
- result = result.concat(curveTo(cx, cy, rx, ry, start - (PI / 2), end, dx, dy));
170
- } else {
171
- var arcAngle = end - start;
172
- result = [
175
+ /** Method to construct a curved path
176
+ * Can 'wrap' around more then 180 degrees
177
+ */
178
+ function curveTo(cx, cy, rx, ry, start, end, dx, dy) {
179
+ var result = [],
180
+ arcAngle = end - start;
181
+ if ((end > start) && (end - start > Math.PI / 2 + 0.0001)) {
182
+ result = result.concat(curveTo(cx, cy, rx, ry, start, start + (Math.PI / 2), dx, dy));
183
+ result = result.concat(curveTo(cx, cy, rx, ry, start + (Math.PI / 2), end, dx, dy));
184
+ return result;
185
+ }
186
+ if ((end < start) && (start - end > Math.PI / 2 + 0.0001)) {
187
+ result = result.concat(curveTo(cx, cy, rx, ry, start, start - (Math.PI / 2), dx, dy));
188
+ result = result.concat(curveTo(cx, cy, rx, ry, start - (Math.PI / 2), end, dx, dy));
189
+ return result;
190
+ }
191
+ return [
173
192
  'C',
174
- cx + (rx * cos(start)) - ((rx * dFactor * arcAngle) * sin(start)) + dx,
175
- cy + (ry * sin(start)) + ((ry * dFactor * arcAngle) * cos(start)) + dy,
176
- cx + (rx * cos(end)) + ((rx * dFactor * arcAngle) * sin(end)) + dx,
177
- cy + (ry * sin(end)) - ((ry * dFactor * arcAngle) * cos(end)) + dy,
193
+ cx + (rx * Math.cos(start)) - ((rx * dFactor * arcAngle) * Math.sin(start)) + dx,
194
+ cy + (ry * Math.sin(start)) + ((ry * dFactor * arcAngle) * Math.cos(start)) + dy,
195
+ cx + (rx * Math.cos(end)) + ((rx * dFactor * arcAngle) * Math.sin(end)) + dx,
196
+ cy + (ry * Math.sin(end)) - ((ry * dFactor * arcAngle) * Math.cos(end)) + dy,
178
197
 
179
- cx + (rx * cos(end)) + dx,
180
- cy + (ry * sin(end)) + dy
198
+ cx + (rx * Math.cos(end)) + dx,
199
+ cy + (ry * Math.sin(end)) + dy
181
200
  ];
182
201
  }
183
- return result;
184
- }
185
202
 
186
- Highcharts.SVGRenderer.prototype.toLinePath = function (points, closed) {
187
- var result = [];
188
203
 
189
- // Put "L x y" for each point
190
- Highcharts.each(points, function (point) {
191
- result.push('L', point.x, point.y);
192
- });
193
204
 
194
- if (points.length) {
195
- // Set the first element to M
196
- result[0] = 'M';
205
+ SVGRenderer.prototype.toLinePath = function(points, closed) {
206
+ var result = [];
207
+
208
+ // Put "L x y" for each point
209
+ each(points, function(point) {
210
+ result.push('L', point.x, point.y);
211
+ });
212
+
213
+ if (points.length) {
214
+ // Set the first element to M
215
+ result[0] = 'M';
197
216
 
198
- // If it is a closed line, add Z
199
- if (closed) {
200
- result.push('Z');
217
+ // If it is a closed line, add Z
218
+ if (closed) {
219
+ result.push('Z');
220
+ }
201
221
  }
202
- }
203
222
 
204
- return result;
205
- };
223
+ return result;
224
+ };
206
225
 
207
- ////// CUBOIDS //////
208
- Highcharts.SVGRenderer.prototype.cuboid = function (shapeArgs) {
226
+ ////// CUBOIDS //////
227
+ SVGRenderer.prototype.cuboid = function(shapeArgs) {
209
228
 
210
- var result = this.g(),
211
- paths = this.cuboidPath(shapeArgs);
229
+ var result = this.g(),
230
+ paths = this.cuboidPath(shapeArgs);
212
231
 
213
- // create the 3 sides
214
- result.front = this.path(paths[0]).attr({ zIndex: paths[3], 'stroke-linejoin': 'round' }).add(result);
215
- result.top = this.path(paths[1]).attr({ zIndex: paths[4], 'stroke-linejoin': 'round' }).add(result);
216
- result.side = this.path(paths[2]).attr({ zIndex: paths[5], 'stroke-linejoin': 'round' }).add(result);
217
232
 
218
- // apply the fill everywhere, the top a bit brighter, the side a bit darker
219
- result.fillSetter = function (color) {
220
- var c0 = color,
221
- c1 = Highcharts.Color(color).brighten(0.1).get(),
222
- c2 = Highcharts.Color(color).brighten(-0.1).get();
233
+ result.attr({
234
+ 'stroke-linejoin': 'round'
235
+ });
223
236
 
224
- this.front.attr({ fill: c0 });
225
- this.top.attr({ fill: c1 });
226
- this.side.attr({ fill: c2 });
227
237
 
228
- this.color = color;
229
- return this;
230
- };
238
+ // create the 3 sides
239
+ result.front = this.path(paths[0]).attr({
240
+ 'class': 'highcharts-3d-front',
241
+ zIndex: paths[3]
242
+ }).add(result);
243
+ result.top = this.path(paths[1]).attr({
244
+ 'class': 'highcharts-3d-top',
245
+ zIndex: paths[4]
246
+ }).add(result);
247
+ result.side = this.path(paths[2]).attr({
248
+ 'class': 'highcharts-3d-side',
249
+ zIndex: paths[5]
250
+ }).add(result);
251
+
252
+ // apply the fill everywhere, the top a bit brighter, the side a bit darker
253
+ result.fillSetter = function(fill) {
254
+ this.front.attr({
255
+ fill: fill
256
+ });
257
+ this.top.attr({
258
+ fill: color(fill).brighten(0.1).get()
259
+ });
260
+ this.side.attr({
261
+ fill: color(fill).brighten(-0.1).get()
262
+ });
231
263
 
232
- // apply opacaity everywhere
233
- result.opacitySetter = function (opacity) {
234
- this.front.attr({ opacity: opacity });
235
- this.top.attr({ opacity: opacity });
236
- this.side.attr({ opacity: opacity });
237
- return this;
238
- };
264
+ this.color = fill;
265
+ return this;
266
+ };
239
267
 
240
- result.attr = function (args) {
241
- if (args.shapeArgs || defined(args.x)) {
242
- var shapeArgs = args.shapeArgs || args;
243
- var paths = this.renderer.cuboidPath(shapeArgs);
244
- this.front.attr({ d: paths[0], zIndex: paths[3] });
245
- this.top.attr({ d: paths[1], zIndex: paths[4] });
246
- this.side.attr({ d: paths[2], zIndex: paths[5] });
247
- } else {
248
- return Highcharts.SVGElement.prototype.attr.call(this, args); // getter returns value
249
- }
268
+ // apply opacaity everywhere
269
+ result.opacitySetter = function(opacity) {
270
+ this.front.attr({
271
+ opacity: opacity
272
+ });
273
+ this.top.attr({
274
+ opacity: opacity
275
+ });
276
+ this.side.attr({
277
+ opacity: opacity
278
+ });
279
+ return this;
280
+ };
250
281
 
251
- return this;
282
+ result.attr = function(args) {
283
+ if (args.shapeArgs || defined(args.x)) {
284
+ var shapeArgs = args.shapeArgs || args;
285
+ var paths = this.renderer.cuboidPath(shapeArgs);
286
+ this.front.attr({
287
+ d: paths[0],
288
+ zIndex: paths[3]
289
+ });
290
+ this.top.attr({
291
+ d: paths[1],
292
+ zIndex: paths[4]
293
+ });
294
+ this.side.attr({
295
+ d: paths[2],
296
+ zIndex: paths[5]
297
+ });
298
+ } else {
299
+ return H.SVGElement.prototype.attr.call(this, args); // getter returns value
300
+ }
301
+
302
+ return this;
303
+ };
304
+
305
+ result.animate = function(args, duration, complete) {
306
+ if (defined(args.x) && defined(args.y)) {
307
+ var paths = this.renderer.cuboidPath(args);
308
+ this.front.attr({
309
+ zIndex: paths[3]
310
+ }).animate({
311
+ d: paths[0]
312
+ }, duration, complete);
313
+ this.top.attr({
314
+ zIndex: paths[4]
315
+ }).animate({
316
+ d: paths[1]
317
+ }, duration, complete);
318
+ this.side.attr({
319
+ zIndex: paths[5]
320
+ }).animate({
321
+ d: paths[2]
322
+ }, duration, complete);
323
+ this.attr({
324
+ zIndex: -paths[6] // #4774
325
+ });
326
+ } else if (args.opacity) {
327
+ this.front.animate(args, duration, complete);
328
+ this.top.animate(args, duration, complete);
329
+ this.side.animate(args, duration, complete);
330
+ } else {
331
+ SVGElement.prototype.animate.call(this, args, duration, complete);
332
+ }
333
+ return this;
334
+ };
335
+
336
+ // destroy all children
337
+ result.destroy = function() {
338
+ this.front.destroy();
339
+ this.top.destroy();
340
+ this.side.destroy();
341
+
342
+ return null;
343
+ };
344
+
345
+ // Apply the Z index to the cuboid group
346
+ result.attr({
347
+ zIndex: -paths[6]
348
+ });
349
+
350
+ return result;
252
351
  };
253
352
 
254
- result.animate = function (args, duration, complete) {
255
- if (defined(args.x) && defined(args.y)) {
256
- var paths = this.renderer.cuboidPath(args);
257
- this.front.attr({ zIndex: paths[3] }).animate({ d: paths[0] }, duration, complete);
258
- this.top.attr({ zIndex: paths[4] }).animate({ d: paths[1] }, duration, complete);
259
- this.side.attr({ zIndex: paths[5] }).animate({ d: paths[2] }, duration, complete);
260
- this.attr({
261
- zIndex: -paths[6] // #4774
262
- });
263
- } else if (args.opacity) {
264
- this.front.animate(args, duration, complete);
265
- this.top.animate(args, duration, complete);
266
- this.side.animate(args, duration, complete);
267
- } else {
268
- Highcharts.SVGElement.prototype.animate.call(this, args, duration, complete);
353
+ /**
354
+ * Generates a cuboid
355
+ */
356
+ SVGRenderer.prototype.cuboidPath = function(shapeArgs) {
357
+ var x = shapeArgs.x,
358
+ y = shapeArgs.y,
359
+ z = shapeArgs.z,
360
+ h = shapeArgs.height,
361
+ w = shapeArgs.width,
362
+ d = shapeArgs.depth,
363
+ chart = charts[this.chartIndex];
364
+
365
+ // The 8 corners of the cube
366
+ var pArr = [{
367
+ x: x,
368
+ y: y,
369
+ z: z
370
+ }, {
371
+ x: x + w,
372
+ y: y,
373
+ z: z
374
+ }, {
375
+ x: x + w,
376
+ y: y + h,
377
+ z: z
378
+ }, {
379
+ x: x,
380
+ y: y + h,
381
+ z: z
382
+ }, {
383
+ x: x,
384
+ y: y + h,
385
+ z: z + d
386
+ }, {
387
+ x: x + w,
388
+ y: y + h,
389
+ z: z + d
390
+ }, {
391
+ x: x + w,
392
+ y: y,
393
+ z: z + d
394
+ }, {
395
+ x: x,
396
+ y: y,
397
+ z: z + d
398
+ }];
399
+
400
+ // apply perspective
401
+ pArr = perspective(pArr, chart, shapeArgs.insidePlotArea);
402
+
403
+ // helper method to decide which side is visible
404
+ function mapPath(i) {
405
+ return pArr[i];
269
406
  }
270
- return this;
271
- };
407
+ var pickShape = function(path1, path2) {
408
+ var ret = [];
409
+ path1 = map(path1, mapPath);
410
+ path2 = map(path2, mapPath);
411
+ if (shapeArea(path1) < 0) {
412
+ ret = path1;
413
+ } else if (shapeArea(path2) < 0) {
414
+ ret = path2;
415
+ }
416
+ return ret;
417
+ };
272
418
 
273
- // destroy all children
274
- result.destroy = function () {
275
- this.front.destroy();
276
- this.top.destroy();
277
- this.side.destroy();
419
+ // front or back
420
+ var front = [3, 2, 1, 0];
421
+ var back = [7, 6, 5, 4];
422
+ var path1 = pickShape(front, back);
278
423
 
279
- return null;
424
+ // top or bottom
425
+ var top = [1, 6, 7, 0];
426
+ var bottom = [4, 5, 2, 3];
427
+ var path2 = pickShape(top, bottom);
428
+
429
+ // side
430
+ var right = [1, 2, 5, 6];
431
+ var left = [0, 7, 4, 3];
432
+ var path3 = pickShape(right, left);
433
+
434
+ return [this.toLinePath(path1, true), this.toLinePath(path2, true), this.toLinePath(path3, true), averageZ(path1), averageZ(path2), averageZ(path3), averageZ(map(bottom, mapPath)) * 9e9]; // #4774
280
435
  };
281
436
 
282
- // Apply the Z index to the cuboid group
283
- result.attr({ zIndex: -paths[6] });
284
-
285
- return result;
286
- };
287
-
288
- /**
289
- * Generates a cuboid
290
- */
291
- Highcharts.SVGRenderer.prototype.cuboidPath = function (shapeArgs) {
292
- var x = shapeArgs.x,
293
- y = shapeArgs.y,
294
- z = shapeArgs.z,
295
- h = shapeArgs.height,
296
- w = shapeArgs.width,
297
- d = shapeArgs.depth,
298
- chart = Highcharts.charts[this.chartIndex],
299
- map = Highcharts.map;
300
-
301
- // The 8 corners of the cube
302
- var pArr = [
303
- { x: x, y: y, z: z },
304
- { x: x + w, y: y, z: z },
305
- { x: x + w, y: y + h, z: z },
306
- { x: x, y: y + h, z: z },
307
- { x: x, y: y + h, z: z + d },
308
- { x: x + w, y: y + h, z: z + d },
309
- { x: x + w, y: y, z: z + d },
310
- { x: x, y: y, z: z + d }
311
- ];
312
-
313
- // apply perspective
314
- pArr = perspective(pArr, chart, shapeArgs.insidePlotArea);
315
-
316
- // helper method to decide which side is visible
317
- function mapPath(i) {
318
- return pArr[i];
319
- }
320
- var pickShape = function (path1, path2) {
321
- var ret = [];
322
- path1 = map(path1, mapPath);
323
- path2 = map(path2, mapPath);
324
- if (shapeArea(path1) < 0) {
325
- ret = path1;
326
- } else if (shapeArea(path2) < 0) {
327
- ret = path2;
437
+ ////// SECTORS //////
438
+ H.SVGRenderer.prototype.arc3d = function(attribs) {
439
+
440
+ var wrapper = this.g(),
441
+ renderer = wrapper.renderer,
442
+ customAttribs = ['x', 'y', 'r', 'innerR', 'start', 'end'];
443
+
444
+ /**
445
+ * Get custom attributes. Mutate the original object and return an object with only custom attr.
446
+ */
447
+ function suckOutCustom(params) {
448
+ var hasCA = false,
449
+ ca = {};
450
+ for (var key in params) {
451
+ if (inArray(key, customAttribs) !== -1) {
452
+ ca[key] = params[key];
453
+ delete params[key];
454
+ hasCA = true;
455
+ }
456
+ }
457
+ return hasCA ? ca : false;
328
458
  }
329
- return ret;
330
- };
331
459
 
332
- // front or back
333
- var front = [3, 2, 1, 0];
334
- var back = [7, 6, 5, 4];
335
- var path1 = pickShape(front, back);
460
+ attribs = merge(attribs);
461
+
462
+ attribs.alpha *= deg2rad;
463
+ attribs.beta *= deg2rad;
464
+
465
+ // Create the different sub sections of the shape
466
+ wrapper.top = renderer.path();
467
+ wrapper.side1 = renderer.path();
468
+ wrapper.side2 = renderer.path();
469
+ wrapper.inn = renderer.path();
470
+ wrapper.out = renderer.path();
471
+
472
+ /**
473
+ * Add all faces
474
+ */
475
+ wrapper.onAdd = function() {
476
+ var parent = wrapper.parentGroup,
477
+ className = wrapper.attr('class');
478
+ wrapper.top.add(wrapper);
479
+
480
+ // These faces are added outside the wrapper group because the z index
481
+ // relates to neighbour elements as well
482
+ each(['out', 'inn', 'side1', 'side2'], function(face) {
483
+ wrapper[face]
484
+ .addClass(className + ' highcharts-3d-side')
485
+ .add(parent);
486
+ });
487
+ };
336
488
 
337
- // top or bottom
338
- var top = [1, 6, 7, 0];
339
- var bottom = [4, 5, 2, 3];
340
- var path2 = pickShape(top, bottom);
489
+ /**
490
+ * Compute the transformed paths and set them to the composite shapes
491
+ */
492
+ wrapper.setPaths = function(attribs) {
341
493
 
342
- // side
343
- var right = [1, 2, 5, 6];
344
- var left = [0, 7, 4, 3];
345
- var path3 = pickShape(right, left);
494
+ var paths = wrapper.renderer.arc3dPath(attribs),
495
+ zIndex = paths.zTop * 100;
346
496
 
347
- return [this.toLinePath(path1, true), this.toLinePath(path2, true), this.toLinePath(path3, true), averageZ(path1), averageZ(path2), averageZ(path3), averageZ(map(bottom, mapPath)) * 9e9]; // #4774
348
- };
497
+ wrapper.attribs = attribs;
349
498
 
350
- ////// SECTORS //////
351
- Highcharts.SVGRenderer.prototype.arc3d = function (attribs) {
499
+ wrapper.top.attr({
500
+ d: paths.top,
501
+ zIndex: paths.zTop
502
+ });
503
+ wrapper.inn.attr({
504
+ d: paths.inn,
505
+ zIndex: paths.zInn
506
+ });
507
+ wrapper.out.attr({
508
+ d: paths.out,
509
+ zIndex: paths.zOut
510
+ });
511
+ wrapper.side1.attr({
512
+ d: paths.side1,
513
+ zIndex: paths.zSide1
514
+ });
515
+ wrapper.side2.attr({
516
+ d: paths.side2,
517
+ zIndex: paths.zSide2
518
+ });
519
+
520
+
521
+ // show all children
522
+ wrapper.zIndex = zIndex;
523
+ wrapper.attr({
524
+ zIndex: zIndex
525
+ });
352
526
 
353
- var wrapper = this.g(),
354
- renderer = wrapper.renderer,
355
- customAttribs = ['x', 'y', 'r', 'innerR', 'start', 'end'];
527
+ // Set the radial gradient center the first time
528
+ if (attribs.center) {
529
+ wrapper.top.setRadialReference(attribs.center);
530
+ delete attribs.center;
531
+ }
532
+ };
533
+ wrapper.setPaths(attribs);
534
+
535
+ // Apply the fill to the top and a darker shade to the sides
536
+ wrapper.fillSetter = function(value) {
537
+ var darker = color(value).brighten(-0.1).get();
538
+
539
+ this.fill = value;
540
+
541
+ this.side1.attr({
542
+ fill: darker
543
+ });
544
+ this.side2.attr({
545
+ fill: darker
546
+ });
547
+ this.inn.attr({
548
+ fill: darker
549
+ });
550
+ this.out.attr({
551
+ fill: darker
552
+ });
553
+ this.top.attr({
554
+ fill: value
555
+ });
556
+ return this;
557
+ };
558
+
559
+ // Apply the same value to all. These properties cascade down to the children
560
+ // when set to the composite arc3d.
561
+ each(['opacity', 'translateX', 'translateY', 'visibility'], function(setter) {
562
+ wrapper[setter + 'Setter'] = function(value, key) {
563
+ wrapper[key] = value;
564
+ each(['out', 'inn', 'side1', 'side2', 'top'], function(el) {
565
+ wrapper[el].attr(key, value);
566
+ });
567
+ };
568
+ });
569
+
570
+ /**
571
+ * Override attr to remove shape attributes and use those to set child paths
572
+ */
573
+ wrap(wrapper, 'attr', function(proceed, params, val) {
574
+ var ca;
575
+ if (typeof params === 'object') {
576
+ ca = suckOutCustom(params);
577
+ if (ca) {
578
+ extend(wrapper.attribs, ca);
579
+ wrapper.setPaths(wrapper.attribs);
580
+ }
581
+ }
582
+ return proceed.call(this, params, val);
583
+ });
584
+
585
+ /**
586
+ * Override the animate function by sucking out custom parameters related to the shapes directly,
587
+ * and update the shapes from the animation step.
588
+ */
589
+ wrap(wrapper, 'animate', function(proceed, params, animation, complete) {
590
+ var ca,
591
+ from = this.attribs,
592
+ to,
593
+ anim;
594
+
595
+ // Attribute-line properties connected to 3D. These shouldn't have been in the
596
+ // attribs collection in the first place.
597
+ delete params.center;
598
+ delete params.z;
599
+ delete params.depth;
600
+ delete params.alpha;
601
+ delete params.beta;
602
+
603
+ anim = animObject(pick(animation, this.renderer.globalAnimation));
604
+
605
+ if (anim.duration) {
606
+ params = merge(params); // Don't mutate the original object
607
+ ca = suckOutCustom(params);
608
+
609
+ if (ca) {
610
+ to = ca;
611
+ anim.step = function(a, fx) {
612
+ function interpolate(key) {
613
+ return from[key] + (pick(to[key], from[key]) - from[key]) * fx.pos;
614
+ }
615
+ fx.elem.setPaths(merge(from, {
616
+ x: interpolate('x'),
617
+ y: interpolate('y'),
618
+ r: interpolate('r'),
619
+ innerR: interpolate('innerR'),
620
+ start: interpolate('start'),
621
+ end: interpolate('end')
622
+ }));
623
+ };
624
+ }
625
+ animation = anim; // Only when duration (#5572)
626
+ }
627
+ return proceed.call(this, params, animation, complete);
628
+ });
629
+
630
+ // destroy all children
631
+ wrapper.destroy = function() {
632
+ this.top.destroy();
633
+ this.out.destroy();
634
+ this.inn.destroy();
635
+ this.side1.destroy();
636
+ this.side2.destroy();
637
+
638
+ SVGElement.prototype.destroy.call(this);
639
+ };
640
+ // hide all children
641
+ wrapper.hide = function() {
642
+ this.top.hide();
643
+ this.out.hide();
644
+ this.inn.hide();
645
+ this.side1.hide();
646
+ this.side2.hide();
647
+ };
648
+ wrapper.show = function() {
649
+ this.top.show();
650
+ this.out.show();
651
+ this.inn.show();
652
+ this.side1.show();
653
+ this.side2.show();
654
+ };
655
+ return wrapper;
656
+ };
356
657
 
357
658
  /**
358
- * Get custom attributes. Mutate the original object and return an object with only custom attr.
659
+ * Generate the paths required to draw a 3D arc
359
660
  */
360
- function suckOutCustom(params) {
361
- var hasCA = false,
362
- ca = {};
363
- for (var key in params) {
364
- if (inArray(key, customAttribs) !== -1) {
365
- ca[key] = params[key];
366
- delete params[key];
367
- hasCA = true;
661
+ SVGRenderer.prototype.arc3dPath = function(shapeArgs) {
662
+ var cx = shapeArgs.x, // x coordinate of the center
663
+ cy = shapeArgs.y, // y coordinate of the center
664
+ start = shapeArgs.start, // start angle
665
+ end = shapeArgs.end - 0.00001, // end angle
666
+ r = shapeArgs.r, // radius
667
+ ir = shapeArgs.innerR, // inner radius
668
+ d = shapeArgs.depth, // depth
669
+ alpha = shapeArgs.alpha, // alpha rotation of the chart
670
+ beta = shapeArgs.beta; // beta rotation of the chart
671
+
672
+ // Derived Variables
673
+ var cs = Math.cos(start), // cosinus of the start angle
674
+ ss = Math.sin(start), // sinus of the start angle
675
+ ce = Math.cos(end), // cosinus of the end angle
676
+ se = Math.sin(end), // sinus of the end angle
677
+ rx = r * Math.cos(beta), // x-radius
678
+ ry = r * Math.cos(alpha), // y-radius
679
+ irx = ir * Math.cos(beta), // x-radius (inner)
680
+ iry = ir * Math.cos(alpha), // y-radius (inner)
681
+ dx = d * Math.sin(beta), // distance between top and bottom in x
682
+ dy = d * Math.sin(alpha); // distance between top and bottom in y
683
+
684
+ // TOP
685
+ var top = ['M', cx + (rx * cs), cy + (ry * ss)];
686
+ top = top.concat(curveTo(cx, cy, rx, ry, start, end, 0, 0));
687
+ top = top.concat([
688
+ 'L', cx + (irx * ce), cy + (iry * se)
689
+ ]);
690
+ top = top.concat(curveTo(cx, cy, irx, iry, end, start, 0, 0));
691
+ top = top.concat(['Z']);
692
+ // OUTSIDE
693
+ var b = (beta > 0 ? Math.PI / 2 : 0),
694
+ a = (alpha > 0 ? 0 : Math.PI / 2);
695
+
696
+ var start2 = start > -b ? start : (end > -b ? -b : start),
697
+ end2 = end < PI - a ? end : (start < PI - a ? PI - a : end),
698
+ midEnd = 2 * PI - a;
699
+
700
+ // When slice goes over bottom middle, need to add both, left and right outer side.
701
+ // Additionally, when we cross right hand edge, create sharp edge. Outer shape/wall:
702
+ //
703
+ // -------
704
+ // / ^ \
705
+ // 4) / / \ \ 1)
706
+ // / / \ \
707
+ // / / \ \
708
+ // (c)=> ==== ==== <=(d)
709
+ // \ \ / /
710
+ // \ \<=(a)/ /
711
+ // \ \ / / <=(b)
712
+ // 3) \ v / 2)
713
+ // -------
714
+ //
715
+ // (a) - inner side
716
+ // (b) - outer side
717
+ // (c) - left edge (sharp)
718
+ // (d) - right edge (sharp)
719
+ // 1..n - rendering order for startAngle = 0, when set to e.g 90, order changes clockwise (1->2, 2->3, n->1) and counterclockwise for negative startAngle
720
+
721
+ var out = ['M', cx + (rx * cos(start2)), cy + (ry * sin(start2))];
722
+ out = out.concat(curveTo(cx, cy, rx, ry, start2, end2, 0, 0));
723
+
724
+ if (end > midEnd && start < midEnd) { // When shape is wide, it can cross both, (c) and (d) edges, when using startAngle
725
+ // Go to outer side
726
+ out = out.concat([
727
+ 'L', cx + (rx * cos(end2)) + dx, cy + (ry * sin(end2)) + dy
728
+ ]);
729
+ // Curve to the right edge of the slice (d)
730
+ out = out.concat(curveTo(cx, cy, rx, ry, end2, midEnd, dx, dy));
731
+ // Go to the inner side
732
+ out = out.concat([
733
+ 'L', cx + (rx * cos(midEnd)), cy + (ry * sin(midEnd))
734
+ ]);
735
+ // Curve to the true end of the slice
736
+ out = out.concat(curveTo(cx, cy, rx, ry, midEnd, end, 0, 0));
737
+ // Go to the outer side
738
+ out = out.concat([
739
+ 'L', cx + (rx * cos(end)) + dx, cy + (ry * sin(end)) + dy
740
+ ]);
741
+ // Go back to middle (d)
742
+ out = out.concat(curveTo(cx, cy, rx, ry, end, midEnd, dx, dy));
743
+ out = out.concat([
744
+ 'L', cx + (rx * cos(midEnd)), cy + (ry * sin(midEnd))
745
+ ]);
746
+ // Go back to the left edge
747
+ out = out.concat(curveTo(cx, cy, rx, ry, midEnd, end2, 0, 0));
748
+ } else if (end > PI - a && start < PI - a) { // But shape can cross also only (c) edge:
749
+ // Go to outer side
750
+ out = out.concat([
751
+ 'L', cx + (rx * Math.cos(end2)) + dx, cy + (ry * Math.sin(end2)) + dy
752
+ ]);
753
+ // Curve to the true end of the slice
754
+ out = out.concat(curveTo(cx, cy, rx, ry, end2, end, dx, dy));
755
+ // Go to the inner side
756
+ out = out.concat([
757
+ 'L', cx + (rx * Math.cos(end)), cy + (ry * Math.sin(end))
758
+ ]);
759
+ // Go back to the artifical end2
760
+ out = out.concat(curveTo(cx, cy, rx, ry, end, end2, 0, 0));
761
+ }
762
+
763
+ out = out.concat([
764
+ 'L', cx + (rx * Math.cos(end2)) + dx, cy + (ry * Math.sin(end2)) + dy
765
+ ]);
766
+ out = out.concat(curveTo(cx, cy, rx, ry, end2, start2, dx, dy));
767
+ out = out.concat(['Z']);
768
+
769
+ // INSIDE
770
+ var inn = ['M', cx + (irx * cs), cy + (iry * ss)];
771
+ inn = inn.concat(curveTo(cx, cy, irx, iry, start, end, 0, 0));
772
+ inn = inn.concat([
773
+ 'L', cx + (irx * Math.cos(end)) + dx, cy + (iry * Math.sin(end)) + dy
774
+ ]);
775
+ inn = inn.concat(curveTo(cx, cy, irx, iry, end, start, dx, dy));
776
+ inn = inn.concat(['Z']);
777
+
778
+ // SIDES
779
+ var side1 = [
780
+ 'M', cx + (rx * cs), cy + (ry * ss),
781
+ 'L', cx + (rx * cs) + dx, cy + (ry * ss) + dy,
782
+ 'L', cx + (irx * cs) + dx, cy + (iry * ss) + dy,
783
+ 'L', cx + (irx * cs), cy + (iry * ss),
784
+ 'Z'
785
+ ];
786
+ var side2 = [
787
+ 'M', cx + (rx * ce), cy + (ry * se),
788
+ 'L', cx + (rx * ce) + dx, cy + (ry * se) + dy,
789
+ 'L', cx + (irx * ce) + dx, cy + (iry * se) + dy,
790
+ 'L', cx + (irx * ce), cy + (iry * se),
791
+ 'Z'
792
+ ];
793
+
794
+ // correction for changed position of vanishing point caused by alpha and beta rotations
795
+ var angleCorr = Math.atan2(dy, -dx),
796
+ angleEnd = Math.abs(end + angleCorr),
797
+ angleStart = Math.abs(start + angleCorr),
798
+ angleMid = Math.abs((start + end) / 2 + angleCorr);
799
+
800
+ // set to 0-PI range
801
+ function toZeroPIRange(angle) {
802
+ angle = angle % (2 * Math.PI);
803
+ if (angle > Math.PI) {
804
+ angle = 2 * Math.PI - angle;
368
805
  }
806
+ return angle;
369
807
  }
370
- return hasCA ? ca : false;
371
- }
808
+ angleEnd = toZeroPIRange(angleEnd);
809
+ angleStart = toZeroPIRange(angleStart);
810
+ angleMid = toZeroPIRange(angleMid);
372
811
 
373
- attribs = merge(attribs);
812
+ // *1e5 is to compensate pInt in zIndexSetter
813
+ var incPrecision = 1e5,
814
+ a1 = angleMid * incPrecision,
815
+ a2 = angleStart * incPrecision,
816
+ a3 = angleEnd * incPrecision;
374
817
 
375
- attribs.alpha *= deg2rad;
376
- attribs.beta *= deg2rad;
377
-
378
- // Create the different sub sections of the shape
379
- wrapper.top = renderer.path();
380
- wrapper.side1 = renderer.path();
381
- wrapper.side2 = renderer.path();
382
- wrapper.inn = renderer.path();
383
- wrapper.out = renderer.path();
818
+ return {
819
+ top: top,
820
+ zTop: Math.PI * incPrecision + 1, // max angle is PI, so this is allways higher
821
+ out: out,
822
+ zOut: Math.max(a1, a2, a3),
823
+ inn: inn,
824
+ zInn: Math.max(a1, a2, a3),
825
+ side1: side1,
826
+ zSide1: a3 * 0.99, // to keep below zOut and zInn in case of same values
827
+ side2: side2,
828
+ zSide2: a2 * 0.99
829
+ };
830
+ };
384
831
 
832
+ }(Highcharts));
833
+ (function(H) {
385
834
  /**
386
- * Add all faces
835
+ * (c) 2010-2016 Torstein Honsi
836
+ *
837
+ * License: www.highcharts.com/license
387
838
  */
388
- wrapper.onAdd = function () {
389
- var parent = wrapper.parentGroup;
390
- wrapper.top.add(wrapper);
391
- wrapper.out.add(parent);
392
- wrapper.inn.add(parent);
393
- wrapper.side1.add(parent);
394
- wrapper.side2.add(parent);
839
+ 'use strict';
840
+ var Chart = H.Chart,
841
+ each = H.each,
842
+ merge = H.merge,
843
+ perspective = H.perspective,
844
+ pick = H.pick,
845
+ wrap = H.wrap;
846
+
847
+ /***
848
+ EXTENSION FOR 3D CHARTS
849
+ ***/
850
+ // Shorthand to check the is3d flag
851
+ Chart.prototype.is3d = function() {
852
+ return this.options.chart.options3d && this.options.chart.options3d.enabled; // #4280
395
853
  };
396
854
 
855
+ Chart.prototype.propsRequireDirtyBox.push('chart.options3d');
856
+ Chart.prototype.propsRequireUpdateSeries.push('chart.options3d');
857
+
397
858
  /**
398
- * Compute the transformed paths and set them to the composite shapes
859
+ * Calculate scale of the 3D view. That is required to
860
+ * fit chart's 3D projection into the actual plotting area. Reported as #4933.
861
+ * @notice This function should ideally take the plot values instead of a chart object,
862
+ * but since the chart object is needed for perspective it is not practical.
863
+ * Possible to make both getScale and perspective more logical and also immutable.
864
+ * @param {Object} chart Chart object
865
+ * @param {Number} chart.plotLeft
866
+ * @param {Number} chart.plotWidth
867
+ * @param {Number} chart.plotTop
868
+ * @param {Number} chart.plotHeight
869
+ * @param {Number} depth The depth of the chart
870
+ * @return {Number} The scale to fit the 3D chart into the plotting area.
399
871
  */
400
- wrapper.setPaths = function (attribs) {
872
+ function getScale(chart, depth) {
873
+ var plotLeft = chart.plotLeft,
874
+ plotRight = chart.plotWidth + plotLeft,
875
+ plotTop = chart.plotTop,
876
+ plotBottom = chart.plotHeight + plotTop,
877
+ originX = plotLeft + chart.plotWidth / 2,
878
+ originY = plotTop + chart.plotHeight / 2,
879
+ bbox3d = {
880
+ minX: Number.MAX_VALUE,
881
+ maxX: -Number.MAX_VALUE,
882
+ minY: Number.MAX_VALUE,
883
+ maxY: -Number.MAX_VALUE
884
+ },
885
+ corners,
886
+ scale = 1;
887
+
888
+ // Top left corners:
889
+ corners = [{
890
+ x: plotLeft,
891
+ y: plotTop,
892
+ z: 0
893
+ }, {
894
+ x: plotLeft,
895
+ y: plotTop,
896
+ z: depth
897
+ }];
898
+
899
+ // Top right corners:
900
+ each([0, 1], function(i) {
901
+ corners.push({
902
+ x: plotRight,
903
+ y: corners[i].y,
904
+ z: corners[i].z
905
+ });
906
+ });
401
907
 
402
- var paths = wrapper.renderer.arc3dPath(attribs),
403
- zIndex = paths.zTop * 100;
908
+ // All bottom corners:
909
+ each([0, 1, 2, 3], function(i) {
910
+ corners.push({
911
+ x: corners[i].x,
912
+ y: plotBottom,
913
+ z: corners[i].z
914
+ });
915
+ });
404
916
 
405
- wrapper.attribs = attribs;
917
+ // Calculate 3D corners:
918
+ corners = perspective(corners, chart, false);
406
919
 
407
- wrapper.top.attr({ d: paths.top, zIndex: paths.zTop });
408
- wrapper.inn.attr({ d: paths.inn, zIndex: paths.zInn });
409
- wrapper.out.attr({ d: paths.out, zIndex: paths.zOut });
410
- wrapper.side1.attr({ d: paths.side1, zIndex: paths.zSide1 });
411
- wrapper.side2.attr({ d: paths.side2, zIndex: paths.zSide2 });
920
+ // Get bounding box of 3D element:
921
+ each(corners, function(corner) {
922
+ bbox3d.minX = Math.min(bbox3d.minX, corner.x);
923
+ bbox3d.maxX = Math.max(bbox3d.maxX, corner.x);
924
+ bbox3d.minY = Math.min(bbox3d.minY, corner.y);
925
+ bbox3d.maxY = Math.max(bbox3d.maxY, corner.y);
926
+ });
412
927
 
928
+ // Left edge:
929
+ if (plotLeft > bbox3d.minX) {
930
+ scale = Math.min(scale, 1 - Math.abs((plotLeft + originX) / (bbox3d.minX + originX)) % 1);
931
+ }
413
932
 
414
- // show all children
415
- wrapper.zIndex = zIndex;
416
- wrapper.attr({ zIndex: zIndex });
933
+ // Right edge:
934
+ if (plotRight < bbox3d.maxX) {
935
+ scale = Math.min(scale, (plotRight - originX) / (bbox3d.maxX - originX));
936
+ }
417
937
 
418
- // Set the radial gradient center the first time
419
- if (attribs.center) {
420
- wrapper.top.setRadialReference(attribs.center);
421
- delete attribs.center;
938
+ // Top edge:
939
+ if (plotTop > bbox3d.minY) {
940
+ if (bbox3d.minY < 0) {
941
+ scale = Math.min(scale, (plotTop + originY) / (-bbox3d.minY + plotTop + originY));
942
+ } else {
943
+ scale = Math.min(scale, 1 - (plotTop + originY) / (bbox3d.minY + originY) % 1);
944
+ }
422
945
  }
423
- };
424
- wrapper.setPaths(attribs);
425
-
426
- // Apply the fill to the top and a darker shade to the sides
427
- wrapper.fillSetter = function (value) {
428
- var darker = Highcharts.Color(value).brighten(-0.1).get();
429
-
430
- this.fill = value;
431
-
432
- this.side1.attr({ fill: darker });
433
- this.side2.attr({ fill: darker });
434
- this.inn.attr({ fill: darker });
435
- this.out.attr({ fill: darker });
436
- this.top.attr({ fill: value });
437
- return this;
438
- };
439
946
 
440
- // Apply the same value to all. These properties cascade down to the children
441
- // when set to the composite arc3d.
442
- each(['opacity', 'translateX', 'translateY', 'visibility'], function (setter) {
443
- wrapper[setter + 'Setter'] = function (value, key) {
444
- wrapper[key] = value;
445
- each(['out', 'inn', 'side1', 'side2', 'top'], function (el) {
446
- wrapper[el].attr(key, value);
447
- });
448
- };
947
+ // Bottom edge:
948
+ if (plotBottom < bbox3d.maxY) {
949
+ scale = Math.min(scale, Math.abs((plotBottom - originY) / (bbox3d.maxY - originY)));
950
+ }
951
+
952
+ return scale;
953
+ }
954
+
955
+
956
+
957
+ H.wrap(H.Chart.prototype, 'isInsidePlot', function(proceed) {
958
+ return this.is3d() || proceed.apply(this, [].slice.call(arguments, 1));
449
959
  });
450
960
 
451
- /**
452
- * Override attr to remove shape attributes and use those to set child paths
453
- */
454
- wrap(wrapper, 'attr', function (proceed, params, val) {
455
- var ca;
456
- if (typeof params === 'object') {
457
- ca = suckOutCustom(params);
458
- if (ca) {
459
- extend(wrapper.attribs, ca);
460
- wrapper.setPaths(wrapper.attribs);
961
+ var defaultOptions = H.getOptions();
962
+ merge(true, defaultOptions, {
963
+ chart: {
964
+ options3d: {
965
+ enabled: false,
966
+ alpha: 0,
967
+ beta: 0,
968
+ depth: 100,
969
+ fitToPlot: true,
970
+ viewDistance: 25,
971
+ frame: {
972
+ bottom: {
973
+ size: 1
974
+ },
975
+ side: {
976
+ size: 1
977
+ },
978
+ back: {
979
+ size: 1
980
+ }
981
+ }
461
982
  }
462
983
  }
463
- return proceed.call(this, params, val);
984
+
464
985
  });
465
986
 
466
- /**
467
- * Override the animate function by sucking out custom parameters related to the shapes directly,
468
- * and update the shapes from the animation step.
469
- */
470
- wrap(wrapper, 'animate', function (proceed, params, animation, complete) {
471
- var ca,
472
- from = this.attribs,
473
- to,
474
- anim;
475
-
476
- // Attribute-line properties connected to 3D. These shouldn't have been in the
477
- // attribs collection in the first place.
478
- delete params.center;
479
- delete params.z;
480
- delete params.depth;
481
- delete params.alpha;
482
- delete params.beta;
483
-
484
- anim = animObject(pick(animation, this.renderer.globalAnimation));
485
-
486
- if (anim.duration) {
487
- params = merge(params); // Don't mutate the original object
488
- ca = suckOutCustom(params);
489
-
490
- if (ca) {
491
- to = ca;
492
- anim.step = function (a, fx) {
493
- function interpolate(key) {
494
- return from[key] + (pick(to[key], from[key]) - from[key]) * fx.pos;
495
- }
496
- fx.elem.setPaths(merge(from, {
497
- x: interpolate('x'),
498
- y: interpolate('y'),
499
- r: interpolate('r'),
500
- innerR: interpolate('innerR'),
501
- start: interpolate('start'),
502
- end: interpolate('end')
503
- }));
504
- };
987
+ wrap(Chart.prototype, 'setClassName', function(proceed) {
988
+ proceed.apply(this, [].slice.call(arguments, 1));
989
+
990
+ if (this.is3d()) {
991
+ this.container.className += ' highcharts-3d-chart';
992
+ }
993
+ });
994
+
995
+ H.wrap(H.Chart.prototype, 'setChartSize', function(proceed) {
996
+ var chart = this,
997
+ options3d = chart.options.chart.options3d;
998
+
999
+ proceed.apply(chart, [].slice.call(arguments, 1));
1000
+
1001
+ if (chart.is3d()) {
1002
+ var inverted = chart.inverted,
1003
+ clipBox = chart.clipBox,
1004
+ margin = chart.margin,
1005
+ x = inverted ? 'y' : 'x',
1006
+ y = inverted ? 'x' : 'y',
1007
+ w = inverted ? 'height' : 'width',
1008
+ h = inverted ? 'width' : 'height';
1009
+
1010
+ clipBox[x] = -(margin[3] || 0);
1011
+ clipBox[y] = -(margin[0] || 0);
1012
+ clipBox[w] = chart.chartWidth + (margin[3] || 0) + (margin[1] || 0);
1013
+ clipBox[h] = chart.chartHeight + (margin[0] || 0) + (margin[2] || 0);
1014
+
1015
+ // Set scale, used later in perspective method():
1016
+ chart.scale3d = 1; // @notice getScale uses perspective, so scale3d has to be reset.
1017
+ if (options3d.fitToPlot === true) {
1018
+ chart.scale3d = getScale(chart, options3d.depth);
505
1019
  }
506
- animation = anim; // Only when duration (#5572)
507
1020
  }
508
- return proceed.call(this, params, animation, complete);
509
1021
  });
510
1022
 
511
- // destroy all children
512
- wrapper.destroy = function () {
513
- this.top.destroy();
514
- this.out.destroy();
515
- this.inn.destroy();
516
- this.side1.destroy();
517
- this.side2.destroy();
1023
+ wrap(Chart.prototype, 'redraw', function(proceed) {
1024
+ if (this.is3d()) {
1025
+ // Set to force a redraw of all elements
1026
+ this.isDirtyBox = true;
1027
+ }
1028
+ proceed.apply(this, [].slice.call(arguments, 1));
1029
+ });
518
1030
 
519
- Highcharts.SVGElement.prototype.destroy.call(this);
520
- };
521
- // hide all children
522
- wrapper.hide = function () {
523
- this.top.hide();
524
- this.out.hide();
525
- this.inn.hide();
526
- this.side1.hide();
527
- this.side2.hide();
528
- };
529
- wrapper.show = function () {
530
- this.top.show();
531
- this.out.show();
532
- this.inn.show();
533
- this.side1.show();
534
- this.side2.show();
535
- };
536
- return wrapper;
537
- };
538
-
539
- /**
540
- * Generate the paths required to draw a 3D arc
541
- */
542
- Highcharts.SVGRenderer.prototype.arc3dPath = function (shapeArgs) {
543
- var cx = shapeArgs.x, // x coordinate of the center
544
- cy = shapeArgs.y, // y coordinate of the center
545
- start = shapeArgs.start, // start angle
546
- end = shapeArgs.end - 0.00001, // end angle
547
- r = shapeArgs.r, // radius
548
- ir = shapeArgs.innerR, // inner radius
549
- d = shapeArgs.depth, // depth
550
- alpha = shapeArgs.alpha, // alpha rotation of the chart
551
- beta = shapeArgs.beta; // beta rotation of the chart
552
-
553
- // Derived Variables
554
- var cs = cos(start), // cosinus of the start angle
555
- ss = sin(start), // sinus of the start angle
556
- ce = cos(end), // cosinus of the end angle
557
- se = sin(end), // sinus of the end angle
558
- rx = r * cos(beta), // x-radius
559
- ry = r * cos(alpha), // y-radius
560
- irx = ir * cos(beta), // x-radius (inner)
561
- iry = ir * cos(alpha), // y-radius (inner)
562
- dx = d * sin(beta), // distance between top and bottom in x
563
- dy = d * sin(alpha); // distance between top and bottom in y
564
-
565
- // TOP
566
- var top = ['M', cx + (rx * cs), cy + (ry * ss)];
567
- top = top.concat(curveTo(cx, cy, rx, ry, start, end, 0, 0));
568
- top = top.concat([
569
- 'L', cx + (irx * ce), cy + (iry * se)
570
- ]);
571
- top = top.concat(curveTo(cx, cy, irx, iry, end, start, 0, 0));
572
- top = top.concat(['Z']);
573
- // OUTSIDE
574
- var b = (beta > 0 ? PI / 2 : 0),
575
- a = (alpha > 0 ? 0 : PI / 2);
576
-
577
- var start2 = start > -b ? start : (end > -b ? -b : start),
578
- end2 = end < PI - a ? end : (start < PI - a ? PI - a : end),
579
- midEnd = 2 * PI - a;
580
-
581
- // When slice goes over bottom middle, need to add both, left and right outer side.
582
- // Additionally, when we cross right hand edge, create sharp edge. Outer shape/wall:
583
- //
584
- // -------
585
- // / ^ \
586
- // 4) / / \ \ 1)
587
- // / / \ \
588
- // / / \ \
589
- // (c)=> ==== ==== <=(d)
590
- // \ \ / /
591
- // \ \<=(a)/ /
592
- // \ \ / / <=(b)
593
- // 3) \ v / 2)
594
- // -------
595
- //
596
- // (a) - inner side
597
- // (b) - outer side
598
- // (c) - left edge (sharp)
599
- // (d) - right edge (sharp)
600
- // 1..n - rendering order for startAngle = 0, when set to e.g 90, order changes clockwise (1->2, 2->3, n->1) and counterclockwise for negative startAngle
601
-
602
- var out = ['M', cx + (rx * cos(start2)), cy + (ry * sin(start2))];
603
- out = out.concat(curveTo(cx, cy, rx, ry, start2, end2, 0, 0));
604
-
605
- if (end > midEnd && start < midEnd) { // When shape is wide, it can cross both, (c) and (d) edges, when using startAngle
606
- // Go to outer side
607
- out = out.concat([
608
- 'L', cx + (rx * cos(end2)) + dx, cy + (ry * sin(end2)) + dy
609
- ]);
610
- // Curve to the right edge of the slice (d)
611
- out = out.concat(curveTo(cx, cy, rx, ry, end2, midEnd, dx, dy));
612
- // Go to the inner side
613
- out = out.concat([
614
- 'L', cx + (rx * cos(midEnd)), cy + (ry * sin(midEnd))
615
- ]);
616
- // Curve to the true end of the slice
617
- out = out.concat(curveTo(cx, cy, rx, ry, midEnd, end, 0, 0));
618
- // Go to the outer side
619
- out = out.concat([
620
- 'L', cx + (rx * cos(end)) + dx, cy + (ry * sin(end)) + dy
621
- ]);
622
- // Go back to middle (d)
623
- out = out.concat(curveTo(cx, cy, rx, ry, end, midEnd, dx, dy));
624
- out = out.concat([
625
- 'L', cx + (rx * cos(midEnd)), cy + (ry * sin(midEnd))
626
- ]);
627
- // Go back to the left edge
628
- out = out.concat(curveTo(cx, cy, rx, ry, midEnd, end2, 0, 0));
629
- } else if (end > PI - a && start < PI - a) { // But shape can cross also only (c) edge:
630
- // Go to outer side
631
- out = out.concat([
632
- 'L', cx + (rx * cos(end2)) + dx, cy + (ry * sin(end2)) + dy
633
- ]);
634
- // Curve to the true end of the slice
635
- out = out.concat(curveTo(cx, cy, rx, ry, end2, end, dx, dy));
636
- // Go to the inner side
637
- out = out.concat([
638
- 'L', cx + (rx * cos(end)), cy + (ry * sin(end))
639
- ]);
640
- // Go back to the artifical end2
641
- out = out.concat(curveTo(cx, cy, rx, ry, end, end2, 0, 0));
642
- }
1031
+ // Draw the series in the reverse order (#3803, #3917)
1032
+ wrap(Chart.prototype, 'renderSeries', function(proceed) {
1033
+ var series,
1034
+ i = this.series.length;
643
1035
 
644
- out = out.concat([
645
- 'L', cx + (rx * cos(end2)) + dx, cy + (ry * sin(end2)) + dy
646
- ]);
647
- out = out.concat(curveTo(cx, cy, rx, ry, end2, start2, dx, dy));
648
- out = out.concat(['Z']);
649
-
650
- // INSIDE
651
- var inn = ['M', cx + (irx * cs), cy + (iry * ss)];
652
- inn = inn.concat(curveTo(cx, cy, irx, iry, start, end, 0, 0));
653
- inn = inn.concat([
654
- 'L', cx + (irx * cos(end)) + dx, cy + (iry * sin(end)) + dy
655
- ]);
656
- inn = inn.concat(curveTo(cx, cy, irx, iry, end, start, dx, dy));
657
- inn = inn.concat(['Z']);
658
-
659
- // SIDES
660
- var side1 = [
661
- 'M', cx + (rx * cs), cy + (ry * ss),
662
- 'L', cx + (rx * cs) + dx, cy + (ry * ss) + dy,
663
- 'L', cx + (irx * cs) + dx, cy + (iry * ss) + dy,
664
- 'L', cx + (irx * cs), cy + (iry * ss),
665
- 'Z'
666
- ];
667
- var side2 = [
668
- 'M', cx + (rx * ce), cy + (ry * se),
669
- 'L', cx + (rx * ce) + dx, cy + (ry * se) + dy,
670
- 'L', cx + (irx * ce) + dx, cy + (iry * se) + dy,
671
- 'L', cx + (irx * ce), cy + (iry * se),
672
- 'Z'
673
- ];
674
-
675
- // correction for changed position of vanishing point caused by alpha and beta rotations
676
- var angleCorr = Math.atan2(dy, -dx),
677
- angleEnd = Math.abs(end + angleCorr),
678
- angleStart = Math.abs(start + angleCorr),
679
- angleMid = Math.abs((start + end) / 2 + angleCorr);
680
-
681
- // set to 0-PI range
682
- function toZeroPIRange(angle) {
683
- angle = angle % (2 * PI);
684
- if (angle > PI) {
685
- angle = 2 * PI - angle;
1036
+ if (this.is3d()) {
1037
+ while (i--) {
1038
+ series = this.series[i];
1039
+ series.translate();
1040
+ series.render();
1041
+ }
1042
+ } else {
1043
+ proceed.call(this);
686
1044
  }
687
- return angle;
688
- }
689
- angleEnd = toZeroPIRange(angleEnd);
690
- angleStart = toZeroPIRange(angleStart);
691
- angleMid = toZeroPIRange(angleMid);
692
-
693
- // *1e5 is to compensate pInt in zIndexSetter
694
- var incPrecision = 1e5,
695
- a1 = angleMid * incPrecision,
696
- a2 = angleStart * incPrecision,
697
- a3 = angleEnd * incPrecision;
698
-
699
- return {
700
- top: top,
701
- zTop: PI * incPrecision + 1, // max angle is PI, so this is allways higher
702
- out: out,
703
- zOut: Math.max(a1, a2, a3),
704
- inn: inn,
705
- zInn: Math.max(a1, a2, a3),
706
- side1: side1,
707
- zSide1: a3 * 0.99, // to keep below zOut and zInn in case of same values
708
- side2: side2,
709
- zSide2: a2 * 0.99
710
- };
711
- };
712
- /***
713
- EXTENSION FOR 3D CHARTS
714
- ***/
715
- // Shorthand to check the is3d flag
716
- Highcharts.Chart.prototype.is3d = function () {
717
- return this.options.chart.options3d && this.options.chart.options3d.enabled; // #4280
718
- };
719
-
720
- /**
721
- * Calculate scale of the 3D view. That is required to
722
- * fit chart's 3D projection into the actual plotting area. Reported as #4933.
723
- * @notice This function should ideally take the plot values instead of a chart object,
724
- * but since the chart object is needed for perspective it is not practical.
725
- * Possible to make both getScale and perspective more logical and also immutable.
726
- * @param {Object} chart Chart object
727
- * @param {Number} chart.plotLeft
728
- * @param {Number} chart.plotWidth
729
- * @param {Number} chart.plotTop
730
- * @param {Number} chart.plotHeight
731
- * @param {Number} depth The depth of the chart
732
- * @return {Number} The scale to fit the 3D chart into the plotting area.
733
- */
734
- function getScale(chart, depth) {
735
- var plotLeft = chart.plotLeft,
736
- plotRight = chart.plotWidth + plotLeft,
737
- plotTop = chart.plotTop,
738
- plotBottom = chart.plotHeight + plotTop,
739
- originX = plotLeft + chart.plotWidth / 2,
740
- originY = plotTop + chart.plotHeight / 2,
741
- bbox3d = {
742
- minX: Number.MAX_VALUE,
743
- maxX: -Number.MAX_VALUE,
744
- minY: Number.MAX_VALUE,
745
- maxY: -Number.MAX_VALUE
746
- },
747
- corners,
748
- scale = 1;
749
-
750
- // Top left corners:
751
- corners = [{
752
- x: plotLeft,
753
- y: plotTop,
754
- z: 0
755
- }, {
756
- x: plotLeft,
757
- y: plotTop,
758
- z: depth
759
- }];
760
-
761
- // Top right corners:
762
- each([0, 1], function (i) {
763
- corners.push({
764
- x: plotRight,
765
- y: corners[i].y,
766
- z: corners[i].z
767
- });
768
1045
  });
769
1046
 
770
- // All bottom corners:
771
- each([0, 1, 2, 3], function (i) {
772
- corners.push({
773
- x: corners[i].x,
774
- y: plotBottom,
775
- z: corners[i].z
1047
+ Chart.prototype.retrieveStacks = function(stacking) {
1048
+ var series = this.series,
1049
+ stacks = {},
1050
+ stackNumber,
1051
+ i = 1;
1052
+
1053
+ each(this.series, function(s) {
1054
+ stackNumber = pick(s.options.stack, (stacking ? 0 : series.length - 1 - s.index)); // #3841, #4532
1055
+ if (!stacks[stackNumber]) {
1056
+ stacks[stackNumber] = {
1057
+ series: [s],
1058
+ position: i
1059
+ };
1060
+ i++;
1061
+ } else {
1062
+ stacks[stackNumber].series.push(s);
1063
+ }
776
1064
  });
777
- });
778
1065
 
779
- // Calculate 3D corners:
780
- corners = perspective(corners, chart, false);
1066
+ stacks.totalStacks = i + 1;
1067
+ return stacks;
1068
+ };
781
1069
 
782
- // Get bounding box of 3D element:
783
- each(corners, function (corner) {
784
- bbox3d.minX = Math.min(bbox3d.minX, corner.x);
785
- bbox3d.maxX = Math.max(bbox3d.maxX, corner.x);
786
- bbox3d.minY = Math.min(bbox3d.minY, corner.y);
787
- bbox3d.maxY = Math.max(bbox3d.maxY, corner.y);
1070
+ }(Highcharts));
1071
+ (function(H) {
1072
+ /**
1073
+ * (c) 2010-2016 Torstein Honsi
1074
+ *
1075
+ * License: www.highcharts.com/license
1076
+ */
1077
+ 'use strict';
1078
+ var ZAxis,
1079
+
1080
+ Axis = H.Axis,
1081
+ Chart = H.Chart,
1082
+ each = H.each,
1083
+ extend = H.extend,
1084
+ merge = H.merge,
1085
+ perspective = H.perspective,
1086
+ pick = H.pick,
1087
+ splat = H.splat,
1088
+ Tick = H.Tick,
1089
+ wrap = H.wrap;
1090
+ /***
1091
+ EXTENSION TO THE AXIS
1092
+ ***/
1093
+ wrap(Axis.prototype, 'setOptions', function(proceed, userOptions) {
1094
+ var options;
1095
+ proceed.call(this, userOptions);
1096
+ if (this.chart.is3d()) {
1097
+ options = this.options;
1098
+ options.tickWidth = pick(options.tickWidth, 0);
1099
+ options.gridLineWidth = pick(options.gridLineWidth, 1);
1100
+ }
788
1101
  });
789
1102
 
790
- // Left edge:
791
- if (plotLeft > bbox3d.minX) {
792
- scale = Math.min(scale, 1 - Math.abs((plotLeft + originX) / (bbox3d.minX + originX)) % 1);
793
- }
1103
+ wrap(Axis.prototype, 'render', function(proceed) {
1104
+ proceed.apply(this, [].slice.call(arguments, 1));
794
1105
 
795
- // Right edge:
796
- if (plotRight < bbox3d.maxX) {
797
- scale = Math.min(scale, (plotRight - originX) / (bbox3d.maxX - originX));
798
- }
1106
+ // Do not do this if the chart is not 3D
1107
+ if (!this.chart.is3d()) {
1108
+ return;
1109
+ }
799
1110
 
800
- // Top edge:
801
- if (plotTop > bbox3d.minY) {
802
- if (bbox3d.minY < 0) {
803
- scale = Math.min(scale, (plotTop + originY) / (-bbox3d.minY + plotTop + originY));
804
- } else {
805
- scale = Math.min(scale, 1 - (plotTop + originY) / (bbox3d.minY + originY) % 1);
1111
+ var chart = this.chart,
1112
+ renderer = chart.renderer,
1113
+ options3d = chart.options.chart.options3d,
1114
+ frame = options3d.frame,
1115
+ fbottom = frame.bottom,
1116
+ fback = frame.back,
1117
+ fside = frame.side,
1118
+ depth = options3d.depth,
1119
+ height = this.height,
1120
+ width = this.width,
1121
+ left = this.left,
1122
+ top = this.top;
1123
+
1124
+ if (this.isZAxis) {
1125
+ return;
806
1126
  }
807
- }
1127
+ if (this.horiz) {
1128
+ var bottomShape = {
1129
+ x: left,
1130
+ y: top + (chart.xAxis[0].opposite ? -fbottom.size : height),
1131
+ z: 0,
1132
+ width: width,
1133
+ height: fbottom.size,
1134
+ depth: depth,
1135
+ insidePlotArea: false
1136
+ };
1137
+ if (!this.bottomFrame) {
1138
+ this.bottomFrame = renderer.cuboid(bottomShape).attr({
1139
+ 'class': 'highcharts-3d-frame highcharts-3d-frame-bottom',
1140
+ 'zIndex': (chart.yAxis[0].reversed && options3d.alpha > 0 ? 4 : -1)
1141
+ }).add();
808
1142
 
809
- // Bottom edge:
810
- if (plotBottom < bbox3d.maxY) {
811
- scale = Math.min(scale, Math.abs((plotBottom - originY) / (bbox3d.maxY - originY)));
812
- }
813
1143
 
814
- return scale;
815
- }
1144
+ this.bottomFrame.attr({
1145
+ fill: fbottom.color || 'none',
1146
+ stroke: fbottom.color || 'none'
1147
+ });
816
1148
 
1149
+ } else {
1150
+ this.bottomFrame.animate(bottomShape);
1151
+ }
1152
+ } else {
1153
+ // BACK
1154
+ var backShape = {
1155
+ x: left + (chart.yAxis[0].opposite ? 0 : -fside.size),
1156
+ y: top + (chart.xAxis[0].opposite ? -fbottom.size : 0),
1157
+ z: depth,
1158
+ width: width + fside.size,
1159
+ height: height + fbottom.size,
1160
+ depth: fback.size,
1161
+ insidePlotArea: false
1162
+ };
1163
+ if (!this.backFrame) {
1164
+ this.backFrame = renderer.cuboid(backShape).attr({
1165
+ 'class': 'highcharts-3d-frame highcharts-3d-frame-back',
1166
+ zIndex: -3
1167
+ }).add();
817
1168
 
818
1169
 
819
- Highcharts.wrap(Highcharts.Chart.prototype, 'isInsidePlot', function (proceed) {
820
- return this.is3d() || proceed.apply(this, [].slice.call(arguments, 1));
821
- });
1170
+ this.backFrame.attr({
1171
+ fill: fback.color || 'none',
1172
+ stroke: fback.color || 'none'
1173
+ });
822
1174
 
823
- var defaultChartOptions = Highcharts.getOptions();
824
- defaultChartOptions.chart.options3d = {
825
- enabled: false,
826
- alpha: 0,
827
- beta: 0,
828
- depth: 100,
829
- fitToPlot: true,
830
- viewDistance: 25,
831
- frame: {
832
- bottom: { size: 1, color: 'rgba(255,255,255,0)' },
833
- side: { size: 1, color: 'rgba(255,255,255,0)' },
834
- back: { size: 1, color: 'rgba(255,255,255,0)' }
835
- }
836
- };
1175
+ } else {
1176
+ this.backFrame.animate(backShape);
1177
+ }
1178
+ var sideShape = {
1179
+ x: left + (chart.yAxis[0].opposite ? width : -fside.size),
1180
+ y: top + (chart.xAxis[0].opposite ? -fbottom.size : 0),
1181
+ z: 0,
1182
+ width: fside.size,
1183
+ height: height + fbottom.size,
1184
+ depth: depth,
1185
+ insidePlotArea: false
1186
+ };
1187
+ if (!this.sideFrame) {
1188
+ this.sideFrame = renderer.cuboid(sideShape).attr({
1189
+ 'class': 'highcharts-3d-frame highcharts-3d-frame-side',
1190
+ zIndex: -2
1191
+ }).add();
837
1192
 
838
- Highcharts.wrap(Highcharts.Chart.prototype, 'init', function (proceed) {
839
- var args = [].slice.call(arguments, 1),
840
- plotOptions,
841
- pieOptions;
842
1193
 
843
- if (args[0].chart && args[0].chart.options3d && args[0].chart.options3d.enabled) {
844
- // Normalize alpha and beta to (-360, 360) range
845
- args[0].chart.options3d.alpha = (args[0].chart.options3d.alpha || 0) % 360;
846
- args[0].chart.options3d.beta = (args[0].chart.options3d.beta || 0) % 360;
1194
+ this.sideFrame.attr({
1195
+ fill: fside.color || 'none',
1196
+ stroke: fside.color || 'none'
1197
+ });
847
1198
 
848
- plotOptions = args[0].plotOptions || {};
849
- pieOptions = plotOptions.pie || {};
850
1199
 
851
- pieOptions.borderColor = Highcharts.pick(pieOptions.borderColor, undefined);
852
- }
853
- proceed.apply(this, args);
854
- });
855
-
856
- Highcharts.wrap(Highcharts.Chart.prototype, 'setChartSize', function (proceed) {
857
- var chart = this,
858
- options3d = chart.options.chart.options3d;
859
-
860
- proceed.apply(chart, [].slice.call(arguments, 1));
861
-
862
- if (chart.is3d()) {
863
- var inverted = chart.inverted,
864
- clipBox = chart.clipBox,
865
- margin = chart.margin,
866
- x = inverted ? 'y' : 'x',
867
- y = inverted ? 'x' : 'y',
868
- w = inverted ? 'height' : 'width',
869
- h = inverted ? 'width' : 'height';
870
-
871
- clipBox[x] = -(margin[3] || 0);
872
- clipBox[y] = -(margin[0] || 0);
873
- clipBox[w] = chart.chartWidth + (margin[3] || 0) + (margin[1] || 0);
874
- clipBox[h] = chart.chartHeight + (margin[0] || 0) + (margin[2] || 0);
875
-
876
- // Set scale, used later in perspective method():
877
- chart.scale3d = 1; // @notice getScale uses perspective, so scale3d has to be reset.
878
- if (options3d.fitToPlot === true) {
879
- chart.scale3d = getScale(chart, options3d.depth);
1200
+ } else {
1201
+ this.sideFrame.animate(sideShape);
1202
+ }
880
1203
  }
881
- }
882
- });
1204
+ });
883
1205
 
884
- Highcharts.wrap(Highcharts.Chart.prototype, 'redraw', function (proceed) {
885
- if (this.is3d()) {
886
- // Set to force a redraw of all elements
887
- this.isDirtyBox = true;
888
- }
889
- proceed.apply(this, [].slice.call(arguments, 1));
890
- });
891
-
892
- // Draw the series in the reverse order (#3803, #3917)
893
- Highcharts.wrap(Highcharts.Chart.prototype, 'renderSeries', function (proceed) {
894
- var series,
895
- i = this.series.length;
896
-
897
- if (this.is3d()) {
898
- while (i--) {
899
- series = this.series[i];
900
- series.translate();
901
- series.render();
1206
+ wrap(Axis.prototype, 'getPlotLinePath', function(proceed) {
1207
+ var path = proceed.apply(this, [].slice.call(arguments, 1));
1208
+
1209
+ // Do not do this if the chart is not 3D
1210
+ if (!this.chart.is3d()) {
1211
+ return path;
902
1212
  }
903
- } else {
904
- proceed.call(this);
905
- }
906
- });
907
-
908
- Highcharts.Chart.prototype.retrieveStacks = function (stacking) {
909
- var series = this.series,
910
- stacks = {},
911
- stackNumber,
912
- i = 1;
913
-
914
- Highcharts.each(this.series, function (s) {
915
- stackNumber = pick(s.options.stack, (stacking ? 0 : series.length - 1 - s.index)); // #3841, #4532
916
- if (!stacks[stackNumber]) {
917
- stacks[stackNumber] = { series: [s], position: i };
918
- i++;
919
- } else {
920
- stacks[stackNumber].series.push(s);
1213
+
1214
+ if (path === null) {
1215
+ return path;
921
1216
  }
922
- });
923
1217
 
924
- stacks.totalStacks = i + 1;
925
- return stacks;
926
- };
927
-
928
- /***
929
- EXTENSION TO THE AXIS
930
- ***/
931
- Highcharts.wrap(Highcharts.Axis.prototype, 'setOptions', function (proceed, userOptions) {
932
- var options;
933
- proceed.call(this, userOptions);
934
- if (this.chart.is3d()) {
935
- options = this.options;
936
- options.tickWidth = Highcharts.pick(options.tickWidth, 0);
937
- options.gridLineWidth = Highcharts.pick(options.gridLineWidth, 1);
938
- }
939
- });
1218
+ var chart = this.chart,
1219
+ options3d = chart.options.chart.options3d,
1220
+ d = this.isZAxis ? chart.plotWidth : options3d.depth,
1221
+ opposite = this.opposite;
1222
+ if (this.horiz) {
1223
+ opposite = !opposite;
1224
+ }
1225
+ var pArr = [
1226
+ this.swapZ({
1227
+ x: path[1],
1228
+ y: path[2],
1229
+ z: (opposite ? d : 0)
1230
+ }),
1231
+ this.swapZ({
1232
+ x: path[1],
1233
+ y: path[2],
1234
+ z: d
1235
+ }),
1236
+ this.swapZ({
1237
+ x: path[4],
1238
+ y: path[5],
1239
+ z: d
1240
+ }),
1241
+ this.swapZ({
1242
+ x: path[4],
1243
+ y: path[5],
1244
+ z: (opposite ? 0 : d)
1245
+ })
1246
+ ];
940
1247
 
941
- Highcharts.wrap(Highcharts.Axis.prototype, 'render', function (proceed) {
942
- proceed.apply(this, [].slice.call(arguments, 1));
1248
+ pArr = perspective(pArr, this.chart, false);
1249
+ path = this.chart.renderer.toLinePath(pArr, false);
943
1250
 
944
- // Do not do this if the chart is not 3D
945
- if (!this.chart.is3d()) {
946
- return;
947
- }
1251
+ return path;
1252
+ });
948
1253
 
949
- var chart = this.chart,
950
- renderer = chart.renderer,
951
- options3d = chart.options.chart.options3d,
952
- frame = options3d.frame,
953
- fbottom = frame.bottom,
954
- fback = frame.back,
955
- fside = frame.side,
956
- depth = options3d.depth,
957
- height = this.height,
958
- width = this.width,
959
- left = this.left,
960
- top = this.top;
961
-
962
- if (this.isZAxis) {
963
- return;
964
- }
965
- if (this.horiz) {
966
- var bottomShape = {
967
- x: left,
968
- y: top + (chart.xAxis[0].opposite ? -fbottom.size : height),
969
- z: 0,
970
- width: width,
971
- height: fbottom.size,
972
- depth: depth,
973
- insidePlotArea: false
974
- };
975
- if (!this.bottomFrame) {
976
- this.bottomFrame = renderer.cuboid(bottomShape).attr({
977
- fill: fbottom.color,
978
- zIndex: (chart.yAxis[0].reversed && options3d.alpha > 0 ? 4 : -1)
979
- })
980
- .css({
981
- stroke: fbottom.color
982
- }).add();
983
- } else {
984
- this.bottomFrame.animate(bottomShape);
1254
+ // Do not draw axislines in 3D
1255
+ wrap(Axis.prototype, 'getLinePath', function(proceed) {
1256
+ return this.chart.is3d() ? [] : proceed.apply(this, [].slice.call(arguments, 1));
1257
+ });
1258
+
1259
+ wrap(Axis.prototype, 'getPlotBandPath', function(proceed) {
1260
+ // Do not do this if the chart is not 3D
1261
+ if (!this.chart.is3d()) {
1262
+ return proceed.apply(this, [].slice.call(arguments, 1));
985
1263
  }
986
- } else {
987
- // BACK
988
- var backShape = {
989
- x: left + (chart.yAxis[0].opposite ? 0 : -fside.size),
990
- y: top + (chart.xAxis[0].opposite ? -fbottom.size : 0),
991
- z: depth,
992
- width: width + fside.size,
993
- height: height + fbottom.size,
994
- depth: fback.size,
995
- insidePlotArea: false
996
- };
997
- if (!this.backFrame) {
998
- this.backFrame = renderer.cuboid(backShape).attr({
999
- fill: fback.color,
1000
- zIndex: -3
1001
- }).css({
1002
- stroke: fback.color
1003
- }).add();
1004
- } else {
1005
- this.backFrame.animate(backShape);
1264
+
1265
+ var args = arguments,
1266
+ from = args[1],
1267
+ to = args[2],
1268
+ toPath = this.getPlotLinePath(to),
1269
+ path = this.getPlotLinePath(from);
1270
+
1271
+ if (path && toPath) {
1272
+ path.push(
1273
+ 'L',
1274
+ toPath[10], // These two do not exist in the regular getPlotLine
1275
+ toPath[11], // ---- # 3005
1276
+ 'L',
1277
+ toPath[7],
1278
+ toPath[8],
1279
+ 'L',
1280
+ toPath[4],
1281
+ toPath[5],
1282
+ 'L',
1283
+ toPath[1],
1284
+ toPath[2]
1285
+ );
1286
+ } else { // outside the axis area
1287
+ path = null;
1006
1288
  }
1007
- var sideShape = {
1008
- x: left + (chart.yAxis[0].opposite ? width : -fside.size),
1009
- y: top + (chart.xAxis[0].opposite ? -fbottom.size : 0),
1010
- z: 0,
1011
- width: fside.size,
1012
- height: height + fbottom.size,
1013
- depth: depth,
1014
- insidePlotArea: false
1015
- };
1016
- if (!this.sideFrame) {
1017
- this.sideFrame = renderer.cuboid(sideShape).attr({
1018
- fill: fside.color,
1019
- zIndex: -2
1020
- }).css({
1021
- stroke: fside.color
1022
- }).add();
1023
- } else {
1024
- this.sideFrame.animate(sideShape);
1289
+
1290
+ return path;
1291
+ });
1292
+
1293
+ /***
1294
+ EXTENSION TO THE TICKS
1295
+ ***/
1296
+
1297
+ wrap(Tick.prototype, 'getMarkPath', function(proceed) {
1298
+ var path = proceed.apply(this, [].slice.call(arguments, 1));
1299
+
1300
+ // Do not do this if the chart is not 3D
1301
+ if (!this.axis.chart.is3d()) {
1302
+ return path;
1025
1303
  }
1026
- }
1027
- });
1028
1304
 
1029
- Highcharts.wrap(Highcharts.Axis.prototype, 'getPlotLinePath', function (proceed) {
1030
- var path = proceed.apply(this, [].slice.call(arguments, 1));
1305
+ var pArr = [
1306
+ this.axis.swapZ({
1307
+ x: path[1],
1308
+ y: path[2],
1309
+ z: 0
1310
+ }),
1311
+ this.axis.swapZ({
1312
+ x: path[4],
1313
+ y: path[5],
1314
+ z: 0
1315
+ })
1316
+ ];
1031
1317
 
1032
- // Do not do this if the chart is not 3D
1033
- if (!this.chart.is3d()) {
1318
+ pArr = perspective(pArr, this.axis.chart, false);
1319
+ path = [
1320
+ 'M', pArr[0].x, pArr[0].y,
1321
+ 'L', pArr[1].x, pArr[1].y
1322
+ ];
1034
1323
  return path;
1035
- }
1324
+ });
1036
1325
 
1037
- if (path === null) {
1038
- return path;
1039
- }
1326
+ wrap(Tick.prototype, 'getLabelPosition', function(proceed) {
1327
+ var pos = proceed.apply(this, [].slice.call(arguments, 1));
1040
1328
 
1041
- var chart = this.chart,
1042
- options3d = chart.options.chart.options3d,
1043
- d = this.isZAxis ? chart.plotWidth : options3d.depth,
1044
- opposite = this.opposite;
1045
- if (this.horiz) {
1046
- opposite = !opposite;
1047
- }
1048
- var pArr = [
1049
- this.swapZ({ x: path[1], y: path[2], z: (opposite ? d : 0) }),
1050
- this.swapZ({ x: path[1], y: path[2], z: d }),
1051
- this.swapZ({ x: path[4], y: path[5], z: d }),
1052
- this.swapZ({ x: path[4], y: path[5], z: (opposite ? 0 : d) })
1053
- ];
1054
-
1055
- pArr = perspective(pArr, this.chart, false);
1056
- path = this.chart.renderer.toLinePath(pArr, false);
1057
-
1058
- return path;
1059
- });
1060
-
1061
- // Do not draw axislines in 3D
1062
- Highcharts.wrap(Highcharts.Axis.prototype, 'getLinePath', function (proceed) {
1063
- return this.chart.is3d() ? [] : proceed.apply(this, [].slice.call(arguments, 1));
1064
- });
1065
-
1066
- Highcharts.wrap(Highcharts.Axis.prototype, 'getPlotBandPath', function (proceed) {
1067
- // Do not do this if the chart is not 3D
1068
- if (!this.chart.is3d()) {
1069
- return proceed.apply(this, [].slice.call(arguments, 1));
1070
- }
1071
-
1072
- var args = arguments,
1073
- from = args[1],
1074
- to = args[2],
1075
- toPath = this.getPlotLinePath(to),
1076
- path = this.getPlotLinePath(from);
1077
-
1078
- if (path && toPath) {
1079
- path.push(
1080
- 'L',
1081
- toPath[10], // These two do not exist in the regular getPlotLine
1082
- toPath[11], // ---- # 3005
1083
- 'L',
1084
- toPath[7],
1085
- toPath[8],
1086
- 'L',
1087
- toPath[4],
1088
- toPath[5],
1089
- 'L',
1090
- toPath[1],
1091
- toPath[2]
1092
- );
1093
- } else { // outside the axis area
1094
- path = null;
1095
- }
1329
+ // Do not do this if the chart is not 3D
1330
+ if (this.axis.chart.is3d()) {
1331
+ pos = perspective([this.axis.swapZ({
1332
+ x: pos.x,
1333
+ y: pos.y,
1334
+ z: 0
1335
+ })], this.axis.chart, false)[0];
1336
+ }
1337
+ return pos;
1338
+ });
1096
1339
 
1097
- return path;
1098
- });
1340
+ H.wrap(Axis.prototype, 'getTitlePosition', function(proceed) {
1341
+ var is3d = this.chart.is3d(),
1342
+ pos,
1343
+ axisTitleMargin;
1099
1344
 
1100
- /***
1101
- EXTENSION TO THE TICKS
1102
- ***/
1345
+ // Pull out the axis title margin, that is not subject to the perspective
1346
+ if (is3d) {
1347
+ axisTitleMargin = this.axisTitleMargin;
1348
+ this.axisTitleMargin = 0;
1349
+ }
1103
1350
 
1104
- Highcharts.wrap(Highcharts.Tick.prototype, 'getMarkPath', function (proceed) {
1105
- var path = proceed.apply(this, [].slice.call(arguments, 1));
1351
+ pos = proceed.apply(this, [].slice.call(arguments, 1));
1106
1352
 
1107
- // Do not do this if the chart is not 3D
1108
- if (!this.axis.chart.is3d()) {
1109
- return path;
1110
- }
1353
+ if (is3d) {
1354
+ pos = perspective([this.swapZ({
1355
+ x: pos.x,
1356
+ y: pos.y,
1357
+ z: 0
1358
+ })], this.chart, false)[0];
1111
1359
 
1112
- var pArr = [
1113
- this.axis.swapZ({ x: path[1], y: path[2], z: 0 }),
1114
- this.axis.swapZ({ x: path[4], y: path[5], z: 0 })
1115
- ];
1116
-
1117
- pArr = perspective(pArr, this.axis.chart, false);
1118
- path = [
1119
- 'M', pArr[0].x, pArr[0].y,
1120
- 'L', pArr[1].x, pArr[1].y
1121
- ];
1122
- return path;
1123
- });
1124
-
1125
- Highcharts.wrap(Highcharts.Tick.prototype, 'getLabelPosition', function (proceed) {
1126
- var pos = proceed.apply(this, [].slice.call(arguments, 1));
1127
-
1128
- // Do not do this if the chart is not 3D
1129
- if (this.axis.chart.is3d()) {
1130
- pos = perspective([this.axis.swapZ({ x: pos.x, y: pos.y, z: 0 })], this.axis.chart, false)[0];
1131
- }
1132
- return pos;
1133
- });
1134
-
1135
- Highcharts.wrap(Highcharts.Axis.prototype, 'getTitlePosition', function (proceed) {
1136
- var is3d = this.chart.is3d(),
1137
- pos,
1138
- axisTitleMargin;
1139
-
1140
- // Pull out the axis title margin, that is not subject to the perspective
1141
- if (is3d) {
1142
- axisTitleMargin = this.axisTitleMargin;
1143
- this.axisTitleMargin = 0;
1144
- }
1360
+ // Re-apply the axis title margin outside the perspective
1361
+ pos[this.horiz ? 'y' : 'x'] += (this.horiz ? 1 : -1) * // horizontal axis reverses the margin ...
1362
+ (this.opposite ? -1 : 1) * // ... so does opposite axes
1363
+ axisTitleMargin;
1364
+ this.axisTitleMargin = axisTitleMargin;
1365
+ }
1366
+ return pos;
1367
+ });
1145
1368
 
1146
- pos = proceed.apply(this, [].slice.call(arguments, 1));
1369
+ wrap(Axis.prototype, 'drawCrosshair', function(proceed) {
1370
+ var args = arguments;
1371
+ if (this.chart.is3d()) {
1372
+ if (args[2]) {
1373
+ args[2] = {
1374
+ plotX: args[2].plotXold || args[2].plotX,
1375
+ plotY: args[2].plotYold || args[2].plotY
1376
+ };
1377
+ }
1378
+ }
1379
+ proceed.apply(this, [].slice.call(args, 1));
1380
+ });
1147
1381
 
1148
- if (is3d) {
1149
- pos = perspective([this.swapZ({ x: pos.x, y: pos.y, z: 0 })], this.chart, false)[0];
1382
+ /***
1383
+ Z-AXIS
1384
+ ***/
1150
1385
 
1151
- // Re-apply the axis title margin outside the perspective
1152
- pos[this.horiz ? 'y' : 'x'] += (this.horiz ? 1 : -1) * // horizontal axis reverses the margin ...
1153
- (this.opposite ? -1 : 1) * // ... so does opposite axes
1154
- axisTitleMargin;
1155
- this.axisTitleMargin = axisTitleMargin;
1156
- }
1157
- return pos;
1158
- });
1159
-
1160
- Highcharts.wrap(Highcharts.Axis.prototype, 'drawCrosshair', function (proceed) {
1161
- var args = arguments;
1162
- if (this.chart.is3d()) {
1163
- if (args[2]) {
1164
- args[2] = {
1165
- plotX: args[2].plotXold || args[2].plotX,
1166
- plotY: args[2].plotYold || args[2].plotY
1386
+ Axis.prototype.swapZ = function(p, insidePlotArea) {
1387
+ if (this.isZAxis) {
1388
+ var plotLeft = insidePlotArea ? 0 : this.chart.plotLeft;
1389
+ var chart = this.chart;
1390
+ return {
1391
+ x: plotLeft + (chart.yAxis[0].opposite ? p.z : chart.xAxis[0].width - p.z),
1392
+ y: p.y,
1393
+ z: p.x - plotLeft
1167
1394
  };
1168
1395
  }
1169
- }
1170
- proceed.apply(this, [].slice.call(args, 1));
1171
- });
1396
+ return p;
1397
+ };
1172
1398
 
1173
- /***
1174
- Z-AXIS
1175
- ***/
1399
+ ZAxis = H.ZAxis = function() {
1400
+ this.isZAxis = true;
1401
+ this.init.apply(this, arguments);
1402
+ };
1403
+ extend(ZAxis.prototype, Axis.prototype);
1404
+ extend(ZAxis.prototype, {
1405
+ setOptions: function(userOptions) {
1406
+ userOptions = merge({
1407
+ offset: 0,
1408
+ lineWidth: 0
1409
+ }, userOptions);
1410
+ Axis.prototype.setOptions.call(this, userOptions);
1411
+ this.coll = 'zAxis';
1412
+ },
1413
+ setAxisSize: function() {
1414
+ Axis.prototype.setAxisSize.call(this);
1415
+ this.width = this.len = this.chart.options.chart.options3d.depth;
1416
+ this.right = this.chart.chartWidth - this.width - this.left;
1417
+ },
1418
+ getSeriesExtremes: function() {
1419
+ var axis = this,
1420
+ chart = axis.chart;
1176
1421
 
1177
- Highcharts.Axis.prototype.swapZ = function (p, insidePlotArea) {
1178
- if (this.isZAxis) {
1179
- var plotLeft = insidePlotArea ? 0 : this.chart.plotLeft;
1180
- var chart = this.chart;
1181
- return {
1182
- x: plotLeft + (chart.yAxis[0].opposite ? p.z : chart.xAxis[0].width - p.z),
1183
- y: p.y,
1184
- z: p.x - plotLeft
1185
- };
1186
- }
1187
- return p;
1188
- };
1189
-
1190
- var ZAxis = Highcharts.ZAxis = function () {
1191
- this.isZAxis = true;
1192
- this.init.apply(this, arguments);
1193
- };
1194
- Highcharts.extend(ZAxis.prototype, Highcharts.Axis.prototype);
1195
- Highcharts.extend(ZAxis.prototype, {
1196
- setOptions: function (userOptions) {
1197
- userOptions = Highcharts.merge({
1198
- offset: 0,
1199
- lineWidth: 0
1200
- }, userOptions);
1201
- Highcharts.Axis.prototype.setOptions.call(this, userOptions);
1202
- this.coll = 'zAxis';
1203
- },
1204
- setAxisSize: function () {
1205
- Highcharts.Axis.prototype.setAxisSize.call(this);
1206
- this.width = this.len = this.chart.options.chart.options3d.depth;
1207
- this.right = this.chart.chartWidth - this.width - this.left;
1208
- },
1209
- getSeriesExtremes: function () {
1210
- var axis = this,
1211
- chart = axis.chart;
1212
-
1213
- axis.hasVisibleSeries = false;
1214
-
1215
- // Reset properties in case we're redrawing (#3353)
1216
- axis.dataMin = axis.dataMax = axis.ignoreMinPadding = axis.ignoreMaxPadding = null;
1217
-
1218
- if (axis.buildStacks) {
1219
- axis.buildStacks();
1220
- }
1422
+ axis.hasVisibleSeries = false;
1221
1423
 
1222
- // loop through this axis' series
1223
- Highcharts.each(axis.series, function (series) {
1424
+ // Reset properties in case we're redrawing (#3353)
1425
+ axis.dataMin = axis.dataMax = axis.ignoreMinPadding = axis.ignoreMaxPadding = null;
1224
1426
 
1225
- if (series.visible || !chart.options.chart.ignoreHiddenSeries) {
1427
+ if (axis.buildStacks) {
1428
+ axis.buildStacks();
1429
+ }
1226
1430
 
1227
- var seriesOptions = series.options,
1228
- zData,
1229
- threshold = seriesOptions.threshold;
1431
+ // loop through this axis' series
1432
+ each(axis.series, function(series) {
1230
1433
 
1231
- axis.hasVisibleSeries = true;
1434
+ if (series.visible || !chart.options.chart.ignoreHiddenSeries) {
1232
1435
 
1233
- // Validate threshold in logarithmic axes
1234
- if (axis.isLog && threshold <= 0) {
1235
- threshold = null;
1236
- }
1436
+ var seriesOptions = series.options,
1437
+ zData,
1438
+ threshold = seriesOptions.threshold;
1237
1439
 
1238
- zData = series.zData;
1239
- if (zData.length) {
1240
- axis.dataMin = Math.min(pick(axis.dataMin, zData[0]), Math.min.apply(null, zData));
1241
- axis.dataMax = Math.max(pick(axis.dataMax, zData[0]), Math.max.apply(null, zData));
1440
+ axis.hasVisibleSeries = true;
1441
+
1442
+ // Validate threshold in logarithmic axes
1443
+ if (axis.isLog && threshold <= 0) {
1444
+ threshold = null;
1445
+ }
1446
+
1447
+ zData = series.zData;
1448
+ if (zData.length) {
1449
+ axis.dataMin = Math.min(pick(axis.dataMin, zData[0]), Math.min.apply(null, zData));
1450
+ axis.dataMax = Math.max(pick(axis.dataMax, zData[0]), Math.max.apply(null, zData));
1451
+ }
1242
1452
  }
1243
- }
1244
- });
1245
- }
1246
- });
1453
+ });
1454
+ }
1455
+ });
1247
1456
 
1248
1457
 
1249
- /**
1250
- * Extend the chart getAxes method to also get the color axis
1251
- */
1252
- Highcharts.wrap(Highcharts.Chart.prototype, 'getAxes', function (proceed) {
1253
- var chart = this,
1254
- options = this.options,
1255
- zAxisOptions = options.zAxis = Highcharts.splat(options.zAxis || {});
1458
+ /**
1459
+ * Extend the chart getAxes method to also get the color axis
1460
+ */
1461
+ wrap(Chart.prototype, 'getAxes', function(proceed) {
1462
+ var chart = this,
1463
+ options = this.options,
1464
+ zAxisOptions = options.zAxis = splat(options.zAxis || {});
1256
1465
 
1257
- proceed.call(this);
1466
+ proceed.call(this);
1258
1467
 
1259
- if (!chart.is3d()) {
1260
- return;
1261
- }
1262
- this.zAxis = [];
1263
- Highcharts.each(zAxisOptions, function (axisOptions, i) {
1264
- axisOptions.index = i;
1265
- axisOptions.isX = true; //Z-Axis is shown horizontally, so it's kind of a X-Axis
1266
- var zAxis = new ZAxis(chart, axisOptions);
1267
- zAxis.setScale();
1468
+ if (!chart.is3d()) {
1469
+ return;
1470
+ }
1471
+ this.zAxis = [];
1472
+ each(zAxisOptions, function(axisOptions, i) {
1473
+ axisOptions.index = i;
1474
+ axisOptions.isX = true; //Z-Axis is shown horizontally, so it's kind of a X-Axis
1475
+ var zAxis = new ZAxis(chart, axisOptions);
1476
+ zAxis.setScale();
1477
+ });
1268
1478
  });
1269
- });
1270
- /***
1271
- EXTENSION FOR 3D COLUMNS
1272
- ***/
1273
- Highcharts.wrap(Highcharts.seriesTypes.column.prototype, 'translate', function (proceed) {
1274
- proceed.apply(this, [].slice.call(arguments, 1));
1275
-
1276
- // Do not do this if the chart is not 3D
1277
- if (!this.chart.is3d()) {
1278
- return;
1279
- }
1280
1479
 
1281
- var series = this,
1282
- chart = series.chart,
1283
- seriesOptions = series.options,
1284
- depth = seriesOptions.depth || 25;
1480
+ }(Highcharts));
1481
+ (function(H) {
1482
+ /**
1483
+ * (c) 2010-2016 Torstein Honsi
1484
+ *
1485
+ * License: www.highcharts.com/license
1486
+ */
1487
+ 'use strict';
1488
+ var each = H.each,
1489
+ perspective = H.perspective,
1490
+ pick = H.pick,
1491
+ Series = H.Series,
1492
+ seriesTypes = H.seriesTypes,
1493
+ svg = H.svg,
1494
+ wrap = H.wrap;
1495
+ /***
1496
+ EXTENSION FOR 3D COLUMNS
1497
+ ***/
1498
+ wrap(seriesTypes.column.prototype, 'translate', function(proceed) {
1499
+ proceed.apply(this, [].slice.call(arguments, 1));
1285
1500
 
1286
- var stack = seriesOptions.stacking ? (seriesOptions.stack || 0) : series._i;
1287
- var z = stack * (depth + (seriesOptions.groupZPadding || 1));
1501
+ // Do not do this if the chart is not 3D
1502
+ if (!this.chart.is3d()) {
1503
+ return;
1504
+ }
1288
1505
 
1289
- if (seriesOptions.grouping !== false) {
1290
- z = 0;
1291
- }
1506
+ var series = this,
1507
+ chart = series.chart,
1508
+ seriesOptions = series.options,
1509
+ depth = seriesOptions.depth || 25;
1292
1510
 
1293
- z += (seriesOptions.groupZPadding || 1);
1511
+ var stack = seriesOptions.stacking ? (seriesOptions.stack || 0) : series._i;
1512
+ var z = stack * (depth + (seriesOptions.groupZPadding || 1));
1294
1513
 
1295
- Highcharts.each(series.data, function (point) {
1296
- if (point.y !== null) {
1297
- var shapeArgs = point.shapeArgs,
1298
- tooltipPos = point.tooltipPos;
1514
+ if (seriesOptions.grouping !== false) {
1515
+ z = 0;
1516
+ }
1299
1517
 
1300
- point.shapeType = 'cuboid';
1301
- shapeArgs.z = z;
1302
- shapeArgs.depth = depth;
1303
- shapeArgs.insidePlotArea = true;
1518
+ z += (seriesOptions.groupZPadding || 1);
1304
1519
 
1305
- // Translate the tooltip position in 3d space
1306
- tooltipPos = perspective([{ x: tooltipPos[0], y: tooltipPos[1], z: z }], chart, true)[0];
1307
- point.tooltipPos = [tooltipPos.x, tooltipPos.y];
1308
- }
1520
+ each(series.data, function(point) {
1521
+ if (point.y !== null) {
1522
+ var shapeArgs = point.shapeArgs,
1523
+ tooltipPos = point.tooltipPos;
1524
+
1525
+ point.shapeType = 'cuboid';
1526
+ shapeArgs.z = z;
1527
+ shapeArgs.depth = depth;
1528
+ shapeArgs.insidePlotArea = true;
1529
+
1530
+ // Translate the tooltip position in 3d space
1531
+ tooltipPos = perspective([{
1532
+ x: tooltipPos[0],
1533
+ y: tooltipPos[1],
1534
+ z: z
1535
+ }], chart, true)[0];
1536
+ point.tooltipPos = [tooltipPos.x, tooltipPos.y];
1537
+ }
1538
+ });
1539
+ // store for later use #4067
1540
+ series.z = z;
1309
1541
  });
1310
- // store for later use #4067
1311
- series.z = z;
1312
- });
1313
1542
 
1314
- Highcharts.wrap(Highcharts.seriesTypes.column.prototype, 'animate', function (proceed) {
1315
- if (!this.chart.is3d()) {
1316
- proceed.apply(this, [].slice.call(arguments, 1));
1317
- } else {
1318
- var args = arguments,
1319
- init = args[1],
1320
- yAxis = this.yAxis,
1321
- series = this,
1322
- reversed = this.yAxis.reversed;
1323
-
1324
- if (Highcharts.svg) { // VML is too slow anyway
1325
- if (init) {
1326
- Highcharts.each(series.data, function (point) {
1327
- if (point.y !== null) {
1328
- point.height = point.shapeArgs.height;
1329
- point.shapey = point.shapeArgs.y; //#2968
1330
- point.shapeArgs.height = 1;
1331
- if (!reversed) {
1332
- if (point.stackY) {
1333
- point.shapeArgs.y = point.plotY + yAxis.translate(point.stackY);
1334
- } else {
1335
- point.shapeArgs.y = point.plotY + (point.negative ? -point.height : point.height);
1543
+ wrap(seriesTypes.column.prototype, 'animate', function(proceed) {
1544
+ if (!this.chart.is3d()) {
1545
+ proceed.apply(this, [].slice.call(arguments, 1));
1546
+ } else {
1547
+ var args = arguments,
1548
+ init = args[1],
1549
+ yAxis = this.yAxis,
1550
+ series = this,
1551
+ reversed = this.yAxis.reversed;
1552
+
1553
+ if (svg) { // VML is too slow anyway
1554
+ if (init) {
1555
+ each(series.data, function(point) {
1556
+ if (point.y !== null) {
1557
+ point.height = point.shapeArgs.height;
1558
+ point.shapey = point.shapeArgs.y; //#2968
1559
+ point.shapeArgs.height = 1;
1560
+ if (!reversed) {
1561
+ if (point.stackY) {
1562
+ point.shapeArgs.y = point.plotY + yAxis.translate(point.stackY);
1563
+ } else {
1564
+ point.shapeArgs.y = point.plotY + (point.negative ? -point.height : point.height);
1565
+ }
1336
1566
  }
1337
1567
  }
1338
- }
1339
- });
1340
-
1341
- } else { // run the animation
1342
- Highcharts.each(series.data, function (point) {
1343
- if (point.y !== null) {
1344
- point.shapeArgs.height = point.height;
1345
- point.shapeArgs.y = point.shapey; //#2968
1346
- // null value do not have a graphic
1347
- if (point.graphic) {
1348
- point.graphic.animate(point.shapeArgs, series.options.animation);
1568
+ });
1569
+
1570
+ } else { // run the animation
1571
+ each(series.data, function(point) {
1572
+ if (point.y !== null) {
1573
+ point.shapeArgs.height = point.height;
1574
+ point.shapeArgs.y = point.shapey; //#2968
1575
+ // null value do not have a graphic
1576
+ if (point.graphic) {
1577
+ point.graphic.animate(point.shapeArgs, series.options.animation);
1578
+ }
1349
1579
  }
1350
- }
1351
- });
1580
+ });
1352
1581
 
1353
- // redraw datalabels to the correct position
1354
- this.drawDataLabels();
1582
+ // redraw datalabels to the correct position
1583
+ this.drawDataLabels();
1355
1584
 
1356
- // delete this function to allow it only once
1357
- series.animate = null;
1585
+ // delete this function to allow it only once
1586
+ series.animate = null;
1587
+ }
1358
1588
  }
1359
1589
  }
1360
- }
1361
- });
1590
+ });
1362
1591
 
1363
- Highcharts.wrap(Highcharts.seriesTypes.column.prototype, 'init', function (proceed) {
1364
- proceed.apply(this, [].slice.call(arguments, 1));
1592
+ wrap(seriesTypes.column.prototype, 'init', function(proceed) {
1593
+ proceed.apply(this, [].slice.call(arguments, 1));
1365
1594
 
1366
- if (this.chart.is3d()) {
1367
- var seriesOptions = this.options,
1368
- grouping = seriesOptions.grouping,
1369
- stacking = seriesOptions.stacking,
1370
- reversedStacks = pick(this.yAxis.options.reversedStacks, true),
1371
- z = 0;
1372
-
1373
- if (!(grouping !== undefined && !grouping)) {
1374
- var stacks = this.chart.retrieveStacks(stacking),
1375
- stack = seriesOptions.stack || 0,
1376
- i; // position within the stack
1377
- for (i = 0; i < stacks[stack].series.length; i++) {
1378
- if (stacks[stack].series[i] === this) {
1379
- break;
1595
+ if (this.chart.is3d()) {
1596
+ var seriesOptions = this.options,
1597
+ grouping = seriesOptions.grouping,
1598
+ stacking = seriesOptions.stacking,
1599
+ reversedStacks = pick(this.yAxis.options.reversedStacks, true),
1600
+ z = 0;
1601
+
1602
+ if (!(grouping !== undefined && !grouping)) {
1603
+ var stacks = this.chart.retrieveStacks(stacking),
1604
+ stack = seriesOptions.stack || 0,
1605
+ i; // position within the stack
1606
+ for (i = 0; i < stacks[stack].series.length; i++) {
1607
+ if (stacks[stack].series[i] === this) {
1608
+ break;
1609
+ }
1380
1610
  }
1381
- }
1382
- z = (10 * (stacks.totalStacks - stacks[stack].position)) + (reversedStacks ? i : -i); // #4369
1611
+ z = (10 * (stacks.totalStacks - stacks[stack].position)) + (reversedStacks ? i : -i); // #4369
1383
1612
 
1384
- // In case when axis is reversed, columns are also reversed inside the group (#3737)
1385
- if (!this.xAxis.reversed) {
1386
- z = (stacks.totalStacks * 10) - z;
1613
+ // In case when axis is reversed, columns are also reversed inside the group (#3737)
1614
+ if (!this.xAxis.reversed) {
1615
+ z = (stacks.totalStacks * 10) - z;
1616
+ }
1387
1617
  }
1388
- }
1389
1618
 
1390
- seriesOptions.zIndex = z;
1391
- }
1392
- });
1393
- function draw3DPoints(proceed) {
1394
- // Do not do this if the chart is not 3D
1395
- if (this.chart.is3d()) {
1396
- var grouping = this.chart.options.plotOptions.column.grouping;
1397
- if (grouping !== undefined && !grouping && this.group.zIndex !== undefined && !this.zIndexSet) {
1398
- this.group.attr({ zIndex: this.group.zIndex * 10 });
1399
- this.zIndexSet = true; // #4062 set zindex only once
1619
+ seriesOptions.zIndex = z;
1400
1620
  }
1621
+ });
1401
1622
 
1402
- var options = this.options,
1403
- states = this.options.states;
1404
1623
 
1405
- this.borderWidth = options.borderWidth = defined(options.edgeWidth) ? options.edgeWidth : 1; //#4055
1624
+ function pointAttribs(proceed) {
1625
+ var attr = proceed.apply(this, [].slice.call(arguments, 1));
1406
1626
 
1407
- Highcharts.each(this.data, function (point) {
1408
- if (point.y !== null) {
1409
- var pointAttr = point.pointAttr;
1627
+ if (this.chart.is3d()) {
1628
+ // Set the fill color to the fill color to provide a smooth edge
1629
+ attr.stroke = this.options.edgeColor || attr.fill;
1630
+ attr['stroke-width'] = pick(this.options.edgeWidth, 1); // #4055
1631
+ }
1410
1632
 
1411
- // Set the border color to the fill color to provide a smooth edge
1412
- this.borderColor = Highcharts.pick(options.edgeColor, pointAttr[''].fill);
1633
+ return attr;
1634
+ }
1413
1635
 
1414
- pointAttr[''].stroke = this.borderColor;
1415
- pointAttr.hover.stroke = Highcharts.pick(states.hover.edgeColor, this.borderColor);
1416
- pointAttr.select.stroke = Highcharts.pick(states.select.edgeColor, this.borderColor);
1417
- }
1418
- });
1636
+ wrap(seriesTypes.column.prototype, 'pointAttribs', pointAttribs);
1637
+ if (seriesTypes.columnrange) {
1638
+ wrap(seriesTypes.columnrange.prototype, 'pointAttribs', pointAttribs);
1419
1639
  }
1420
1640
 
1421
- proceed.apply(this, [].slice.call(arguments, 1));
1422
- }
1423
1641
 
1424
- Highcharts.wrap(Highcharts.Series.prototype, 'alignDataLabel', function (proceed) {
1642
+ function draw3DPoints(proceed) {
1643
+ // Do not do this if the chart is not 3D
1644
+ if (this.chart.is3d()) {
1645
+ var grouping = this.chart.options.plotOptions.column.grouping;
1646
+ if (grouping !== undefined && !grouping && this.group.zIndex !== undefined && !this.zIndexSet) {
1647
+ this.group.attr({
1648
+ zIndex: this.group.zIndex * 10
1649
+ });
1650
+ this.zIndexSet = true; // #4062 set zindex only once
1651
+ }
1652
+ }
1425
1653
 
1426
- // Only do this for 3D columns and columnranges
1427
- if (this.chart.is3d() && (this.type === 'column' || this.type === 'columnrange')) {
1428
- var series = this,
1429
- chart = series.chart;
1654
+ proceed.apply(this, [].slice.call(arguments, 1));
1655
+ }
1430
1656
 
1431
- var args = arguments,
1432
- alignTo = args[4];
1657
+ wrap(Series.prototype, 'alignDataLabel', function(proceed) {
1433
1658
 
1434
- var pos = ({ x: alignTo.x, y: alignTo.y, z: series.z });
1435
- pos = perspective([pos], chart, true)[0];
1436
- alignTo.x = pos.x;
1437
- alignTo.y = pos.y;
1438
- }
1659
+ // Only do this for 3D columns and columnranges
1660
+ if (this.chart.is3d() && (this.type === 'column' || this.type === 'columnrange')) {
1661
+ var series = this,
1662
+ chart = series.chart;
1439
1663
 
1440
- proceed.apply(this, [].slice.call(arguments, 1));
1441
- });
1664
+ var args = arguments,
1665
+ alignTo = args[4];
1442
1666
 
1443
- if (Highcharts.seriesTypes.columnrange) {
1444
- Highcharts.wrap(Highcharts.seriesTypes.columnrange.prototype, 'drawPoints', draw3DPoints);
1445
- }
1667
+ var pos = ({
1668
+ x: alignTo.x,
1669
+ y: alignTo.y,
1670
+ z: series.z
1671
+ });
1672
+ pos = perspective([pos], chart, true)[0];
1673
+ alignTo.x = pos.x;
1674
+ alignTo.y = pos.y;
1675
+ }
1676
+
1677
+ proceed.apply(this, [].slice.call(arguments, 1));
1678
+ });
1446
1679
 
1447
- Highcharts.wrap(Highcharts.seriesTypes.column.prototype, 'drawPoints', draw3DPoints);
1448
-
1449
- /***
1450
- EXTENSION FOR 3D CYLINDRICAL COLUMNS
1451
- Not supported
1452
- ***/
1453
- /*
1454
- var defaultOptions = Highcharts.getOptions();
1455
- defaultOptions.plotOptions.cylinder = Highcharts.merge(defaultOptions.plotOptions.column);
1456
- var CylinderSeries = Highcharts.extendClass(Highcharts.seriesTypes.column, {
1457
- type: 'cylinder'
1458
- });
1459
- Highcharts.seriesTypes.cylinder = CylinderSeries;
1460
-
1461
- Highcharts.wrap(Highcharts.seriesTypes.cylinder.prototype, 'translate', function (proceed) {
1462
- proceed.apply(this, [].slice.call(arguments, 1));
1463
-
1464
- // Do not do this if the chart is not 3D
1465
- if (!this.chart.is3d()) {
1466
- return;
1680
+ if (seriesTypes.columnrange) {
1681
+ wrap(seriesTypes.columnrange.prototype, 'drawPoints', draw3DPoints);
1467
1682
  }
1468
1683
 
1469
- var series = this,
1470
- chart = series.chart,
1471
- options = chart.options,
1472
- cylOptions = options.plotOptions.cylinder,
1473
- options3d = options.chart.options3d,
1474
- depth = cylOptions.depth || 0,
1475
- alpha = options3d.alpha;
1476
-
1477
- var z = cylOptions.stacking ? (this.options.stack || 0) * depth : series._i * depth;
1478
- z += depth / 2;
1479
-
1480
- if (cylOptions.grouping !== false) { z = 0; }
1481
-
1482
- Highcharts.each(series.data, function (point) {
1483
- var shapeArgs = point.shapeArgs;
1484
- point.shapeType = 'arc3d';
1485
- shapeArgs.x += depth / 2;
1486
- shapeArgs.z = z;
1487
- shapeArgs.start = 0;
1488
- shapeArgs.end = 2 * PI;
1489
- shapeArgs.r = depth * 0.95;
1490
- shapeArgs.innerR = 0;
1491
- shapeArgs.depth = shapeArgs.height * (1 / sin((90 - alpha) * deg2rad)) - z;
1492
- shapeArgs.alpha = 90 - alpha;
1493
- shapeArgs.beta = 0;
1684
+ wrap(seriesTypes.column.prototype, 'drawPoints', draw3DPoints);
1685
+
1686
+ /***
1687
+ EXTENSION FOR 3D CYLINDRICAL COLUMNS
1688
+ Not supported
1689
+ ***/
1690
+ /*
1691
+ var defaultOptions = H.getOptions();
1692
+ defaultOptions.plotOptions.cylinder = H.merge(defaultOptions.plotOptions.column);
1693
+ var CylinderSeries = H.extendClass(seriesTypes.column, {
1694
+ type: 'cylinder'
1494
1695
  });
1495
- });
1496
- */
1497
- /***
1498
- EXTENSION FOR 3D PIES
1499
- ***/
1500
-
1501
- Highcharts.wrap(Highcharts.seriesTypes.pie.prototype, 'translate', function (proceed) {
1502
- proceed.apply(this, [].slice.call(arguments, 1));
1503
-
1504
- // Do not do this if the chart is not 3D
1505
- if (!this.chart.is3d()) {
1506
- return;
1507
- }
1696
+ seriesTypes.cylinder = CylinderSeries;
1697
+
1698
+ wrap(seriesTypes.cylinder.prototype, 'translate', function (proceed) {
1699
+ proceed.apply(this, [].slice.call(arguments, 1));
1700
+
1701
+ // Do not do this if the chart is not 3D
1702
+ if (!this.chart.is3d()) {
1703
+ return;
1704
+ }
1705
+
1706
+ var series = this,
1707
+ chart = series.chart,
1708
+ options = chart.options,
1709
+ cylOptions = options.plotOptions.cylinder,
1710
+ options3d = options.chart.options3d,
1711
+ depth = cylOptions.depth || 0,
1712
+ alpha = chart.alpha3d;
1713
+
1714
+ var z = cylOptions.stacking ? (this.options.stack || 0) * depth : series._i * depth;
1715
+ z += depth / 2;
1716
+
1717
+ if (cylOptions.grouping !== false) { z = 0; }
1718
+
1719
+ each(series.data, function (point) {
1720
+ var shapeArgs = point.shapeArgs,
1721
+ deg2rad = H.deg2rad;
1722
+ point.shapeType = 'arc3d';
1723
+ shapeArgs.x += depth / 2;
1724
+ shapeArgs.z = z;
1725
+ shapeArgs.start = 0;
1726
+ shapeArgs.end = 2 * PI;
1727
+ shapeArgs.r = depth * 0.95;
1728
+ shapeArgs.innerR = 0;
1729
+ shapeArgs.depth = shapeArgs.height * (1 / sin((90 - alpha) * deg2rad)) - z;
1730
+ shapeArgs.alpha = 90 - alpha;
1731
+ shapeArgs.beta = 0;
1732
+ });
1733
+ });
1734
+ */
1735
+
1736
+ }(Highcharts));
1737
+ (function(H) {
1738
+ /**
1739
+ * (c) 2010-2016 Torstein Honsi
1740
+ *
1741
+ * License: www.highcharts.com/license
1742
+ */
1743
+ 'use strict';
1744
+ var deg2rad = H.deg2rad,
1745
+ each = H.each,
1746
+ pick = H.pick,
1747
+ seriesTypes = H.seriesTypes,
1748
+ svg = H.svg,
1749
+ wrap = H.wrap;
1750
+
1751
+ /***
1752
+ EXTENSION FOR 3D PIES
1753
+ ***/
1754
+
1755
+ wrap(seriesTypes.pie.prototype, 'translate', function(proceed) {
1756
+ proceed.apply(this, [].slice.call(arguments, 1));
1508
1757
 
1509
- var series = this,
1510
- chart = series.chart,
1511
- options = chart.options,
1512
- seriesOptions = series.options,
1513
- depth = seriesOptions.depth || 0,
1514
- options3d = options.chart.options3d,
1515
- alpha = options3d.alpha,
1516
- beta = options3d.beta,
1517
- z = seriesOptions.stacking ? (seriesOptions.stack || 0) * depth : series._i * depth;
1758
+ // Do not do this if the chart is not 3D
1759
+ if (!this.chart.is3d()) {
1760
+ return;
1761
+ }
1762
+
1763
+ var series = this,
1764
+ seriesOptions = series.options,
1765
+ depth = seriesOptions.depth || 0,
1766
+ options3d = series.chart.options.chart.options3d,
1767
+ alpha = options3d.alpha,
1768
+ beta = options3d.beta,
1769
+ z = seriesOptions.stacking ? (seriesOptions.stack || 0) * depth : series._i * depth;
1518
1770
 
1519
- z += depth / 2;
1771
+ z += depth / 2;
1520
1772
 
1521
- if (seriesOptions.grouping !== false) {
1522
- z = 0;
1523
- }
1773
+ if (seriesOptions.grouping !== false) {
1774
+ z = 0;
1775
+ }
1524
1776
 
1525
- each(series.data, function (point) {
1777
+ each(series.data, function(point) {
1526
1778
 
1527
- var shapeArgs = point.shapeArgs,
1528
- angle;
1779
+ var shapeArgs = point.shapeArgs,
1780
+ angle;
1529
1781
 
1530
- point.shapeType = 'arc3d';
1782
+ point.shapeType = 'arc3d';
1531
1783
 
1532
- shapeArgs.z = z;
1533
- shapeArgs.depth = depth * 0.75;
1534
- shapeArgs.alpha = alpha;
1535
- shapeArgs.beta = beta;
1536
- shapeArgs.center = series.center;
1784
+ shapeArgs.z = z;
1785
+ shapeArgs.depth = depth * 0.75;
1786
+ shapeArgs.alpha = alpha;
1787
+ shapeArgs.beta = beta;
1788
+ shapeArgs.center = series.center;
1537
1789
 
1538
- angle = (shapeArgs.end + shapeArgs.start) / 2;
1790
+ angle = (shapeArgs.end + shapeArgs.start) / 2;
1539
1791
 
1540
- point.slicedTranslation = {
1541
- translateX: round(cos(angle) * seriesOptions.slicedOffset * cos(alpha * deg2rad)),
1542
- translateY: round(sin(angle) * seriesOptions.slicedOffset * cos(alpha * deg2rad))
1543
- };
1544
- });
1545
- });
1546
-
1547
- Highcharts.wrap(Highcharts.seriesTypes.pie.prototype.pointClass.prototype, 'haloPath', function (proceed) {
1548
- var args = arguments;
1549
- return this.series.chart.is3d() ? [] : proceed.call(this, args[1]);
1550
- });
1551
-
1552
- Highcharts.wrap(Highcharts.seriesTypes.pie.prototype, 'drawPoints', function (proceed) {
1553
-
1554
- var options = this.options,
1555
- states = options.states;
1556
-
1557
- // Do not do this if the chart is not 3D
1558
- if (this.chart.is3d()) {
1559
- // Set the border color to the fill color to provide a smooth edge
1560
- this.borderWidth = options.borderWidth = options.edgeWidth || 1;
1561
- this.borderColor = options.edgeColor = Highcharts.pick(options.edgeColor, options.borderColor, undefined);
1562
-
1563
- states.hover.borderColor = Highcharts.pick(states.hover.edgeColor, this.borderColor);
1564
- states.hover.borderWidth = Highcharts.pick(states.hover.edgeWidth, this.borderWidth);
1565
- states.select.borderColor = Highcharts.pick(states.select.edgeColor, this.borderColor);
1566
- states.select.borderWidth = Highcharts.pick(states.select.edgeWidth, this.borderWidth);
1567
-
1568
- each(this.data, function (point) {
1569
- var pointAttr = point.pointAttr;
1570
- pointAttr[''].stroke = point.series.borderColor || point.color;
1571
- pointAttr['']['stroke-width'] = point.series.borderWidth;
1572
- pointAttr.hover.stroke = states.hover.borderColor;
1573
- pointAttr.hover['stroke-width'] = states.hover.borderWidth;
1574
- pointAttr.select.stroke = states.select.borderColor;
1575
- pointAttr.select['stroke-width'] = states.select.borderWidth;
1792
+ point.slicedTranslation = {
1793
+ translateX: Math.round(Math.cos(angle) * seriesOptions.slicedOffset * Math.cos(alpha * deg2rad)),
1794
+ translateY: Math.round(Math.sin(angle) * seriesOptions.slicedOffset * Math.cos(alpha * deg2rad))
1795
+ };
1576
1796
  });
1577
- }
1797
+ });
1578
1798
 
1579
- proceed.apply(this, [].slice.call(arguments, 1));
1799
+ wrap(seriesTypes.pie.prototype.pointClass.prototype, 'haloPath', function(proceed) {
1800
+ var args = arguments;
1801
+ return this.series.chart.is3d() ? [] : proceed.call(this, args[1]);
1802
+ });
1580
1803
 
1581
- if (this.chart.is3d()) {
1582
- each(this.points, function (point) {
1583
- var graphic = point.graphic;
1584
1804
 
1585
- // #4584 Check if has graphic - null points don't have it
1586
- if (graphic) {
1587
- // Hide null or 0 points (#3006, 3650)
1588
- graphic[point.y && point.visible ? 'show' : 'hide']();
1589
- }
1590
- });
1591
- }
1592
- });
1805
+ wrap(seriesTypes.pie.prototype, 'pointAttribs', function(proceed, point, state) {
1806
+ var attr = proceed.call(this, point, state),
1807
+ options = this.options;
1593
1808
 
1594
- Highcharts.wrap(Highcharts.seriesTypes.pie.prototype, 'drawDataLabels', function (proceed) {
1595
- if (this.chart.is3d()) {
1596
- var series = this,
1597
- chart = series.chart,
1598
- options3d = chart.options.chart.options3d;
1599
- each(series.data, function (point) {
1600
- var shapeArgs = point.shapeArgs,
1601
- r = shapeArgs.r,
1602
- a1 = (shapeArgs.alpha || options3d.alpha) * deg2rad, //#3240 issue with datalabels for 0 and null values
1603
- b1 = (shapeArgs.beta || options3d.beta) * deg2rad,
1604
- a2 = (shapeArgs.start + shapeArgs.end) / 2,
1605
- labelPos = point.labelPos,
1606
- labelIndexes = [0, 2, 4], // [x1, y1, x2, y2, x3, y3]
1607
- yOffset = (-r * (1 - cos(a1)) * sin(a2)), // + (sin(a2) > 0 ? sin(a1) * d : 0)
1608
- xOffset = r * (cos(b1) - 1) * cos(a2);
1609
-
1610
- // Apply perspective on label positions
1611
- each(labelIndexes, function (index) {
1612
- labelPos[index] += xOffset;
1613
- labelPos[index + 1] += yOffset;
1614
- });
1615
- });
1616
- }
1809
+ if (this.chart.is3d()) {
1810
+ attr.stroke = options.edgeColor || point.color || this.color;
1811
+ attr['stroke-width'] = pick(options.edgeWidth, 1);
1812
+ }
1617
1813
 
1618
- proceed.apply(this, [].slice.call(arguments, 1));
1619
- });
1814
+ return attr;
1815
+ });
1620
1816
 
1621
- Highcharts.wrap(Highcharts.seriesTypes.pie.prototype, 'addPoint', function (proceed) {
1622
- proceed.apply(this, [].slice.call(arguments, 1));
1623
- if (this.chart.is3d()) {
1624
- // destroy (and rebuild) everything!!!
1625
- this.update(this.userOptions, true); // #3845 pass the old options
1626
- }
1627
- });
1628
1817
 
1629
- Highcharts.wrap(Highcharts.seriesTypes.pie.prototype, 'animate', function (proceed) {
1630
- if (!this.chart.is3d()) {
1818
+ wrap(seriesTypes.pie.prototype, 'drawPoints', function(proceed) {
1631
1819
  proceed.apply(this, [].slice.call(arguments, 1));
1632
- } else {
1633
- var args = arguments,
1634
- init = args[1],
1635
- animation = this.options.animation,
1636
- attribs,
1637
- center = this.center,
1638
- group = this.group,
1639
- markerGroup = this.markerGroup;
1640
1820
 
1641
- if (Highcharts.svg) { // VML is too slow anyway
1821
+ if (this.chart.is3d()) {
1822
+ each(this.points, function(point) {
1823
+ var graphic = point.graphic;
1642
1824
 
1643
- if (animation === true) {
1644
- animation = {};
1645
- }
1646
- // Initialize the animation
1647
- if (init) {
1648
-
1649
- // Scale down the group and place it in the center
1650
- group.oldtranslateX = group.translateX;
1651
- group.oldtranslateY = group.translateY;
1652
- attribs = {
1653
- translateX: center[0],
1654
- translateY: center[1],
1655
- scaleX: 0.001, // #1499
1656
- scaleY: 0.001
1657
- };
1825
+ // #4584 Check if has graphic - null points don't have it
1826
+ if (graphic) {
1827
+ // Hide null or 0 points (#3006, 3650)
1828
+ graphic[point.y && point.visible ? 'show' : 'hide']();
1829
+ }
1830
+ });
1831
+ }
1832
+ });
1833
+
1834
+ wrap(seriesTypes.pie.prototype, 'drawDataLabels', function(proceed) {
1835
+ if (this.chart.is3d()) {
1836
+ var series = this,
1837
+ chart = series.chart,
1838
+ options3d = chart.options.chart.options3d;
1839
+ each(series.data, function(point) {
1840
+ var shapeArgs = point.shapeArgs,
1841
+ r = shapeArgs.r,
1842
+ a1 = (shapeArgs.alpha || options3d.alpha) * deg2rad, //#3240 issue with datalabels for 0 and null values
1843
+ b1 = (shapeArgs.beta || options3d.beta) * deg2rad,
1844
+ a2 = (shapeArgs.start + shapeArgs.end) / 2,
1845
+ labelPos = point.labelPos,
1846
+ labelIndexes = [0, 2, 4], // [x1, y1, x2, y2, x3, y3]
1847
+ yOffset = (-r * (1 - Math.cos(a1)) * Math.sin(a2)), // + (sin(a2) > 0 ? sin(a1) * d : 0)
1848
+ xOffset = r * (Math.cos(b1) - 1) * Math.cos(a2);
1849
+
1850
+ // Apply perspective on label positions
1851
+ each(labelIndexes, function(index) {
1852
+ labelPos[index] += xOffset;
1853
+ labelPos[index + 1] += yOffset;
1854
+ });
1855
+ });
1856
+ }
1857
+
1858
+ proceed.apply(this, [].slice.call(arguments, 1));
1859
+ });
1860
+
1861
+ wrap(seriesTypes.pie.prototype, 'addPoint', function(proceed) {
1862
+ proceed.apply(this, [].slice.call(arguments, 1));
1863
+ if (this.chart.is3d()) {
1864
+ // destroy (and rebuild) everything!!!
1865
+ this.update(this.userOptions, true); // #3845 pass the old options
1866
+ }
1867
+ });
1658
1868
 
1659
- group.attr(attribs);
1660
- if (markerGroup) {
1661
- markerGroup.attrSetters = group.attrSetters;
1662
- markerGroup.attr(attribs);
1869
+ wrap(seriesTypes.pie.prototype, 'animate', function(proceed) {
1870
+ if (!this.chart.is3d()) {
1871
+ proceed.apply(this, [].slice.call(arguments, 1));
1872
+ } else {
1873
+ var args = arguments,
1874
+ init = args[1],
1875
+ animation = this.options.animation,
1876
+ attribs,
1877
+ center = this.center,
1878
+ group = this.group,
1879
+ markerGroup = this.markerGroup;
1880
+
1881
+ if (svg) { // VML is too slow anyway
1882
+
1883
+ if (animation === true) {
1884
+ animation = {};
1663
1885
  }
1886
+ // Initialize the animation
1887
+ if (init) {
1888
+
1889
+ // Scale down the group and place it in the center
1890
+ group.oldtranslateX = group.translateX;
1891
+ group.oldtranslateY = group.translateY;
1892
+ attribs = {
1893
+ translateX: center[0],
1894
+ translateY: center[1],
1895
+ scaleX: 0.001, // #1499
1896
+ scaleY: 0.001
1897
+ };
1898
+
1899
+ group.attr(attribs);
1900
+ if (markerGroup) {
1901
+ markerGroup.attrSetters = group.attrSetters;
1902
+ markerGroup.attr(attribs);
1903
+ }
1664
1904
 
1665
- // Run the animation
1666
- } else {
1667
- attribs = {
1668
- translateX: group.oldtranslateX,
1669
- translateY: group.oldtranslateY,
1670
- scaleX: 1,
1671
- scaleY: 1
1672
- };
1673
- group.animate(attribs, animation);
1905
+ // Run the animation
1906
+ } else {
1907
+ attribs = {
1908
+ translateX: group.oldtranslateX,
1909
+ translateY: group.oldtranslateY,
1910
+ scaleX: 1,
1911
+ scaleY: 1
1912
+ };
1913
+ group.animate(attribs, animation);
1914
+
1915
+ if (markerGroup) {
1916
+ markerGroup.animate(attribs, animation);
1917
+ }
1674
1918
 
1675
- if (markerGroup) {
1676
- markerGroup.animate(attribs, animation);
1919
+ // Delete this function to allow it only once
1920
+ this.animate = null;
1677
1921
  }
1678
1922
 
1679
- // Delete this function to allow it only once
1680
- this.animate = null;
1681
1923
  }
1682
-
1683
1924
  }
1684
- }
1685
- });
1686
- /***
1687
- EXTENSION FOR 3D SCATTER CHART
1688
- ***/
1925
+ });
1689
1926
 
1690
- Highcharts.wrap(Highcharts.seriesTypes.scatter.prototype, 'translate', function (proceed) {
1691
- //function translate3d(proceed) {
1692
- proceed.apply(this, [].slice.call(arguments, 1));
1927
+ }(Highcharts));
1928
+ (function(H) {
1929
+ /**
1930
+ * (c) 2010-2016 Torstein Honsi
1931
+ *
1932
+ * License: www.highcharts.com/license
1933
+ */
1934
+ 'use strict';
1935
+ var perspective = H.perspective,
1936
+ pick = H.pick,
1937
+ seriesTypes = H.seriesTypes,
1938
+ wrap = H.wrap;
1939
+
1940
+ /***
1941
+ EXTENSION FOR 3D SCATTER CHART
1942
+ ***/
1693
1943
 
1694
- if (!this.chart.is3d()) {
1695
- return;
1696
- }
1944
+ wrap(seriesTypes.scatter.prototype, 'translate', function(proceed) {
1945
+ //function translate3d(proceed) {
1946
+ proceed.apply(this, [].slice.call(arguments, 1));
1697
1947
 
1698
- var series = this,
1699
- chart = series.chart,
1700
- zAxis = Highcharts.pick(series.zAxis, chart.options.zAxis[0]),
1701
- rawPoints = [],
1702
- rawPoint,
1703
- projectedPoints,
1704
- projectedPoint,
1705
- zValue,
1706
- i;
1707
-
1708
- for (i = 0; i < series.data.length; i++) {
1709
- rawPoint = series.data[i];
1710
- zValue = zAxis.isLog && zAxis.val2lin ? zAxis.val2lin(rawPoint.z) : rawPoint.z; // #4562
1711
- rawPoint.plotZ = zAxis.translate(zValue);
1712
-
1713
- rawPoint.isInside = rawPoint.isInside ? (zValue >= zAxis.min && zValue <= zAxis.max) : false;
1714
-
1715
- rawPoints.push({
1716
- x: rawPoint.plotX,
1717
- y: rawPoint.plotY,
1718
- z: rawPoint.plotZ
1719
- });
1720
- }
1948
+ if (!this.chart.is3d()) {
1949
+ return;
1950
+ }
1951
+
1952
+ var series = this,
1953
+ chart = series.chart,
1954
+ zAxis = pick(series.zAxis, chart.options.zAxis[0]),
1955
+ rawPoints = [],
1956
+ rawPoint,
1957
+ projectedPoints,
1958
+ projectedPoint,
1959
+ zValue,
1960
+ i;
1961
+
1962
+ for (i = 0; i < series.data.length; i++) {
1963
+ rawPoint = series.data[i];
1964
+ zValue = zAxis.isLog && zAxis.val2lin ? zAxis.val2lin(rawPoint.z) : rawPoint.z; // #4562
1965
+ rawPoint.plotZ = zAxis.translate(zValue);
1966
+
1967
+ rawPoint.isInside = rawPoint.isInside ? (zValue >= zAxis.min && zValue <= zAxis.max) : false;
1968
+
1969
+ rawPoints.push({
1970
+ x: rawPoint.plotX,
1971
+ y: rawPoint.plotY,
1972
+ z: rawPoint.plotZ
1973
+ });
1974
+ }
1721
1975
 
1722
- projectedPoints = perspective(rawPoints, chart, true);
1976
+ projectedPoints = perspective(rawPoints, chart, true);
1723
1977
 
1724
- for (i = 0; i < series.data.length; i++) {
1725
- rawPoint = series.data[i];
1726
- projectedPoint = projectedPoints[i];
1978
+ for (i = 0; i < series.data.length; i++) {
1979
+ rawPoint = series.data[i];
1980
+ projectedPoint = projectedPoints[i];
1727
1981
 
1728
- rawPoint.plotXold = rawPoint.plotX;
1729
- rawPoint.plotYold = rawPoint.plotY;
1730
- rawPoint.plotZold = rawPoint.plotZ;
1982
+ rawPoint.plotXold = rawPoint.plotX;
1983
+ rawPoint.plotYold = rawPoint.plotY;
1984
+ rawPoint.plotZold = rawPoint.plotZ;
1731
1985
 
1732
- rawPoint.plotX = projectedPoint.x;
1733
- rawPoint.plotY = projectedPoint.y;
1734
- rawPoint.plotZ = projectedPoint.z;
1986
+ rawPoint.plotX = projectedPoint.x;
1987
+ rawPoint.plotY = projectedPoint.y;
1988
+ rawPoint.plotZ = projectedPoint.z;
1735
1989
 
1736
1990
 
1737
- }
1991
+ }
1738
1992
 
1739
- });
1993
+ });
1740
1994
 
1741
- Highcharts.wrap(Highcharts.seriesTypes.scatter.prototype, 'init', function (proceed, chart, options) {
1742
- if (chart.is3d()) {
1743
- // add a third coordinate
1744
- this.axisTypes = ['xAxis', 'yAxis', 'zAxis'];
1745
- this.pointArrayMap = ['x', 'y', 'z'];
1746
- this.parallelArrays = ['x', 'y', 'z'];
1995
+ wrap(seriesTypes.scatter.prototype, 'init', function(proceed, chart, options) {
1996
+ if (chart.is3d()) {
1997
+ // add a third coordinate
1998
+ this.axisTypes = ['xAxis', 'yAxis', 'zAxis'];
1999
+ this.pointArrayMap = ['x', 'y', 'z'];
2000
+ this.parallelArrays = ['x', 'y', 'z'];
1747
2001
 
1748
- // Require direct touch rather than using the k-d-tree, because the k-d-tree currently doesn't
1749
- // take the xyz coordinate system into account (#4552)
1750
- this.directTouch = true;
1751
- }
2002
+ // Require direct touch rather than using the k-d-tree, because the k-d-tree currently doesn't
2003
+ // take the xyz coordinate system into account (#4552)
2004
+ this.directTouch = true;
2005
+ }
1752
2006
 
1753
- var result = proceed.apply(this, [chart, options]);
2007
+ var result = proceed.apply(this, [chart, options]);
1754
2008
 
1755
- if (this.chart.is3d()) {
1756
- // Set a new default tooltip formatter
1757
- var default3dScatterTooltip = 'x: <b>{point.x}</b><br/>y: <b>{point.y}</b><br/>z: <b>{point.z}</b><br/>';
1758
- if (this.userOptions.tooltip) {
1759
- this.tooltipOptions.pointFormat = this.userOptions.tooltip.pointFormat || default3dScatterTooltip;
1760
- } else {
1761
- this.tooltipOptions.pointFormat = default3dScatterTooltip;
2009
+ if (this.chart.is3d()) {
2010
+ // Set a new default tooltip formatter
2011
+ var default3dScatterTooltip = 'x: <b>{point.x}</b><br/>y: <b>{point.y}</b><br/>z: <b>{point.z}</b><br/>';
2012
+ if (this.userOptions.tooltip) {
2013
+ this.tooltipOptions.pointFormat = this.userOptions.tooltip.pointFormat || default3dScatterTooltip;
2014
+ } else {
2015
+ this.tooltipOptions.pointFormat = default3dScatterTooltip;
2016
+ }
1762
2017
  }
1763
- }
1764
- return result;
1765
- });
1766
- /**
1767
- * Extension to the VML Renderer
1768
- */
1769
- if (Highcharts.VMLRenderer) {
2018
+ return result;
2019
+ });
1770
2020
 
1771
- Highcharts.setOptions({ animate: false });
2021
+ }(Highcharts));
2022
+ (function(H) {
2023
+ /**
2024
+ * (c) 2010-2016 Torstein Honsi
2025
+ *
2026
+ * License: www.highcharts.com/license
2027
+ */
2028
+ 'use strict';
1772
2029
 
1773
- Highcharts.VMLRenderer.prototype.cuboid = Highcharts.SVGRenderer.prototype.cuboid;
1774
- Highcharts.VMLRenderer.prototype.cuboidPath = Highcharts.SVGRenderer.prototype.cuboidPath;
2030
+ var Axis = H.Axis,
2031
+ SVGRenderer = H.SVGRenderer,
2032
+ VMLRenderer = H.VMLRenderer;
1775
2033
 
1776
- Highcharts.VMLRenderer.prototype.toLinePath = Highcharts.SVGRenderer.prototype.toLinePath;
2034
+ /**
2035
+ * Extension to the VML Renderer
2036
+ */
2037
+ if (VMLRenderer) {
1777
2038
 
1778
- Highcharts.VMLRenderer.prototype.createElement3D = Highcharts.SVGRenderer.prototype.createElement3D;
2039
+ H.setOptions({
2040
+ animate: false
2041
+ });
1779
2042
 
1780
- Highcharts.VMLRenderer.prototype.arc3d = function (shapeArgs) {
1781
- var result = Highcharts.SVGRenderer.prototype.arc3d.call(this, shapeArgs);
1782
- result.css({ zIndex: result.zIndex });
1783
- return result;
1784
- };
2043
+ VMLRenderer.prototype.cuboid = SVGRenderer.prototype.cuboid;
2044
+ VMLRenderer.prototype.cuboidPath = SVGRenderer.prototype.cuboidPath;
1785
2045
 
1786
- Highcharts.VMLRenderer.prototype.arc3dPath = Highcharts.SVGRenderer.prototype.arc3dPath;
2046
+ VMLRenderer.prototype.toLinePath = SVGRenderer.prototype.toLinePath;
1787
2047
 
1788
- Highcharts.wrap(Highcharts.Axis.prototype, 'render', function (proceed) {
1789
- proceed.apply(this, [].slice.call(arguments, 1));
1790
- // VML doesn't support a negative z-index
1791
- if (this.sideFrame) {
1792
- this.sideFrame.css({ zIndex: 0 });
1793
- this.sideFrame.front.attr({ fill: this.sideFrame.color });
1794
- }
1795
- if (this.bottomFrame) {
1796
- this.bottomFrame.css({ zIndex: 1 });
1797
- this.bottomFrame.front.attr({ fill: this.bottomFrame.color });
1798
- }
1799
- if (this.backFrame) {
1800
- this.backFrame.css({ zIndex: 0 });
1801
- this.backFrame.front.attr({ fill: this.backFrame.color });
1802
- }
1803
- });
2048
+ VMLRenderer.prototype.createElement3D = SVGRenderer.prototype.createElement3D;
2049
+
2050
+ VMLRenderer.prototype.arc3d = function(shapeArgs) {
2051
+ var result = SVGRenderer.prototype.arc3d.call(this, shapeArgs);
2052
+ result.css({
2053
+ zIndex: result.zIndex
2054
+ });
2055
+ return result;
2056
+ };
2057
+
2058
+ H.VMLRenderer.prototype.arc3dPath = H.SVGRenderer.prototype.arc3dPath;
2059
+
2060
+ H.wrap(Axis.prototype, 'render', function(proceed) {
2061
+ proceed.apply(this, [].slice.call(arguments, 1));
2062
+ // VML doesn't support a negative z-index
2063
+ if (this.sideFrame) {
2064
+ this.sideFrame.css({
2065
+ zIndex: 0
2066
+ });
2067
+ this.sideFrame.front.attr({
2068
+ fill: this.sideFrame.color
2069
+ });
2070
+ }
2071
+ if (this.bottomFrame) {
2072
+ this.bottomFrame.css({
2073
+ zIndex: 1
2074
+ });
2075
+ this.bottomFrame.front.attr({
2076
+ fill: this.bottomFrame.color
2077
+ });
2078
+ }
2079
+ if (this.backFrame) {
2080
+ this.backFrame.css({
2081
+ zIndex: 0
2082
+ });
2083
+ this.backFrame.front.attr({
2084
+ fill: this.backFrame.color
2085
+ });
2086
+ }
2087
+ });
2088
+
2089
+ }
1804
2090
 
1805
- }
1806
2091
 
2092
+ }(Highcharts));
1807
2093
  }));