standalone-framework.src.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603
  1. /**
  2. * @license Highcharts JS v4.1.5 (2015-04-13)
  3. *
  4. * Standalone Highcharts Framework
  5. *
  6. * License: MIT License
  7. */
  8. /*global Highcharts */
  9. var HighchartsAdapter = (function () {
  10. var UNDEFINED,
  11. doc = document,
  12. emptyArray = [],
  13. timers = [],
  14. timerId,
  15. animSetters = {},
  16. Fx;
  17. Math.easeInOutSine = function (t, b, c, d) {
  18. return -c / 2 * (Math.cos(Math.PI * t / d) - 1) + b;
  19. };
  20. /**
  21. * Extend given object with custom events
  22. */
  23. function augment(obj) {
  24. function removeOneEvent(el, type, fn) {
  25. el.removeEventListener(type, fn, false);
  26. }
  27. function IERemoveOneEvent(el, type, fn) {
  28. fn = el.HCProxiedMethods[fn.toString()];
  29. el.detachEvent('on' + type, fn);
  30. }
  31. function removeAllEvents(el, type) {
  32. var events = el.HCEvents,
  33. remove,
  34. types,
  35. len,
  36. n;
  37. if (el.removeEventListener) {
  38. remove = removeOneEvent;
  39. } else if (el.attachEvent) {
  40. remove = IERemoveOneEvent;
  41. } else {
  42. return; // break on non-DOM events
  43. }
  44. if (type) {
  45. types = {};
  46. types[type] = true;
  47. } else {
  48. types = events;
  49. }
  50. for (n in types) {
  51. if (events[n]) {
  52. len = events[n].length;
  53. while (len--) {
  54. remove(el, n, events[n][len]);
  55. }
  56. }
  57. }
  58. }
  59. if (!obj.HCExtended) {
  60. Highcharts.extend(obj, {
  61. HCExtended: true,
  62. HCEvents: {},
  63. bind: function (name, fn) {
  64. var el = this,
  65. events = this.HCEvents,
  66. wrappedFn;
  67. // handle DOM events in modern browsers
  68. if (el.addEventListener) {
  69. el.addEventListener(name, fn, false);
  70. // handle old IE implementation
  71. } else if (el.attachEvent) {
  72. wrappedFn = function (e) {
  73. e.target = e.srcElement || window; // #2820
  74. fn.call(el, e);
  75. };
  76. if (!el.HCProxiedMethods) {
  77. el.HCProxiedMethods = {};
  78. }
  79. // link wrapped fn with original fn, so we can get this in removeEvent
  80. el.HCProxiedMethods[fn.toString()] = wrappedFn;
  81. el.attachEvent('on' + name, wrappedFn);
  82. }
  83. if (events[name] === UNDEFINED) {
  84. events[name] = [];
  85. }
  86. events[name].push(fn);
  87. },
  88. unbind: function (name, fn) {
  89. var events,
  90. index;
  91. if (name) {
  92. events = this.HCEvents[name] || [];
  93. if (fn) {
  94. index = HighchartsAdapter.inArray(fn, events);
  95. if (index > -1) {
  96. events.splice(index, 1);
  97. this.HCEvents[name] = events;
  98. }
  99. if (this.removeEventListener) {
  100. removeOneEvent(this, name, fn);
  101. } else if (this.attachEvent) {
  102. IERemoveOneEvent(this, name, fn);
  103. }
  104. } else {
  105. removeAllEvents(this, name);
  106. this.HCEvents[name] = [];
  107. }
  108. } else {
  109. removeAllEvents(this);
  110. this.HCEvents = {};
  111. }
  112. },
  113. trigger: function (name, args) {
  114. var events = this.HCEvents[name] || [],
  115. target = this,
  116. len = events.length,
  117. i,
  118. preventDefault,
  119. fn;
  120. // Attach a simple preventDefault function to skip default handler if called
  121. preventDefault = function () {
  122. args.defaultPrevented = true;
  123. };
  124. for (i = 0; i < len; i++) {
  125. fn = events[i];
  126. // args is never null here
  127. if (args.stopped) {
  128. return;
  129. }
  130. args.preventDefault = preventDefault;
  131. args.target = target;
  132. // If the type is not set, we're running a custom event (#2297). If it is set,
  133. // we're running a browser event, and setting it will cause en error in
  134. // IE8 (#2465).
  135. if (!args.type) {
  136. args.type = name;
  137. }
  138. // If the event handler return false, prevent the default handler from executing
  139. if (fn.call(this, args) === false) {
  140. args.preventDefault();
  141. }
  142. }
  143. }
  144. });
  145. }
  146. return obj;
  147. }
  148. return {
  149. /**
  150. * Initialize the adapter. This is run once as Highcharts is first run.
  151. */
  152. init: function (pathAnim) {
  153. /**
  154. * Compatibility section to add support for legacy IE. This can be removed if old IE
  155. * support is not needed.
  156. */
  157. if (!doc.defaultView) {
  158. this._getStyle = function (el, prop) {
  159. var val;
  160. if (el.style[prop]) {
  161. return el.style[prop];
  162. } else {
  163. if (prop === 'opacity') {
  164. prop = 'filter';
  165. }
  166. /*jslint unparam: true*/
  167. val = el.currentStyle[prop.replace(/\-(\w)/g, function (a, b) { return b.toUpperCase(); })];
  168. if (prop === 'filter') {
  169. val = val.replace(
  170. /alpha\(opacity=([0-9]+)\)/,
  171. function (a, b) {
  172. return b / 100;
  173. }
  174. );
  175. }
  176. /*jslint unparam: false*/
  177. return val === '' ? 1 : val;
  178. }
  179. };
  180. this.adapterRun = function (elem, method) {
  181. var alias = { width: 'clientWidth', height: 'clientHeight' }[method];
  182. if (alias) {
  183. elem.style.zoom = 1;
  184. return elem[alias] - 2 * parseInt(HighchartsAdapter._getStyle(elem, 'padding'), 10);
  185. }
  186. };
  187. }
  188. if (!Array.prototype.forEach) {
  189. this.each = function (arr, fn) { // legacy
  190. var i = 0,
  191. len = arr.length;
  192. for (; i < len; i++) {
  193. if (fn.call(arr[i], arr[i], i, arr) === false) {
  194. return i;
  195. }
  196. }
  197. };
  198. }
  199. if (!Array.prototype.indexOf) {
  200. this.inArray = function (item, arr) {
  201. var len,
  202. i = 0;
  203. if (arr) {
  204. len = arr.length;
  205. for (; i < len; i++) {
  206. if (arr[i] === item) {
  207. return i;
  208. }
  209. }
  210. }
  211. return -1;
  212. };
  213. }
  214. if (!Array.prototype.filter) {
  215. this.grep = function (elements, callback) {
  216. var ret = [],
  217. i = 0,
  218. length = elements.length;
  219. for (; i < length; i++) {
  220. if (!!callback(elements[i], i)) {
  221. ret.push(elements[i]);
  222. }
  223. }
  224. return ret;
  225. };
  226. }
  227. //--- End compatibility section ---
  228. /**
  229. * Start of animation specific code
  230. */
  231. Fx = function (elem, options, prop) {
  232. this.options = options;
  233. this.elem = elem;
  234. this.prop = prop;
  235. };
  236. Fx.prototype = {
  237. update: function () {
  238. var styles,
  239. paths = this.paths,
  240. elem = this.elem,
  241. elemelem = elem.element; // if destroyed, it is null
  242. // Animation setter defined from outside
  243. if (animSetters[this.prop]) {
  244. animSetters[this.prop](this);
  245. // Animating a path definition on SVGElement
  246. } else if (paths && elemelem) {
  247. elem.attr('d', pathAnim.step(paths[0], paths[1], this.now, this.toD));
  248. // Other animations on SVGElement
  249. } else if (elem.attr) {
  250. if (elemelem) {
  251. elem.attr(this.prop, this.now);
  252. }
  253. // HTML styles
  254. } else {
  255. styles = {};
  256. styles[this.prop] = this.now + this.unit;
  257. Highcharts.css(elem, styles);
  258. }
  259. if (this.options.step) {
  260. this.options.step.call(this.elem, this.now, this);
  261. }
  262. },
  263. custom: function (from, to, unit) {
  264. var self = this,
  265. t = function (gotoEnd) {
  266. return self.step(gotoEnd);
  267. },
  268. i;
  269. this.startTime = +new Date();
  270. this.start = from;
  271. this.end = to;
  272. this.unit = unit;
  273. this.now = this.start;
  274. this.pos = this.state = 0;
  275. t.elem = this.elem;
  276. if (t() && timers.push(t) === 1) {
  277. timerId = setInterval(function () {
  278. for (i = 0; i < timers.length; i++) {
  279. if (!timers[i]()) {
  280. timers.splice(i--, 1);
  281. }
  282. }
  283. if (!timers.length) {
  284. clearInterval(timerId);
  285. }
  286. }, 13);
  287. }
  288. },
  289. step: function (gotoEnd) {
  290. var t = +new Date(),
  291. ret,
  292. done,
  293. options = this.options,
  294. elem = this.elem,
  295. i;
  296. if (elem.stopAnimation || (elem.attr && !elem.element)) { // #2616, element including flag is destroyed
  297. ret = false;
  298. } else if (gotoEnd || t >= options.duration + this.startTime) {
  299. this.now = this.end;
  300. this.pos = this.state = 1;
  301. this.update();
  302. this.options.curAnim[this.prop] = true;
  303. done = true;
  304. for (i in options.curAnim) {
  305. if (options.curAnim[i] !== true) {
  306. done = false;
  307. }
  308. }
  309. if (done) {
  310. if (options.complete) {
  311. options.complete.call(elem);
  312. }
  313. }
  314. ret = false;
  315. } else {
  316. var n = t - this.startTime;
  317. this.state = n / options.duration;
  318. this.pos = options.easing(n, 0, 1, options.duration);
  319. this.now = this.start + ((this.end - this.start) * this.pos);
  320. this.update();
  321. ret = true;
  322. }
  323. return ret;
  324. }
  325. };
  326. /**
  327. * The adapter animate method
  328. */
  329. this.animate = function (el, prop, opt) {
  330. var start,
  331. unit = '',
  332. end,
  333. fx,
  334. args,
  335. name;
  336. el.stopAnimation = false; // ready for new
  337. if (typeof opt !== 'object' || opt === null) {
  338. args = arguments;
  339. opt = {
  340. duration: args[2],
  341. easing: args[3],
  342. complete: args[4]
  343. };
  344. }
  345. if (typeof opt.duration !== 'number') {
  346. opt.duration = 400;
  347. }
  348. opt.easing = Math[opt.easing] || Math.easeInOutSine;
  349. opt.curAnim = Highcharts.extend({}, prop);
  350. for (name in prop) {
  351. fx = new Fx(el, opt, name);
  352. end = null;
  353. if (name === 'd') {
  354. fx.paths = pathAnim.init(
  355. el,
  356. el.d,
  357. prop.d
  358. );
  359. fx.toD = prop.d;
  360. start = 0;
  361. end = 1;
  362. } else if (el.attr) {
  363. start = el.attr(name);
  364. } else {
  365. start = parseFloat(HighchartsAdapter._getStyle(el, name)) || 0;
  366. if (name !== 'opacity') {
  367. unit = 'px';
  368. }
  369. }
  370. if (!end) {
  371. end = prop[name];
  372. }
  373. fx.custom(start, end, unit);
  374. }
  375. };
  376. },
  377. /**
  378. * Internal method to return CSS value for given element and property
  379. */
  380. _getStyle: function (el, prop) {
  381. return window.getComputedStyle(el, undefined).getPropertyValue(prop);
  382. },
  383. /**
  384. * Add an animation setter for a specific property
  385. */
  386. addAnimSetter: function (prop, fn) {
  387. animSetters[prop] = fn;
  388. },
  389. /**
  390. * Downloads a script and executes a callback when done.
  391. * @param {String} scriptLocation
  392. * @param {Function} callback
  393. */
  394. getScript: function (scriptLocation, callback) {
  395. // We cannot assume that Assets class from mootools-more is available so instead insert a script tag to download script.
  396. var head = doc.getElementsByTagName('head')[0],
  397. script = doc.createElement('script');
  398. script.type = 'text/javascript';
  399. script.src = scriptLocation;
  400. script.onload = callback;
  401. head.appendChild(script);
  402. },
  403. /**
  404. * Return the index of an item in an array, or -1 if not found
  405. */
  406. inArray: function (item, arr) {
  407. return arr.indexOf ? arr.indexOf(item) : emptyArray.indexOf.call(arr, item);
  408. },
  409. /**
  410. * A direct link to adapter methods
  411. */
  412. adapterRun: function (elem, method) {
  413. return parseInt(HighchartsAdapter._getStyle(elem, method), 10);
  414. },
  415. /**
  416. * Filter an array
  417. */
  418. grep: function (elements, callback) {
  419. return emptyArray.filter.call(elements, callback);
  420. },
  421. /**
  422. * Map an array
  423. */
  424. map: function (arr, fn) {
  425. var results = [], i = 0, len = arr.length;
  426. for (; i < len; i++) {
  427. results[i] = fn.call(arr[i], arr[i], i, arr);
  428. }
  429. return results;
  430. },
  431. /**
  432. * Get the element's offset position, corrected by overflow:auto. Loosely based on jQuery's offset method.
  433. */
  434. offset: function (el) {
  435. var docElem = document.documentElement,
  436. box = el.getBoundingClientRect();
  437. return {
  438. top: box.top + (window.pageYOffset || docElem.scrollTop) - (docElem.clientTop || 0),
  439. left: box.left + (window.pageXOffset || docElem.scrollLeft) - (docElem.clientLeft || 0)
  440. };
  441. },
  442. /**
  443. * Add an event listener
  444. */
  445. addEvent: function (el, type, fn) {
  446. augment(el).bind(type, fn);
  447. },
  448. /**
  449. * Remove event added with addEvent
  450. */
  451. removeEvent: function (el, type, fn) {
  452. augment(el).unbind(type, fn);
  453. },
  454. /**
  455. * Fire an event on a custom object
  456. */
  457. fireEvent: function (el, type, eventArguments, defaultFunction) {
  458. var e;
  459. if (doc.createEvent && (el.dispatchEvent || el.fireEvent)) {
  460. e = doc.createEvent('Events');
  461. e.initEvent(type, true, true);
  462. e.target = el;
  463. Highcharts.extend(e, eventArguments);
  464. if (el.dispatchEvent) {
  465. el.dispatchEvent(e);
  466. } else {
  467. el.fireEvent(type, e);
  468. }
  469. } else if (el.HCExtended === true) {
  470. eventArguments = eventArguments || {};
  471. el.trigger(type, eventArguments);
  472. }
  473. if (eventArguments && eventArguments.defaultPrevented) {
  474. defaultFunction = null;
  475. }
  476. if (defaultFunction) {
  477. defaultFunction(eventArguments);
  478. }
  479. },
  480. washMouseEvent: function (e) {
  481. return e;
  482. },
  483. /**
  484. * Stop running animation
  485. */
  486. stop: function (el) {
  487. el.stopAnimation = true;
  488. },
  489. /**
  490. * Utility for iterating over an array. Parameters are reversed compared to jQuery.
  491. * @param {Array} arr
  492. * @param {Function} fn
  493. */
  494. each: function (arr, fn) { // modern browsers
  495. return Array.prototype.forEach.call(arr, fn);
  496. }
  497. };
  498. }());