Utilities.js 81 KB

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