Utilities.js 80 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647
  1. /* *
  2. *
  3. * (c) 2010-2020 Torstein Honsi
  4. *
  5. * License: www.highcharts.com/license
  6. *
  7. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  8. *
  9. * */
  10. 'use strict';
  11. import H from './Globals.js';
  12. /**
  13. * An animation configuration. Animation configurations can also be defined as
  14. * booleans, where `false` turns off animation and `true` defaults to a duration
  15. * of 500ms.
  16. *
  17. * @interface Highcharts.AnimationOptionsObject
  18. */ /**
  19. * A callback function to exectute when the animation finishes.
  20. * @name Highcharts.AnimationOptionsObject#complete
  21. * @type {Function|undefined}
  22. */ /**
  23. * The animation duration in milliseconds.
  24. * @name Highcharts.AnimationOptionsObject#duration
  25. * @type {number|undefined}
  26. */ /**
  27. * The name of an easing function as defined on the `Math` object.
  28. * @name Highcharts.AnimationOptionsObject#easing
  29. * @type {string|Function|undefined}
  30. */ /**
  31. * A callback function to execute on each step of each attribute or CSS property
  32. * that's being animated. The first argument contains information about the
  33. * animation and progress.
  34. * @name Highcharts.AnimationOptionsObject#step
  35. * @type {Function|undefined}
  36. */
  37. /**
  38. * Creates a frame for the animated SVG element.
  39. *
  40. * @callback Highcharts.AnimationStepCallbackFunction
  41. *
  42. * @param {Highcharts.SVGElement} this
  43. * The SVG element to animate.
  44. *
  45. * @return {void}
  46. */
  47. /**
  48. * Interface description for a class.
  49. *
  50. * @interface Highcharts.Class<T>
  51. * @extends Function
  52. */ /**
  53. * Class costructor.
  54. * @function Highcharts.Class<T>#new
  55. * @param {...Array<*>} args
  56. * Constructor arguments.
  57. * @return {T}
  58. * Class instance.
  59. */
  60. /**
  61. * A style object with camel case property names to define visual appearance of
  62. * a SVG element or HTML element. The properties can be whatever styles are
  63. * supported on the given SVG or HTML element.
  64. *
  65. * @example
  66. * {
  67. * fontFamily: 'monospace',
  68. * fontSize: '1.2em'
  69. * }
  70. *
  71. * @interface Highcharts.CSSObject
  72. */ /**
  73. * @name Highcharts.CSSObject#[key:string]
  74. * @type {boolean|number|string|undefined}
  75. */ /**
  76. * Background style for the element.
  77. * @name Highcharts.CSSObject#background
  78. * @type {string|undefined}
  79. */ /**
  80. * Background color of the element.
  81. * @name Highcharts.CSSObject#backgroundColor
  82. * @type {Highcharts.ColorString|undefined}
  83. */ /**
  84. * Border style for the element.
  85. * @name Highcharts.CSSObject#border
  86. * @type {string|undefined}
  87. */ /**
  88. * Radius of the element border.
  89. * @name Highcharts.CSSObject#borderRadius
  90. * @type {number|undefined}
  91. */ /**
  92. * Color used in the element. The 'contrast' option is a Highcharts custom
  93. * property that results in black or white, depending on the background of the
  94. * element.
  95. * @name Highcharts.CSSObject#color
  96. * @type {'contrast'|Highcharts.ColorString|undefined}
  97. */ /**
  98. * Style of the mouse cursor when resting over the element.
  99. * @name Highcharts.CSSObject#cursor
  100. * @type {Highcharts.CursorValue|undefined}
  101. */ /**
  102. * Font family of the element text. Multiple values have to be in decreasing
  103. * preference order and separated by comma.
  104. * @name Highcharts.CSSObject#fontFamily
  105. * @type {string|undefined}
  106. */ /**
  107. * Font size of the element text.
  108. * @name Highcharts.CSSObject#fontSize
  109. * @type {string|undefined}
  110. */ /**
  111. * Font weight of the element text.
  112. * @name Highcharts.CSSObject#fontWeight
  113. * @type {string|undefined}
  114. */ /**
  115. * Height of the element.
  116. * @name Highcharts.CSSObject#height
  117. * @type {number|undefined}
  118. */ /**
  119. * Width of the element border.
  120. * @name Highcharts.CSSObject#lineWidth
  121. * @type {number|undefined}
  122. */ /**
  123. * Opacity of the element.
  124. * @name Highcharts.CSSObject#opacity
  125. * @type {number|undefined}
  126. */ /**
  127. * Space around the element content.
  128. * @name Highcharts.CSSObject#padding
  129. * @type {string|undefined}
  130. */ /**
  131. * Behaviour of the element when the mouse cursor rests over it.
  132. * @name Highcharts.CSSObject#pointerEvents
  133. * @type {string|undefined}
  134. */ /**
  135. * Positioning of the element.
  136. * @name Highcharts.CSSObject#position
  137. * @type {string|undefined}
  138. */ /**
  139. * Alignment of the element text.
  140. * @name Highcharts.CSSObject#textAlign
  141. * @type {string|undefined}
  142. */ /**
  143. * Additional decoration of the element text.
  144. * @name Highcharts.CSSObject#textDecoration
  145. * @type {string|undefined}
  146. */ /**
  147. * Outline style of the element text.
  148. * @name Highcharts.CSSObject#textOutline
  149. * @type {string|undefined}
  150. */ /**
  151. * Line break style of the element text. Highcharts SVG elements support
  152. * `ellipsis` when a `width` is set.
  153. * @name Highcharts.CSSObject#textOverflow
  154. * @type {string|undefined}
  155. */ /**
  156. * Top spacing of the element relative to the parent element.
  157. * @name Highcharts.CSSObject#top
  158. * @type {string|undefined}
  159. */ /**
  160. * Animated transition of selected element properties.
  161. * @name Highcharts.CSSObject#transition
  162. * @type {string|undefined}
  163. */ /**
  164. * Line break style of the element text.
  165. * @name Highcharts.CSSObject#whiteSpace
  166. * @type {string|undefined}
  167. */ /**
  168. * Width of the element.
  169. * @name Highcharts.CSSObject#width
  170. * @type {number|undefined}
  171. */
  172. /**
  173. * All possible cursor styles.
  174. *
  175. * @typedef {'alias'|'all-scroll'|'auto'|'cell'|'col-resize'|'context-menu'|'copy'|'crosshair'|'default'|'e-resize'|'ew-resize'|'grab'|'grabbing'|'help'|'move'|'n-resize'|'ne-resize'|'nesw-resize'|'no-drop'|'none'|'not-allowed'|'ns-resize'|'nw-resize'|'nwse-resize'|'pointer'|'progress'|'row-resize'|'s-resize'|'se-resize'|'sw-resize'|'text'|'vertical-text'|'w-resize'|'wait'|'zoom-in'|'zoom-out'} Highcharts.CursorValue
  176. */
  177. /**
  178. * All possible dash styles.
  179. *
  180. * @typedef {'Dash'|'DashDot'|'Dot'|'LongDash'|'LongDashDot'|'LongDashDotDot'|'ShortDash'|'ShortDashDot'|'ShortDashDotDot'|'ShortDot'|'Solid'} Highcharts.DashStyleValue
  181. */
  182. /**
  183. * Generic dictionary in TypeScript notation.
  184. * Use the native `Record<string, any>` instead.
  185. *
  186. * @deprecated
  187. * @interface Highcharts.Dictionary<T>
  188. */ /**
  189. * @name Highcharts.Dictionary<T>#[key:string]
  190. * @type {T}
  191. */
  192. /**
  193. * The function callback to execute when the event is fired. The `this` context
  194. * contains the instance, that fired the event.
  195. *
  196. * @callback Highcharts.EventCallbackFunction<T>
  197. *
  198. * @param {T} this
  199. *
  200. * @param {Highcharts.Dictionary<*>|Event} [eventArguments]
  201. * Event arguments.
  202. *
  203. * @return {boolean|void}
  204. */
  205. /**
  206. * The event options for adding function callback.
  207. *
  208. * @interface Highcharts.EventOptionsObject
  209. */ /**
  210. * The order the event handler should be called. This opens for having one
  211. * handler be called before another, independent of in which order they were
  212. * added.
  213. * @name Highcharts.EventOptionsObject#order
  214. * @type {number}
  215. */
  216. /**
  217. * Formats data as a string. Usually the data is accessible throught the `this`
  218. * keyword.
  219. *
  220. * @callback Highcharts.FormatterCallbackFunction<T>
  221. *
  222. * @param {T} this
  223. * Context to format
  224. *
  225. * @return {string}
  226. * Formatted text
  227. */
  228. /**
  229. * An object of key-value pairs for HTML attributes.
  230. *
  231. * @typedef {Highcharts.Dictionary<boolean|number|string|Function>} Highcharts.HTMLAttributes
  232. */
  233. /**
  234. * An HTML DOM element. The type is a reference to the regular HTMLElement in
  235. * the global scope.
  236. *
  237. * @typedef {global.HTMLElement} Highcharts.HTMLDOMElement
  238. *
  239. * @see https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement
  240. */
  241. /**
  242. * The iterator callback.
  243. *
  244. * @callback Highcharts.ObjectEachCallbackFunction<T>
  245. *
  246. * @param {T} this
  247. * The context.
  248. *
  249. * @param {*} value
  250. * The property value.
  251. *
  252. * @param {string} key
  253. * The property key.
  254. *
  255. * @param {*} obj
  256. * The object that objectEach is being applied to.
  257. */
  258. /**
  259. * An object containing `left` and `top` properties for the position in the
  260. * page.
  261. *
  262. * @interface Highcharts.OffsetObject
  263. */ /**
  264. * Left distance to the page border.
  265. * @name Highcharts.OffsetObject#left
  266. * @type {number}
  267. */ /**
  268. * Top distance to the page border.
  269. * @name Highcharts.OffsetObject#top
  270. * @type {number}
  271. */
  272. /**
  273. * Describes a range.
  274. *
  275. * @interface Highcharts.RangeObject
  276. */ /**
  277. * Maximum number of the range.
  278. * @name Highcharts.RangeObject#max
  279. * @type {number}
  280. */ /**
  281. * Minimum number of the range.
  282. * @name Highcharts.RangeObject#min
  283. * @type {number}
  284. */
  285. /**
  286. * If a number is given, it defines the pixel length. If a percentage string is
  287. * given, like for example `'50%'`, the setting defines a length relative to a
  288. * base size, for example the size of a container.
  289. *
  290. * @typedef {number|string} Highcharts.RelativeSize
  291. */
  292. /**
  293. * Proceed function to call original (wrapped) function.
  294. *
  295. * @callback Highcharts.WrapProceedFunction
  296. *
  297. * @param {*} [arg1]
  298. * Optional argument. Without any arguments defaults to first argument of
  299. * the wrapping function.
  300. *
  301. * @param {*} [arg2]
  302. * Optional argument. Without any arguments defaults to second argument
  303. * of the wrapping function.
  304. *
  305. * @param {*} [arg3]
  306. * Optional argument. Without any arguments defaults to third argument of
  307. * the wrapping function.
  308. *
  309. * @return {*}
  310. * Return value of the original function.
  311. */
  312. /**
  313. * The Highcharts object is the placeholder for all other members, and various
  314. * utility functions. The most important member of the namespace would be the
  315. * chart constructor.
  316. *
  317. * @example
  318. * var chart = Highcharts.chart('container', { ... });
  319. *
  320. * @namespace Highcharts
  321. */
  322. H.timers = [];
  323. var charts = H.charts, doc = H.doc, win = H.win;
  324. /**
  325. * Provide error messages for debugging, with links to online explanation. This
  326. * function can be overridden to provide custom error handling.
  327. *
  328. * @sample highcharts/chart/highcharts-error/
  329. * Custom error handler
  330. *
  331. * @function Highcharts.error
  332. *
  333. * @param {number|string} code
  334. * The error code. See
  335. * [errors.xml](https://github.com/highcharts/highcharts/blob/master/errors/errors.xml)
  336. * for available codes. If it is a string, the error message is printed
  337. * directly in the console.
  338. *
  339. * @param {boolean} [stop=false]
  340. * Whether to throw an error or just log a warning in the console.
  341. *
  342. * @param {Highcharts.Chart} [chart]
  343. * Reference to the chart that causes the error. Used in 'debugger'
  344. * module to display errors directly on the chart.
  345. * Important note: This argument is undefined for errors that lack
  346. * access to the Chart instance.
  347. *
  348. * @param {Highcharts.Dictionary<string>} [params]
  349. * Additional parameters for the generated message.
  350. *
  351. * @return {void}
  352. */
  353. function error(code, stop, chart, params) {
  354. var severity = stop ? 'Highcharts error' : 'Highcharts warning';
  355. if (code === 32) {
  356. code = severity + ": Deprecated member";
  357. }
  358. var isCode = isNumber(code), message = isCode ?
  359. severity + " #" + code + ": www.highcharts.com/errors/" + code + "/" :
  360. code.toString(), defaultHandler = function () {
  361. if (stop) {
  362. throw new Error(message);
  363. }
  364. // else ...
  365. if (win.console &&
  366. error.messages.indexOf(message) === -1 // prevent console flooting
  367. ) {
  368. console.log(message); // eslint-disable-line no-console
  369. }
  370. };
  371. if (typeof params !== 'undefined') {
  372. var additionalMessages_1 = '';
  373. if (isCode) {
  374. message += '?';
  375. }
  376. objectEach(params, function (value, key) {
  377. additionalMessages_1 += "\n - " + key + ": " + value;
  378. if (isCode) {
  379. message += encodeURI(key) + '=' + encodeURI(value);
  380. }
  381. });
  382. message += additionalMessages_1;
  383. }
  384. if (chart) {
  385. fireEvent(chart, 'displayError', { code: code, message: message, params: params }, defaultHandler);
  386. }
  387. else {
  388. defaultHandler();
  389. }
  390. error.messages.push(message);
  391. }
  392. (function (error) {
  393. error.messages = [];
  394. })(error || (error = {}));
  395. H.error = error;
  396. /* eslint-disable no-invalid-this, valid-jsdoc */
  397. /**
  398. * An animator object used internally. One instance applies to one property
  399. * (attribute or style prop) on one element. Animation is always initiated
  400. * through {@link SVGElement#animate}.
  401. *
  402. * @example
  403. * var rect = renderer.rect(0, 0, 10, 10).add();
  404. * rect.animate({ width: 100 });
  405. *
  406. * @private
  407. * @class
  408. * @name Highcharts.Fx
  409. */
  410. var Fx = /** @class */ (function () {
  411. /* *
  412. *
  413. * Constructors
  414. *
  415. * */
  416. /**
  417. *
  418. * @param {Highcharts.HTMLDOMElement|Highcharts.SVGElement} elem
  419. * The element to animate.
  420. *
  421. * @param {Highcharts.AnimationOptionsObject} options
  422. * Animation options.
  423. *
  424. * @param {string} prop
  425. * The single attribute or CSS property to animate.
  426. */
  427. function Fx(elem, options, prop) {
  428. this.options = options;
  429. this.elem = elem;
  430. this.prop = prop;
  431. }
  432. /* *
  433. *
  434. * Functions
  435. *
  436. * */
  437. /**
  438. * Set the current step of a path definition on SVGElement.
  439. *
  440. * @function Highcharts.Fx#dSetter
  441. *
  442. * @return {void}
  443. */
  444. Fx.prototype.dSetter = function () {
  445. var paths = this.paths, start = paths && paths[0], end = paths && paths[1], path = [], now = this.now || 0;
  446. // Land on the final path without adjustment points appended in the ends
  447. if (now === 1 || !start || !end) {
  448. path = this.toD || [];
  449. }
  450. else if (start.length === end.length && now < 1) {
  451. for (var i = 0; i < end.length; i++) {
  452. // Tween between the start segment and the end segment. Start
  453. // with a copy of the end segment and tween the appropriate
  454. // numerics
  455. var startSeg = start[i];
  456. var endSeg = end[i];
  457. var tweenSeg = [];
  458. for (var j = 0; j < endSeg.length; j++) {
  459. var startItem = startSeg[j];
  460. var endItem = endSeg[j];
  461. // Tween numbers
  462. if (typeof startItem === 'number' &&
  463. typeof endItem === 'number' &&
  464. // Arc boolean flags
  465. !(endSeg[0] === 'A' && (j === 4 || j === 5))) {
  466. tweenSeg[j] = startItem + now * (endItem - startItem);
  467. // Strings, take directly from the end segment
  468. }
  469. else {
  470. tweenSeg[j] = endItem;
  471. }
  472. }
  473. path.push(tweenSeg);
  474. }
  475. // If animation is finished or length not matching, land on right value
  476. }
  477. else {
  478. path = end;
  479. }
  480. this.elem.attr('d', path, void 0, true);
  481. };
  482. /**
  483. * Update the element with the current animation step.
  484. *
  485. * @function Highcharts.Fx#update
  486. *
  487. * @return {void}
  488. */
  489. Fx.prototype.update = function () {
  490. var elem = this.elem, prop = this.prop, // if destroyed, it is null
  491. now = this.now, step = this.options.step;
  492. // Animation setter defined from outside
  493. if (this[prop + 'Setter']) {
  494. this[prop + 'Setter']();
  495. // Other animations on SVGElement
  496. }
  497. else if (elem.attr) {
  498. if (elem.element) {
  499. elem.attr(prop, now, null, true);
  500. }
  501. // HTML styles, raw HTML content like container size
  502. }
  503. else {
  504. elem.style[prop] = now + this.unit;
  505. }
  506. if (step) {
  507. step.call(elem, now, this);
  508. }
  509. };
  510. /**
  511. * Run an animation.
  512. *
  513. * @function Highcharts.Fx#run
  514. *
  515. * @param {number} from
  516. * The current value, value to start from.
  517. *
  518. * @param {number} to
  519. * The end value, value to land on.
  520. *
  521. * @param {string} unit
  522. * The property unit, for example `px`.
  523. *
  524. * @return {void}
  525. */
  526. Fx.prototype.run = function (from, to, unit) {
  527. var self = this, options = self.options, timer = function (gotoEnd) {
  528. return timer.stopped ? false : self.step(gotoEnd);
  529. }, requestAnimationFrame = win.requestAnimationFrame ||
  530. function (step) {
  531. setTimeout(step, 13);
  532. }, step = function () {
  533. for (var i = 0; i < H.timers.length; i++) {
  534. if (!H.timers[i]()) {
  535. H.timers.splice(i--, 1);
  536. }
  537. }
  538. if (H.timers.length) {
  539. requestAnimationFrame(step);
  540. }
  541. };
  542. if (from === to && !this.elem['forceAnimate:' + this.prop]) {
  543. delete options.curAnim[this.prop];
  544. if (options.complete && Object.keys(options.curAnim).length === 0) {
  545. options.complete.call(this.elem);
  546. }
  547. }
  548. else { // #7166
  549. this.startTime = +new Date();
  550. this.start = from;
  551. this.end = to;
  552. this.unit = unit;
  553. this.now = this.start;
  554. this.pos = 0;
  555. timer.elem = this.elem;
  556. timer.prop = this.prop;
  557. if (timer() && H.timers.push(timer) === 1) {
  558. requestAnimationFrame(step);
  559. }
  560. }
  561. };
  562. /**
  563. * Run a single step in the animation.
  564. *
  565. * @function Highcharts.Fx#step
  566. *
  567. * @param {boolean} [gotoEnd]
  568. * Whether to go to the endpoint of the animation after abort.
  569. *
  570. * @return {boolean}
  571. * Returns `true` if animation continues.
  572. */
  573. Fx.prototype.step = function (gotoEnd) {
  574. var t = +new Date(), ret, done, options = this.options, elem = this.elem, complete = options.complete, duration = options.duration, curAnim = options.curAnim;
  575. if (elem.attr && !elem.element) { // #2616, element is destroyed
  576. ret = false;
  577. }
  578. else if (gotoEnd || t >= duration + this.startTime) {
  579. this.now = this.end;
  580. this.pos = 1;
  581. this.update();
  582. curAnim[this.prop] = true;
  583. done = true;
  584. objectEach(curAnim, function (val) {
  585. if (val !== true) {
  586. done = false;
  587. }
  588. });
  589. if (done && complete) {
  590. complete.call(elem);
  591. }
  592. ret = false;
  593. }
  594. else {
  595. this.pos = options.easing((t - this.startTime) / duration);
  596. this.now = this.start + ((this.end - this.start) * this.pos);
  597. this.update();
  598. ret = true;
  599. }
  600. return ret;
  601. };
  602. /**
  603. * Prepare start and end values so that the path can be animated one to one.
  604. *
  605. * @function Highcharts.Fx#initPath
  606. *
  607. * @param {Highcharts.SVGElement} elem
  608. * The SVGElement item.
  609. *
  610. * @param {Highcharts.SVGPathArray|undefined} fromD
  611. * Starting path definition.
  612. *
  613. * @param {Highcharts.SVGPathArray} toD
  614. * Ending path definition.
  615. *
  616. * @return {Array<Highcharts.SVGPathArray,Highcharts.SVGPathArray>}
  617. * An array containing start and end paths in array form so that
  618. * they can be animated in parallel.
  619. */
  620. Fx.prototype.initPath = function (elem, fromD, toD) {
  621. var shift, startX = elem.startX, endX = elem.endX, fullLength, i, start = fromD && fromD.slice(), // copy
  622. end = toD.slice(), // copy
  623. isArea = elem.isArea, positionFactor = isArea ? 2 : 1, reverse;
  624. if (!start) {
  625. return [end, end];
  626. }
  627. /**
  628. * If shifting points, prepend a dummy point to the end path.
  629. * @private
  630. * @param {Highcharts.SVGPathArray} arr - array
  631. * @param {Highcharts.SVGPathArray} other - array
  632. * @return {void}
  633. */
  634. function prepend(arr, other) {
  635. while (arr.length < fullLength) {
  636. // Move to, line to or curve to?
  637. var moveSegment = arr[0], otherSegment = other[fullLength - arr.length];
  638. if (otherSegment && moveSegment[0] === 'M') {
  639. if (otherSegment[0] === 'C') {
  640. arr[0] = [
  641. 'C',
  642. moveSegment[1],
  643. moveSegment[2],
  644. moveSegment[1],
  645. moveSegment[2],
  646. moveSegment[1],
  647. moveSegment[2]
  648. ];
  649. }
  650. else {
  651. arr[0] = ['L', moveSegment[1], moveSegment[2]];
  652. }
  653. }
  654. // Prepend a copy of the first point
  655. arr.unshift(moveSegment);
  656. // For areas, the bottom path goes back again to the left, so we
  657. // need to append a copy of the last point.
  658. if (isArea) {
  659. arr.push(arr[arr.length - 1]);
  660. }
  661. }
  662. }
  663. /**
  664. * Copy and append last point until the length matches the end length.
  665. * @private
  666. * @param {Highcharts.SVGPathArray} arr - array
  667. * @param {Highcharts.SVGPathArray} other - array
  668. * @return {void}
  669. */
  670. function append(arr, other) {
  671. while (arr.length < fullLength) {
  672. // Pull out the slice that is going to be appended or inserted.
  673. // In a line graph, the positionFactor is 1, and the last point
  674. // is sliced out. In an area graph, the positionFactor is 2,
  675. // causing the middle two points to be sliced out, since an area
  676. // path starts at left, follows the upper path then turns and
  677. // follows the bottom back.
  678. var segmentToAdd = arr[arr.length / positionFactor - 1].slice();
  679. // Disable the first control point of curve segments
  680. if (segmentToAdd[0] === 'C') {
  681. segmentToAdd[1] = segmentToAdd[5];
  682. segmentToAdd[2] = segmentToAdd[6];
  683. }
  684. if (!isArea) {
  685. arr.push(segmentToAdd);
  686. }
  687. else {
  688. var lowerSegmentToAdd = arr[arr.length / positionFactor].slice();
  689. arr.splice(arr.length / 2, 0, segmentToAdd, lowerSegmentToAdd);
  690. }
  691. }
  692. }
  693. // For sideways animation, find out how much we need to shift to get the
  694. // start path Xs to match the end path Xs.
  695. if (startX && endX) {
  696. for (i = 0; i < startX.length; i++) {
  697. // Moving left, new points coming in on right
  698. if (startX[i] === endX[0]) {
  699. shift = i;
  700. break;
  701. // Moving right
  702. }
  703. else if (startX[0] ===
  704. endX[endX.length - startX.length + i]) {
  705. shift = i;
  706. reverse = true;
  707. break;
  708. // Fixed from the right side, "scaling" left
  709. }
  710. else if (startX[startX.length - 1] ===
  711. endX[endX.length - startX.length + i]) {
  712. shift = startX.length - i;
  713. break;
  714. }
  715. }
  716. if (typeof shift === 'undefined') {
  717. start = [];
  718. }
  719. }
  720. if (start.length && isNumber(shift)) {
  721. // The common target length for the start and end array, where both
  722. // arrays are padded in opposite ends
  723. fullLength = end.length + shift * positionFactor;
  724. if (!reverse) {
  725. prepend(end, start);
  726. append(start, end);
  727. }
  728. else {
  729. prepend(start, end);
  730. append(end, start);
  731. }
  732. }
  733. return [start, end];
  734. };
  735. /**
  736. * Handle animation of the color attributes directly.
  737. *
  738. * @function Highcharts.Fx#fillSetter
  739. *
  740. * @return {void}
  741. */
  742. Fx.prototype.fillSetter = function () {
  743. Fx.prototype.strokeSetter.apply(this, arguments);
  744. };
  745. /**
  746. * Handle animation of the color attributes directly.
  747. *
  748. * @function Highcharts.Fx#strokeSetter
  749. *
  750. * @return {void}
  751. */
  752. Fx.prototype.strokeSetter = function () {
  753. this.elem.attr(this.prop, H.color(this.start).tweenTo(H.color(this.end), this.pos), null, true);
  754. };
  755. return Fx;
  756. }());
  757. H.Fx = Fx;
  758. /* eslint-disable valid-jsdoc */
  759. /**
  760. * Utility function to deep merge two or more objects and return a third object.
  761. * If the first argument is true, the contents of the second object is copied
  762. * into the first object. The merge function can also be used with a single
  763. * object argument to create a deep copy of an object.
  764. *
  765. * @function Highcharts.merge<T>
  766. *
  767. * @param {boolean} extend
  768. * Whether to extend the left-side object (a) or return a whole new
  769. * object.
  770. *
  771. * @param {T|undefined} a
  772. * The first object to extend. When only this is given, the function
  773. * returns a deep copy.
  774. *
  775. * @param {...Array<object|undefined>} [n]
  776. * An object to merge into the previous one.
  777. *
  778. * @return {T}
  779. * The merged object. If the first argument is true, the return is the
  780. * same as the second argument.
  781. */ /**
  782. * Utility function to deep merge two or more objects and return a third object.
  783. * The merge function can also be used with a single object argument to create a
  784. * deep copy of an object.
  785. *
  786. * @function Highcharts.merge<T>
  787. *
  788. * @param {T|undefined} a
  789. * The first object to extend. When only this is given, the function
  790. * returns a deep copy.
  791. *
  792. * @param {...Array<object|undefined>} [n]
  793. * An object to merge into the previous one.
  794. *
  795. * @return {T}
  796. * The merged object. If the first argument is true, the return is the
  797. * same as the second argument.
  798. */
  799. function merge() {
  800. /* eslint-enable valid-jsdoc */
  801. var i, args = arguments, len, ret = {}, doCopy = function (copy, original) {
  802. // An object is replacing a primitive
  803. if (typeof copy !== 'object') {
  804. copy = {};
  805. }
  806. objectEach(original, function (value, key) {
  807. // Copy the contents of objects, but not arrays or DOM nodes
  808. if (isObject(value, true) &&
  809. !isClass(value) &&
  810. !isDOMElement(value)) {
  811. copy[key] = doCopy(copy[key] || {}, value);
  812. // Primitives and arrays are copied over directly
  813. }
  814. else {
  815. copy[key] = original[key];
  816. }
  817. });
  818. return copy;
  819. };
  820. // If first argument is true, copy into the existing object. Used in
  821. // setOptions.
  822. if (args[0] === true) {
  823. ret = args[1];
  824. args = Array.prototype.slice.call(args, 2);
  825. }
  826. // For each argument, extend the return
  827. len = args.length;
  828. for (i = 0; i < len; i++) {
  829. ret = doCopy(ret, args[i]);
  830. }
  831. return ret;
  832. }
  833. H.merge = merge;
  834. /**
  835. * Constrain a value to within a lower and upper threshold.
  836. *
  837. * @private
  838. * @param {number} value The initial value
  839. * @param {number} min The lower threshold
  840. * @param {number} max The upper threshold
  841. * @return {number} Returns a number value within min and max.
  842. */
  843. function clamp(value, min, max) {
  844. return value > min ? value < max ? value : max : min;
  845. }
  846. /**
  847. * Shortcut for parseInt
  848. *
  849. * @private
  850. * @function Highcharts.pInt
  851. *
  852. * @param {*} s
  853. * any
  854. *
  855. * @param {number} [mag]
  856. * Magnitude
  857. *
  858. * @return {number}
  859. * number
  860. */
  861. var pInt = H.pInt = function pInt(s, mag) {
  862. return parseInt(s, mag || 10);
  863. };
  864. /**
  865. * Utility function to check for string type.
  866. *
  867. * @function Highcharts.isString
  868. *
  869. * @param {*} s
  870. * The item to check.
  871. *
  872. * @return {boolean}
  873. * True if the argument is a string.
  874. */
  875. var isString = H.isString = function isString(s) {
  876. return typeof s === 'string';
  877. };
  878. /**
  879. * Utility function to check if an item is an array.
  880. *
  881. * @function Highcharts.isArray
  882. *
  883. * @param {*} obj
  884. * The item to check.
  885. *
  886. * @return {boolean}
  887. * True if the argument is an array.
  888. */
  889. var isArray = H.isArray = function isArray(obj) {
  890. var str = Object.prototype.toString.call(obj);
  891. return str === '[object Array]' || str === '[object Array Iterator]';
  892. };
  893. /**
  894. * Utility function to check if an item is of type object.
  895. *
  896. * @function Highcharts.isObject
  897. *
  898. * @param {*} obj
  899. * The item to check.
  900. *
  901. * @param {boolean} [strict=false]
  902. * Also checks that the object is not an array.
  903. *
  904. * @return {boolean}
  905. * True if the argument is an object.
  906. */
  907. function isObject(obj, strict) {
  908. return (!!obj &&
  909. typeof obj === 'object' &&
  910. (!strict || !isArray(obj))); // eslint-disable-line @typescript-eslint/no-explicit-any
  911. }
  912. H.isObject = isObject;
  913. /**
  914. * Utility function to check if an Object is a HTML Element.
  915. *
  916. * @function Highcharts.isDOMElement
  917. *
  918. * @param {*} obj
  919. * The item to check.
  920. *
  921. * @return {boolean}
  922. * True if the argument is a HTML Element.
  923. */
  924. var isDOMElement = H.isDOMElement = function isDOMElement(obj) {
  925. return isObject(obj) && typeof obj.nodeType === 'number';
  926. };
  927. /**
  928. * Utility function to check if an Object is a class.
  929. *
  930. * @function Highcharts.isClass
  931. *
  932. * @param {object|undefined} obj
  933. * The item to check.
  934. *
  935. * @return {boolean}
  936. * True if the argument is a class.
  937. */
  938. var isClass = H.isClass = function isClass(obj) {
  939. var c = obj && obj.constructor;
  940. return !!(isObject(obj, true) &&
  941. !isDOMElement(obj) &&
  942. (c && c.name && c.name !== 'Object'));
  943. };
  944. /**
  945. * Utility function to check if an item is a number and it is finite (not NaN,
  946. * Infinity or -Infinity).
  947. *
  948. * @function Highcharts.isNumber
  949. *
  950. * @param {*} n
  951. * The item to check.
  952. *
  953. * @return {boolean}
  954. * True if the item is a finite number
  955. */
  956. var isNumber = H.isNumber = function isNumber(n) {
  957. return typeof n === 'number' && !isNaN(n) && n < Infinity && n > -Infinity;
  958. };
  959. /**
  960. * Remove the last occurence of an item from an array.
  961. *
  962. * @function Highcharts.erase
  963. *
  964. * @param {Array<*>} arr
  965. * The array.
  966. *
  967. * @param {*} item
  968. * The item to remove.
  969. *
  970. * @return {void}
  971. */
  972. var erase = H.erase = function erase(arr, item) {
  973. var i = arr.length;
  974. while (i--) {
  975. if (arr[i] === item) {
  976. arr.splice(i, 1);
  977. break;
  978. }
  979. }
  980. };
  981. /**
  982. * Check if an object is null or undefined.
  983. *
  984. * @function Highcharts.defined
  985. *
  986. * @param {*} obj
  987. * The object to check.
  988. *
  989. * @return {boolean}
  990. * False if the object is null or undefined, otherwise true.
  991. */
  992. var defined = H.defined = function defined(obj) {
  993. return typeof obj !== 'undefined' && obj !== null;
  994. };
  995. /**
  996. * Set or get an attribute or an object of attributes. To use as a setter, pass
  997. * a key and a value, or let the second argument be a collection of keys and
  998. * values. To use as a getter, pass only a string as the second argument.
  999. *
  1000. * @function Highcharts.attr
  1001. *
  1002. * @param {Highcharts.HTMLDOMElement|Highcharts.SVGDOMElement} elem
  1003. * The DOM element to receive the attribute(s).
  1004. *
  1005. * @param {string|Highcharts.HTMLAttributes|Highcharts.SVGAttributes} [prop]
  1006. * The property or an object of key-value pairs.
  1007. *
  1008. * @param {number|string} [value]
  1009. * The value if a single property is set.
  1010. *
  1011. * @return {string|null|undefined}
  1012. * When used as a getter, return the value.
  1013. */
  1014. function attr(elem, prop, value) {
  1015. var ret;
  1016. // if the prop is a string
  1017. if (isString(prop)) {
  1018. // set the value
  1019. if (defined(value)) {
  1020. elem.setAttribute(prop, value);
  1021. // get the value
  1022. }
  1023. else if (elem && elem.getAttribute) {
  1024. ret = elem.getAttribute(prop);
  1025. // IE7 and below cannot get class through getAttribute (#7850)
  1026. if (!ret && prop === 'class') {
  1027. ret = elem.getAttribute(prop + 'Name');
  1028. }
  1029. }
  1030. // else if prop is defined, it is a hash of key/value pairs
  1031. }
  1032. else {
  1033. objectEach(prop, function (val, key) {
  1034. elem.setAttribute(key, val);
  1035. });
  1036. }
  1037. return ret;
  1038. }
  1039. H.attr = attr;
  1040. /**
  1041. * Check if an element is an array, and if not, make it into an array.
  1042. *
  1043. * @function Highcharts.splat
  1044. *
  1045. * @param {*} obj
  1046. * The object to splat.
  1047. *
  1048. * @return {Array}
  1049. * The produced or original array.
  1050. */
  1051. var splat = H.splat = function splat(obj) {
  1052. return isArray(obj) ? obj : [obj];
  1053. };
  1054. /**
  1055. * Set a timeout if the delay is given, otherwise perform the function
  1056. * synchronously.
  1057. *
  1058. * @function Highcharts.syncTimeout
  1059. *
  1060. * @param {Function} fn
  1061. * The function callback.
  1062. *
  1063. * @param {number} delay
  1064. * Delay in milliseconds.
  1065. *
  1066. * @param {*} [context]
  1067. * An optional context to send to the function callback.
  1068. *
  1069. * @return {number}
  1070. * An identifier for the timeout that can later be cleared with
  1071. * Highcharts.clearTimeout. Returns -1 if there is no timeout.
  1072. */
  1073. var syncTimeout = H.syncTimeout = function syncTimeout(fn, delay, context) {
  1074. if (delay > 0) {
  1075. return setTimeout(fn, delay, context);
  1076. }
  1077. fn.call(0, context);
  1078. return -1;
  1079. };
  1080. /**
  1081. * Internal clear timeout. The function checks that the `id` was not removed
  1082. * (e.g. by `chart.destroy()`). For the details see
  1083. * [issue #7901](https://github.com/highcharts/highcharts/issues/7901).
  1084. *
  1085. * @function Highcharts.clearTimeout
  1086. *
  1087. * @param {number} id
  1088. * Id of a timeout.
  1089. *
  1090. * @return {void}
  1091. */
  1092. var internalClearTimeout = H.clearTimeout = function (id) {
  1093. if (defined(id)) {
  1094. clearTimeout(id);
  1095. }
  1096. };
  1097. /* eslint-disable valid-jsdoc */
  1098. /**
  1099. * Utility function to extend an object with the members of another.
  1100. *
  1101. * @function Highcharts.extend<T>
  1102. *
  1103. * @param {T|undefined} a
  1104. * The object to be extended.
  1105. *
  1106. * @param {object} b
  1107. * The object to add to the first one.
  1108. *
  1109. * @return {T}
  1110. * Object a, the original object.
  1111. */
  1112. var extend = H.extend = function extend(a, b) {
  1113. /* eslint-enable valid-jsdoc */
  1114. var n;
  1115. if (!a) {
  1116. a = {};
  1117. }
  1118. for (n in b) { // eslint-disable-line guard-for-in
  1119. a[n] = b[n];
  1120. }
  1121. return a;
  1122. };
  1123. /* eslint-disable valid-jsdoc */
  1124. /**
  1125. * Return the first value that is not null or undefined.
  1126. *
  1127. * @function Highcharts.pick<T>
  1128. *
  1129. * @param {...Array<T|null|undefined>} items
  1130. * Variable number of arguments to inspect.
  1131. *
  1132. * @return {T}
  1133. * The value of the first argument that is not null or undefined.
  1134. */
  1135. function pick() {
  1136. var args = arguments;
  1137. var length = args.length;
  1138. for (var i = 0; i < length; i++) {
  1139. var arg = args[i];
  1140. if (typeof arg !== 'undefined' && arg !== null) {
  1141. return arg;
  1142. }
  1143. }
  1144. }
  1145. H.pick = pick;
  1146. /**
  1147. * Set CSS on a given element.
  1148. *
  1149. * @function Highcharts.css
  1150. *
  1151. * @param {Highcharts.HTMLDOMElement|Highcharts.SVGDOMElement} el
  1152. * An HTML DOM element.
  1153. *
  1154. * @param {Highcharts.CSSObject} styles
  1155. * Style object with camel case property names.
  1156. *
  1157. * @return {void}
  1158. */
  1159. var css = H.css = function css(el, styles) {
  1160. if (H.isMS && !H.svg) { // #2686
  1161. if (styles && typeof styles.opacity !== 'undefined') {
  1162. styles.filter =
  1163. 'alpha(opacity=' + (styles.opacity * 100) + ')';
  1164. }
  1165. }
  1166. extend(el.style, styles);
  1167. };
  1168. /**
  1169. * Utility function to create an HTML element with attributes and styles.
  1170. *
  1171. * @function Highcharts.createElement
  1172. *
  1173. * @param {string} tag
  1174. * The HTML tag.
  1175. *
  1176. * @param {Highcharts.HTMLAttributes} [attribs]
  1177. * Attributes as an object of key-value pairs.
  1178. *
  1179. * @param {Highcharts.CSSObject} [styles]
  1180. * Styles as an object of key-value pairs.
  1181. *
  1182. * @param {Highcharts.HTMLDOMElement} [parent]
  1183. * The parent HTML object.
  1184. *
  1185. * @param {boolean} [nopad=false]
  1186. * If true, remove all padding, border and margin.
  1187. *
  1188. * @return {Highcharts.HTMLDOMElement}
  1189. * The created DOM element.
  1190. */
  1191. var createElement = H.createElement = function createElement(tag, attribs, styles, parent, nopad) {
  1192. var el = doc.createElement(tag);
  1193. if (attribs) {
  1194. extend(el, attribs);
  1195. }
  1196. if (nopad) {
  1197. css(el, { padding: '0', border: 'none', margin: '0' });
  1198. }
  1199. if (styles) {
  1200. css(el, styles);
  1201. }
  1202. if (parent) {
  1203. parent.appendChild(el);
  1204. }
  1205. return el;
  1206. };
  1207. // eslint-disable-next-line valid-jsdoc
  1208. /**
  1209. * Extend a prototyped class by new members.
  1210. *
  1211. * @function Highcharts.extendClass<T>
  1212. *
  1213. * @param {Highcharts.Class<T>} parent
  1214. * The parent prototype to inherit.
  1215. *
  1216. * @param {Highcharts.Dictionary<*>} members
  1217. * A collection of prototype members to add or override compared to the
  1218. * parent prototype.
  1219. *
  1220. * @return {Highcharts.Class<T>}
  1221. * A new prototype.
  1222. */
  1223. var extendClass = H.extendClass = function extendClass(parent, members) {
  1224. var obj = (function () { });
  1225. obj.prototype = new parent(); // eslint-disable-line new-cap
  1226. extend(obj.prototype, members);
  1227. return obj;
  1228. };
  1229. /**
  1230. * Left-pad a string to a given length by adding a character repetetively.
  1231. *
  1232. * @function Highcharts.pad
  1233. *
  1234. * @param {number} number
  1235. * The input string or number.
  1236. *
  1237. * @param {number} [length]
  1238. * The desired string length.
  1239. *
  1240. * @param {string} [padder=0]
  1241. * The character to pad with.
  1242. *
  1243. * @return {string}
  1244. * The padded string.
  1245. */
  1246. var pad = H.pad = function pad(number, length, padder) {
  1247. return new Array((length || 2) +
  1248. 1 -
  1249. String(number)
  1250. .replace('-', '')
  1251. .length).join(padder || '0') + number;
  1252. };
  1253. /**
  1254. * Return a length based on either the integer value, or a percentage of a base.
  1255. *
  1256. * @function Highcharts.relativeLength
  1257. *
  1258. * @param {Highcharts.RelativeSize} value
  1259. * A percentage string or a number.
  1260. *
  1261. * @param {number} base
  1262. * The full length that represents 100%.
  1263. *
  1264. * @param {number} [offset=0]
  1265. * A pixel offset to apply for percentage values. Used internally in
  1266. * axis positioning.
  1267. *
  1268. * @return {number}
  1269. * The computed length.
  1270. */
  1271. var relativeLength = H.relativeLength = function relativeLength(value, base, offset) {
  1272. return (/%$/).test(value) ?
  1273. (base * parseFloat(value) / 100) + (offset || 0) :
  1274. parseFloat(value);
  1275. };
  1276. /**
  1277. * Wrap a method with extended functionality, preserving the original function.
  1278. *
  1279. * @function Highcharts.wrap
  1280. *
  1281. * @param {*} obj
  1282. * The context object that the method belongs to. In real cases, this is
  1283. * often a prototype.
  1284. *
  1285. * @param {string} method
  1286. * The name of the method to extend.
  1287. *
  1288. * @param {Highcharts.WrapProceedFunction} func
  1289. * A wrapper function callback. This function is called with the same
  1290. * arguments as the original function, except that the original function
  1291. * is unshifted and passed as the first argument.
  1292. */
  1293. var wrap = H.wrap = function wrap(obj, method, func) {
  1294. var proceed = obj[method];
  1295. obj[method] = function () {
  1296. var args = Array.prototype.slice.call(arguments), outerArgs = arguments, ctx = this, ret;
  1297. ctx.proceed = function () {
  1298. proceed.apply(ctx, arguments.length ? arguments : outerArgs);
  1299. };
  1300. args.unshift(proceed);
  1301. ret = func.apply(this, args);
  1302. ctx.proceed = null;
  1303. return ret;
  1304. };
  1305. };
  1306. /**
  1307. * Format a string according to a subset of the rules of Python's String.format
  1308. * method.
  1309. *
  1310. * @example
  1311. * var s = Highcharts.format(
  1312. * 'The {color} fox was {len:.2f} feet long',
  1313. * { color: 'red', len: Math.PI }
  1314. * );
  1315. * // => The red fox was 3.14 feet long
  1316. *
  1317. * @function Highcharts.format
  1318. *
  1319. * @param {string} str
  1320. * The string to format.
  1321. *
  1322. * @param {Record<string, *>} ctx
  1323. * The context, a collection of key-value pairs where each key is
  1324. * replaced by its value.
  1325. *
  1326. * @param {Highcharts.Chart} [chart]
  1327. * A `Chart` instance used to get numberFormatter and time.
  1328. *
  1329. * @return {string}
  1330. * The formatted string.
  1331. */
  1332. var format = H.format = function (str, ctx, chart) {
  1333. var splitter = '{', isInside = false, segment, valueAndFormat, ret = [], val, index;
  1334. var floatRegex = /f$/;
  1335. var decRegex = /\.([0-9])/;
  1336. var lang = H.defaultOptions.lang;
  1337. var time = chart && chart.time || H.time;
  1338. var numberFormatter = chart && chart.numberFormatter || numberFormat;
  1339. while (str) {
  1340. index = str.indexOf(splitter);
  1341. if (index === -1) {
  1342. break;
  1343. }
  1344. segment = str.slice(0, index);
  1345. if (isInside) { // we're on the closing bracket looking back
  1346. valueAndFormat = segment.split(':');
  1347. val = getNestedProperty(valueAndFormat.shift() || '', ctx);
  1348. // Format the replacement
  1349. if (valueAndFormat.length && typeof val === 'number') {
  1350. segment = valueAndFormat.join(':');
  1351. if (floatRegex.test(segment)) { // float
  1352. var decimals = parseInt((segment.match(decRegex) || ['', '-1'])[1], 10);
  1353. if (val !== null) {
  1354. val = numberFormatter(val, decimals, lang.decimalPoint, segment.indexOf(',') > -1 ? lang.thousandsSep : '');
  1355. }
  1356. }
  1357. else {
  1358. val = time.dateFormat(segment, val);
  1359. }
  1360. }
  1361. // Push the result and advance the cursor
  1362. ret.push(val);
  1363. }
  1364. else {
  1365. ret.push(segment);
  1366. }
  1367. str = str.slice(index + 1); // the rest
  1368. isInside = !isInside; // toggle
  1369. splitter = isInside ? '}' : '{'; // now look for next matching bracket
  1370. }
  1371. ret.push(str);
  1372. return ret.join('');
  1373. };
  1374. /**
  1375. * Get the magnitude of a number.
  1376. *
  1377. * @function Highcharts.getMagnitude
  1378. *
  1379. * @param {number} num
  1380. * The number.
  1381. *
  1382. * @return {number}
  1383. * The magnitude, where 1-9 are magnitude 1, 10-99 magnitude 2 etc.
  1384. */
  1385. var getMagnitude = H.getMagnitude = function (num) {
  1386. return Math.pow(10, Math.floor(Math.log(num) / Math.LN10));
  1387. };
  1388. /**
  1389. * Take an interval and normalize it to multiples of round numbers.
  1390. *
  1391. * @deprecated
  1392. * @function Highcharts.normalizeTickInterval
  1393. *
  1394. * @param {number} interval
  1395. * The raw, un-rounded interval.
  1396. *
  1397. * @param {Array<*>} [multiples]
  1398. * Allowed multiples.
  1399. *
  1400. * @param {number} [magnitude]
  1401. * The magnitude of the number.
  1402. *
  1403. * @param {boolean} [allowDecimals]
  1404. * Whether to allow decimals.
  1405. *
  1406. * @param {boolean} [hasTickAmount]
  1407. * If it has tickAmount, avoid landing on tick intervals lower than
  1408. * original.
  1409. *
  1410. * @return {number}
  1411. * The normalized interval.
  1412. *
  1413. * @todo
  1414. * Move this function to the Axis prototype. It is here only for historical
  1415. * reasons.
  1416. */
  1417. var normalizeTickInterval = H.normalizeTickInterval = function (interval, multiples, magnitude, allowDecimals, hasTickAmount) {
  1418. var normalized, i, retInterval = interval;
  1419. // round to a tenfold of 1, 2, 2.5 or 5
  1420. magnitude = pick(magnitude, 1);
  1421. normalized = interval / magnitude;
  1422. // multiples for a linear scale
  1423. if (!multiples) {
  1424. multiples = hasTickAmount ?
  1425. // Finer grained ticks when the tick amount is hard set, including
  1426. // when alignTicks is true on multiple axes (#4580).
  1427. [1, 1.2, 1.5, 2, 2.5, 3, 4, 5, 6, 8, 10] :
  1428. // Else, let ticks fall on rounder numbers
  1429. [1, 2, 2.5, 5, 10];
  1430. // the allowDecimals option
  1431. if (allowDecimals === false) {
  1432. if (magnitude === 1) {
  1433. multiples = multiples.filter(function (num) {
  1434. return num % 1 === 0;
  1435. });
  1436. }
  1437. else if (magnitude <= 0.1) {
  1438. multiples = [1 / magnitude];
  1439. }
  1440. }
  1441. }
  1442. // normalize the interval to the nearest multiple
  1443. for (i = 0; i < multiples.length; i++) {
  1444. retInterval = multiples[i];
  1445. // only allow tick amounts smaller than natural
  1446. if ((hasTickAmount &&
  1447. retInterval * magnitude >= interval) ||
  1448. (!hasTickAmount &&
  1449. (normalized <=
  1450. (multiples[i] +
  1451. (multiples[i + 1] || multiples[i])) / 2))) {
  1452. break;
  1453. }
  1454. }
  1455. // Multiply back to the correct magnitude. Correct floats to appropriate
  1456. // precision (#6085).
  1457. retInterval = correctFloat(retInterval * magnitude, -Math.round(Math.log(0.001) / Math.LN10));
  1458. return retInterval;
  1459. };
  1460. /**
  1461. * Sort an object array and keep the order of equal items. The ECMAScript
  1462. * standard does not specify the behaviour when items are equal.
  1463. *
  1464. * @function Highcharts.stableSort
  1465. *
  1466. * @param {Array<*>} arr
  1467. * The array to sort.
  1468. *
  1469. * @param {Function} sortFunction
  1470. * The function to sort it with, like with regular Array.prototype.sort.
  1471. *
  1472. * @return {void}
  1473. */
  1474. var stableSort = H.stableSort = function stableSort(arr, sortFunction) {
  1475. // @todo It seems like Chrome since v70 sorts in a stable way internally,
  1476. // plus all other browsers do it, so over time we may be able to remove this
  1477. // function
  1478. var length = arr.length, sortValue, i;
  1479. // Add index to each item
  1480. for (i = 0; i < length; i++) {
  1481. arr[i].safeI = i; // stable sort index
  1482. }
  1483. arr.sort(function (a, b) {
  1484. sortValue = sortFunction(a, b);
  1485. return sortValue === 0 ? a.safeI - b.safeI : sortValue;
  1486. });
  1487. // Remove index from items
  1488. for (i = 0; i < length; i++) {
  1489. delete arr[i].safeI; // stable sort index
  1490. }
  1491. };
  1492. /**
  1493. * Non-recursive method to find the lowest member of an array. `Math.min` raises
  1494. * a maximum call stack size exceeded error in Chrome when trying to apply more
  1495. * than 150.000 points. This method is slightly slower, but safe.
  1496. *
  1497. * @function Highcharts.arrayMin
  1498. *
  1499. * @param {Array<*>} data
  1500. * An array of numbers.
  1501. *
  1502. * @return {number}
  1503. * The lowest number.
  1504. */
  1505. var arrayMin = H.arrayMin = function arrayMin(data) {
  1506. var i = data.length, min = data[0];
  1507. while (i--) {
  1508. if (data[i] < min) {
  1509. min = data[i];
  1510. }
  1511. }
  1512. return min;
  1513. };
  1514. /**
  1515. * Non-recursive method to find the lowest member of an array. `Math.max` raises
  1516. * a maximum call stack size exceeded error in Chrome when trying to apply more
  1517. * than 150.000 points. This method is slightly slower, but safe.
  1518. *
  1519. * @function Highcharts.arrayMax
  1520. *
  1521. * @param {Array<*>} data
  1522. * An array of numbers.
  1523. *
  1524. * @return {number}
  1525. * The highest number.
  1526. */
  1527. var arrayMax = H.arrayMax = function arrayMax(data) {
  1528. var i = data.length, max = data[0];
  1529. while (i--) {
  1530. if (data[i] > max) {
  1531. max = data[i];
  1532. }
  1533. }
  1534. return max;
  1535. };
  1536. /**
  1537. * Utility method that destroys any SVGElement instances that are properties on
  1538. * the given object. It loops all properties and invokes destroy if there is a
  1539. * destroy method. The property is then delete.
  1540. *
  1541. * @function Highcharts.destroyObjectProperties
  1542. *
  1543. * @param {*} obj
  1544. * The object to destroy properties on.
  1545. *
  1546. * @param {*} [except]
  1547. * Exception, do not destroy this property, only delete it.
  1548. *
  1549. * @return {void}
  1550. */
  1551. var destroyObjectProperties = H.destroyObjectProperties =
  1552. function destroyObjectProperties(obj, except) {
  1553. objectEach(obj, function (val, n) {
  1554. // If the object is non-null and destroy is defined
  1555. if (val && val !== except && val.destroy) {
  1556. // Invoke the destroy
  1557. val.destroy();
  1558. }
  1559. // Delete the property from the object.
  1560. delete obj[n];
  1561. });
  1562. };
  1563. /**
  1564. * Discard a HTML element by moving it to the bin and delete.
  1565. *
  1566. * @function Highcharts.discardElement
  1567. *
  1568. * @param {Highcharts.HTMLDOMElement} element
  1569. * The HTML node to discard.
  1570. *
  1571. * @return {void}
  1572. */
  1573. var discardElement = H.discardElement = function discardElement(element) {
  1574. var garbageBin = H.garbageBin;
  1575. // create a garbage bin element, not part of the DOM
  1576. if (!garbageBin) {
  1577. garbageBin = createElement('div');
  1578. }
  1579. // move the node and empty bin
  1580. if (element) {
  1581. garbageBin.appendChild(element);
  1582. }
  1583. garbageBin.innerHTML = '';
  1584. };
  1585. /**
  1586. * Fix JS round off float errors.
  1587. *
  1588. * @function Highcharts.correctFloat
  1589. *
  1590. * @param {number} num
  1591. * A float number to fix.
  1592. *
  1593. * @param {number} [prec=14]
  1594. * The precision.
  1595. *
  1596. * @return {number}
  1597. * The corrected float number.
  1598. */
  1599. var correctFloat = H.correctFloat = function correctFloat(num, prec) {
  1600. return parseFloat(num.toPrecision(prec || 14));
  1601. };
  1602. /**
  1603. * Set the global animation to either a given value, or fall back to the given
  1604. * chart's animation option.
  1605. *
  1606. * @function Highcharts.setAnimation
  1607. *
  1608. * @param {boolean|Highcharts.AnimationOptionsObject|undefined} animation
  1609. * The animation object.
  1610. *
  1611. * @param {Highcharts.Chart} chart
  1612. * The chart instance.
  1613. *
  1614. * @return {void}
  1615. *
  1616. * @todo
  1617. * This function always relates to a chart, and sets a property on the renderer,
  1618. * so it should be moved to the SVGRenderer.
  1619. */
  1620. var setAnimation = H.setAnimation = function setAnimation(animation, chart) {
  1621. chart.renderer.globalAnimation = pick(animation, chart.options.chart.animation, true);
  1622. };
  1623. /**
  1624. * Get the animation in object form, where a disabled animation is always
  1625. * returned as `{ duration: 0 }`.
  1626. *
  1627. * @function Highcharts.animObject
  1628. *
  1629. * @param {boolean|Highcharts.AnimationOptionsObject} [animation=0]
  1630. * An animation setting. Can be an object with duration, complete and
  1631. * easing properties, or a boolean to enable or disable.
  1632. *
  1633. * @return {Highcharts.AnimationOptionsObject}
  1634. * An object with at least a duration property.
  1635. */
  1636. var animObject = H.animObject = function animObject(animation) {
  1637. return isObject(animation) ?
  1638. merge(animation) :
  1639. { duration: animation ? 500 : 0 };
  1640. };
  1641. /**
  1642. * The time unit lookup
  1643. *
  1644. * @ignore
  1645. */
  1646. var timeUnits = H.timeUnits = {
  1647. millisecond: 1,
  1648. second: 1000,
  1649. minute: 60000,
  1650. hour: 3600000,
  1651. day: 24 * 3600000,
  1652. week: 7 * 24 * 3600000,
  1653. month: 28 * 24 * 3600000,
  1654. year: 364 * 24 * 3600000
  1655. };
  1656. /**
  1657. * Format a number and return a string based on input settings.
  1658. *
  1659. * @sample highcharts/members/highcharts-numberformat/
  1660. * Custom number format
  1661. *
  1662. * @function Highcharts.numberFormat
  1663. *
  1664. * @param {number} number
  1665. * The input number to format.
  1666. *
  1667. * @param {number} decimals
  1668. * The amount of decimals. A value of -1 preserves the amount in the
  1669. * input number.
  1670. *
  1671. * @param {string} [decimalPoint]
  1672. * The decimal point, defaults to the one given in the lang options, or
  1673. * a dot.
  1674. *
  1675. * @param {string} [thousandsSep]
  1676. * The thousands separator, defaults to the one given in the lang
  1677. * options, or a space character.
  1678. *
  1679. * @return {string}
  1680. * The formatted number.
  1681. */
  1682. var numberFormat = H.numberFormat = function numberFormat(number, decimals, decimalPoint, thousandsSep) {
  1683. number = +number || 0;
  1684. decimals = +decimals;
  1685. var lang = H.defaultOptions.lang, origDec = (number.toString().split('.')[1] || '').split('e')[0].length, strinteger, thousands, ret, roundedNumber, exponent = number.toString().split('e'), fractionDigits;
  1686. if (decimals === -1) {
  1687. // Preserve decimals. Not huge numbers (#3793).
  1688. decimals = Math.min(origDec, 20);
  1689. }
  1690. else if (!isNumber(decimals)) {
  1691. decimals = 2;
  1692. }
  1693. else if (decimals && exponent[1] && exponent[1] < 0) {
  1694. // Expose decimals from exponential notation (#7042)
  1695. fractionDigits = decimals + +exponent[1];
  1696. if (fractionDigits >= 0) {
  1697. // remove too small part of the number while keeping the notation
  1698. exponent[0] = (+exponent[0]).toExponential(fractionDigits)
  1699. .split('e')[0];
  1700. decimals = fractionDigits;
  1701. }
  1702. else {
  1703. // fractionDigits < 0
  1704. exponent[0] = exponent[0].split('.')[0] || 0;
  1705. if (decimals < 20) {
  1706. // use number instead of exponential notation (#7405)
  1707. number = (exponent[0] * Math.pow(10, exponent[1]))
  1708. .toFixed(decimals);
  1709. }
  1710. else {
  1711. // or zero
  1712. number = 0;
  1713. }
  1714. exponent[1] = 0;
  1715. }
  1716. }
  1717. // Add another decimal to avoid rounding errors of float numbers. (#4573)
  1718. // Then use toFixed to handle rounding.
  1719. roundedNumber = (Math.abs(exponent[1] ? exponent[0] : number) +
  1720. Math.pow(10, -Math.max(decimals, origDec) - 1)).toFixed(decimals);
  1721. // A string containing the positive integer component of the number
  1722. strinteger = String(pInt(roundedNumber));
  1723. // Leftover after grouping into thousands. Can be 0, 1 or 2.
  1724. thousands = strinteger.length > 3 ? strinteger.length % 3 : 0;
  1725. // Language
  1726. decimalPoint = pick(decimalPoint, lang.decimalPoint);
  1727. thousandsSep = pick(thousandsSep, lang.thousandsSep);
  1728. // Start building the return
  1729. ret = number < 0 ? '-' : '';
  1730. // Add the leftover after grouping into thousands. For example, in the
  1731. // number 42 000 000, this line adds 42.
  1732. ret += thousands ? strinteger.substr(0, thousands) + thousandsSep : '';
  1733. // Add the remaining thousands groups, joined by the thousands separator
  1734. ret += strinteger
  1735. .substr(thousands)
  1736. .replace(/(\d{3})(?=\d)/g, '$1' + thousandsSep);
  1737. // Add the decimal point and the decimal component
  1738. if (decimals) {
  1739. // Get the decimal component
  1740. ret += decimalPoint + roundedNumber.slice(-decimals);
  1741. }
  1742. if (exponent[1] && +ret !== 0) {
  1743. ret += 'e' + exponent[1];
  1744. }
  1745. return ret;
  1746. };
  1747. /**
  1748. * Easing definition
  1749. *
  1750. * @private
  1751. * @function Math.easeInOutSine
  1752. *
  1753. * @param {number} pos
  1754. * Current position, ranging from 0 to 1.
  1755. *
  1756. * @return {number}
  1757. * Ease result
  1758. */
  1759. Math.easeInOutSine = function (pos) {
  1760. return -0.5 * (Math.cos(Math.PI * pos) - 1);
  1761. };
  1762. /**
  1763. * Returns the value of a property path on a given object.
  1764. *
  1765. * @private
  1766. * @function getNestedProperty
  1767. *
  1768. * @param {string} path
  1769. * Path to the property, for example `custom.myValue`.
  1770. *
  1771. * @param {unknown} obj
  1772. * Instance containing the property on the specific path.
  1773. *
  1774. * @return {unknown}
  1775. * The unknown property value.
  1776. */
  1777. function getNestedProperty(path, obj) {
  1778. if (!path) {
  1779. return obj;
  1780. }
  1781. var pathElements = path.split('.').reverse();
  1782. var subProperty = obj;
  1783. if (pathElements.length === 1) {
  1784. return subProperty[path];
  1785. }
  1786. var pathElement = pathElements.pop();
  1787. while (typeof pathElement !== 'undefined' &&
  1788. typeof subProperty !== 'undefined' &&
  1789. subProperty !== null) {
  1790. subProperty = subProperty[pathElement];
  1791. pathElement = pathElements.pop();
  1792. }
  1793. return subProperty;
  1794. }
  1795. /**
  1796. * Get the computed CSS value for given element and property, only for numerical
  1797. * properties. For width and height, the dimension of the inner box (excluding
  1798. * padding) is returned. Used for fitting the chart within the container.
  1799. *
  1800. * @function Highcharts.getStyle
  1801. *
  1802. * @param {Highcharts.HTMLDOMElement} el
  1803. * An HTML element.
  1804. *
  1805. * @param {string} prop
  1806. * The property name.
  1807. *
  1808. * @param {boolean} [toInt=true]
  1809. * Parse to integer.
  1810. *
  1811. * @return {number|string}
  1812. * The numeric value.
  1813. */
  1814. var getStyle = H.getStyle = function (el, prop, toInt) {
  1815. var style;
  1816. // For width and height, return the actual inner pixel size (#4913)
  1817. if (prop === 'width') {
  1818. var offsetWidth = Math.min(el.offsetWidth, el.scrollWidth);
  1819. // In flex boxes, we need to use getBoundingClientRect and floor it,
  1820. // because scrollWidth doesn't support subpixel precision (#6427) ...
  1821. var boundingClientRectWidth = el.getBoundingClientRect &&
  1822. el.getBoundingClientRect().width;
  1823. // ...unless if the containing div or its parents are transform-scaled
  1824. // down, in which case the boundingClientRect can't be used as it is
  1825. // also scaled down (#9871, #10498).
  1826. if (boundingClientRectWidth < offsetWidth &&
  1827. boundingClientRectWidth >= offsetWidth - 1) {
  1828. offsetWidth = Math.floor(boundingClientRectWidth);
  1829. }
  1830. return Math.max(0, // #8377
  1831. (offsetWidth -
  1832. H.getStyle(el, 'padding-left') -
  1833. H.getStyle(el, 'padding-right')));
  1834. }
  1835. if (prop === 'height') {
  1836. return Math.max(0, // #8377
  1837. Math.min(el.offsetHeight, el.scrollHeight) -
  1838. H.getStyle(el, 'padding-top') -
  1839. H.getStyle(el, 'padding-bottom'));
  1840. }
  1841. if (!win.getComputedStyle) {
  1842. // SVG not supported, forgot to load oldie.js?
  1843. error(27, true);
  1844. }
  1845. // Otherwise, get the computed style
  1846. style = win.getComputedStyle(el, undefined); // eslint-disable-line no-undefined
  1847. if (style) {
  1848. style = style.getPropertyValue(prop);
  1849. if (pick(toInt, prop !== 'opacity')) {
  1850. style = pInt(style);
  1851. }
  1852. }
  1853. return style;
  1854. };
  1855. /**
  1856. * Search for an item in an array.
  1857. *
  1858. * @function Highcharts.inArray
  1859. *
  1860. * @deprecated
  1861. *
  1862. * @param {*} item
  1863. * The item to search for.
  1864. *
  1865. * @param {Array<*>} arr
  1866. * The array or node collection to search in.
  1867. *
  1868. * @param {number} [fromIndex=0]
  1869. * The index to start searching from.
  1870. *
  1871. * @return {number}
  1872. * The index within the array, or -1 if not found.
  1873. */
  1874. var inArray = H.inArray = function (item, arr, fromIndex) {
  1875. error(32, false, void 0, { 'Highcharts.inArray': 'use Array.indexOf' });
  1876. return arr.indexOf(item, fromIndex);
  1877. };
  1878. /* eslint-disable valid-jsdoc */
  1879. /**
  1880. * Return the value of the first element in the array that satisfies the
  1881. * provided testing function.
  1882. *
  1883. * @function Highcharts.find<T>
  1884. *
  1885. * @param {Array<T>} arr
  1886. * The array to test.
  1887. *
  1888. * @param {Function} callback
  1889. * The callback function. The function receives the item as the first
  1890. * argument. Return `true` if this item satisfies the condition.
  1891. *
  1892. * @return {T|undefined}
  1893. * The value of the element.
  1894. */
  1895. var find = H.find = Array.prototype.find ?
  1896. /* eslint-enable valid-jsdoc */
  1897. function (arr, callback) {
  1898. return arr.find(callback);
  1899. } :
  1900. // Legacy implementation. PhantomJS, IE <= 11 etc. #7223.
  1901. function (arr, callback) {
  1902. var i, length = arr.length;
  1903. for (i = 0; i < length; i++) {
  1904. if (callback(arr[i], i)) { // eslint-disable-line callback-return
  1905. return arr[i];
  1906. }
  1907. }
  1908. };
  1909. /**
  1910. * Returns an array of a given object's own properties.
  1911. *
  1912. * @function Highcharts.keys
  1913. * @deprecated
  1914. *
  1915. * @param {*} obj
  1916. * The object of which the properties are to be returned.
  1917. *
  1918. * @return {Array<string>}
  1919. * An array of strings that represents all the properties.
  1920. */
  1921. H.keys = function (obj) {
  1922. error(32, false, void 0, { 'Highcharts.keys': 'use Object.keys' });
  1923. return Object.keys(obj);
  1924. };
  1925. /**
  1926. * Get the element's offset position, corrected for `overflow: auto`.
  1927. *
  1928. * @function Highcharts.offset
  1929. *
  1930. * @param {global.Element} el
  1931. * The DOM element.
  1932. *
  1933. * @return {Highcharts.OffsetObject}
  1934. * An object containing `left` and `top` properties for the position in
  1935. * the page.
  1936. */
  1937. var offset = H.offset = function offset(el) {
  1938. var docElem = doc.documentElement, box = (el.parentElement || el.parentNode) ?
  1939. el.getBoundingClientRect() :
  1940. { top: 0, left: 0 };
  1941. return {
  1942. top: box.top + (win.pageYOffset || docElem.scrollTop) -
  1943. (docElem.clientTop || 0),
  1944. left: box.left + (win.pageXOffset || docElem.scrollLeft) -
  1945. (docElem.clientLeft || 0)
  1946. };
  1947. };
  1948. /**
  1949. * Stop running animation.
  1950. *
  1951. * @function Highcharts.stop
  1952. *
  1953. * @param {Highcharts.SVGElement} el
  1954. * The SVGElement to stop animation on.
  1955. *
  1956. * @param {string} [prop]
  1957. * The property to stop animating. If given, the stop method will stop a
  1958. * single property from animating, while others continue.
  1959. *
  1960. * @return {void}
  1961. *
  1962. * @todo
  1963. * A possible extension to this would be to stop a single property, when
  1964. * we want to continue animating others. Then assign the prop to the timer
  1965. * in the Fx.run method, and check for the prop here. This would be an
  1966. * improvement in all cases where we stop the animation from .attr. Instead of
  1967. * stopping everything, we can just stop the actual attributes we're setting.
  1968. */
  1969. var stop = H.stop = function (el, prop) {
  1970. var i = H.timers.length;
  1971. // Remove timers related to this element (#4519)
  1972. while (i--) {
  1973. if (H.timers[i].elem === el && (!prop || prop === H.timers[i].prop)) {
  1974. H.timers[i].stopped = true; // #4667
  1975. }
  1976. }
  1977. };
  1978. /* eslint-disable valid-jsdoc */
  1979. /**
  1980. * Iterate over object key pairs in an object.
  1981. *
  1982. * @function Highcharts.objectEach<T>
  1983. *
  1984. * @param {*} obj
  1985. * The object to iterate over.
  1986. *
  1987. * @param {Highcharts.ObjectEachCallbackFunction<T>} fn
  1988. * The iterator callback. It passes three arguments:
  1989. * * value - The property value.
  1990. * * key - The property key.
  1991. * * obj - The object that objectEach is being applied to.
  1992. *
  1993. * @param {T} [ctx]
  1994. * The context.
  1995. *
  1996. * @return {void}
  1997. */
  1998. var objectEach = H.objectEach = function objectEach(obj, fn, ctx) {
  1999. /* eslint-enable valid-jsdoc */
  2000. for (var key in obj) {
  2001. if (Object.hasOwnProperty.call(obj, key)) {
  2002. fn.call(ctx || obj[key], obj[key], key, obj);
  2003. }
  2004. }
  2005. };
  2006. /**
  2007. * Iterate over an array.
  2008. *
  2009. * @deprecated
  2010. * @function Highcharts.each
  2011. *
  2012. * @param {Array<*>} arr
  2013. * The array to iterate over.
  2014. *
  2015. * @param {Function} fn
  2016. * The iterator callback. It passes three arguments:
  2017. * - `item`: The array item.
  2018. * - `index`: The item's index in the array.
  2019. * - `arr`: The array that each is being applied to.
  2020. *
  2021. * @param {*} [ctx]
  2022. * The context.
  2023. *
  2024. * @return {void}
  2025. */
  2026. /**
  2027. * Filter an array by a callback.
  2028. *
  2029. * @deprecated
  2030. * @function Highcharts.grep
  2031. *
  2032. * @param {Array<*>} arr
  2033. * The array to filter.
  2034. *
  2035. * @param {Function} callback
  2036. * The callback function. The function receives the item as the first
  2037. * argument. Return `true` if the item is to be preserved.
  2038. *
  2039. * @return {Array<*>}
  2040. * A new, filtered array.
  2041. */
  2042. /**
  2043. * Map an array by a callback.
  2044. *
  2045. * @deprecated
  2046. * @function Highcharts.map
  2047. *
  2048. * @param {Array<*>} arr
  2049. * The array to map.
  2050. *
  2051. * @param {Function} fn
  2052. * The callback function. Return the new value for the new array.
  2053. *
  2054. * @return {Array<*>}
  2055. * A new array item with modified items.
  2056. */
  2057. /**
  2058. * Reduce an array to a single value.
  2059. *
  2060. * @deprecated
  2061. * @function Highcharts.reduce
  2062. *
  2063. * @param {Array<*>} arr
  2064. * The array to reduce.
  2065. *
  2066. * @param {Function} fn
  2067. * The callback function. Return the reduced value. Receives 4
  2068. * arguments: Accumulated/reduced value, current value, current array
  2069. * index, and the array.
  2070. *
  2071. * @param {*} initialValue
  2072. * The initial value of the accumulator.
  2073. *
  2074. * @return {*}
  2075. * The reduced value.
  2076. */
  2077. /**
  2078. * Test whether at least one element in the array passes the test implemented by
  2079. * the provided function.
  2080. *
  2081. * @deprecated
  2082. * @function Highcharts.some
  2083. *
  2084. * @param {Array<*>} arr
  2085. * The array to test
  2086. *
  2087. * @param {Function} fn
  2088. * The function to run on each item. Return truty to pass the test.
  2089. * Receives arguments `currentValue`, `index` and `array`.
  2090. *
  2091. * @param {*} ctx
  2092. * The context.
  2093. *
  2094. * @return {boolean}
  2095. */
  2096. objectEach({
  2097. map: 'map',
  2098. each: 'forEach',
  2099. grep: 'filter',
  2100. reduce: 'reduce',
  2101. some: 'some'
  2102. }, function (val, key) {
  2103. H[key] = function (arr) {
  2104. var _a;
  2105. error(32, false, void 0, (_a = {}, _a["Highcharts." + key] = "use Array." + val, _a));
  2106. return Array.prototype[val].apply(arr, [].slice.call(arguments, 1));
  2107. };
  2108. });
  2109. /* eslint-disable valid-jsdoc */
  2110. /**
  2111. * Add an event listener.
  2112. *
  2113. * @function Highcharts.addEvent<T>
  2114. *
  2115. * @param {Highcharts.Class<T>|T} el
  2116. * The element or object to add a listener to. It can be a
  2117. * {@link HTMLDOMElement}, an {@link SVGElement} or any other object.
  2118. *
  2119. * @param {string} type
  2120. * The event type.
  2121. *
  2122. * @param {Highcharts.EventCallbackFunction<T>|Function} fn
  2123. * The function callback to execute when the event is fired.
  2124. *
  2125. * @param {Highcharts.EventOptionsObject} [options]
  2126. * Options for adding the event.
  2127. *
  2128. * @return {Function}
  2129. * A callback function to remove the added event.
  2130. */
  2131. var addEvent = H.addEvent = function (el, type, fn, options) {
  2132. if (options === void 0) { options = {}; }
  2133. /* eslint-enable valid-jsdoc */
  2134. var events, addEventListener = (el.addEventListener || H.addEventListenerPolyfill);
  2135. // If we're setting events directly on the constructor, use a separate
  2136. // collection, `protoEvents` to distinguish it from the item events in
  2137. // `hcEvents`.
  2138. if (typeof el === 'function' && el.prototype) {
  2139. events = el.prototype.protoEvents = el.prototype.protoEvents || {};
  2140. }
  2141. else {
  2142. events = el.hcEvents = el.hcEvents || {};
  2143. }
  2144. // Allow click events added to points, otherwise they will be prevented by
  2145. // the TouchPointer.pinch function after a pinch zoom operation (#7091).
  2146. if (H.Point &&
  2147. el instanceof H.Point &&
  2148. el.series &&
  2149. el.series.chart) {
  2150. el.series.chart.runTrackerClick = true;
  2151. }
  2152. // Handle DOM events
  2153. if (addEventListener) {
  2154. addEventListener.call(el, type, fn, false);
  2155. }
  2156. if (!events[type]) {
  2157. events[type] = [];
  2158. }
  2159. var eventObject = {
  2160. fn: fn,
  2161. order: typeof options.order === 'number' ? options.order : Infinity
  2162. };
  2163. events[type].push(eventObject);
  2164. // Order the calls
  2165. events[type].sort(function (a, b) {
  2166. return a.order - b.order;
  2167. });
  2168. // Return a function that can be called to remove this event.
  2169. return function () {
  2170. removeEvent(el, type, fn);
  2171. };
  2172. };
  2173. /* eslint-disable valid-jsdoc */
  2174. /**
  2175. * Remove an event that was added with {@link Highcharts#addEvent}.
  2176. *
  2177. * @function Highcharts.removeEvent<T>
  2178. *
  2179. * @param {Highcharts.Class<T>|T} el
  2180. * The element to remove events on.
  2181. *
  2182. * @param {string} [type]
  2183. * The type of events to remove. If undefined, all events are removed
  2184. * from the element.
  2185. *
  2186. * @param {Highcharts.EventCallbackFunction<T>} [fn]
  2187. * The specific callback to remove. If undefined, all events that match
  2188. * the element and optionally the type are removed.
  2189. *
  2190. * @return {void}
  2191. */
  2192. var removeEvent = H.removeEvent = function removeEvent(el, type, fn) {
  2193. /* eslint-enable valid-jsdoc */
  2194. var events;
  2195. /**
  2196. * @private
  2197. * @param {string} type - event type
  2198. * @param {Highcharts.EventCallbackFunction<T>} fn - callback
  2199. * @return {void}
  2200. */
  2201. function removeOneEvent(type, fn) {
  2202. var removeEventListener = (el.removeEventListener || H.removeEventListenerPolyfill);
  2203. if (removeEventListener) {
  2204. removeEventListener.call(el, type, fn, false);
  2205. }
  2206. }
  2207. /**
  2208. * @private
  2209. * @param {any} eventCollection - collection
  2210. * @return {void}
  2211. */
  2212. function removeAllEvents(eventCollection) {
  2213. var types, len;
  2214. if (!el.nodeName) {
  2215. return; // break on non-DOM events
  2216. }
  2217. if (type) {
  2218. types = {};
  2219. types[type] = true;
  2220. }
  2221. else {
  2222. types = eventCollection;
  2223. }
  2224. objectEach(types, function (_val, n) {
  2225. if (eventCollection[n]) {
  2226. len = eventCollection[n].length;
  2227. while (len--) {
  2228. removeOneEvent(n, eventCollection[n][len].fn);
  2229. }
  2230. }
  2231. });
  2232. }
  2233. ['protoEvents', 'hcEvents'].forEach(function (coll, i) {
  2234. var eventElem = i ? el : el.prototype;
  2235. var eventCollection = eventElem && eventElem[coll];
  2236. if (eventCollection) {
  2237. if (type) {
  2238. events = (eventCollection[type] || []);
  2239. if (fn) {
  2240. eventCollection[type] = events.filter(function (obj) {
  2241. return fn !== obj.fn;
  2242. });
  2243. removeOneEvent(type, fn);
  2244. }
  2245. else {
  2246. removeAllEvents(eventCollection);
  2247. eventCollection[type] = [];
  2248. }
  2249. }
  2250. else {
  2251. removeAllEvents(eventCollection);
  2252. eventElem[coll] = {};
  2253. }
  2254. }
  2255. });
  2256. };
  2257. /* eslint-disable valid-jsdoc */
  2258. /**
  2259. * Fire an event that was registered with {@link Highcharts#addEvent}.
  2260. *
  2261. * @function Highcharts.fireEvent<T>
  2262. *
  2263. * @param {T} el
  2264. * The object to fire the event on. It can be a {@link HTMLDOMElement},
  2265. * an {@link SVGElement} or any other object.
  2266. *
  2267. * @param {string} type
  2268. * The type of event.
  2269. *
  2270. * @param {Highcharts.Dictionary<*>|Event} [eventArguments]
  2271. * Custom event arguments that are passed on as an argument to the event
  2272. * handler.
  2273. *
  2274. * @param {Highcharts.EventCallbackFunction<T>|Function} [defaultFunction]
  2275. * The default function to execute if the other listeners haven't
  2276. * returned false.
  2277. *
  2278. * @return {void}
  2279. */
  2280. var fireEvent = H.fireEvent = function (el, type, eventArguments, defaultFunction) {
  2281. /* eslint-enable valid-jsdoc */
  2282. var e, i;
  2283. eventArguments = eventArguments || {};
  2284. if (doc.createEvent &&
  2285. (el.dispatchEvent || el.fireEvent)) {
  2286. e = doc.createEvent('Events');
  2287. e.initEvent(type, true, true);
  2288. extend(e, eventArguments);
  2289. if (el.dispatchEvent) {
  2290. el.dispatchEvent(e);
  2291. }
  2292. else {
  2293. el.fireEvent(type, e);
  2294. }
  2295. }
  2296. else {
  2297. if (!eventArguments.target) {
  2298. // We're running a custom event
  2299. extend(eventArguments, {
  2300. // Attach a simple preventDefault function to skip
  2301. // default handler if called. The built-in
  2302. // defaultPrevented property is not overwritable (#5112)
  2303. preventDefault: function () {
  2304. eventArguments.defaultPrevented = true;
  2305. },
  2306. // Setting target to native events fails with clicking
  2307. // the zoom-out button in Chrome.
  2308. target: el,
  2309. // If the type is not set, we're running a custom event
  2310. // (#2297). If it is set, we're running a browser event,
  2311. // and setting it will cause en error in IE8 (#2465).
  2312. type: type
  2313. });
  2314. }
  2315. var fireInOrder = function (protoEvents, hcEvents) {
  2316. if (protoEvents === void 0) { protoEvents = []; }
  2317. if (hcEvents === void 0) { hcEvents = []; }
  2318. var iA = 0;
  2319. var iB = 0;
  2320. var length = protoEvents.length + hcEvents.length;
  2321. for (i = 0; i < length; i++) {
  2322. var obj = (!protoEvents[iA] ?
  2323. hcEvents[iB++] :
  2324. !hcEvents[iB] ?
  2325. protoEvents[iA++] :
  2326. protoEvents[iA].order <= hcEvents[iB].order ?
  2327. protoEvents[iA++] :
  2328. hcEvents[iB++]);
  2329. // If the event handler return false, prevent the default
  2330. // handler from executing
  2331. if (obj.fn.call(el, eventArguments) === false) {
  2332. eventArguments.preventDefault();
  2333. }
  2334. }
  2335. };
  2336. fireInOrder(el.protoEvents && el.protoEvents[type], el.hcEvents && el.hcEvents[type]);
  2337. }
  2338. // Run the default if not prevented
  2339. if (defaultFunction && !eventArguments.defaultPrevented) {
  2340. defaultFunction.call(el, eventArguments);
  2341. }
  2342. };
  2343. /**
  2344. * The global animate method, which uses Fx to create individual animators.
  2345. *
  2346. * @function Highcharts.animate
  2347. *
  2348. * @param {Highcharts.HTMLDOMElement|Highcharts.SVGElement} el
  2349. * The element to animate.
  2350. *
  2351. * @param {Highcharts.CSSObject|Highcharts.SVGAttributes} params
  2352. * An object containing key-value pairs of the properties to animate.
  2353. * Supports numeric as pixel-based CSS properties for HTML objects and
  2354. * attributes for SVGElements.
  2355. *
  2356. * @param {Highcharts.AnimationOptionsObject} [opt]
  2357. * Animation options.
  2358. *
  2359. * @return {void}
  2360. */
  2361. var animate = H.animate = function (el, params, opt) {
  2362. var start, unit = '', end, fx, args;
  2363. if (!isObject(opt)) { // Number or undefined/null
  2364. args = arguments;
  2365. opt = {
  2366. duration: args[2],
  2367. easing: args[3],
  2368. complete: args[4]
  2369. };
  2370. }
  2371. if (!isNumber(opt.duration)) {
  2372. opt.duration = 400;
  2373. }
  2374. opt.easing = typeof opt.easing === 'function' ?
  2375. opt.easing :
  2376. (Math[opt.easing] || Math.easeInOutSine);
  2377. opt.curAnim = merge(params);
  2378. objectEach(params, function (val, prop) {
  2379. // Stop current running animation of this property
  2380. stop(el, prop);
  2381. fx = new Fx(el, opt, prop);
  2382. end = null;
  2383. if (prop === 'd' && isArray(params.d)) {
  2384. fx.paths = fx.initPath(el, el.pathArray, params.d);
  2385. fx.toD = params.d;
  2386. start = 0;
  2387. end = 1;
  2388. }
  2389. else if (el.attr) {
  2390. start = el.attr(prop);
  2391. }
  2392. else {
  2393. start = parseFloat(getStyle(el, prop)) || 0;
  2394. if (prop !== 'opacity') {
  2395. unit = 'px';
  2396. }
  2397. }
  2398. if (!end) {
  2399. end = val;
  2400. }
  2401. if (end && end.match && end.match('px')) {
  2402. end = end.replace(/px/g, ''); // #4351
  2403. }
  2404. fx.run(start, end, unit);
  2405. });
  2406. };
  2407. /**
  2408. * Factory to create new series prototypes.
  2409. *
  2410. * @function Highcharts.seriesType
  2411. *
  2412. * @param {string} type
  2413. * The series type name.
  2414. *
  2415. * @param {string} parent
  2416. * The parent series type name. Use `line` to inherit from the basic
  2417. * {@link Series} object.
  2418. *
  2419. * @param {Highcharts.SeriesOptionsType|Highcharts.Dictionary<*>} options
  2420. * The additional default options that are merged with the parent's
  2421. * options.
  2422. *
  2423. * @param {Highcharts.Dictionary<*>} [props]
  2424. * The properties (functions and primitives) to set on the new
  2425. * prototype.
  2426. *
  2427. * @param {Highcharts.Dictionary<*>} [pointProps]
  2428. * Members for a series-specific extension of the {@link Point}
  2429. * prototype if needed.
  2430. *
  2431. * @return {Highcharts.Series}
  2432. * The newly created prototype as extended from {@link Series} or its
  2433. * derivatives.
  2434. */
  2435. // docs: add to API + extending Highcharts
  2436. var seriesType = H.seriesType = function (type, parent, options, props, pointProps) {
  2437. var defaultOptions = getOptions(), seriesTypes = H.seriesTypes;
  2438. // Merge the options
  2439. defaultOptions.plotOptions[type] = merge(defaultOptions.plotOptions[parent], options);
  2440. // Create the class
  2441. seriesTypes[type] = extendClass(seriesTypes[parent] || function () { }, props);
  2442. seriesTypes[type].prototype.type = type;
  2443. // Create the point class if needed
  2444. if (pointProps) {
  2445. seriesTypes[type].prototype.pointClass =
  2446. extendClass(H.Point, pointProps);
  2447. }
  2448. return seriesTypes[type];
  2449. };
  2450. var serialMode;
  2451. /**
  2452. * Get a unique key for using in internal element id's and pointers. The key is
  2453. * composed of a random hash specific to this Highcharts instance, and a
  2454. * counter.
  2455. *
  2456. * @example
  2457. * var id = uniqueKey(); // => 'highcharts-x45f6hp-0'
  2458. *
  2459. * @function Highcharts.uniqueKey
  2460. *
  2461. * @return {string}
  2462. * A unique key.
  2463. */
  2464. var uniqueKey = H.uniqueKey = (function () {
  2465. var hash = Math.random().toString(36).substring(2, 9) + '-';
  2466. var id = 0;
  2467. return function () {
  2468. return 'highcharts-' + (serialMode ? '' : hash) + id++;
  2469. };
  2470. }());
  2471. /**
  2472. * Activates a serial mode for element IDs provided by
  2473. * {@link Highcharts.uniqueKey}. This mode can be used in automated tests, where
  2474. * a simple comparison of two rendered SVG graphics is needed.
  2475. *
  2476. * **Note:** This is only for testing purposes and will break functionality in
  2477. * webpages with multiple charts.
  2478. *
  2479. * @example
  2480. * if (
  2481. * process &&
  2482. * process.env.NODE_ENV === 'development'
  2483. * ) {
  2484. * Highcharts.useSerialIds(true);
  2485. * }
  2486. *
  2487. * @function Highcharts.useSerialIds
  2488. *
  2489. * @param {boolean} [mode]
  2490. * Changes the state of serial mode.
  2491. *
  2492. * @return {boolean|undefined}
  2493. * State of the serial mode.
  2494. */
  2495. var useSerialIds = H.useSerialIds = function (mode) {
  2496. return (serialMode = pick(mode, serialMode));
  2497. };
  2498. var isFunction = H.isFunction = function (obj) {
  2499. return typeof obj === 'function';
  2500. };
  2501. /**
  2502. * Get the updated default options. Until 3.0.7, merely exposing defaultOptions
  2503. * for outside modules wasn't enough because the setOptions method created a new
  2504. * object.
  2505. *
  2506. * @function Highcharts.getOptions
  2507. *
  2508. * @return {Highcharts.Options}
  2509. */
  2510. var getOptions = H.getOptions = function () {
  2511. return H.defaultOptions;
  2512. };
  2513. /**
  2514. * Merge the default options with custom options and return the new options
  2515. * structure. Commonly used for defining reusable templates.
  2516. *
  2517. * @sample highcharts/global/useutc-false Setting a global option
  2518. * @sample highcharts/members/setoptions Applying a global theme
  2519. *
  2520. * @function Highcharts.setOptions
  2521. *
  2522. * @param {Highcharts.Options} options
  2523. * The new custom chart options.
  2524. *
  2525. * @return {Highcharts.Options}
  2526. * Updated options.
  2527. */
  2528. var setOptions = H.setOptions = function (options) {
  2529. // Copy in the default options
  2530. H.defaultOptions = merge(true, H.defaultOptions, options);
  2531. // Update the time object
  2532. if (options.time || options.global) {
  2533. H.time.update(merge(H.defaultOptions.global, H.defaultOptions.time, options.global, options.time));
  2534. }
  2535. return H.defaultOptions;
  2536. };
  2537. // Register Highcharts as a plugin in jQuery
  2538. if (win.jQuery) {
  2539. /**
  2540. * Highcharts-extended JQuery.
  2541. *
  2542. * @external JQuery
  2543. */
  2544. /**
  2545. * Helper function to return the chart of the current JQuery selector
  2546. * element.
  2547. *
  2548. * @function external:JQuery#highcharts
  2549. *
  2550. * @return {Highcharts.Chart}
  2551. * The chart that is linked to the JQuery selector element.
  2552. */ /**
  2553. * Factory function to create a chart in the current JQuery selector
  2554. * element.
  2555. *
  2556. * @function external:JQuery#highcharts
  2557. *
  2558. * @param {'Chart'|'Map'|'StockChart'|string} [className]
  2559. * Name of the factory class in the Highcharts namespace.
  2560. *
  2561. * @param {Highcharts.Options} [options]
  2562. * The chart options structure.
  2563. *
  2564. * @param {Highcharts.ChartCallbackFunction} [callback]
  2565. * Function to run when the chart has loaded and and all external
  2566. * images are loaded. Defining a
  2567. * [chart.events.load](https://api.highcharts.com/highcharts/chart.events.load)
  2568. * handler is equivalent.
  2569. *
  2570. * @return {JQuery}
  2571. * The current JQuery selector.
  2572. */
  2573. win.jQuery.fn.highcharts = function () {
  2574. var args = [].slice.call(arguments);
  2575. if (this[0]) { // this[0] is the renderTo div
  2576. // Create the chart
  2577. if (args[0]) {
  2578. new H[ // eslint-disable-line computed-property-spacing, no-new
  2579. // Constructor defaults to Chart
  2580. isString(args[0]) ? args.shift() : 'Chart'](this[0], args[0], args[1]);
  2581. return this;
  2582. }
  2583. // When called without parameters or with the return argument,
  2584. // return an existing chart
  2585. return charts[attr(this[0], 'data-highcharts-chart')];
  2586. }
  2587. };
  2588. }
  2589. // TODO use named exports when supported.
  2590. var utilitiesModule = {
  2591. Fx: H.Fx,
  2592. addEvent: addEvent,
  2593. animate: animate,
  2594. animObject: animObject,
  2595. arrayMax: arrayMax,
  2596. arrayMin: arrayMin,
  2597. attr: attr,
  2598. clamp: clamp,
  2599. clearTimeout: internalClearTimeout,
  2600. correctFloat: correctFloat,
  2601. createElement: createElement,
  2602. css: css,
  2603. defined: defined,
  2604. destroyObjectProperties: destroyObjectProperties,
  2605. discardElement: discardElement,
  2606. erase: erase,
  2607. error: error,
  2608. extend: extend,
  2609. extendClass: extendClass,
  2610. find: find,
  2611. fireEvent: fireEvent,
  2612. format: format,
  2613. getMagnitude: getMagnitude,
  2614. getNestedProperty: getNestedProperty,
  2615. getOptions: getOptions,
  2616. getStyle: getStyle,
  2617. inArray: inArray,
  2618. isArray: isArray,
  2619. isClass: isClass,
  2620. isDOMElement: isDOMElement,
  2621. isFunction: isFunction,
  2622. isNumber: isNumber,
  2623. isObject: isObject,
  2624. isString: isString,
  2625. merge: merge,
  2626. normalizeTickInterval: normalizeTickInterval,
  2627. numberFormat: numberFormat,
  2628. objectEach: objectEach,
  2629. offset: offset,
  2630. pad: pad,
  2631. pick: pick,
  2632. pInt: pInt,
  2633. relativeLength: relativeLength,
  2634. removeEvent: removeEvent,
  2635. seriesType: seriesType,
  2636. setAnimation: setAnimation,
  2637. setOptions: setOptions,
  2638. splat: splat,
  2639. stableSort: stableSort,
  2640. stop: stop,
  2641. syncTimeout: syncTimeout,
  2642. timeUnits: timeUnits,
  2643. uniqueKey: uniqueKey,
  2644. useSerialIds: useSerialIds,
  2645. wrap: wrap
  2646. };
  2647. export default utilitiesModule;