highcharts-rails 4.1.10 → 4.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f0bbd3e24903d6c17ce946b0cddf685519ed26b8
4
- data.tar.gz: eb4fbd79cb6f2eb2a2bb71d6d0a72a7d06cf98e3
3
+ metadata.gz: 9734fc00bcd24efb69ab2624ca3102fe197ec239
4
+ data.tar.gz: 166596c4c874aa229806fb2a710fef89d51448e0
5
5
  SHA512:
6
- metadata.gz: 346f98296c52780d3e9786a5f2140f0720cbe317ac318fa22b98427f8b9bdeb8c7b7ec00a754fadb1b44f94b74fa8e515066498cd7357601229706352321bf09
7
- data.tar.gz: 7c55ec8893f3886376eae5d783ec66a82ba434266447d833715e199d0fdc694e4c0a64a3cd3e208e4ac2d81a850a126fd5f8c963e2aeb157c1acf15269739db3
6
+ metadata.gz: e14ab6d55b82b4661cd8fc9ecbbf8b4d8fa8bdcb7184a9ab287035abcc6432953176dcb13e390a7d17aff2dde9e4ba93a08c15298e8d42f7ee0cab38a3f6841c
7
+ data.tar.gz: 4402b64121cfbb659bb291d516c0a0b936f3d85f4fc09ef2b59a3d00e04104238713bcb276e4987d506a8fdb8fffb5f6eecfa063b4285b232866f5af8eb4d721
@@ -1,3 +1,20 @@
1
+ # 4.2.0 / 2016-04-09
2
+
3
+ * Updated Highcharts to 4.2.0 (2015-12-15)
4
+ * Included the Standalone Framework in Highcharts and removed the concept of adapters.
5
+ * Removed global properties in Highcharts and modules. Closes #4389.
6
+ * Added new constructor, Highcharts.chart, that allows instanciating a chart without the new keyword.
7
+ * Added an option to set the renderTo div as the first argument to the constructor, like Highcharts.chart(renderTo, options);
8
+ * Added support for fill-opacity and stroke-opacity attributes on VML renderer. Support semi-transparent fill with named colors on area series.
9
+ * Breaking change: Easing functions from jQuery UI no longer work. They will fall back to the default "swing" easing. With Highcharts 4.2, the easing function must be defined on the Math object itself.
10
+ * Breaking change: The sparkline demo has some changes in the constructor.
11
+ * Fixed #3372, tooltip for columnrange series was misplaced.
12
+ * Fixed #4667, column was left semi-opaque after drill up with the Standalone Framework.
13
+ * Fixed #4782, marker image width and height didn't apply to legend.
14
+ * Fixed #4799, wrong position of columns when setting grouping:false in charts with multiple columns.
15
+ * Fixed #4801, setting visibility by series.update() didn't update series group.
16
+ * Fixed #4811, legend checkbox position was wrong with legend title present.
17
+
1
18
  # 4.1.10 / 2016-04-09
2
19
 
3
20
  * Updated Highcharts to 4.1.10 (2015-12-07)
@@ -2,7 +2,7 @@
2
2
  // @compilation_level SIMPLE_OPTIMIZATIONS
3
3
 
4
4
  /**
5
- * @license Highcharts JS v4.1.10 (2015-12-07)
5
+ * @license Highcharts JS v4.2.0 (2105-12-15)
6
6
  *
7
7
  * (c) 2009-2014 Torstein Honsi
8
8
  *
@@ -11,18 +11,15 @@
11
11
 
12
12
  (function (root, factory) {
13
13
  if (typeof module === 'object' && module.exports) {
14
- module.exports = root.document ?
15
- factory(root) :
16
- function (w) {
17
- return factory(w);
18
- };
14
+ module.exports = root.document ?
15
+ factory(root) :
16
+ factory;
19
17
  } else {
20
- root.Highcharts = factory();
18
+ root.Highcharts = factory(root);
21
19
  }
22
- }(typeof window !== 'undefined' ? window : this, function (w) {
20
+ }(typeof window !== 'undefined' ? window : this, function (win) { // eslint-disable-line no-undef
23
21
  // encapsulated variables
24
22
  var UNDEFINED,
25
- win = w || window,
26
23
  doc = win.document,
27
24
  math = Math,
28
25
  mathRound = math.round,
@@ -38,17 +35,17 @@
38
35
 
39
36
 
40
37
  // some variables
41
- userAgent = navigator.userAgent,
38
+ userAgent = (win.navigator && win.navigator.userAgent) || '',
42
39
  isOpera = win.opera,
43
40
  isMS = /(msie|trident|edge)/i.test(userAgent) && !isOpera,
44
- docMode8 = doc.documentMode === 8,
41
+ docMode8 = doc && doc.documentMode === 8,
45
42
  isWebKit = !isMS && /AppleWebKit/.test(userAgent),
46
43
  isFirefox = /Firefox/.test(userAgent),
47
44
  isTouchDevice = /(Mobile|Android|Windows Phone)/.test(userAgent),
48
45
  SVG_NS = 'http://www.w3.org/2000/svg',
49
- hasSVG = !!doc.createElementNS && !!doc.createElementNS(SVG_NS, 'svg').createSVGRect,
46
+ hasSVG = doc && doc.createElementNS && !!doc.createElementNS(SVG_NS, 'svg').createSVGRect,
50
47
  hasBidiBug = isFirefox && parseInt(userAgent.split('Firefox/')[1], 10) < 4, // issue #38
51
- useCanVG = !hasSVG && !isMS && !!doc.createElement('canvas').getContext,
48
+ useCanVG = doc && !hasSVG && !isMS && !!doc.createElement('canvas').getContext,
52
49
  Renderer,
53
50
  hasTouch,
54
51
  symbolSizes = {},
@@ -62,7 +59,7 @@
62
59
  charts = [],
63
60
  chartCount = 0,
64
61
  PRODUCT = 'Highcharts',
65
- VERSION = '4.1.10',
62
+ VERSION = '4.2.0',
66
63
 
67
64
  // some constants for frequently used strings
68
65
  DIV = 'div',
@@ -126,12 +123,248 @@
126
123
  }
127
124
 
128
125
  // The Highcharts namespace
129
- Highcharts = win.Highcharts ? error(16, true) : function (adapter) {
130
- Highcharts.loadAdapter(adapter);
131
- return Highcharts;
132
- };
126
+ Highcharts = win.Highcharts ? error(16, true) : { win: win };
133
127
 
134
128
  Highcharts.seriesTypes = seriesTypes;
129
+ var timers = [],
130
+ getStyle,
131
+
132
+ // Previous adapter functions
133
+ inArray,
134
+ each,
135
+ grep,
136
+ offset,
137
+ map,
138
+ addEvent,
139
+ removeEvent,
140
+ fireEvent,
141
+ animate,
142
+ stop;
143
+
144
+ /**
145
+ * An animator object. One instance applies to one property (attribute or style prop)
146
+ * on one element.
147
+ *
148
+ * @param {object} elem The element to animate. May be a DOM element or a Highcharts SVGElement wrapper.
149
+ * @param {object} options Animation options, including duration, easing, step and complete.
150
+ * @param {object} prop The property to animate.
151
+ */
152
+ function Fx(elem, options, prop) {
153
+ this.options = options;
154
+ this.elem = elem;
155
+ this.prop = prop;
156
+ }
157
+ Fx.prototype = {
158
+
159
+ /**
160
+ * Animating a path definition on SVGElement
161
+ * @returns {undefined}
162
+ */
163
+ dSetter: function () {
164
+ var start = this.paths[0],
165
+ end = this.paths[1],
166
+ ret = [],
167
+ now = this.now,
168
+ i = start.length,
169
+ startVal;
170
+
171
+ if (now === 1) { // land on the final path without adjustment points appended in the ends
172
+ ret = this.toD;
173
+
174
+ } else if (i === end.length && now < 1) {
175
+ while (i--) {
176
+ startVal = parseFloat(start[i]);
177
+ ret[i] =
178
+ isNaN(startVal) ? // a letter instruction like M or L
179
+ start[i] :
180
+ now * (parseFloat(end[i] - startVal)) + startVal;
181
+
182
+ }
183
+ } else { // if animation is finished or length not matching, land on right value
184
+ ret = end;
185
+ }
186
+ this.elem.attr('d', ret);
187
+ },
188
+
189
+ /**
190
+ * Update the element with the current animation step
191
+ * @returns {undefined}
192
+ */
193
+ update: function () {
194
+ var elem = this.elem,
195
+ prop = this.prop, // if destroyed, it is null
196
+ now = this.now,
197
+ step = this.options.step;
198
+
199
+ // Animation setter defined from outside
200
+ if (this[prop + 'Setter']) {
201
+ this[prop + 'Setter']();
202
+
203
+ // Other animations on SVGElement
204
+ } else if (elem.attr) {
205
+ if (elem.element) {
206
+ elem.attr(prop, now);
207
+ }
208
+
209
+ // HTML styles, raw HTML content like container size
210
+ } else {
211
+ elem.style[prop] = now + this.unit;
212
+ }
213
+
214
+ if (step) {
215
+ step.call(elem, now, this);
216
+ }
217
+
218
+ },
219
+
220
+ /**
221
+ * Run an animation
222
+ */
223
+ run: function (from, to, unit) {
224
+ var self = this,
225
+ timer = function (gotoEnd) {
226
+ return timer.stopped ? false : self.step(gotoEnd);
227
+ },
228
+ i;
229
+
230
+ this.startTime = +new Date();
231
+ this.start = from;
232
+ this.end = to;
233
+ this.unit = unit;
234
+ this.now = this.start;
235
+ this.pos = 0;
236
+
237
+ timer.elem = this.elem;
238
+
239
+ if (timer() && timers.push(timer) === 1) {
240
+ timer.timerId = setInterval(function () {
241
+
242
+ for (i = 0; i < timers.length; i++) {
243
+ if (!timers[i]()) {
244
+ timers.splice(i--, 1);
245
+ }
246
+ }
247
+
248
+ if (!timers.length) {
249
+ clearInterval(timer.timerId);
250
+ }
251
+ }, 13);
252
+ }
253
+ },
254
+
255
+ /**
256
+ * Run a single step in the animation
257
+ * @param {Boolean} gotoEnd Whether to go to then endpoint of the animation after abort
258
+ * @returns {Boolean} True if animation continues
259
+ */
260
+ step: function (gotoEnd) {
261
+ var t = +new Date(),
262
+ ret,
263
+ done,
264
+ options = this.options,
265
+ elem = this.elem,
266
+ complete = options.complete,
267
+ duration = options.duration,
268
+ curAnim = options.curAnim,
269
+ i;
270
+
271
+ if (elem.attr && !elem.element) { // #2616, element including flag is destroyed
272
+ ret = false;
273
+
274
+ } else if (gotoEnd || t >= duration + this.startTime) {
275
+ this.now = this.end;
276
+ this.pos = 1;
277
+ this.update();
278
+
279
+ curAnim[this.prop] = true;
280
+
281
+ done = true;
282
+ for (i in curAnim) {
283
+ if (curAnim[i] !== true) {
284
+ done = false;
285
+ }
286
+ }
287
+
288
+ if (done && complete) {
289
+ complete.call(elem);
290
+ }
291
+ ret = false;
292
+
293
+ } else {
294
+ this.pos = options.easing((t - this.startTime) / duration);
295
+ this.now = this.start + ((this.end - this.start) * this.pos);
296
+ this.update();
297
+ ret = true;
298
+ }
299
+ return ret;
300
+ },
301
+
302
+ /**
303
+ * Prepare start and end values so that the path can be animated one to one
304
+ */
305
+ initPath: function (elem, fromD, toD) {
306
+ fromD = fromD || '';
307
+ var shift = elem.shift,
308
+ bezier = fromD.indexOf('C') > -1,
309
+ numParams = bezier ? 7 : 3,
310
+ endLength,
311
+ slice,
312
+ i,
313
+ start = fromD.split(' '),
314
+ end = [].concat(toD), // copy
315
+ startBaseLine,
316
+ endBaseLine,
317
+ sixify = function (arr) { // in splines make move points have six parameters like bezier curves
318
+ i = arr.length;
319
+ while (i--) {
320
+ if (arr[i] === M) {
321
+ arr.splice(i + 1, 0, arr[i + 1], arr[i + 2], arr[i + 1], arr[i + 2]);
322
+ }
323
+ }
324
+ };
325
+
326
+ if (bezier) {
327
+ sixify(start);
328
+ sixify(end);
329
+ }
330
+
331
+ // pull out the base lines before padding
332
+ if (elem.isArea) {
333
+ startBaseLine = start.splice(start.length - 6, 6);
334
+ endBaseLine = end.splice(end.length - 6, 6);
335
+ }
336
+
337
+ // if shifting points, prepend a dummy point to the end path
338
+ if (shift <= end.length / numParams && start.length === end.length) {
339
+ while (shift--) {
340
+ end = [].concat(end).splice(0, numParams).concat(end);
341
+ }
342
+ }
343
+ elem.shift = 0; // reset for following animations
344
+
345
+ // copy and append last point until the length matches the end length
346
+ if (start.length) {
347
+ endLength = end.length;
348
+ while (start.length < endLength) {
349
+
350
+ //bezier && sixify(start);
351
+ slice = [].concat(start).splice(start.length - numParams, numParams);
352
+ if (bezier) { // disable first control point
353
+ slice[numParams - 6] = slice[numParams - 2];
354
+ slice[numParams - 5] = slice[numParams - 1];
355
+ }
356
+ start = start.concat(slice);
357
+ }
358
+ }
359
+
360
+ if (startBaseLine) { // append the base lines for areas
361
+ start = start.concat(startBaseLine);
362
+ end = end.concat(endBaseLine);
363
+ }
364
+ return [start, end];
365
+ }
366
+ }; // End of Fx prototype
367
+
135
368
 
136
369
  /**
137
370
  * Extend an object with the members of another
@@ -267,7 +500,7 @@
267
500
  }
268
501
 
269
502
  /**
270
- * Returns true if the object is not null or undefined. Like MooTools' $.defined.
503
+ * Returns true if the object is not null or undefined.
271
504
  * @param {Object} obj
272
505
  */
273
506
  function defined(obj) {
@@ -306,8 +539,7 @@
306
539
  return ret;
307
540
  }
308
541
  /**
309
- * Check if an element is an array, and if not, make it into an array. Like
310
- * MooTools' $.splat.
542
+ * Check if an element is an array, and if not, make it into an array.
311
543
  */
312
544
  function splat(obj) {
313
545
  return isArray(obj) ? obj : [obj];
@@ -329,7 +561,7 @@
329
561
 
330
562
 
331
563
  /**
332
- * Return the first value that is defined. Like MooTools' $.pick.
564
+ * Return the first value that is defined.
333
565
  */
334
566
  var pick = Highcharts.pick = function () {
335
567
  var args = arguments,
@@ -788,508 +1020,443 @@
788
1020
  return (s + (j ? i.substr(0, j) + t : '') + i.substr(j).replace(/(\d{3})(?=\d)/g, '$1' + t) +
789
1021
  (c ? d + mathAbs(n - i).toFixed(c).slice(2) : ''));
790
1022
  };
1023
+
791
1024
  /**
792
- * Path interpolation algorithm used across adapters
1025
+ * Easing definition
1026
+ * @param {Number} pos Current position, ranging from 0 to 1
793
1027
  */
794
- pathAnim = {
795
- /**
796
- * Prepare start and end values so that the path can be animated one to one
797
- */
798
- init: function (elem, fromD, toD) {
799
- fromD = fromD || '';
800
- var shift = elem.shift,
801
- bezier = fromD.indexOf('C') > -1,
802
- numParams = bezier ? 7 : 3,
803
- endLength,
804
- slice,
805
- i,
806
- start = fromD.split(' '),
807
- end = [].concat(toD), // copy
808
- startBaseLine,
809
- endBaseLine,
810
- sixify = function (arr) { // in splines make move points have six parameters like bezier curves
811
- i = arr.length;
812
- while (i--) {
813
- if (arr[i] === M) {
814
- arr.splice(i + 1, 0, arr[i + 1], arr[i + 2], arr[i + 1], arr[i + 2]);
815
- }
816
- }
817
- };
1028
+ Math.easeInOutSine = function (pos) {
1029
+ return -0.5 * (Math.cos(Math.PI * pos) - 1);
1030
+ };
818
1031
 
819
- if (bezier) {
820
- sixify(start);
821
- sixify(end);
822
- }
1032
+ /**
1033
+ * Internal method to return CSS value for given element and property
1034
+ */
1035
+ getStyle = function (el, prop) {
1036
+ var style = win.getComputedStyle(el, undefined);
1037
+ return style && pInt(style.getPropertyValue(prop));
1038
+ };
823
1039
 
824
- // pull out the base lines before padding
825
- if (elem.isArea) {
826
- startBaseLine = start.splice(start.length - 6, 6);
827
- endBaseLine = end.splice(end.length - 6, 6);
828
- }
1040
+ /**
1041
+ * Return the index of an item in an array, or -1 if not found
1042
+ */
1043
+ inArray = function (item, arr) {
1044
+ return arr.indexOf ? arr.indexOf(item) : [].indexOf.call(arr, item);
1045
+ };
829
1046
 
830
- // if shifting points, prepend a dummy point to the end path
831
- if (shift <= end.length / numParams && start.length === end.length) {
832
- while (shift--) {
833
- end = [].concat(end).splice(0, numParams).concat(end);
834
- }
835
- }
836
- elem.shift = 0; // reset for following animations
1047
+ /**
1048
+ * Filter an array
1049
+ */
1050
+ grep = function (elements, callback) {
1051
+ return [].filter.call(elements, callback);
1052
+ };
837
1053
 
838
- // copy and append last point until the length matches the end length
839
- if (start.length) {
840
- endLength = end.length;
841
- while (start.length < endLength) {
1054
+ /**
1055
+ * Map an array
1056
+ */
1057
+ map = function (arr, fn) {
1058
+ var results = [], i = 0, len = arr.length;
842
1059
 
843
- //bezier && sixify(start);
844
- slice = [].concat(start).splice(start.length - numParams, numParams);
845
- if (bezier) { // disable first control point
846
- slice[numParams - 6] = slice[numParams - 2];
847
- slice[numParams - 5] = slice[numParams - 1];
848
- }
849
- start = start.concat(slice);
850
- }
851
- }
1060
+ for (; i < len; i++) {
1061
+ results[i] = fn.call(arr[i], arr[i], i, arr);
1062
+ }
852
1063
 
853
- if (startBaseLine) { // append the base lines for areas
854
- start = start.concat(startBaseLine);
855
- end = end.concat(endBaseLine);
856
- }
857
- return [start, end];
858
- },
1064
+ return results;
1065
+ };
859
1066
 
860
- /**
861
- * Interpolate each value of the path and return the array
862
- */
863
- step: function (start, end, pos, complete) {
864
- var ret = [],
865
- i = start.length,
866
- startVal;
1067
+ /**
1068
+ * Get the element's offset position, corrected by overflow:auto.
1069
+ */
1070
+ offset = function (el) {
1071
+ var docElem = doc.documentElement,
1072
+ box = el.getBoundingClientRect();
867
1073
 
868
- if (pos === 1) { // land on the final path without adjustment points appended in the ends
869
- ret = complete;
1074
+ return {
1075
+ top: box.top + (win.pageYOffset || docElem.scrollTop) - (docElem.clientTop || 0),
1076
+ left: box.left + (win.pageXOffset || docElem.scrollLeft) - (docElem.clientLeft || 0)
1077
+ };
1078
+ };
870
1079
 
871
- } else if (i === end.length && pos < 1) {
872
- while (i--) {
873
- startVal = parseFloat(start[i]);
874
- ret[i] =
875
- isNaN(startVal) ? // a letter instruction like M or L
876
- start[i] :
877
- pos * (parseFloat(end[i] - startVal)) + startVal;
1080
+ /**
1081
+ * Stop running animation.
1082
+ * A possible extension to this would be to stop a single property, when
1083
+ * we want to continue animating others. Then assign the prop to the timer
1084
+ * in the Fx.run method, and check for the prop here. This would be an improvement
1085
+ * in all cases where we stop the animation from .attr. Instead of stopping
1086
+ * everything, we can just stop the actual attributes we're setting.
1087
+ */
1088
+ stop = function (el) {
878
1089
 
879
- }
880
- } else { // if animation is finished or length not matching, land on right value
881
- ret = end;
1090
+ var i = timers.length;
1091
+
1092
+ // Remove timers related to this element (#4519)
1093
+ while (i--) {
1094
+ if (timers[i].elem === el) {
1095
+ timers[i].stopped = true; // #4667
882
1096
  }
883
- return ret;
884
1097
  }
885
1098
  };
886
1099
 
887
- function loadJQueryAdapter($) {
888
- /**
889
- * The default HighchartsAdapter for jQuery
890
- */
891
- return {
1100
+ /**
1101
+ * Utility for iterating over an array.
1102
+ * @param {Array} arr
1103
+ * @param {Function} fn
1104
+ */
1105
+ each = function (arr, fn) { // modern browsers
1106
+ return Array.prototype.forEach.call(arr, fn);
1107
+ };
892
1108
 
893
- /**
894
- * Initialize the adapter by applying some extensions to jQuery
895
- */
896
- init: function (pathAnim) {
1109
+ /**
1110
+ * Add an event listener
1111
+ */
1112
+ addEvent = function (el, type, fn) {
1113
+
1114
+ var events = el.hcEvents = el.hcEvents || {};
897
1115
 
898
- // extend the animate function to allow SVG animations
899
- var Fx = $.fx;
1116
+ function wrappedFn(e) {
1117
+ e.target = e.srcElement || win; // #2820
1118
+ fn.call(el, e);
1119
+ }
900
1120
 
901
- $.extend($.easing, {
902
- easeOutQuad: function (x, t, b, c, d) {
903
- return -c * (t /= d) * (t - 2) + b;
904
- }
905
- });
1121
+ // Handle DOM events in modern browsers
1122
+ if (el.addEventListener) {
1123
+ el.addEventListener(type, fn, false);
906
1124
 
907
- // extend some methods to check for elem.attr, which means it is a Highcharts SVG object
908
- $.each(['cur', '_default', 'width', 'height', 'opacity'], function (i, fn) {
909
- var obj = Fx.step,
910
- base;
1125
+ // Handle old IE implementation
1126
+ } else if (el.attachEvent) {
911
1127
 
912
- // Handle different parent objects
913
- if (fn === 'cur') {
914
- obj = Fx.prototype; // 'cur', the getter, relates to Fx.prototype
1128
+ if (!el.hcEventsIE) {
1129
+ el.hcEventsIE = {};
1130
+ }
915
1131
 
916
- } else if (fn === '_default' && $.Tween) { // jQuery 1.8 model
917
- obj = $.Tween.propHooks[fn];
918
- fn = 'set';
919
- }
1132
+ // Link wrapped fn with original fn, so we can get this in removeEvent
1133
+ el.hcEventsIE[fn.toString()] = wrappedFn;
920
1134
 
921
- // Overwrite the method
922
- base = obj[fn];
923
- if (base) { // step.width and step.height don't exist in jQuery < 1.7
1135
+ el.attachEvent('on' + type, wrappedFn);
1136
+ }
924
1137
 
925
- // create the extended function replacement
926
- obj[fn] = function (effects) {
1138
+ if (!events[type]) {
1139
+ events[type] = [];
1140
+ }
927
1141
 
928
- var elem, fx;
1142
+ events[type].push(fn);
1143
+ };
929
1144
 
930
- // Fx.prototype.cur does not use fx argument
931
- fx = i ? effects : this;
1145
+ /**
1146
+ * Remove event added with addEvent
1147
+ */
1148
+ removeEvent = function (el, type, fn) {
1149
+
1150
+ var events,
1151
+ hcEvents = el.hcEvents,
1152
+ index;
932
1153
 
933
- // Don't run animations on textual properties like align (#1821)
934
- if (fx.prop === 'align') {
935
- return;
936
- }
1154
+ function removeOneEvent(type, fn) {
1155
+ if (el.removeEventListener) {
1156
+ el.removeEventListener(type, fn, false);
1157
+ } else if (el.attachEvent) {
1158
+ fn = el.hcEventsIE[fn.toString()];
1159
+ el.detachEvent('on' + type, fn);
1160
+ }
1161
+ }
937
1162
 
938
- // shortcut
939
- elem = fx.elem;
1163
+ function removeAllEvents() {
1164
+ var types,
1165
+ len,
1166
+ n;
940
1167
 
941
- // Fx.prototype.cur returns the current value. The other ones are setters
942
- // and returning a value has no effect.
943
- if (elem.attr) { // is SVG element wrapper
944
- return elem.attr(
945
- fx.prop.replace('strokeWidth', 'stroke-width'), // #4721
946
- fn === 'cur' ? undefined : fx.now
947
- );
948
- }
1168
+ if (!el.nodeName) {
1169
+ return; // break on non-DOM events
1170
+ }
949
1171
 
950
- return base.apply(this, arguments); // use jQuery's built-in method
951
- };
952
- }
953
- });
1172
+ if (type) {
1173
+ types = {};
1174
+ types[type] = true;
1175
+ } else {
1176
+ types = hcEvents;
1177
+ }
954
1178
 
955
- // Extend the opacity getter, needed for fading opacity with IE9 and jQuery 1.10+
956
- wrap($.cssHooks.opacity, 'get', function (proceed, elem, computed) {
957
- return elem.attr ? (elem.opacity || 0) : proceed.call(this, elem, computed);
958
- });
1179
+ for (n in types) {
1180
+ if (hcEvents[n]) {
1181
+ len = hcEvents[n].length;
1182
+ while (len--) {
1183
+ removeOneEvent(n, hcEvents[n][len]);
1184
+ }
1185
+ }
1186
+ }
1187
+ }
959
1188
 
960
- // Define the setter function for d (path definitions)
961
- this.addAnimSetter('d', function (fx) {
962
- var elem = fx.elem,
963
- ends;
964
-
965
- // Normally start and end should be set in state == 0, but sometimes,
966
- // for reasons unknown, this doesn't happen. Perhaps state == 0 is skipped
967
- // in these cases
968
- if (!fx.started) {
969
- ends = pathAnim.init(elem, elem.d, elem.toD);
970
- fx.start = ends[0];
971
- fx.end = ends[1];
972
- fx.started = true;
1189
+ if (hcEvents) {
1190
+ if (type) {
1191
+ events = hcEvents[type] || [];
1192
+ if (fn) {
1193
+ index = inArray(fn, events);
1194
+ if (index > -1) {
1195
+ events.splice(index, 1);
1196
+ hcEvents[type] = events;
973
1197
  }
1198
+ removeOneEvent(type, fn);
974
1199
 
975
- // Interpolate each value of the path
976
- elem.attr('d', pathAnim.step(fx.start, fx.end, fx.pos, elem.toD));
977
- });
1200
+ } else {
1201
+ removeAllEvents();
1202
+ hcEvents[type] = [];
1203
+ }
1204
+ } else {
1205
+ removeAllEvents();
1206
+ el.hcEvents = {};
1207
+ }
1208
+ }
1209
+ };
978
1210
 
979
- /**
980
- * Utility for iterating over an array. Parameters are reversed compared to jQuery.
981
- * @param {Array} arr
982
- * @param {Function} fn
983
- */
984
- this.each = Array.prototype.forEach ?
985
- function each(arr, fn) { // modern browsers
986
- return Array.prototype.forEach.call(arr, fn);
987
-
988
- } :
989
- function each(arr, fn) { // legacy
990
- var i,
991
- len = arr.length;
992
- for (i = 0; i < len; i++) {
993
- if (fn.call(arr[i], arr[i], i, arr) === false) {
994
- return i;
995
- }
996
- }
997
- };
1211
+ /**
1212
+ * Fire an event on a custom object
1213
+ */
1214
+ fireEvent = function (el, type, eventArguments, defaultFunction) {
1215
+ var e,
1216
+ hcEvents = el.hcEvents,
1217
+ events,
1218
+ len,
1219
+ i,
1220
+ preventDefault,
1221
+ fn;
998
1222
 
999
- /**
1000
- * Register Highcharts as a plugin in the respective framework
1001
- */
1002
- $.fn.highcharts = function () {
1003
- var constr = 'Chart', // default constructor
1004
- args = arguments,
1005
- options,
1006
- ret;
1223
+ eventArguments = eventArguments || {};
1007
1224
 
1008
- if (this[0]) {
1225
+ if (doc.createEvent && (el.dispatchEvent || el.fireEvent)) {
1226
+ e = doc.createEvent('Events');
1227
+ e.initEvent(type, true, true);
1228
+ e.target = el;
1009
1229
 
1010
- if (isString(args[0])) {
1011
- constr = args[0];
1012
- args = Array.prototype.slice.call(args, 1);
1013
- }
1014
- options = args[0];
1015
-
1016
- // Create the chart
1017
- if (options !== UNDEFINED) {
1018
- options.chart = options.chart || {};
1019
- options.chart.renderTo = this[0];
1020
- ret = new Highcharts[constr](options, args[1]);
1021
- ret = this;
1022
- }
1230
+ extend(e, eventArguments);
1023
1231
 
1024
- // When called without parameters or with the return argument, get a predefined chart
1025
- if (options === UNDEFINED) {
1026
- ret = charts[attr(this[0], 'data-highcharts-chart')];
1027
- }
1028
- }
1232
+ if (el.dispatchEvent) {
1233
+ el.dispatchEvent(e);
1234
+ } else {
1235
+ el.fireEvent(type, e);
1236
+ }
1029
1237
 
1030
- return ret;
1031
- };
1238
+ } else if (hcEvents) {
1239
+
1240
+ events = hcEvents[type] || [];
1241
+ len = events.length;
1032
1242
 
1033
- },
1243
+ // Attach a simple preventDefault function to skip default handler if called
1244
+ preventDefault = function () {
1245
+ eventArguments.defaultPrevented = true;
1246
+ };
1247
+
1248
+ for (i = 0; i < len; i++) {
1249
+ fn = events[i];
1034
1250
 
1035
- /**
1036
- * Add an animation setter for a specific property
1037
- */
1038
- addAnimSetter: function (prop, setter) {
1039
- // jQuery 1.8 style
1040
- if ($.Tween) {
1041
- $.Tween.propHooks[prop] = {
1042
- set: setter
1043
- };
1044
- // pre 1.8
1045
- } else {
1046
- $.fx.step[prop] = setter;
1251
+ // eventArguments is never null here
1252
+ if (eventArguments.stopped) {
1253
+ return;
1047
1254
  }
1048
- },
1049
1255
 
1050
- /**
1051
- * Downloads a script and executes a callback when done.
1052
- * @param {String} scriptLocation
1053
- * @param {Function} callback
1054
- */
1055
- getScript: $.getScript,
1256
+ eventArguments.preventDefault = preventDefault;
1257
+ eventArguments.target = el;
1056
1258
 
1057
- /**
1058
- * Return the index of an item in an array, or -1 if not found
1059
- */
1060
- inArray: $.inArray,
1061
-
1062
- /**
1063
- * A direct link to jQuery methods. MooTools and Prototype adapters must be implemented for each case of method.
1064
- * @param {Object} elem The HTML element
1065
- * @param {String} method Which method to run on the wrapped element
1066
- */
1067
- adapterRun: function (elem, method) {
1068
- return $(elem)[method]();
1069
- },
1259
+ // If the type is not set, we're running a custom event (#2297). If it is set,
1260
+ // we're running a browser event, and setting it will cause en error in
1261
+ // IE8 (#2465).
1262
+ if (!eventArguments.type) {
1263
+ eventArguments.type = type;
1264
+ }
1265
+
1266
+ // If the event handler return false, prevent the default handler from executing
1267
+ if (fn.call(el, eventArguments) === false) {
1268
+ eventArguments.preventDefault();
1269
+ }
1270
+ }
1271
+ }
1070
1272
 
1071
- /**
1072
- * Filter an array
1073
- */
1074
- grep: $.grep,
1273
+ // Run the default if not prevented
1274
+ if (defaultFunction && !eventArguments.defaultPrevented) {
1275
+ defaultFunction(eventArguments);
1276
+ }
1277
+ };
1075
1278
 
1076
- /**
1077
- * Map an array
1078
- * @param {Array} arr
1079
- * @param {Function} fn
1080
- */
1081
- map: function (arr, fn) {
1082
- //return jQuery.map(arr, fn);
1083
- var results = [],
1084
- i,
1085
- len = arr.length;
1086
- for (i = 0; i < len; i++) {
1087
- results[i] = fn.call(arr[i], arr[i], i, arr);
1279
+ /**
1280
+ * The global animate method, which uses Fx to create individual animators.
1281
+ */
1282
+ animate = function (el, params, opt) {
1283
+ var start,
1284
+ unit = '',
1285
+ end,
1286
+ fx,
1287
+ args,
1288
+ prop;
1289
+
1290
+ if (!isObject(opt)) { // Number or undefined/null
1291
+ args = arguments;
1292
+ opt = {
1293
+ duration: args[2],
1294
+ easing: args[3],
1295
+ complete: args[4]
1296
+ };
1297
+ }
1298
+ if (!isNumber(opt.duration)) {
1299
+ opt.duration = 400;
1300
+ }
1301
+ opt.easing = Math[opt.easing] || Math.easeInOutSine;
1302
+ opt.curAnim = merge(params);
1303
+
1304
+ for (prop in params) {
1305
+ fx = new Fx(el, opt, prop);
1306
+ end = null;
1307
+
1308
+ if (prop === 'd') {
1309
+ fx.paths = fx.initPath(
1310
+ el,
1311
+ el.d,
1312
+ params.d
1313
+ );
1314
+ fx.toD = params.d;
1315
+ start = 0;
1316
+ end = 1;
1317
+ } else if (el.attr) {
1318
+ start = el.attr(prop);
1319
+ } else {
1320
+ start = parseFloat(getStyle(el, prop)) || 0;
1321
+ if (prop !== 'opacity') {
1322
+ unit = 'px';
1088
1323
  }
1089
- return results;
1324
+ }
1090
1325
 
1091
- },
1326
+ if (!end) {
1327
+ end = params[prop];
1328
+ }
1329
+ if (end.match && end.match('px')) {
1330
+ end = end.replace(/px/g, ''); // #4351
1331
+ }
1332
+ fx.run(start, end, unit);
1333
+ }
1334
+ };
1092
1335
 
1093
- /**
1094
- * Get the position of an element relative to the top left of the page
1095
- */
1096
- offset: function (el) {
1097
- return $(el).offset();
1098
- },
1336
+ /**
1337
+ * Register Highcharts as a plugin in jQuery
1338
+ */
1339
+ if (win.jQuery) {
1340
+ win.jQuery.fn.highcharts = function () {
1341
+ var args = [].slice.call(arguments);
1099
1342
 
1100
- /**
1101
- * Add an event listener
1102
- * @param {Object} el A HTML element or custom object
1103
- * @param {String} event The event type
1104
- * @param {Function} fn The event handler
1105
- */
1106
- addEvent: function (el, event, fn) {
1107
- $(el).bind(event, fn);
1108
- },
1343
+ if (this[0]) { // this[0] is the renderTo div
1109
1344
 
1110
- /**
1111
- * Remove event added with addEvent
1112
- * @param {Object} el The object
1113
- * @param {String} eventType The event type. Leave blank to remove all events.
1114
- * @param {Function} handler The function to remove
1115
- */
1116
- removeEvent: function (el, eventType, handler) {
1117
- // workaround for jQuery issue with unbinding custom events:
1118
- // http://forum.jQuery.com/topic/javascript-error-when-unbinding-a-custom-event-using-jQuery-1-4-2
1119
- var func = doc.removeEventListener ? 'removeEventListener' : 'detachEvent';
1120
- if (doc[func] && el && !el[func]) {
1121
- el[func] = function () {};
1345
+ // Create the chart
1346
+ if (args[0]) {
1347
+ new Highcharts[ // eslint-disable-line no-new
1348
+ isString(args[0]) ? args.shift() : 'Chart' // Constructor defaults to Chart
1349
+ ](this[0], args[0], args[1]);
1350
+ return this;
1122
1351
  }
1123
1352
 
1124
- $(el).unbind(eventType, handler);
1125
- },
1353
+ // When called without parameters or with the return argument, return an existing chart
1354
+ return charts[attr(this[0], 'data-highcharts-chart')];
1355
+ }
1356
+ };
1357
+ }
1126
1358
 
1127
- /**
1128
- * Fire an event on a custom object
1129
- * @param {Object} el
1130
- * @param {String} type
1131
- * @param {Object} eventArguments
1132
- * @param {Function} defaultFunction
1133
- */
1134
- fireEvent: function (el, type, eventArguments, defaultFunction) {
1135
- var event = $.Event(type),
1136
- detachedType = 'detached' + type,
1137
- defaultPrevented;
1138
-
1139
- // Remove warnings in Chrome when accessing returnValue (#2790), layerX and layerY. Although Highcharts
1140
- // never uses these properties, Chrome includes them in the default click event and
1141
- // raises the warning when they are copied over in the extend statement below.
1142
- //
1143
- // To avoid problems in IE (see #1010) where we cannot delete the properties and avoid
1144
- // testing if they are there (warning in chrome) the only option is to test if running IE.
1145
- if (!isMS && eventArguments) {
1146
- delete eventArguments.layerX;
1147
- delete eventArguments.layerY;
1148
- delete eventArguments.returnValue;
1149
- }
1150
-
1151
- extend(event, eventArguments);
1152
-
1153
- // Prevent jQuery from triggering the object method that is named the
1154
- // same as the event. For example, if the event is 'select', jQuery
1155
- // attempts calling el.select and it goes into a loop.
1156
- if (el[type]) {
1157
- el[detachedType] = el[type];
1158
- el[type] = null;
1159
- }
1160
-
1161
- // Wrap preventDefault and stopPropagation in try/catch blocks in
1162
- // order to prevent JS errors when cancelling events on non-DOM
1163
- // objects. #615.
1164
- $.each(['preventDefault', 'stopPropagation'], function (i, fn) {
1165
- var base = event[fn];
1166
- event[fn] = function () {
1167
- try {
1168
- base.call(event);
1169
- } catch (e) {
1170
- if (fn === 'preventDefault') {
1171
- defaultPrevented = true;
1172
- }
1173
- }
1174
- };
1175
- });
1176
1359
 
1177
- // trigger it
1178
- $(el).trigger(event);
1360
+ /**
1361
+ * Compatibility section to add support for legacy IE. This can be removed if old IE
1362
+ * support is not needed.
1363
+ */
1364
+ if (doc && !doc.defaultView) {
1365
+ getStyle = function (el, prop) {
1366
+ var val,
1367
+ alias = { width: 'clientWidth', height: 'clientHeight' }[prop];
1368
+
1369
+ if (el.style[prop]) {
1370
+ return pInt(el.style[prop]);
1371
+ }
1372
+ if (prop === 'opacity') {
1373
+ prop = 'filter';
1374
+ }
1179
1375
 
1180
- // attach the method
1181
- if (el[detachedType]) {
1182
- el[type] = el[detachedType];
1183
- el[detachedType] = null;
1184
- }
1376
+ // Getting the rendered width and height
1377
+ if (alias) {
1378
+ el.style.zoom = 1;
1379
+ return el[alias] - 2 * getStyle(el, 'padding');
1380
+ }
1381
+
1382
+ val = el.currentStyle[prop.replace(/\-(\w)/g, function (a, b) {
1383
+ return b.toUpperCase();
1384
+ })];
1385
+ if (prop === 'filter') {
1386
+ val = val.replace(
1387
+ /alpha\(opacity=([0-9]+)\)/,
1388
+ function (a, b) {
1389
+ return b / 100;
1390
+ }
1391
+ );
1392
+ }
1393
+
1394
+ return val === '' ? 1 : pInt(val);
1395
+ };
1396
+ }
1185
1397
 
1186
- if (defaultFunction && !event.isDefaultPrevented() && !defaultPrevented) {
1187
- defaultFunction(event);
1398
+ if (!Array.prototype.forEach) {
1399
+ each = function (arr, fn) { // legacy
1400
+ var i = 0,
1401
+ len = arr.length;
1402
+ for (; i < len; i++) {
1403
+ if (fn.call(arr[i], arr[i], i, arr) === false) {
1404
+ return i;
1188
1405
  }
1189
- },
1406
+ }
1407
+ };
1408
+ }
1190
1409
 
1191
- /**
1192
- * Extension method needed for MooTools
1193
- */
1194
- washMouseEvent: function (e) {
1195
- var ret = e.originalEvent || e;
1410
+ if (!Array.prototype.indexOf) {
1411
+ inArray = function (item, arr) {
1412
+ var len,
1413
+ i = 0;
1196
1414
 
1197
- // computed by jQuery, needed by IE8
1198
- if (ret.pageX === UNDEFINED) { // #1236
1199
- ret.pageX = e.pageX;
1200
- ret.pageY = e.pageY;
1415
+ if (arr) {
1416
+ len = arr.length;
1417
+
1418
+ for (; i < len; i++) {
1419
+ if (arr[i] === item) {
1420
+ return i;
1421
+ }
1201
1422
  }
1423
+ }
1202
1424
 
1203
- return ret;
1204
- },
1205
-
1206
- /**
1207
- * Animate a HTML element or SVG element wrapper
1208
- * @param {Object} el
1209
- * @param {Object} params
1210
- * @param {Object} options jQuery-like animation options: duration, easing, callback
1211
- */
1212
- animate: function (el, params, options) {
1213
- var $el = $(el);
1214
- if (!el.style) {
1215
- el.style = {}; // #1881
1216
- }
1217
- if (params.d) {
1218
- el.toD = params.d; // keep the array form for paths, used in $.fx.step.d
1219
- params.d = 1; // because in jQuery, animating to an array has a different meaning
1220
- }
1425
+ return -1;
1426
+ };
1427
+ }
1221
1428
 
1222
- $el.stop();
1223
- if (params.opacity !== UNDEFINED && el.attr) {
1224
- params.opacity += 'px'; // force jQuery to use same logic as width and height (#2161)
1225
- }
1226
- el.hasAnim = 1; // #3342
1227
- $el.animate(params, options);
1429
+ if (!Array.prototype.filter) {
1430
+ grep = function (elements, fn) {
1431
+ var ret = [],
1432
+ i = 0,
1433
+ length = elements.length;
1228
1434
 
1229
- },
1230
- /**
1231
- * Stop running animation
1232
- */
1233
- stop: function (el) {
1234
- if (el.hasAnim) { // #3342, memory leak on calling $(el) from destroy
1235
- $(el).stop();
1435
+ for (; i < length; i++) {
1436
+ if (fn(elements[i], i)) {
1437
+ ret.push(elements[i]);
1236
1438
  }
1237
1439
  }
1440
+
1441
+ return ret;
1238
1442
  };
1239
1443
  }
1240
- // Utility functions. If the HighchartsAdapter is not defined, adapter is an empty object
1241
- // and all the utility functions will be null. In that case they are populated by the
1242
- // default adapters below.
1243
- var adapterRun,
1244
- inArray,
1245
- each,
1246
- grep,
1247
- offset,
1248
- map,
1249
- addEvent,
1250
- removeEvent,
1251
- fireEvent,
1252
- washMouseEvent,
1253
- animate,
1254
- stop;
1255
1444
 
1256
- /**
1257
- * Helper function to load and extend Highcharts with adapter functionality.
1258
- * @param {object|function} adapter - HighchartsAdapter or jQuery
1259
- */
1260
- Highcharts.loadAdapter = function (adapter) {
1261
-
1262
- if (adapter) {
1263
- // If jQuery, then load our default jQueryAdapter
1264
- if (adapter.fn && adapter.fn.jquery) {
1265
- adapter = loadJQueryAdapter(adapter);
1266
- }
1267
- // Initialize the adapter.
1268
- if (adapter.init) {
1269
- adapter.init(pathAnim);
1270
- delete adapter.init; // Avoid copying to Highcharts object
1271
- }
1272
- // Extend Highcharts with adapter functionality.
1273
- Highcharts.extend(Highcharts, adapter);
1274
-
1275
- // Assign values to local functions.
1276
- adapterRun = Highcharts.adapterRun;
1277
- inArray = Highcharts.inArray;
1278
- each = Highcharts.each;
1279
- grep = Highcharts.grep;
1280
- offset = Highcharts.offset;
1281
- map = Highcharts.map;
1282
- addEvent = Highcharts.addEvent;
1283
- removeEvent = Highcharts.removeEvent;
1284
- fireEvent = Highcharts.fireEvent;
1285
- washMouseEvent = Highcharts.washMouseEvent;
1286
- animate = Highcharts.animate;
1287
- stop = Highcharts.stop;
1288
- }
1289
- };
1445
+ //--- End compatibility section ---
1446
+
1447
+ // Expose utilities
1448
+ Highcharts.Fx = Fx;
1449
+ Highcharts.inArray = inArray;
1450
+ Highcharts.each = each;
1451
+ Highcharts.grep = grep;
1452
+ Highcharts.offset = offset;
1453
+ Highcharts.map = map;
1454
+ Highcharts.addEvent = addEvent;
1455
+ Highcharts.removeEvent = removeEvent;
1456
+ Highcharts.fireEvent = fireEvent;
1457
+ Highcharts.animate = animate;
1458
+ Highcharts.stop = stop;
1290
1459
 
1291
- // Load adapter if HighchartsAdapter or jQuery is set on the window.
1292
- Highcharts.loadAdapter(win.HighchartsAdapter || win.jQuery);
1293
1460
  /* ****************************************************************************
1294
1461
  * Handle the options *
1295
1462
  *****************************************************************************/
@@ -1314,7 +1481,7 @@
1314
1481
  useUTC: true,
1315
1482
  //timezoneOffset: 0,
1316
1483
  canvasToolsURL: 'http://code.highcharts.com/modules/canvas-tools.js',
1317
- VMLRadialGradientURL: 'http://code.highcharts.com/4.1.10/gfx/vml-radial-gradient.png'
1484
+ VMLRadialGradientURL: 'http://code.highcharts.com/4.2.0/gfx/vml-radial-gradient.png'
1318
1485
  },
1319
1486
  chart: {
1320
1487
  //animation: true,
@@ -1639,7 +1806,7 @@
1639
1806
  SET = useUTC ? 'setUTC' : 'set';
1640
1807
 
1641
1808
 
1642
- Date = globalOptions.Date || window.Date;
1809
+ Date = globalOptions.Date || win.Date;
1643
1810
  timezoneOffset = useUTC && globalOptions.timezoneOffset;
1644
1811
  getTimezoneOffset = useUTC && globalOptions.getTimezoneOffset;
1645
1812
  makeTime = function (year, month, date, hours, minutes, seconds) {
@@ -1878,7 +2045,7 @@
1878
2045
  /**
1879
2046
  * Animate a given attribute
1880
2047
  * @param {Object} params
1881
- * @param {Number} options The same options as in jQuery animation
2048
+ * @param {Number} options Options include duration, easing, step and complete
1882
2049
  * @param {Function} complete Function to perform at the end of animation
1883
2050
  */
1884
2051
  animate: function (params, options, complete) {
@@ -3077,7 +3244,6 @@
3077
3244
  */
3078
3245
  init: function (container, width, height, style, forExport, allowHTML) {
3079
3246
  var renderer = this,
3080
- loc = location,
3081
3247
  boxWrapper,
3082
3248
  element,
3083
3249
  desc;
@@ -3103,7 +3269,7 @@
3103
3269
 
3104
3270
  // Page url used for internal references. #24, #672, #1070
3105
3271
  renderer.url = (isFirefox || isWebKit) && doc.getElementsByTagName('base').length ?
3106
- loc.href
3272
+ win.location.href
3107
3273
  .replace(/#.*?$/, '') // remove the hash
3108
3274
  .replace(/([\('\)])/g, '\\$1') // escape parantheses and quotes
3109
3275
  .replace(/ /g, '%20') : // replace spaces (needed for Safari only)
@@ -3915,7 +4081,7 @@
3915
4081
  position: ABSOLUTE,
3916
4082
  top: '-999em'
3917
4083
  });
3918
- document.body.appendChild(this);
4084
+ doc.body.appendChild(this);
3919
4085
  }
3920
4086
 
3921
4087
  // Center the image
@@ -5226,6 +5392,14 @@
5226
5392
  this.setAttr('fillcolor', this.renderer.color(value, element, key, this));
5227
5393
  }
5228
5394
  },
5395
+ 'fill-opacitySetter': function (value, key, element) {
5396
+ createElement(
5397
+ this.renderer.prepVML(['<', key.split('-')[0], ' opacity="', value, '"/>']),
5398
+ null,
5399
+ null,
5400
+ element
5401
+ );
5402
+ },
5229
5403
  opacitySetter: noop, // Don't bother - animation is too slow and filters introduce artifacts
5230
5404
  rotationSetter: function (value, key, element) {
5231
5405
  var style = element.style;
@@ -5236,7 +5410,7 @@
5236
5410
  style.top = mathRound(mathCos(value * deg2rad)) + PX;
5237
5411
  },
5238
5412
  strokeSetter: function (value, key, element) {
5239
- this.setAttr('strokecolor', this.renderer.color(value, element, key));
5413
+ this.setAttr('strokecolor', this.renderer.color(value, element, key, this));
5240
5414
  },
5241
5415
  'stroke-widthSetter': function (value, key, element) {
5242
5416
  element.stroked = !!value; // VML "stroked" attribute
@@ -5302,6 +5476,8 @@
5302
5476
  element.style[key] = value;
5303
5477
  }
5304
5478
  };
5479
+ VMLElement['stroke-opacitySetter'] = VMLElement['fill-opacitySetter'];
5480
+
5305
5481
  Highcharts.VMLElement = VMLElement = extendClass(SVGElement, VMLElement);
5306
5482
 
5307
5483
  // Some shared setters
@@ -5592,14 +5768,13 @@
5592
5768
  ret = stopColor;
5593
5769
  }
5594
5770
 
5595
- // if the color is an rgba color, split it and add a fill node
5771
+ // If the color is an rgba color, split it and add a fill node
5596
5772
  // to hold the opacity component
5597
5773
  } else if (regexRgba.test(color) && elem.tagName !== 'IMG') {
5598
5774
 
5599
5775
  colorObject = Color(color);
5600
5776
 
5601
- markup = ['<', prop, ' opacity="', colorObject.get('a'), '"/>'];
5602
- createElement(this.prepVML(markup), null, null, elem);
5777
+ wrapper[prop + '-opacitySetter'](colorObject.get('a'), prop, elem);
5603
5778
 
5604
5779
  ret = colorObject.get('rgb');
5605
5780
 
@@ -5899,6 +6074,22 @@
5899
6074
  var CanVGRenderer,
5900
6075
  CanVGController;
5901
6076
 
6077
+ /**
6078
+ * Downloads a script and executes a callback when done.
6079
+ * @param {String} scriptLocation
6080
+ * @param {Function} callback
6081
+ */
6082
+ function getScript(scriptLocation, callback) {
6083
+ var head = doc.getElementsByTagName('head')[0],
6084
+ script = doc.createElement('script');
6085
+
6086
+ script.type = 'text/javascript';
6087
+ script.src = scriptLocation;
6088
+ script.onload = callback;
6089
+
6090
+ head.appendChild(script);
6091
+ }
6092
+
5902
6093
  if (useCanVG) {
5903
6094
  /**
5904
6095
  * The CanVGRenderer is empty from start to keep the source footprint small.
@@ -5942,7 +6133,7 @@
5942
6133
  push: function (func, scriptLocation) {
5943
6134
  // Only get the script once
5944
6135
  if (deferredRenderCalls.length === 0) {
5945
- Highcharts.getScript(scriptLocation, drawDeferred);
6136
+ getScript(scriptLocation, drawDeferred);
5946
6137
  }
5947
6138
  // Register render call
5948
6139
  deferredRenderCalls.push(func);
@@ -9685,7 +9876,7 @@
9685
9876
  var hoverChartIndex;
9686
9877
 
9687
9878
  // Global flag for touch support
9688
- hasTouch = doc.documentElement.ontouchstart !== UNDEFINED;
9879
+ hasTouch = doc && doc.documentElement.ontouchstart !== UNDEFINED;
9689
9880
 
9690
9881
  /**
9691
9882
  * The mouse tracker object. All methods starting with "on" are primary DOM event handlers.
@@ -9744,13 +9935,8 @@
9744
9935
  chartY,
9745
9936
  ePos;
9746
9937
 
9747
- // common IE normalizing
9748
- e = e || window.event;
9749
-
9750
- // Framework specific normalizing (#1165)
9751
- e = washMouseEvent(e);
9752
-
9753
- // More IE normalizing, needs to go after washMouseEvent
9938
+ // IE normalizing
9939
+ e = e || win.event;
9754
9940
  if (!e.target) {
9755
9941
  e.target = e.srcElement;
9756
9942
  }
@@ -10144,8 +10330,7 @@
10144
10330
  if (this.selectionMarker) {
10145
10331
  var selectionData = {
10146
10332
  xAxis: [],
10147
- yAxis: [],
10148
- originalEvent: e.originalEvent || e
10333
+ yAxis: []
10149
10334
  },
10150
10335
  selectionBox = this.selectionMarker,
10151
10336
  selectionLeft = selectionBox.attr ? selectionBox.attr('x') : selectionBox.x,
@@ -10305,7 +10490,6 @@
10305
10490
  plotTop = chart.plotTop;
10306
10491
 
10307
10492
  e = this.normalize(e);
10308
- e.originalEvent = e; // #3913
10309
10493
 
10310
10494
  if (!chart.cancelClick) {
10311
10495
 
@@ -10645,7 +10829,6 @@
10645
10829
  },
10646
10830
  translateMSPointer = function (e, method, wktype, func) {
10647
10831
  var p;
10648
- e = e.originalEvent || e;
10649
10832
  if ((e.pointerType === 'touch' || e.pointerType === e.MSPOINTER_TYPE_TOUCH) && charts[hoverChartIndex]) {
10650
10833
  func(e);
10651
10834
  p = charts[hoverChartIndex].pointer;
@@ -10877,7 +11060,8 @@
10877
11060
  positionCheckboxes: function (scrollOffset) {
10878
11061
  var alignAttr = this.group.alignAttr,
10879
11062
  translateY,
10880
- clipHeight = this.clipHeight || this.legendHeight;
11063
+ clipHeight = this.clipHeight || this.legendHeight,
11064
+ titleHeight = this.titleHeight;
10881
11065
 
10882
11066
  if (alignAttr) {
10883
11067
  translateY = alignAttr.translateY;
@@ -10886,7 +11070,7 @@
10886
11070
  top;
10887
11071
 
10888
11072
  if (checkbox) {
10889
- top = (translateY + checkbox.y + (scrollOffset || 0) + 3);
11073
+ top = translateY + titleHeight + checkbox.y + (scrollOffset || 0) + 3;
10890
11074
  css(checkbox, {
10891
11075
  left: (alignAttr.translateX + item.checkboxOffset + checkbox.x - 20) + PX,
10892
11076
  top: top + PX,
@@ -11497,7 +11681,8 @@
11497
11681
  (symbolWidth / 2) - radius,
11498
11682
  verticalCenter - radius,
11499
11683
  2 * radius,
11500
- 2 * radius
11684
+ 2 * radius,
11685
+ markerOptions
11501
11686
  )
11502
11687
  .add(legendItemGroup);
11503
11688
  legendSymbol.isMarker = true;
@@ -11526,12 +11711,17 @@
11526
11711
  });
11527
11712
  }
11528
11713
  /**
11529
- * The chart class
11714
+ * The Chart class
11715
+ * @param {String|Object} renderTo The DOM element to render to, or its id
11530
11716
  * @param {Object} options
11531
11717
  * @param {Function} callback Function to run when the chart has loaded
11532
11718
  */
11533
11719
  var Chart = Highcharts.Chart = function () {
11534
- this.init.apply(this, arguments);
11720
+ this.getArgs.apply(this, arguments);
11721
+ };
11722
+
11723
+ Highcharts.chart = function (a, b, c) {
11724
+ return new Chart(a, b, c);
11535
11725
  };
11536
11726
 
11537
11727
  Chart.prototype = {
@@ -11541,6 +11731,21 @@
11541
11731
  */
11542
11732
  callbacks: [],
11543
11733
 
11734
+ /**
11735
+ * Handle the arguments passed to the constructor
11736
+ * @returns {Array} Arguments without renderTo
11737
+ */
11738
+ getArgs: function () {
11739
+ var args = [].slice.call(arguments);
11740
+
11741
+ // Remove the optional first argument, renderTo, and
11742
+ // set it on this.
11743
+ if (isString(args[0]) || args[0].nodeName) {
11744
+ this.renderTo = args.shift();
11745
+ }
11746
+ this.init(args[0], args[1]);
11747
+ },
11748
+
11544
11749
  /**
11545
11750
  * Initialize the chart
11546
11751
  */
@@ -11819,7 +12024,7 @@
11819
12024
  renderer.draw();
11820
12025
 
11821
12026
  // fire the event
11822
- fireEvent(chart, 'redraw'); // jQuery breaks this when calling it from addEvent. Overwrites chart.redraw
12027
+ fireEvent(chart, 'redraw');
11823
12028
 
11824
12029
  if (isHiddenChart) {
11825
12030
  chart.cloneRenderTo(true);
@@ -12029,12 +12234,12 @@
12029
12234
  heightOption = optionsChart.height,
12030
12235
  renderTo = chart.renderToClone || chart.renderTo;
12031
12236
 
12032
- // get inner width and height from jQuery (#824)
12237
+ // Get inner width and height
12033
12238
  if (!defined(widthOption)) {
12034
- chart.containerWidth = adapterRun(renderTo, 'width');
12239
+ chart.containerWidth = getStyle(renderTo, 'width');
12035
12240
  }
12036
12241
  if (!defined(heightOption)) {
12037
- chart.containerHeight = adapterRun(renderTo, 'height');
12242
+ chart.containerHeight = getStyle(renderTo, 'height');
12038
12243
  }
12039
12244
 
12040
12245
  chart.chartWidth = mathMax(0, widthOption || chart.containerWidth || 600); // #1393, 1460
@@ -12091,15 +12296,16 @@
12091
12296
  optionsChart = options.chart,
12092
12297
  chartWidth,
12093
12298
  chartHeight,
12094
- renderTo,
12299
+ renderTo = chart.renderTo,
12095
12300
  indexAttrName = 'data-highcharts-chart',
12096
12301
  oldChartIndex,
12097
12302
  Ren,
12098
- containerId;
12099
-
12100
- chart.renderTo = renderTo = optionsChart.renderTo;
12101
- containerId = PREFIX + idCounter++;
12303
+ containerId = 'highcharts-' + idCounter++;
12102
12304
 
12305
+ if (!renderTo) {
12306
+ chart.renderTo = renderTo = optionsChart.renderTo;
12307
+ }
12308
+
12103
12309
  if (isString(renderTo)) {
12104
12310
  chart.renderTo = renderTo = doc.getElementById(renderTo);
12105
12311
  }
@@ -12246,9 +12452,9 @@
12246
12452
  var chart = this,
12247
12453
  optionsChart = chart.options.chart,
12248
12454
  renderTo = chart.renderTo,
12249
- width = optionsChart.width || adapterRun(renderTo, 'width'),
12250
- height = optionsChart.height || adapterRun(renderTo, 'height'),
12251
- target = e ? e.target : win; // #805 - MooTools doesn't supply e
12455
+ width = optionsChart.width || getStyle(renderTo, 'width'),
12456
+ height = optionsChart.height || getStyle(renderTo, 'height'),
12457
+ target = e ? e.target : win;
12252
12458
 
12253
12459
  // Width and height checks for display:none. Target is doc in IE8 and Opera,
12254
12460
  // win in Firefox, Chrome and IE9.
@@ -12753,7 +12959,7 @@
12753
12959
  )
12754
12960
  .on('click', function () {
12755
12961
  if (credits.href) {
12756
- location.href = credits.href;
12962
+ win.location.href = credits.href;
12757
12963
  }
12758
12964
  })
12759
12965
  .attr({
@@ -13195,8 +13401,7 @@
13195
13401
  },
13196
13402
 
13197
13403
  /**
13198
- * Fire an event on the Point object. Must not be renamed to fireEvent, as this
13199
- * causes a name clash in MooTools
13404
+ * Fire an event on the Point object.
13200
13405
  * @param {String} eventType
13201
13406
  * @param {Object} eventArgs Additional event arguments
13202
13407
  * @param {Function} defaultFunction Default event handler
@@ -14813,7 +15018,6 @@
14813
15018
  if (isNew) {
14814
15019
  this[prop] = group = this.chart.renderer.g(name)
14815
15020
  .attr({
14816
- visibility: visibility,
14817
15021
  zIndex: zIndex || 0.1 // IE8 needs this
14818
15022
  })
14819
15023
  .add(parent);
@@ -14822,7 +15026,7 @@
14822
15026
  }
14823
15027
 
14824
15028
  // Place it on first and subsequent (redraw) calls
14825
- group[isNew ? 'attr' : 'animate'](this.getPlotBox());
15029
+ group.attr({ visibility: visibility })[isNew ? 'attr' : 'animate'](this.getPlotBox());
14826
15030
  return group;
14827
15031
  },
14828
15032
 
@@ -15873,35 +16077,24 @@
15873
16077
  * @param {Boolean|Object} animation Whether to apply animation, and optionally animation
15874
16078
  * configuration
15875
16079
  */
15876
-
15877
16080
  remove: function (redraw, animation) {
15878
16081
  var series = this,
15879
16082
  chart = series.chart;
15880
- redraw = pick(redraw, true);
15881
-
15882
- if (!series.isRemoving) { /* prevent triggering native event in jQuery
15883
- (calling the remove function from the remove event) */
15884
- series.isRemoving = true;
15885
-
15886
- // fire the event with a default handler of removing the point
15887
- fireEvent(series, 'remove', null, function () {
15888
-
15889
16083
 
15890
- // destroy elements
15891
- series.destroy();
16084
+ // Fire the event with a default handler of removing the point
16085
+ fireEvent(series, 'remove', null, function () {
15892
16086
 
16087
+ // Destroy elements
16088
+ series.destroy();
15893
16089
 
15894
- // redraw
15895
- chart.isDirtyLegend = chart.isDirtyBox = true;
15896
- chart.linkSeries();
16090
+ // Redraw
16091
+ chart.isDirtyLegend = chart.isDirtyBox = true;
16092
+ chart.linkSeries();
15897
16093
 
15898
- if (redraw) {
15899
- chart.redraw(animation);
15900
- }
15901
- });
15902
-
15903
- }
15904
- series.isRemoving = false;
16094
+ if (pick(redraw, true)) {
16095
+ chart.redraw(animation);
16096
+ }
16097
+ });
15905
16098
  },
15906
16099
 
15907
16100
  /**
@@ -16225,21 +16418,24 @@
16225
16418
  });
16226
16419
  each(props, function (prop) {
16227
16420
  var areaKey = prop[0],
16228
- area = series[areaKey];
16421
+ area = series[areaKey],
16422
+ attr;
16229
16423
 
16230
16424
  // Create or update the area
16231
16425
  if (area) { // update
16232
16426
  area.animate({ d: areaPath });
16233
16427
 
16234
16428
  } else { // create
16429
+ attr = {
16430
+ fill: prop[2] || prop[1],
16431
+ zIndex: 0 // #1069
16432
+ };
16433
+ if (!prop[2]) {
16434
+ attr['fill-opacity'] = options.fillOpacity || 0.75;
16435
+ }
16235
16436
  series[areaKey] = series.chart.renderer.path(areaPath)
16236
- .attr({
16237
- fill: pick(
16238
- prop[2],
16239
- Color(prop[1]).setOpacity(pick(options.fillOpacity, 0.75)).get()
16240
- ),
16241
- zIndex: 0 // #1069
16242
- }).add(series.group);
16437
+ .attr(attr)
16438
+ .add(series.group);
16243
16439
  }
16244
16440
  });
16245
16441
  },
@@ -16486,7 +16682,6 @@
16486
16682
  reversedXAxis = xAxis.reversed,
16487
16683
  stackKey,
16488
16684
  stackGroups = {},
16489
- columnIndex,
16490
16685
  columnCount = 0;
16491
16686
 
16492
16687
  // Get the total number of column type series.
@@ -16497,7 +16692,8 @@
16497
16692
  } else {
16498
16693
  each(series.chart.series, function (otherSeries) {
16499
16694
  var otherOptions = otherSeries.options,
16500
- otherYAxis = otherSeries.yAxis;
16695
+ otherYAxis = otherSeries.yAxis,
16696
+ columnIndex;
16501
16697
  if (otherSeries.type === series.type && otherSeries.visible &&
16502
16698
  yAxis.len === otherYAxis.len && yAxis.pos === otherYAxis.pos) { // #642, #2086
16503
16699
  if (otherOptions.stacking) {
@@ -18546,9 +18742,9 @@
18546
18742
  newMin = axis.toValue(startPos - mousePos, true) + halfPointRange,
18547
18743
  newMax = axis.toValue(startPos + chart[isX ? 'plotWidth' : 'plotHeight'] - mousePos, true) - halfPointRange,
18548
18744
  goingLeft = startPos > mousePos; // #3613
18549
-
18745
+
18550
18746
  if (axis.series.length &&
18551
- (goingLeft || newMin > mathMin(extremes.dataMin, extremes.min)) &&
18747
+ (goingLeft || newMin > mathMin(extremes.dataMin, extremes.min)) &&
18552
18748
  (!goingLeft || newMax < mathMax(extremes.dataMax, extremes.max))) {
18553
18749
  axis.setExtremes(newMin, newMax, false, false, { trigger: 'pan' });
18554
18750
  doRedraw = true;
@@ -18581,7 +18777,7 @@
18581
18777
 
18582
18778
  selected = pick(selected, !point.selected);
18583
18779
 
18584
- // fire the event with the defalut handler
18780
+ // fire the event with the default handler
18585
18781
  point.firePointEvent(selected ? 'select' : 'unselect', { accumulate: accumulate }, function () {
18586
18782
  point.selected = point.options.selected = selected;
18587
18783
  series.options.data[inArray(point, series.data)] = point.options;
@@ -18788,12 +18984,9 @@
18788
18984
  series.halo = halo = chart.renderer.path()
18789
18985
  .add(chart.seriesGroup);
18790
18986
  }
18791
- halo.attr(extend(hasSVG ? {
18987
+ halo.attr(extend({
18792
18988
  fill: point.color || series.color,
18793
18989
  'fill-opacity': haloOptions.opacity
18794
- } : {
18795
- // Old IE doesn't take fill-opacity
18796
- fill: Color(point.color || series.color).setOpacity(haloOptions.opacity).get()
18797
18990
  },
18798
18991
  haloOptions.attributes))[move ? 'animate' : 'attr']({
18799
18992
  d: point.haloPath(haloOptions.size)