highcharts 6.1.4 → 6.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (695) hide show
  1. package/bower.json +1 -1
  2. package/css/highcharts.css +17 -0
  3. package/css/highcharts.scss +14 -0
  4. package/css/themes/dark-unica.css +17 -0
  5. package/css/themes/grid-light.css +17 -0
  6. package/css/themes/sand-signika.css +17 -0
  7. package/es-modules/indicators/momentum.src.js +1 -1
  8. package/es-modules/indicators/pivot-points.src.js +6 -1
  9. package/es-modules/masters/highcharts-gantt.src.js +11 -0
  10. package/es-modules/masters/modules/annotations.src.js +1 -1
  11. package/es-modules/masters/modules/arrow-symbols.src.js +12 -0
  12. package/es-modules/masters/modules/broken-axis.src.js +1 -1
  13. package/es-modules/masters/modules/current-date-indicator.src.js +12 -0
  14. package/es-modules/masters/modules/data.src.js +1 -1
  15. package/es-modules/masters/modules/draggable-points.src.js +9 -0
  16. package/es-modules/masters/modules/export-data.src.js +1 -1
  17. package/es-modules/masters/modules/exporting.src.js +1 -1
  18. package/es-modules/masters/modules/funnel.src.js +1 -1
  19. package/es-modules/masters/modules/gantt.src.js +2 -1
  20. package/es-modules/masters/modules/grid-axis.src.js +1 -1
  21. package/es-modules/masters/modules/heatmap.src.js +1 -1
  22. package/es-modules/masters/modules/item-series.src.js +1 -1
  23. package/es-modules/masters/modules/map.src.js +1 -1
  24. package/es-modules/masters/modules/overlapping-datalabels.src.js +1 -1
  25. package/es-modules/masters/modules/pathfinder.src.js +12 -0
  26. package/es-modules/masters/modules/sankey.src.js +1 -1
  27. package/es-modules/masters/modules/series-label.src.js +1 -1
  28. package/es-modules/masters/modules/solid-gauge.src.js +1 -1
  29. package/es-modules/masters/modules/stock.src.js +1 -1
  30. package/es-modules/masters/modules/streamgraph.src.js +1 -1
  31. package/es-modules/masters/modules/treegrid.src.js +12 -0
  32. package/es-modules/masters/modules/variwide.src.js +1 -1
  33. package/es-modules/masters/modules/vector.src.js +1 -1
  34. package/es-modules/masters/modules/windbarb.src.js +1 -1
  35. package/es-modules/masters/modules/xrange.src.js +1 -1
  36. package/es-modules/masters/themes/dark-blue.src.js +1 -1
  37. package/es-modules/masters/themes/dark-green.src.js +1 -1
  38. package/es-modules/masters/themes/dark-unica.src.js +1 -1
  39. package/es-modules/masters/themes/gray.src.js +1 -1
  40. package/es-modules/masters/themes/grid-light.src.js +1 -1
  41. package/es-modules/masters/themes/grid.src.js +1 -1
  42. package/es-modules/masters/themes/sand-signika.src.js +1 -1
  43. package/es-modules/masters/themes/skies.src.js +1 -1
  44. package/es-modules/mixins/centered-series.js +1 -1
  45. package/es-modules/mixins/on-series.js +1 -1
  46. package/es-modules/modules/boost.src.js +22 -14
  47. package/es-modules/modules/broken-axis.src.js +169 -134
  48. package/es-modules/modules/data.src.js +2 -2
  49. package/es-modules/modules/draggable-points.src.js +2257 -0
  50. package/es-modules/modules/drilldown.src.js +1 -0
  51. package/es-modules/modules/export-data.src.js +1 -1
  52. package/es-modules/modules/exporting.src.js +1 -1
  53. package/es-modules/modules/funnel.src.js +1 -1
  54. package/es-modules/modules/item-series.src.js +1 -1
  55. package/es-modules/modules/no-data-to-display.src.js +5 -5
  56. package/es-modules/modules/oldie.src.js +1 -1
  57. package/es-modules/modules/overlapping-datalabels.src.js +38 -22
  58. package/es-modules/modules/parallel-coordinates.src.js +3 -2
  59. package/es-modules/modules/sankey.src.js +1 -1
  60. package/es-modules/modules/series-label.src.js +2 -2
  61. package/es-modules/modules/solid-gauge.src.js +1 -1
  62. package/es-modules/modules/static-scale.src.js +67 -28
  63. package/es-modules/modules/streamgraph.src.js +1 -1
  64. package/es-modules/modules/tilemap.src.js +231 -134
  65. package/es-modules/modules/variwide.src.js +1 -1
  66. package/es-modules/modules/vector.src.js +92 -22
  67. package/es-modules/modules/windbarb.src.js +1 -1
  68. package/es-modules/modules/xrange.src.js +257 -77
  69. package/es-modules/parts/AreaSeries.js +77 -77
  70. package/es-modules/parts/AreaSplineSeries.js +64 -27
  71. package/es-modules/parts/Axis.js +160 -67
  72. package/es-modules/parts/BarSeries.js +68 -51
  73. package/es-modules/parts/CandlestickSeries.js +1 -1
  74. package/es-modules/parts/Chart.js +31 -55
  75. package/es-modules/parts/Color.js +29 -18
  76. package/es-modules/parts/ColumnSeries.js +264 -142
  77. package/es-modules/parts/DataGrouping.js +9 -6
  78. package/es-modules/parts/DataLabels.js +261 -210
  79. package/es-modules/parts/DateTimeAxis.js +26 -7
  80. package/es-modules/parts/Dynamics.js +5 -2
  81. package/es-modules/parts/FlagsSeries.js +1 -1
  82. package/es-modules/parts/Globals.js +1 -1
  83. package/es-modules/parts/Html.js +64 -12
  84. package/es-modules/parts/Interaction.js +187 -63
  85. package/es-modules/parts/Legend.js +7 -3
  86. package/es-modules/parts/LogarithmicAxis.js +35 -4
  87. package/es-modules/parts/MSPointer.js +1 -1
  88. package/es-modules/parts/Navigator.js +27 -5
  89. package/es-modules/parts/OHLCSeries.js +1 -1
  90. package/es-modules/parts/Options.js +15 -13
  91. package/es-modules/parts/OrdinalAxis.js +1 -1
  92. package/es-modules/parts/PieSeries.js +256 -140
  93. package/es-modules/parts/PlotBandSeries.experimental.js +1 -1
  94. package/es-modules/parts/PlotLineOrBand.js +7 -40
  95. package/es-modules/parts/Point.js +28 -4
  96. package/es-modules/parts/Pointer.js +8 -6
  97. package/es-modules/parts/RangeSelector.js +1 -1
  98. package/es-modules/parts/Responsive.js +82 -36
  99. package/es-modules/parts/ScatterSeries.js +57 -25
  100. package/es-modules/parts/ScrollablePlotArea.js +17 -7
  101. package/es-modules/parts/Scrollbar.js +9 -2
  102. package/es-modules/parts/Series.js +22 -9
  103. package/es-modules/parts/SplineSeries.js +51 -29
  104. package/es-modules/parts/Stacking.js +100 -6
  105. package/es-modules/parts/StockChart.js +9 -3
  106. package/es-modules/parts/SvgRenderer.js +15 -10
  107. package/es-modules/parts/Tick.js +150 -30
  108. package/es-modules/parts/Time.js +23 -5
  109. package/es-modules/parts/Tooltip.js +2 -2
  110. package/es-modules/parts/TouchPointer.js +1 -1
  111. package/es-modules/parts/Utilities.js +16 -1
  112. package/es-modules/parts-3d/Axis.js +1 -1
  113. package/es-modules/parts-3d/Chart.js +1 -1
  114. package/es-modules/parts-3d/Column.js +1 -1
  115. package/es-modules/parts-3d/Math.js +1 -1
  116. package/es-modules/parts-3d/Pie.js +1 -1
  117. package/es-modules/parts-3d/SVGRenderer.js +1 -1
  118. package/es-modules/parts-3d/Scatter.js +1 -1
  119. package/es-modules/parts-3d/Series.js +1 -1
  120. package/es-modules/parts-3d/VMLRenderer.js +1 -1
  121. package/es-modules/parts-gantt/ArrowSymbols.js +110 -0
  122. package/es-modules/parts-gantt/CurrentDateIndicator.js +92 -0
  123. package/es-modules/parts-gantt/GanttChart.js +111 -0
  124. package/es-modules/parts-gantt/GanttSeries.js +376 -0
  125. package/es-modules/parts-gantt/GridAxis.js +965 -0
  126. package/es-modules/parts-gantt/Pathfinder.js +1247 -0
  127. package/es-modules/parts-gantt/PathfinderAlgorithms.js +746 -0
  128. package/es-modules/parts-gantt/Tree.js +146 -0
  129. package/es-modules/parts-gantt/TreeGrid.js +917 -0
  130. package/es-modules/parts-map/ColorAxis.js +1 -1
  131. package/es-modules/parts-map/ColorSeriesMixin.js +1 -1
  132. package/es-modules/parts-map/GeoJSON.js +1 -1
  133. package/es-modules/parts-map/HeatmapSeries.js +124 -53
  134. package/es-modules/parts-map/Map.js +1 -1
  135. package/es-modules/parts-map/MapAxis.js +1 -1
  136. package/es-modules/parts-map/MapBubbleSeries.js +1 -1
  137. package/es-modules/parts-map/MapLineSeries.js +1 -1
  138. package/es-modules/parts-map/MapNavigation.js +1 -1
  139. package/es-modules/parts-map/MapPointSeries.js +1 -1
  140. package/es-modules/parts-map/MapPointer.js +1 -1
  141. package/es-modules/parts-map/MapSeries.js +2 -2
  142. package/es-modules/parts-more/AreaRangeSeries.js +80 -38
  143. package/es-modules/parts-more/AreaSplineRangeSeries.js +1 -1
  144. package/es-modules/parts-more/BoxPlotSeries.js +1 -1
  145. package/es-modules/parts-more/BubbleSeries.js +1 -1
  146. package/es-modules/parts-more/ColumnRangeSeries.js +1 -1
  147. package/es-modules/parts-more/ErrorBarSeries.js +1 -1
  148. package/es-modules/parts-more/GaugeSeries.js +1 -1
  149. package/es-modules/parts-more/Pane.js +2 -1
  150. package/es-modules/parts-more/Polar.js +1 -1
  151. package/es-modules/parts-more/PolygonSeries.js +1 -1
  152. package/es-modules/parts-more/RadialAxis.js +5 -4
  153. package/es-modules/parts-more/WaterfallSeries.js +1 -1
  154. package/es-modules/supplemental.docs.js +0 -1955
  155. package/es-modules/themes/dark-blue.js +1 -1
  156. package/es-modules/themes/dark-green.js +1 -1
  157. package/es-modules/themes/dark-unica.js +1 -1
  158. package/es-modules/themes/gray.js +1 -1
  159. package/es-modules/themes/grid-light.js +1 -1
  160. package/es-modules/themes/grid.js +1 -1
  161. package/es-modules/themes/sand-signika.js +1 -1
  162. package/es-modules/themes/skies.js +1 -1
  163. package/highcharts-3d.js +1 -1
  164. package/highcharts-3d.src.js +10 -10
  165. package/highcharts-gantt.js +503 -0
  166. package/highcharts-gantt.js.map +1 -0
  167. package/highcharts-gantt.src.js +49289 -0
  168. package/highcharts-more.js +65 -64
  169. package/highcharts-more.js.map +1 -1
  170. package/highcharts-more.src.js +97 -53
  171. package/highcharts.js +415 -410
  172. package/highcharts.js.map +1 -1
  173. package/highcharts.src.js +2170 -1128
  174. package/highmaps.js +443 -438
  175. package/highmaps.js.map +1 -1
  176. package/highmaps.src.js +1647 -849
  177. package/highstock.js +553 -548
  178. package/highstock.js.map +1 -1
  179. package/highstock.src.js +2398 -1283
  180. package/indicators/accumulation-distribution.js +1 -1
  181. package/indicators/accumulation-distribution.src.js +1 -1
  182. package/indicators/atr.js +1 -1
  183. package/indicators/atr.src.js +1 -1
  184. package/indicators/bollinger-bands.js +1 -1
  185. package/indicators/bollinger-bands.src.js +1 -1
  186. package/indicators/cci.js +1 -1
  187. package/indicators/cci.src.js +1 -1
  188. package/indicators/cmf.js +1 -1
  189. package/indicators/cmf.src.js +1 -1
  190. package/indicators/ema.js +1 -1
  191. package/indicators/ema.src.js +1 -1
  192. package/indicators/ichimoku-kinko-hyo.js +1 -1
  193. package/indicators/ichimoku-kinko-hyo.src.js +1 -1
  194. package/indicators/indicators.js +1 -1
  195. package/indicators/indicators.src.js +1 -1
  196. package/indicators/macd.js +1 -1
  197. package/indicators/macd.src.js +1 -1
  198. package/indicators/mfi.js +1 -1
  199. package/indicators/mfi.src.js +1 -1
  200. package/indicators/momentum.js +1 -1
  201. package/indicators/momentum.src.js +2 -2
  202. package/indicators/pivot-points.js +4 -4
  203. package/indicators/pivot-points.js.map +1 -1
  204. package/indicators/pivot-points.src.js +7 -2
  205. package/indicators/price-envelopes.js +1 -1
  206. package/indicators/price-envelopes.src.js +1 -1
  207. package/indicators/psar.js +1 -1
  208. package/indicators/psar.src.js +1 -1
  209. package/indicators/roc.js +1 -1
  210. package/indicators/roc.src.js +1 -1
  211. package/indicators/rsi.js +1 -1
  212. package/indicators/rsi.src.js +1 -1
  213. package/indicators/stochastic.js +1 -1
  214. package/indicators/stochastic.src.js +1 -1
  215. package/indicators/volume-by-price.js +1 -1
  216. package/indicators/volume-by-price.src.js +1 -1
  217. package/indicators/vwap.js +1 -1
  218. package/indicators/vwap.src.js +1 -1
  219. package/indicators/wma.js +1 -1
  220. package/indicators/wma.src.js +1 -1
  221. package/indicators/zigzag.js +1 -1
  222. package/indicators/zigzag.src.js +1 -1
  223. package/js/es-modules/indicators/momentum.src.js +1 -1
  224. package/js/es-modules/indicators/pivot-points.src.js +6 -1
  225. package/js/es-modules/masters/highcharts-gantt.src.js +11 -0
  226. package/js/es-modules/masters/modules/annotations.src.js +1 -1
  227. package/js/es-modules/masters/modules/arrow-symbols.src.js +12 -0
  228. package/js/es-modules/masters/modules/broken-axis.src.js +1 -1
  229. package/js/es-modules/masters/modules/current-date-indicator.src.js +12 -0
  230. package/js/es-modules/masters/modules/data.src.js +1 -1
  231. package/js/es-modules/masters/modules/draggable-points.src.js +9 -0
  232. package/js/es-modules/masters/modules/export-data.src.js +1 -1
  233. package/js/es-modules/masters/modules/exporting.src.js +1 -1
  234. package/js/es-modules/masters/modules/funnel.src.js +1 -1
  235. package/js/es-modules/masters/modules/gantt.src.js +2 -1
  236. package/js/es-modules/masters/modules/grid-axis.src.js +1 -1
  237. package/js/es-modules/masters/modules/heatmap.src.js +1 -1
  238. package/js/es-modules/masters/modules/item-series.src.js +1 -1
  239. package/js/es-modules/masters/modules/map.src.js +1 -1
  240. package/js/es-modules/masters/modules/overlapping-datalabels.src.js +1 -1
  241. package/js/es-modules/masters/modules/pathfinder.src.js +12 -0
  242. package/js/es-modules/masters/modules/sankey.src.js +1 -1
  243. package/js/es-modules/masters/modules/series-label.src.js +1 -1
  244. package/js/es-modules/masters/modules/solid-gauge.src.js +1 -1
  245. package/js/es-modules/masters/modules/stock.src.js +1 -1
  246. package/js/es-modules/masters/modules/streamgraph.src.js +1 -1
  247. package/js/es-modules/masters/modules/treegrid.src.js +12 -0
  248. package/js/es-modules/masters/modules/variwide.src.js +1 -1
  249. package/js/es-modules/masters/modules/vector.src.js +1 -1
  250. package/js/es-modules/masters/modules/windbarb.src.js +1 -1
  251. package/js/es-modules/masters/modules/xrange.src.js +1 -1
  252. package/js/es-modules/masters/themes/dark-blue.src.js +1 -1
  253. package/js/es-modules/masters/themes/dark-green.src.js +1 -1
  254. package/js/es-modules/masters/themes/dark-unica.src.js +1 -1
  255. package/js/es-modules/masters/themes/gray.src.js +1 -1
  256. package/js/es-modules/masters/themes/grid-light.src.js +1 -1
  257. package/js/es-modules/masters/themes/grid.src.js +1 -1
  258. package/js/es-modules/masters/themes/sand-signika.src.js +1 -1
  259. package/js/es-modules/masters/themes/skies.src.js +1 -1
  260. package/js/es-modules/mixins/centered-series.js +1 -1
  261. package/js/es-modules/mixins/on-series.js +1 -1
  262. package/js/es-modules/modules/boost.src.js +22 -14
  263. package/js/es-modules/modules/broken-axis.src.js +169 -134
  264. package/js/es-modules/modules/data.src.js +2 -2
  265. package/js/es-modules/modules/draggable-points.src.js +2257 -0
  266. package/js/es-modules/modules/drilldown.src.js +1 -0
  267. package/js/es-modules/modules/export-data.src.js +1 -1
  268. package/js/es-modules/modules/exporting.src.js +1 -1
  269. package/js/es-modules/modules/funnel.src.js +1 -1
  270. package/js/es-modules/modules/item-series.src.js +1 -1
  271. package/js/es-modules/modules/no-data-to-display.src.js +5 -5
  272. package/js/es-modules/modules/oldie.src.js +1 -1
  273. package/js/es-modules/modules/overlapping-datalabels.src.js +38 -22
  274. package/js/es-modules/modules/parallel-coordinates.src.js +3 -2
  275. package/js/es-modules/modules/sankey.src.js +1 -1
  276. package/js/es-modules/modules/series-label.src.js +2 -2
  277. package/js/es-modules/modules/solid-gauge.src.js +1 -1
  278. package/js/es-modules/modules/static-scale.src.js +67 -28
  279. package/js/es-modules/modules/streamgraph.src.js +1 -1
  280. package/js/es-modules/modules/tilemap.src.js +231 -134
  281. package/js/es-modules/modules/variwide.src.js +1 -1
  282. package/js/es-modules/modules/vector.src.js +92 -22
  283. package/js/es-modules/modules/windbarb.src.js +1 -1
  284. package/js/es-modules/modules/xrange.src.js +255 -68
  285. package/js/es-modules/parts/AreaSeries.js +77 -77
  286. package/js/es-modules/parts/AreaSplineSeries.js +64 -27
  287. package/js/es-modules/parts/Axis.js +160 -67
  288. package/js/es-modules/parts/BarSeries.js +68 -51
  289. package/js/es-modules/parts/CandlestickSeries.js +1 -1
  290. package/js/es-modules/parts/Chart.js +31 -55
  291. package/js/es-modules/parts/Color.js +29 -18
  292. package/js/es-modules/parts/ColumnSeries.js +231 -123
  293. package/js/es-modules/parts/DataGrouping.js +9 -6
  294. package/js/es-modules/parts/DataLabels.js +230 -182
  295. package/js/es-modules/parts/DateTimeAxis.js +26 -7
  296. package/js/es-modules/parts/Dynamics.js +5 -2
  297. package/js/es-modules/parts/FlagsSeries.js +1 -1
  298. package/js/es-modules/parts/Globals.js +1 -1
  299. package/js/es-modules/parts/Html.js +64 -12
  300. package/js/es-modules/parts/Interaction.js +178 -61
  301. package/js/es-modules/parts/Legend.js +7 -3
  302. package/js/es-modules/parts/LogarithmicAxis.js +35 -4
  303. package/js/es-modules/parts/MSPointer.js +1 -1
  304. package/js/es-modules/parts/Navigator.js +27 -5
  305. package/js/es-modules/parts/OHLCSeries.js +1 -1
  306. package/js/es-modules/parts/Options.js +13 -12
  307. package/js/es-modules/parts/OrdinalAxis.js +1 -1
  308. package/js/es-modules/parts/PieSeries.js +245 -132
  309. package/js/es-modules/parts/PlotBandSeries.experimental.js +1 -1
  310. package/js/es-modules/parts/PlotLineOrBand.js +7 -40
  311. package/js/es-modules/parts/Point.js +28 -4
  312. package/js/es-modules/parts/Pointer.js +8 -6
  313. package/js/es-modules/parts/RangeSelector.js +1 -1
  314. package/js/es-modules/parts/Responsive.js +82 -36
  315. package/js/es-modules/parts/ScatterSeries.js +56 -25
  316. package/js/es-modules/parts/ScrollablePlotArea.js +17 -7
  317. package/js/es-modules/parts/Scrollbar.js +9 -2
  318. package/js/es-modules/parts/Series.js +22 -9
  319. package/js/es-modules/parts/SplineSeries.js +51 -29
  320. package/js/es-modules/parts/Stacking.js +100 -6
  321. package/js/es-modules/parts/StockChart.js +9 -3
  322. package/js/es-modules/parts/SvgRenderer.js +15 -10
  323. package/js/es-modules/parts/Tick.js +150 -30
  324. package/js/es-modules/parts/Time.js +23 -5
  325. package/js/es-modules/parts/Tooltip.js +2 -2
  326. package/js/es-modules/parts/TouchPointer.js +1 -1
  327. package/js/es-modules/parts/Utilities.js +16 -1
  328. package/js/es-modules/parts-3d/Axis.js +1 -1
  329. package/js/es-modules/parts-3d/Chart.js +1 -1
  330. package/js/es-modules/parts-3d/Column.js +1 -1
  331. package/js/es-modules/parts-3d/Math.js +1 -1
  332. package/js/es-modules/parts-3d/Pie.js +1 -1
  333. package/js/es-modules/parts-3d/SVGRenderer.js +1 -1
  334. package/js/es-modules/parts-3d/Scatter.js +1 -1
  335. package/js/es-modules/parts-3d/Series.js +1 -1
  336. package/js/es-modules/parts-3d/VMLRenderer.js +1 -1
  337. package/js/es-modules/parts-gantt/ArrowSymbols.js +110 -0
  338. package/js/es-modules/parts-gantt/CurrentDateIndicator.js +92 -0
  339. package/js/es-modules/parts-gantt/GanttChart.js +111 -0
  340. package/js/es-modules/parts-gantt/GanttSeries.js +371 -0
  341. package/js/es-modules/parts-gantt/GridAxis.js +962 -0
  342. package/js/es-modules/parts-gantt/Pathfinder.js +1225 -0
  343. package/js/es-modules/parts-gantt/PathfinderAlgorithms.js +746 -0
  344. package/js/es-modules/parts-gantt/Tree.js +146 -0
  345. package/js/es-modules/parts-gantt/TreeGrid.js +891 -0
  346. package/js/es-modules/parts-map/ColorAxis.js +1 -1
  347. package/js/es-modules/parts-map/ColorSeriesMixin.js +1 -1
  348. package/js/es-modules/parts-map/GeoJSON.js +1 -1
  349. package/js/es-modules/parts-map/HeatmapSeries.js +122 -52
  350. package/js/es-modules/parts-map/Map.js +1 -1
  351. package/js/es-modules/parts-map/MapAxis.js +1 -1
  352. package/js/es-modules/parts-map/MapBubbleSeries.js +1 -1
  353. package/js/es-modules/parts-map/MapLineSeries.js +1 -1
  354. package/js/es-modules/parts-map/MapNavigation.js +1 -1
  355. package/js/es-modules/parts-map/MapPointSeries.js +1 -1
  356. package/js/es-modules/parts-map/MapPointer.js +1 -1
  357. package/js/es-modules/parts-map/MapSeries.js +2 -2
  358. package/js/es-modules/parts-more/AreaRangeSeries.js +80 -38
  359. package/js/es-modules/parts-more/AreaSplineRangeSeries.js +1 -1
  360. package/js/es-modules/parts-more/BoxPlotSeries.js +1 -1
  361. package/js/es-modules/parts-more/BubbleSeries.js +1 -1
  362. package/js/es-modules/parts-more/ColumnRangeSeries.js +1 -1
  363. package/js/es-modules/parts-more/ErrorBarSeries.js +1 -1
  364. package/js/es-modules/parts-more/GaugeSeries.js +1 -1
  365. package/js/es-modules/parts-more/Pane.js +2 -1
  366. package/js/es-modules/parts-more/Polar.js +1 -1
  367. package/js/es-modules/parts-more/PolygonSeries.js +1 -1
  368. package/js/es-modules/parts-more/RadialAxis.js +5 -4
  369. package/js/es-modules/parts-more/WaterfallSeries.js +1 -1
  370. package/js/es-modules/supplemental.docs.js +0 -1955
  371. package/js/es-modules/themes/dark-blue.js +1 -1
  372. package/js/es-modules/themes/dark-green.js +1 -1
  373. package/js/es-modules/themes/dark-unica.js +1 -1
  374. package/js/es-modules/themes/gray.js +1 -1
  375. package/js/es-modules/themes/grid-light.js +1 -1
  376. package/js/es-modules/themes/grid.js +1 -1
  377. package/js/es-modules/themes/sand-signika.js +1 -1
  378. package/js/es-modules/themes/skies.js +1 -1
  379. package/js/highcharts-3d.js +1 -1
  380. package/js/highcharts-3d.src.js +10 -10
  381. package/js/highcharts-gantt.js +480 -0
  382. package/js/highcharts-gantt.js.map +1 -0
  383. package/js/highcharts-gantt.src.js +47011 -0
  384. package/js/highcharts-more.js +62 -61
  385. package/js/highcharts-more.js.map +1 -1
  386. package/js/highcharts-more.src.js +97 -53
  387. package/js/highcharts.js +394 -390
  388. package/js/highcharts.js.map +1 -1
  389. package/js/highcharts.src.js +2083 -1070
  390. package/js/highmaps.js +420 -416
  391. package/js/highmaps.js.map +1 -1
  392. package/js/highmaps.src.js +1569 -798
  393. package/js/highstock.js +526 -520
  394. package/js/highstock.js.map +1 -1
  395. package/js/highstock.src.js +2311 -1225
  396. package/js/indicators/accumulation-distribution.js +1 -1
  397. package/js/indicators/accumulation-distribution.src.js +1 -1
  398. package/js/indicators/atr.js +1 -1
  399. package/js/indicators/atr.src.js +1 -1
  400. package/js/indicators/bollinger-bands.js +1 -1
  401. package/js/indicators/bollinger-bands.src.js +1 -1
  402. package/js/indicators/cci.js +1 -1
  403. package/js/indicators/cci.src.js +1 -1
  404. package/js/indicators/cmf.js +1 -1
  405. package/js/indicators/cmf.src.js +1 -1
  406. package/js/indicators/ema.js +1 -1
  407. package/js/indicators/ema.src.js +1 -1
  408. package/js/indicators/ichimoku-kinko-hyo.js +1 -1
  409. package/js/indicators/ichimoku-kinko-hyo.src.js +1 -1
  410. package/js/indicators/indicators.js +1 -1
  411. package/js/indicators/indicators.src.js +1 -1
  412. package/js/indicators/macd.js +1 -1
  413. package/js/indicators/macd.src.js +1 -1
  414. package/js/indicators/mfi.js +1 -1
  415. package/js/indicators/mfi.src.js +1 -1
  416. package/js/indicators/momentum.js +1 -1
  417. package/js/indicators/momentum.src.js +2 -2
  418. package/js/indicators/pivot-points.js +4 -4
  419. package/js/indicators/pivot-points.js.map +1 -1
  420. package/js/indicators/pivot-points.src.js +7 -2
  421. package/js/indicators/price-envelopes.js +1 -1
  422. package/js/indicators/price-envelopes.src.js +1 -1
  423. package/js/indicators/psar.js +1 -1
  424. package/js/indicators/psar.src.js +1 -1
  425. package/js/indicators/roc.js +1 -1
  426. package/js/indicators/roc.src.js +1 -1
  427. package/js/indicators/rsi.js +1 -1
  428. package/js/indicators/rsi.src.js +1 -1
  429. package/js/indicators/stochastic.js +1 -1
  430. package/js/indicators/stochastic.src.js +1 -1
  431. package/js/indicators/volume-by-price.js +1 -1
  432. package/js/indicators/volume-by-price.src.js +1 -1
  433. package/js/indicators/vwap.js +1 -1
  434. package/js/indicators/vwap.src.js +1 -1
  435. package/js/indicators/wma.js +1 -1
  436. package/js/indicators/wma.src.js +1 -1
  437. package/js/indicators/zigzag.js +1 -1
  438. package/js/indicators/zigzag.src.js +1 -1
  439. package/js/modules/accessibility.js +1 -1
  440. package/js/modules/accessibility.src.js +1 -1
  441. package/js/modules/annotations.js +2 -2
  442. package/js/modules/annotations.src.js +2 -2
  443. package/js/modules/arrow-symbols.js +13 -0
  444. package/js/modules/arrow-symbols.js.map +1 -0
  445. package/js/modules/arrow-symbols.src.js +138 -0
  446. package/js/modules/boost-canvas.js +1 -1
  447. package/js/modules/boost-canvas.src.js +1 -1
  448. package/js/modules/boost.js +43 -43
  449. package/js/modules/boost.js.map +1 -1
  450. package/js/modules/boost.src.js +23 -15
  451. package/js/modules/broken-axis.js +11 -10
  452. package/js/modules/broken-axis.js.map +1 -1
  453. package/js/modules/broken-axis.src.js +171 -136
  454. package/js/modules/bullet.js +1 -1
  455. package/js/modules/bullet.src.js +1 -1
  456. package/js/modules/current-date-indicator.js +13 -0
  457. package/js/modules/current-date-indicator.js.map +1 -0
  458. package/js/modules/current-date-indicator.src.js +120 -0
  459. package/js/modules/data.js +2 -2
  460. package/js/modules/data.src.js +4 -4
  461. package/js/modules/drag-panes.js +1 -1
  462. package/js/modules/drag-panes.src.js +1 -1
  463. package/js/modules/draggable-points.js +38 -0
  464. package/js/modules/draggable-points.js.map +1 -0
  465. package/js/modules/draggable-points.src.js +2281 -0
  466. package/js/modules/drilldown.js +1 -1
  467. package/js/modules/drilldown.js.map +1 -1
  468. package/js/modules/drilldown.src.js +2 -1
  469. package/js/modules/export-data.js +2 -2
  470. package/js/modules/export-data.src.js +3 -3
  471. package/js/modules/exporting.js +2 -2
  472. package/js/modules/exporting.src.js +3 -3
  473. package/js/modules/funnel.js +2 -2
  474. package/js/modules/funnel.src.js +3 -3
  475. package/js/modules/gantt.js +80 -18
  476. package/js/modules/gantt.js.map +1 -1
  477. package/js/modules/gantt.src.js +5490 -372
  478. package/js/modules/grid-axis.js +15 -11
  479. package/js/modules/grid-axis.js.map +1 -1
  480. package/js/modules/grid-axis.src.js +731 -293
  481. package/js/modules/heatmap.js +2 -2
  482. package/js/modules/heatmap.js.map +1 -1
  483. package/js/modules/heatmap.src.js +126 -56
  484. package/js/modules/histogram-bellcurve.js +1 -1
  485. package/js/modules/histogram-bellcurve.src.js +1 -1
  486. package/js/modules/item-series.js +2 -2
  487. package/js/modules/item-series.src.js +3 -3
  488. package/js/modules/map.js +2 -2
  489. package/js/modules/map.js.map +1 -1
  490. package/js/modules/map.src.js +137 -67
  491. package/js/modules/no-data-to-display.js +1 -1
  492. package/js/modules/no-data-to-display.src.js +6 -6
  493. package/js/modules/offline-exporting.js +2 -2
  494. package/js/modules/offline-exporting.src.js +2 -2
  495. package/js/modules/oldie.js +2 -2
  496. package/js/modules/oldie.src.js +3 -3
  497. package/js/modules/overlapping-datalabels.js +2 -2
  498. package/js/modules/overlapping-datalabels.src.js +2 -2
  499. package/js/modules/parallel-coordinates.js +9 -9
  500. package/js/modules/parallel-coordinates.js.map +1 -1
  501. package/js/modules/parallel-coordinates.src.js +4 -3
  502. package/js/modules/pareto.js +1 -1
  503. package/js/modules/pareto.src.js +1 -1
  504. package/js/modules/pathfinder.js +34 -0
  505. package/js/modules/pathfinder.js.map +1 -0
  506. package/js/modules/pathfinder.src.js +2106 -0
  507. package/js/modules/pattern-fill.js +1 -1
  508. package/js/modules/pattern-fill.src.js +1 -1
  509. package/js/modules/sankey.js +2 -2
  510. package/js/modules/sankey.src.js +3 -3
  511. package/js/modules/series-label.js +2 -2
  512. package/js/modules/series-label.src.js +4 -4
  513. package/js/modules/solid-gauge.js +2 -2
  514. package/js/modules/solid-gauge.src.js +3 -3
  515. package/js/modules/static-scale.js +3 -3
  516. package/js/modules/static-scale.js.map +1 -1
  517. package/js/modules/static-scale.src.js +65 -26
  518. package/js/modules/stock.js +135 -134
  519. package/js/modules/stock.js.map +1 -1
  520. package/js/modules/stock.src.js +230 -157
  521. package/js/modules/streamgraph.js +2 -2
  522. package/js/modules/streamgraph.src.js +3 -3
  523. package/js/modules/sunburst.js +1 -1
  524. package/js/modules/sunburst.src.js +1 -1
  525. package/js/modules/tilemap.js +1 -1
  526. package/js/modules/tilemap.js.map +1 -1
  527. package/js/modules/tilemap.src.js +355 -188
  528. package/js/modules/treegrid.js +51 -0
  529. package/js/modules/treegrid.js.map +1 -0
  530. package/js/modules/treegrid.src.js +2759 -0
  531. package/js/modules/treemap.js +1 -1
  532. package/js/modules/treemap.src.js +1 -1
  533. package/js/modules/variable-pie.js +1 -1
  534. package/js/modules/variable-pie.src.js +1 -1
  535. package/js/modules/variwide.js +2 -2
  536. package/js/modules/variwide.src.js +3 -3
  537. package/js/modules/vector.js +2 -2
  538. package/js/modules/vector.js.map +1 -1
  539. package/js/modules/vector.src.js +94 -24
  540. package/js/modules/windbarb.js +2 -2
  541. package/js/modules/windbarb.src.js +4 -4
  542. package/js/modules/wordcloud.js +1 -1
  543. package/js/modules/wordcloud.src.js +1 -1
  544. package/js/modules/xrange.js +11 -10
  545. package/js/modules/xrange.js.map +1 -1
  546. package/js/modules/xrange.src.js +257 -70
  547. package/js/themes/avocado.js +1 -1
  548. package/js/themes/avocado.src.js +1 -1
  549. package/js/themes/dark-blue.js +2 -2
  550. package/js/themes/dark-blue.src.js +3 -3
  551. package/js/themes/dark-green.js +2 -2
  552. package/js/themes/dark-green.src.js +3 -3
  553. package/js/themes/dark-unica.js +2 -2
  554. package/js/themes/dark-unica.src.js +3 -3
  555. package/js/themes/gray.js +2 -2
  556. package/js/themes/gray.src.js +3 -3
  557. package/js/themes/grid-light.js +2 -2
  558. package/js/themes/grid-light.src.js +3 -3
  559. package/js/themes/grid.js +2 -2
  560. package/js/themes/grid.src.js +3 -3
  561. package/js/themes/sand-signika.js +2 -2
  562. package/js/themes/sand-signika.src.js +3 -3
  563. package/js/themes/skies.js +2 -2
  564. package/js/themes/skies.src.js +3 -3
  565. package/js/themes/sunset.js +1 -1
  566. package/js/themes/sunset.src.js +1 -1
  567. package/modules/accessibility.js +1 -1
  568. package/modules/accessibility.src.js +1 -1
  569. package/modules/annotations.js +2 -2
  570. package/modules/annotations.src.js +2 -2
  571. package/modules/arrow-symbols.js +13 -0
  572. package/modules/arrow-symbols.js.map +1 -0
  573. package/modules/arrow-symbols.src.js +138 -0
  574. package/modules/boost-canvas.js +1 -1
  575. package/modules/boost-canvas.src.js +1 -1
  576. package/modules/boost.js +36 -36
  577. package/modules/boost.js.map +1 -1
  578. package/modules/boost.src.js +23 -15
  579. package/modules/broken-axis.js +11 -10
  580. package/modules/broken-axis.js.map +1 -1
  581. package/modules/broken-axis.src.js +171 -136
  582. package/modules/bullet.js +1 -1
  583. package/modules/bullet.src.js +1 -1
  584. package/modules/current-date-indicator.js +13 -0
  585. package/modules/current-date-indicator.js.map +1 -0
  586. package/modules/current-date-indicator.src.js +120 -0
  587. package/modules/data.js +2 -2
  588. package/modules/data.src.js +4 -4
  589. package/modules/drag-panes.js +1 -1
  590. package/modules/drag-panes.src.js +1 -1
  591. package/modules/draggable-points.js +38 -0
  592. package/modules/draggable-points.js.map +1 -0
  593. package/modules/draggable-points.src.js +2281 -0
  594. package/modules/drilldown.js +1 -1
  595. package/modules/drilldown.js.map +1 -1
  596. package/modules/drilldown.src.js +2 -1
  597. package/modules/export-data.js +2 -2
  598. package/modules/export-data.src.js +3 -3
  599. package/modules/exporting.js +2 -2
  600. package/modules/exporting.src.js +3 -3
  601. package/modules/funnel.js +2 -2
  602. package/modules/funnel.src.js +3 -3
  603. package/modules/gantt.js +83 -19
  604. package/modules/gantt.js.map +1 -1
  605. package/modules/gantt.src.js +5553 -379
  606. package/modules/grid-axis.js +16 -11
  607. package/modules/grid-axis.js.map +1 -1
  608. package/modules/grid-axis.src.js +732 -293
  609. package/modules/heatmap.js +2 -2
  610. package/modules/heatmap.js.map +1 -1
  611. package/modules/heatmap.src.js +128 -57
  612. package/modules/histogram-bellcurve.js +1 -1
  613. package/modules/histogram-bellcurve.src.js +1 -1
  614. package/modules/item-series.js +2 -2
  615. package/modules/item-series.src.js +3 -3
  616. package/modules/map.js +2 -2
  617. package/modules/map.js.map +1 -1
  618. package/modules/map.src.js +139 -68
  619. package/modules/no-data-to-display.js +1 -1
  620. package/modules/no-data-to-display.src.js +6 -6
  621. package/modules/offline-exporting.js +2 -2
  622. package/modules/offline-exporting.src.js +2 -2
  623. package/modules/oldie.js +2 -2
  624. package/modules/oldie.src.js +3 -3
  625. package/modules/overlapping-datalabels.js +2 -2
  626. package/modules/overlapping-datalabels.src.js +2 -2
  627. package/modules/parallel-coordinates.js +8 -8
  628. package/modules/parallel-coordinates.js.map +1 -1
  629. package/modules/parallel-coordinates.src.js +4 -3
  630. package/modules/pareto.js +1 -1
  631. package/modules/pareto.src.js +1 -1
  632. package/modules/pathfinder.js +35 -0
  633. package/modules/pathfinder.js.map +1 -0
  634. package/modules/pathfinder.src.js +2128 -0
  635. package/modules/pattern-fill.js +1 -1
  636. package/modules/pattern-fill.src.js +1 -1
  637. package/modules/sankey.js +2 -2
  638. package/modules/sankey.src.js +3 -3
  639. package/modules/series-label.js +2 -2
  640. package/modules/series-label.src.js +4 -4
  641. package/modules/solid-gauge.js +2 -2
  642. package/modules/solid-gauge.src.js +3 -3
  643. package/modules/static-scale.js +3 -3
  644. package/modules/static-scale.js.map +1 -1
  645. package/modules/static-scale.src.js +65 -26
  646. package/modules/stock.js +142 -142
  647. package/modules/stock.js.map +1 -1
  648. package/modules/stock.src.js +230 -157
  649. package/modules/streamgraph.js +2 -2
  650. package/modules/streamgraph.src.js +3 -3
  651. package/modules/sunburst.js +1 -1
  652. package/modules/sunburst.src.js +1 -1
  653. package/modules/tilemap.js +1 -1
  654. package/modules/tilemap.js.map +1 -1
  655. package/modules/tilemap.src.js +357 -189
  656. package/modules/treegrid.js +52 -0
  657. package/modules/treegrid.js.map +1 -0
  658. package/modules/treegrid.src.js +2797 -0
  659. package/modules/treemap.js +1 -1
  660. package/modules/treemap.src.js +1 -1
  661. package/modules/variable-pie.js +1 -1
  662. package/modules/variable-pie.src.js +1 -1
  663. package/modules/variwide.js +2 -2
  664. package/modules/variwide.src.js +3 -3
  665. package/modules/vector.js +2 -2
  666. package/modules/vector.js.map +1 -1
  667. package/modules/vector.src.js +94 -24
  668. package/modules/windbarb.js +2 -2
  669. package/modules/windbarb.src.js +4 -4
  670. package/modules/wordcloud.js +1 -1
  671. package/modules/wordcloud.src.js +1 -1
  672. package/modules/xrange.js +12 -11
  673. package/modules/xrange.js.map +1 -1
  674. package/modules/xrange.src.js +259 -79
  675. package/package.json +1 -1
  676. package/themes/avocado.js +1 -1
  677. package/themes/avocado.src.js +1 -1
  678. package/themes/dark-blue.js +2 -2
  679. package/themes/dark-blue.src.js +3 -3
  680. package/themes/dark-green.js +2 -2
  681. package/themes/dark-green.src.js +3 -3
  682. package/themes/dark-unica.js +2 -2
  683. package/themes/dark-unica.src.js +3 -3
  684. package/themes/gray.js +2 -2
  685. package/themes/gray.src.js +3 -3
  686. package/themes/grid-light.js +2 -2
  687. package/themes/grid-light.src.js +3 -3
  688. package/themes/grid.js +2 -2
  689. package/themes/grid.src.js +3 -3
  690. package/themes/sand-signika.js +2 -2
  691. package/themes/sand-signika.src.js +3 -3
  692. package/themes/skies.js +2 -2
  693. package/themes/skies.src.js +3 -3
  694. package/themes/sunset.js +1 -1
  695. package/themes/sunset.src.js +1 -1
@@ -0,0 +1,2106 @@
1
+ /**
2
+ * @license Highcharts JS v6.2.0 (2018-10-17)
3
+ * Pathfinder
4
+ *
5
+ * (c) 2016 Øystein Moseng
6
+ *
7
+ * --- WORK IN PROGRESS ---
8
+ *
9
+ * License: www.highcharts.com/license
10
+ */
11
+ 'use strict';
12
+ (function (factory) {
13
+ if (typeof module === 'object' && module.exports) {
14
+ module.exports = factory;
15
+ } else if (typeof define === 'function' && define.amd) {
16
+ define(function () {
17
+ return factory;
18
+ });
19
+ } else {
20
+ factory(Highcharts);
21
+ }
22
+ }(function (Highcharts) {
23
+ var algorithms = (function (H) {
24
+ /**
25
+ * (c) 2016 Highsoft AS
26
+ * Author: Øystein Moseng
27
+ *
28
+ * License: www.highcharts.com/license
29
+ */
30
+
31
+ var min = Math.min,
32
+ max = Math.max,
33
+ abs = Math.abs,
34
+ pick = H.pick;
35
+
36
+ /**
37
+ * Get index of last obstacle before xMin. Employs a type of binary search, and
38
+ * thus requires that obstacles are sorted by xMin value.
39
+ *
40
+ * @param {Array} obstacles Array of obstacles to search in.
41
+ * @param {Number} xMin The xMin threshold.
42
+ * @param {Number} startIx Starting index to search from. Must be within array
43
+ * range.
44
+ *
45
+ * @return {Number} result The index of the last obstacle element before xMin.
46
+ */
47
+ function findLastObstacleBefore(obstacles, xMin, startIx) {
48
+ var left = startIx || 0, // left limit
49
+ right = obstacles.length - 1, // right limit
50
+ min = xMin - 0.0000001, // Make sure we include all obstacles at xMin
51
+ cursor,
52
+ cmp;
53
+ while (left <= right) {
54
+ cursor = (right + left) >> 1;
55
+ cmp = min - obstacles[cursor].xMin;
56
+ if (cmp > 0) {
57
+ left = cursor + 1;
58
+ } else if (cmp < 0) {
59
+ right = cursor - 1;
60
+ } else {
61
+ return cursor;
62
+ }
63
+ }
64
+ return left > 0 ? left - 1 : 0;
65
+ }
66
+
67
+ /**
68
+ * Test if a point lays within an obstacle.
69
+ *
70
+ * @param {Object} obstacle Obstacle to test.
71
+ * @param {Object} point Point with x/y props.
72
+ *
73
+ * @return {Boolean} result Whether point is within the obstacle or not.
74
+ */
75
+ function pointWithinObstacle(obstacle, point) {
76
+ return (
77
+ point.x <= obstacle.xMax &&
78
+ point.x >= obstacle.xMin &&
79
+ point.y <= obstacle.yMax &&
80
+ point.y >= obstacle.yMin
81
+ );
82
+ }
83
+
84
+ /**
85
+ * Find the index of an obstacle that wraps around a point.
86
+ * Returns -1 if not found.
87
+ *
88
+ * @param {Array} obstacles Obstacles to test.
89
+ * @param {Object} point Point with x/y props.
90
+ *
91
+ * @return {Number} result Ix of the obstacle in the array, or -1 if not found.
92
+ */
93
+ function findObstacleFromPoint(obstacles, point) {
94
+ var i = findLastObstacleBefore(obstacles, point.x + 1) + 1;
95
+ while (i--) {
96
+ if (obstacles[i].xMax >= point.x &&
97
+ // optimization using lazy evaluation
98
+ pointWithinObstacle(obstacles[i], point)) {
99
+ return i;
100
+ }
101
+ }
102
+ return -1;
103
+ }
104
+
105
+ /**
106
+ * Get SVG path array from array of line segments.
107
+ *
108
+ * @param {Array} segments The segments to build the path from.
109
+ *
110
+ * @return {Array} result SVG path array as accepted by the SVG Renderer.
111
+ */
112
+ function pathFromSegments(segments) {
113
+ var path = [];
114
+ if (segments.length) {
115
+ path.push('M', segments[0].start.x, segments[0].start.y);
116
+ for (var i = 0; i < segments.length; ++i) {
117
+ path.push('L', segments[i].end.x, segments[i].end.y);
118
+ }
119
+ }
120
+ return path;
121
+ }
122
+
123
+ /**
124
+ * Limits obstacle max/mins in all directions to bounds. Modifies input
125
+ * obstacle.
126
+ *
127
+ * @param {Object} obstacle Obstacle to limit.
128
+ * @param {Object} bounds Bounds to use as limit.
129
+ */
130
+ function limitObstacleToBounds(obstacle, bounds) {
131
+ obstacle.yMin = max(obstacle.yMin, bounds.yMin);
132
+ obstacle.yMax = min(obstacle.yMax, bounds.yMax);
133
+ obstacle.xMin = max(obstacle.xMin, bounds.xMin);
134
+ obstacle.xMax = min(obstacle.xMax, bounds.xMax);
135
+ }
136
+
137
+
138
+
139
+ // Define the available pathfinding algorithms.
140
+ // Algorithms take up to 3 arguments: starting point, ending point, and an
141
+ // options object.
142
+ var algorithms = {
143
+
144
+ /**
145
+ * Get an SVG path from a starting coordinate to an ending coordinate.
146
+ * Draws a straight line.
147
+ *
148
+ * @param {Object} start Starting coordinate, object with x/y props.
149
+ * @param {Object} end Ending coordinate, object with x/y props.
150
+ *
151
+ * @return {Object} result An object with the SVG path in Array form as
152
+ * accepted by the SVG renderer, as well as an array of new obstacles
153
+ * making up this path.
154
+ */
155
+ straight: function (start, end) {
156
+ return {
157
+ path: ['M', start.x, start.y, 'L', end.x, end.y],
158
+ obstacles: [{ start: start, end: end }]
159
+ };
160
+ },
161
+
162
+ /**
163
+ * Find a path from a starting coordinate to an ending coordinate, using
164
+ * right angles only, and taking only starting/ending obstacle into
165
+ * consideration.
166
+ *
167
+ * Options
168
+ * - chartObstacles: Array of chart obstacles to avoid
169
+ * - startDirectionX: Optional. True if starting in the X direction.
170
+ * If not provided, the algorithm starts in the
171
+ * direction that is the furthest between
172
+ * start/end.
173
+ *
174
+ * @param {Object} start Starting coordinate, object with x/y props.
175
+ * @param {Object} end Ending coordinate, object with x/y props.
176
+ * @param {Object} options Options for the algorithm.
177
+ *
178
+ * @return {Object} result An object with the SVG path in Array form as
179
+ * accepted by the SVG renderer, as well as an array of new obstacles
180
+ * making up this path.
181
+ */
182
+ simpleConnect: H.extend(function (start, end, options) {
183
+ var segments = [],
184
+ endSegment,
185
+ dir = pick(
186
+ options.startDirectionX,
187
+ abs(end.x - start.x) > abs(end.y - start.y)
188
+ ) ? 'x' : 'y',
189
+ chartObstacles = options.chartObstacles,
190
+ startObstacleIx = findObstacleFromPoint(chartObstacles, start),
191
+ endObstacleIx = findObstacleFromPoint(chartObstacles, end),
192
+ startObstacle,
193
+ endObstacle,
194
+ prevWaypoint,
195
+ waypoint,
196
+ waypoint2,
197
+ useMax,
198
+ endPoint;
199
+
200
+ // Return a clone of a point with a property set from a target object,
201
+ // optionally with an offset
202
+ function copyFromPoint(from, fromKey, to, toKey, offset) {
203
+ var point = {
204
+ x: from.x,
205
+ y: from.y
206
+ };
207
+ point[fromKey] = to[toKey || fromKey] + (offset || 0);
208
+ return point;
209
+ }
210
+
211
+ // Return waypoint outside obstacle
212
+ function getMeOut(obstacle, point, direction) {
213
+ var useMax = abs(point[direction] - obstacle[direction + 'Min']) >
214
+ abs(point[direction] - obstacle[direction + 'Max']);
215
+ return copyFromPoint(
216
+ point,
217
+ direction,
218
+ obstacle,
219
+ direction + (useMax ? 'Max' : 'Min'),
220
+ useMax ? 1 : -1
221
+ );
222
+ }
223
+
224
+ // Pull out end point
225
+ if (endObstacleIx > -1) {
226
+ endObstacle = chartObstacles[endObstacleIx];
227
+ waypoint = getMeOut(endObstacle, end, dir);
228
+ endSegment = {
229
+ start: waypoint,
230
+ end: end
231
+ };
232
+ endPoint = waypoint;
233
+ } else {
234
+ endPoint = end;
235
+ }
236
+
237
+ // If an obstacle envelops the start point, add a segment to get out,
238
+ // and around it.
239
+ if (startObstacleIx > -1) {
240
+ startObstacle = chartObstacles[startObstacleIx];
241
+ waypoint = getMeOut(startObstacle, start, dir);
242
+ segments.push({
243
+ start: start,
244
+ end: waypoint
245
+ });
246
+
247
+ // If we are going back again, switch direction to get around start
248
+ // obstacle.
249
+ if (
250
+ waypoint[dir] > start[dir] === // Going towards max from start
251
+ waypoint[dir] > endPoint[dir] // Going towards min to end
252
+ ) {
253
+ dir = dir === 'y' ? 'x' : 'y';
254
+ useMax = start[dir] < end[dir];
255
+ segments.push({
256
+ start: waypoint,
257
+ end: copyFromPoint(
258
+ waypoint,
259
+ dir,
260
+ startObstacle,
261
+ dir + (useMax ? 'Max' : 'Min'),
262
+ useMax ? 1 : -1
263
+ )
264
+ });
265
+
266
+ // Switch direction again
267
+ dir = dir === 'y' ? 'x' : 'y';
268
+ }
269
+ }
270
+
271
+ // We are around the start obstacle. Go towards the end in one
272
+ // direction.
273
+ prevWaypoint = segments.length ?
274
+ segments[segments.length - 1].end :
275
+ start;
276
+ waypoint = copyFromPoint(prevWaypoint, dir, endPoint);
277
+ segments.push({
278
+ start: prevWaypoint,
279
+ end: waypoint
280
+ });
281
+
282
+ // Final run to end point in the other direction
283
+ dir = dir === 'y' ? 'x' : 'y';
284
+ waypoint2 = copyFromPoint(waypoint, dir, endPoint);
285
+ segments.push({
286
+ start: waypoint,
287
+ end: waypoint2
288
+ });
289
+
290
+ // Finally add the endSegment
291
+ segments.push(endSegment);
292
+
293
+ return {
294
+ path: pathFromSegments(segments),
295
+ obstacles: segments
296
+ };
297
+ }, {
298
+ requiresObstacles: true
299
+ }),
300
+
301
+ /**
302
+ * Find a path from a starting coordinate to an ending coordinate, taking
303
+ * obstacles into consideration. Might not always find the optimal path,
304
+ * but is fast, and usually good enough.
305
+ *
306
+ * Options
307
+ * - chartObstacles: Array of chart obstacles to avoid
308
+ * - lineObstacles: Array of line obstacles to jump over
309
+ * - obstacleMetrics: Object with metrics of chartObstacles cached
310
+ * - hardBounds: Hard boundaries to not cross
311
+ * - obstacleOptions: Options for the obstacles, including margin
312
+ * - startDirectionX: Optional. True if starting in the X direction.
313
+ * If not provided, the algorithm starts in the
314
+ * direction that is the furthest between
315
+ * start/end.
316
+ *
317
+ * @param {Object} start Starting coordinate, object with x/y props.
318
+ * @param {Object} end Ending coordinate, object with x/y props.
319
+ * @param {Object} options Options for the algorithm.
320
+ *
321
+ * @return {Object} result An object with the SVG path in Array form as
322
+ * accepted by the SVG renderer, as well as an array of new obstacles
323
+ * making up this path.
324
+ */
325
+ fastAvoid: H.extend(function (start, end, options) {
326
+ /*
327
+ Algorithm rules/description
328
+ - Find initial direction
329
+ - Determine soft/hard max for each direction.
330
+ - Move along initial direction until obstacle.
331
+ - Change direction.
332
+ - If hitting obstacle, first try to change length of previous line
333
+ before changing direction again.
334
+
335
+ Soft min/max x = start/destination x +/- widest obstacle + margin
336
+ Soft min/max y = start/destination y +/- tallest obstacle + margin
337
+
338
+ TODO:
339
+ - Make retrospective, try changing prev segment to reduce
340
+ corners
341
+ - Fix logic for breaking out of end-points - not always picking
342
+ the best direction currently
343
+ - When going around the end obstacle we should not always go the
344
+ shortest route, rather pick the one closer to the end point
345
+ */
346
+ var dirIsX = pick(
347
+ options.startDirectionX,
348
+ abs(end.x - start.x) > abs(end.y - start.y)
349
+ ),
350
+ dir = dirIsX ? 'x' : 'y',
351
+ segments,
352
+ useMax,
353
+ extractedEndPoint,
354
+ endSegments = [],
355
+ forceObstacleBreak = false, // Used in clearPathTo to keep track of
356
+ // when to force break through an obstacle.
357
+
358
+ // Boundaries to stay within. If beyond soft boundary, prefer to
359
+ // change direction ASAP. If at hard max, always change immediately.
360
+ metrics = options.obstacleMetrics,
361
+ softMinX = min(start.x, end.x) - metrics.maxWidth - 10,
362
+ softMaxX = max(start.x, end.x) + metrics.maxWidth + 10,
363
+ softMinY = min(start.y, end.y) - metrics.maxHeight - 10,
364
+ softMaxY = max(start.y, end.y) + metrics.maxHeight + 10,
365
+
366
+ // Obstacles
367
+ chartObstacles = options.chartObstacles,
368
+ startObstacleIx = findLastObstacleBefore(chartObstacles, softMinX),
369
+ endObstacleIx = findLastObstacleBefore(chartObstacles, softMaxX);
370
+
371
+ // How far can you go between two points before hitting an obstacle?
372
+ // Does not work for diagonal lines (because it doesn't have to).
373
+ function pivotPoint(fromPoint, toPoint, directionIsX) {
374
+ var firstPoint,
375
+ lastPoint,
376
+ highestPoint,
377
+ lowestPoint,
378
+ i,
379
+ searchDirection = fromPoint.x < toPoint.x ? 1 : -1;
380
+
381
+ if (fromPoint.x < toPoint.x) {
382
+ firstPoint = fromPoint;
383
+ lastPoint = toPoint;
384
+ } else {
385
+ firstPoint = toPoint;
386
+ lastPoint = fromPoint;
387
+ }
388
+
389
+ if (fromPoint.y < toPoint.y) {
390
+ lowestPoint = fromPoint;
391
+ highestPoint = toPoint;
392
+ } else {
393
+ lowestPoint = toPoint;
394
+ highestPoint = fromPoint;
395
+ }
396
+
397
+ // Go through obstacle range in reverse if toPoint is before
398
+ // fromPoint in the X-dimension.
399
+ i = searchDirection < 0 ?
400
+ // Searching backwards, start at last obstacle before last point
401
+ min(findLastObstacleBefore(chartObstacles, lastPoint.x),
402
+ chartObstacles.length - 1) :
403
+ // Forwards. Since we're not sorted by xMax, we have to look
404
+ // at all obstacles.
405
+ 0;
406
+
407
+ // Go through obstacles in this X range
408
+ while (chartObstacles[i] && (
409
+ searchDirection > 0 && chartObstacles[i].xMin <= lastPoint.x ||
410
+ searchDirection < 0 && chartObstacles[i].xMax >= firstPoint.x
411
+ )) {
412
+ // If this obstacle is between from and to points in a straight
413
+ // line, pivot at the intersection.
414
+ if (
415
+ chartObstacles[i].xMin <= lastPoint.x &&
416
+ chartObstacles[i].xMax >= firstPoint.x &&
417
+ chartObstacles[i].yMin <= highestPoint.y &&
418
+ chartObstacles[i].yMax >= lowestPoint.y
419
+ ) {
420
+ if (directionIsX) {
421
+ return {
422
+ y: fromPoint.y,
423
+ x: fromPoint.x < toPoint.x ?
424
+ chartObstacles[i].xMin - 1 :
425
+ chartObstacles[i].xMax + 1,
426
+ obstacle: chartObstacles[i]
427
+ };
428
+ }
429
+ // else ...
430
+ return {
431
+ x: fromPoint.x,
432
+ y: fromPoint.y < toPoint.y ?
433
+ chartObstacles[i].yMin - 1 :
434
+ chartObstacles[i].yMax + 1,
435
+ obstacle: chartObstacles[i]
436
+ };
437
+ }
438
+
439
+ i += searchDirection;
440
+ }
441
+
442
+ return toPoint;
443
+ }
444
+
445
+ /**
446
+ * Decide in which direction to dodge or get out of an obstacle.
447
+ * Considers desired direction, which way is shortest, soft and hard
448
+ * bounds.
449
+ *
450
+ * Returns a string, either xMin, xMax, yMin or yMax.
451
+ *
452
+ * @param {Object} obstacle Obstacle to dodge/escape.
453
+ * @param {Object} fromPoint Point with x/y props that's
454
+ * dodging/escaping.
455
+ * @param {Object} toPoint Goal point.
456
+ * @param {Boolean} dirIsX Dodge in X dimension.
457
+ * @param {Object} bounds Hard and soft boundaries.
458
+ *
459
+ * @return {Boolean} result Use max or not.
460
+ */
461
+ function getDodgeDirection(
462
+ obstacle,
463
+ fromPoint,
464
+ toPoint,
465
+ dirIsX,
466
+ bounds
467
+ ) {
468
+ var softBounds = bounds.soft,
469
+ hardBounds = bounds.hard,
470
+ dir = dirIsX ? 'x' : 'y',
471
+ toPointMax = { x: fromPoint.x, y: fromPoint.y },
472
+ toPointMin = { x: fromPoint.x, y: fromPoint.y },
473
+ minPivot,
474
+ maxPivot,
475
+ maxOutOfSoftBounds = obstacle[dir + 'Max'] >=
476
+ softBounds[dir + 'Max'],
477
+ minOutOfSoftBounds = obstacle[dir + 'Min'] <=
478
+ softBounds[dir + 'Min'],
479
+ maxOutOfHardBounds = obstacle[dir + 'Max'] >=
480
+ hardBounds[dir + 'Max'],
481
+ minOutOfHardBounds = obstacle[dir + 'Min'] <=
482
+ hardBounds[dir + 'Min'],
483
+ // Find out if we should prefer one direction over the other if
484
+ // we can choose freely
485
+ minDistance = abs(obstacle[dir + 'Min'] - fromPoint[dir]),
486
+ maxDistance = abs(obstacle[dir + 'Max'] - fromPoint[dir]),
487
+ // If it's a small difference, pick the one leading towards dest
488
+ // point. Otherwise pick the shortest distance
489
+ useMax = abs(minDistance - maxDistance) < 10 ?
490
+ fromPoint[dir] < toPoint[dir] :
491
+ maxDistance < minDistance;
492
+
493
+ // Check if we hit any obstacles trying to go around in either
494
+ // direction.
495
+ toPointMin[dir] = obstacle[dir + 'Min'];
496
+ toPointMax[dir] = obstacle[dir + 'Max'];
497
+ minPivot = pivotPoint(fromPoint, toPointMin, dirIsX)[dir] !==
498
+ toPointMin[dir];
499
+ maxPivot = pivotPoint(fromPoint, toPointMax, dirIsX)[dir] !==
500
+ toPointMax[dir];
501
+ useMax = minPivot ?
502
+ (maxPivot ? useMax : true) :
503
+ (maxPivot ? false : useMax);
504
+
505
+ // useMax now contains our preferred choice, bounds not taken into
506
+ // account. If both or neither direction is out of bounds we want to
507
+ // use this.
508
+
509
+ // Deal with soft bounds
510
+ useMax = minOutOfSoftBounds ?
511
+ (maxOutOfSoftBounds ? useMax : true) : // Out on min
512
+ (maxOutOfSoftBounds ? false : useMax); // Not out on min
513
+
514
+ // Deal with hard bounds
515
+ useMax = minOutOfHardBounds ?
516
+ (maxOutOfHardBounds ? useMax : true) : // Out on min
517
+ (maxOutOfHardBounds ? false : useMax); // Not out on min
518
+
519
+ return useMax;
520
+ }
521
+
522
+ // Find a clear path between point
523
+ function clearPathTo(fromPoint, toPoint, dirIsX) {
524
+ // Don't waste time if we've hit goal
525
+ if (fromPoint.x === toPoint.x && fromPoint.y === toPoint.y) {
526
+ return [];
527
+ }
528
+
529
+ var dir = dirIsX ? 'x' : 'y',
530
+ pivot,
531
+ segments,
532
+ waypoint,
533
+ waypointUseMax,
534
+ envelopingObstacle,
535
+ secondEnvelopingObstacle,
536
+ envelopWaypoint,
537
+ obstacleMargin = options.obstacleOptions.margin,
538
+ bounds = {
539
+ soft: {
540
+ xMin: softMinX,
541
+ xMax: softMaxX,
542
+ yMin: softMinY,
543
+ yMax: softMaxY
544
+ },
545
+ hard: options.hardBounds
546
+ };
547
+
548
+ // If fromPoint is inside an obstacle we have a problem. Break out
549
+ // by just going to the outside of this obstacle. We prefer to go to
550
+ // the nearest edge in the chosen direction.
551
+ envelopingObstacle =
552
+ findObstacleFromPoint(chartObstacles, fromPoint);
553
+ if (envelopingObstacle > -1) {
554
+ envelopingObstacle = chartObstacles[envelopingObstacle];
555
+ waypointUseMax = getDodgeDirection(
556
+ envelopingObstacle, fromPoint, toPoint, dirIsX, bounds
557
+ );
558
+
559
+ // Cut obstacle to hard bounds to make sure we stay within
560
+ limitObstacleToBounds(envelopingObstacle, options.hardBounds);
561
+
562
+ envelopWaypoint = dirIsX ? {
563
+ y: fromPoint.y,
564
+ x: envelopingObstacle[waypointUseMax ? 'xMax' : 'xMin'] +
565
+ (waypointUseMax ? 1 : -1)
566
+ } : {
567
+ x: fromPoint.x,
568
+ y: envelopingObstacle[waypointUseMax ? 'yMax' : 'yMin'] +
569
+ (waypointUseMax ? 1 : -1)
570
+ };
571
+
572
+ // If we crashed into another obstacle doing this, we put the
573
+ // waypoint between them instead
574
+ secondEnvelopingObstacle = findObstacleFromPoint(
575
+ chartObstacles, envelopWaypoint);
576
+ if (secondEnvelopingObstacle > -1) {
577
+ secondEnvelopingObstacle = chartObstacles[
578
+ secondEnvelopingObstacle
579
+ ];
580
+
581
+ // Cut obstacle to hard bounds
582
+ limitObstacleToBounds(
583
+ secondEnvelopingObstacle,
584
+ options.hardBounds
585
+ );
586
+
587
+ // Modify waypoint to lay between obstacles
588
+ envelopWaypoint[dir] = waypointUseMax ? max(
589
+ envelopingObstacle[dir + 'Max'] - obstacleMargin + 1,
590
+ (
591
+ secondEnvelopingObstacle[dir + 'Min'] +
592
+ envelopingObstacle[dir + 'Max']
593
+ ) / 2
594
+ ) :
595
+ min(
596
+ envelopingObstacle[dir + 'Min'] + obstacleMargin - 1,
597
+ (
598
+ secondEnvelopingObstacle[dir + 'Max'] +
599
+ envelopingObstacle[dir + 'Min']
600
+ ) / 2
601
+ );
602
+
603
+ // We are not going anywhere. If this happens for the first
604
+ // time, do nothing. Otherwise, try to go to the extreme of
605
+ // the obstacle pair in the current direction.
606
+ if (fromPoint.x === envelopWaypoint.x &&
607
+ fromPoint.y === envelopWaypoint.y) {
608
+ if (forceObstacleBreak) {
609
+ envelopWaypoint[dir] = waypointUseMax ?
610
+ max(
611
+ envelopingObstacle[dir + 'Max'],
612
+ secondEnvelopingObstacle[dir + 'Max']
613
+ ) + 1 :
614
+ min(
615
+ envelopingObstacle[dir + 'Min'],
616
+ secondEnvelopingObstacle[dir + 'Min']
617
+ ) - 1;
618
+ }
619
+ // Toggle on if off, and the opposite
620
+ forceObstacleBreak = !forceObstacleBreak;
621
+ } else {
622
+ // This point is not identical to previous.
623
+ // Clear break trigger.
624
+ forceObstacleBreak = false;
625
+ }
626
+ }
627
+
628
+ segments = [{
629
+ start: fromPoint,
630
+ end: envelopWaypoint
631
+ }];
632
+
633
+ } else { // If not enveloping, use standard pivot calculation
634
+
635
+ pivot = pivotPoint(fromPoint, {
636
+ x: dirIsX ? toPoint.x : fromPoint.x,
637
+ y: dirIsX ? fromPoint.y : toPoint.y
638
+ }, dirIsX);
639
+
640
+ segments = [{
641
+ start: fromPoint,
642
+ end: {
643
+ x: pivot.x,
644
+ y: pivot.y
645
+ }
646
+ }];
647
+
648
+ // Pivot before goal, use a waypoint to dodge obstacle
649
+ if (pivot[dirIsX ? 'x' : 'y'] !== toPoint[dirIsX ? 'x' : 'y']) {
650
+ // Find direction of waypoint
651
+ waypointUseMax = getDodgeDirection(
652
+ pivot.obstacle, pivot, toPoint, !dirIsX, bounds
653
+ );
654
+
655
+ // Cut waypoint to hard bounds
656
+ limitObstacleToBounds(pivot.obstacle, options.hardBounds);
657
+
658
+ waypoint = {
659
+ x: dirIsX ?
660
+ pivot.x :
661
+ pivot.obstacle[waypointUseMax ? 'xMax' : 'xMin'] +
662
+ (waypointUseMax ? 1 : -1),
663
+ y: dirIsX ?
664
+ pivot.obstacle[waypointUseMax ? 'yMax' : 'yMin'] +
665
+ (waypointUseMax ? 1 : -1) :
666
+ pivot.y
667
+ };
668
+
669
+ // We're changing direction here, store that to make sure we
670
+ // also change direction when adding the last segment array
671
+ // after handling waypoint.
672
+ dirIsX = !dirIsX;
673
+
674
+ segments = segments.concat(clearPathTo({
675
+ x: pivot.x,
676
+ y: pivot.y
677
+ }, waypoint, dirIsX));
678
+ }
679
+ }
680
+
681
+ // Get segments for the other direction too
682
+ // Recursion is our friend
683
+ segments = segments.concat(clearPathTo(
684
+ segments[segments.length - 1].end, toPoint, !dirIsX
685
+ ));
686
+
687
+ return segments;
688
+ }
689
+
690
+ // Extract point to outside of obstacle in whichever direction is
691
+ // closest. Returns new point outside obstacle.
692
+ function extractFromObstacle(obstacle, point, goalPoint) {
693
+ var dirIsX = min(obstacle.xMax - point.x, point.x - obstacle.xMin) <
694
+ min(obstacle.yMax - point.y, point.y - obstacle.yMin),
695
+ bounds = {
696
+ soft: options.hardBounds,
697
+ hard: options.hardBounds
698
+ },
699
+ useMax = getDodgeDirection(
700
+ obstacle, point, goalPoint, dirIsX, bounds
701
+ );
702
+
703
+ return dirIsX ? {
704
+ y: point.y,
705
+ x: obstacle[useMax ? 'xMax' : 'xMin'] + (useMax ? 1 : -1)
706
+ } : {
707
+ x: point.x,
708
+ y: obstacle[useMax ? 'yMax' : 'yMin'] + (useMax ? 1 : -1)
709
+ };
710
+ }
711
+
712
+ // Cut the obstacle array to soft bounds for optimization in large
713
+ // datasets.
714
+ chartObstacles =
715
+ chartObstacles.slice(startObstacleIx, endObstacleIx + 1);
716
+
717
+ // If an obstacle envelops the end point, move it out of there and add
718
+ // a little segment to where it was.
719
+ if ((endObstacleIx = findObstacleFromPoint(chartObstacles, end)) > -1) {
720
+ extractedEndPoint = extractFromObstacle(
721
+ chartObstacles[endObstacleIx],
722
+ end,
723
+ start
724
+ );
725
+ endSegments.push({
726
+ end: end,
727
+ start: extractedEndPoint
728
+ });
729
+ end = extractedEndPoint;
730
+ }
731
+ // If it's still inside one or more obstacles, get out of there by
732
+ // force-moving towards the start point.
733
+ while (
734
+ (endObstacleIx = findObstacleFromPoint(chartObstacles, end)) > -1
735
+ ) {
736
+ useMax = end[dir] - start[dir] < 0;
737
+ extractedEndPoint = {
738
+ x: end.x,
739
+ y: end.y
740
+ };
741
+ extractedEndPoint[dir] = chartObstacles[endObstacleIx][
742
+ useMax ? dir + 'Max' : dir + 'Min'
743
+ ] + (useMax ? 1 : -1);
744
+ endSegments.push({
745
+ end: end,
746
+ start: extractedEndPoint
747
+ });
748
+ end = extractedEndPoint;
749
+ }
750
+
751
+ // Find the path
752
+ segments = clearPathTo(start, end, dirIsX);
753
+
754
+ // Add the end-point segments
755
+ segments = segments.concat(endSegments.reverse());
756
+
757
+ return {
758
+ path: pathFromSegments(segments),
759
+ obstacles: segments
760
+ };
761
+ }, {
762
+ requiresObstacles: true
763
+ })
764
+ };
765
+
766
+
767
+ return algorithms;
768
+ }(Highcharts));
769
+ (function (H) {
770
+ /**
771
+ * (c) 2017 Highsoft AS
772
+ * Authors: Lars A. V. Cabrera
773
+ *
774
+ * License: www.highcharts.com/license
775
+ */
776
+
777
+ /**
778
+ * Creates an arrow symbol. Like a triangle, except not filled.
779
+ * o
780
+ * o
781
+ * o
782
+ * o
783
+ * o
784
+ * o
785
+ * o
786
+ * @param {number} x x position of the arrow
787
+ * @param {number} y y position of the arrow
788
+ * @param {number} w width of the arrow
789
+ * @param {number} h height of the arrow
790
+ * @return {Array} Path array
791
+ */
792
+ H.SVGRenderer.prototype.symbols.arrow = function (x, y, w, h) {
793
+ return [
794
+ 'M', x, y + h / 2,
795
+ 'L', x + w, y,
796
+ 'L', x, y + h / 2,
797
+ 'L', x + w, y + h
798
+ ];
799
+ };
800
+
801
+ /**
802
+ * Creates a half-width arrow symbol. Like a triangle, except not filled.
803
+ * o
804
+ * o
805
+ * o
806
+ * o
807
+ * o
808
+ * @param {number} x x position of the arrow
809
+ * @param {number} y y position of the arrow
810
+ * @param {number} w width of the arrow
811
+ * @param {number} h height of the arrow
812
+ * @return {Array} Path array
813
+ */
814
+ H.SVGRenderer.prototype.symbols['arrow-half'] = function (x, y, w, h) {
815
+ return H.SVGRenderer.prototype.symbols.arrow(x, y, w / 2, h);
816
+ };
817
+
818
+ /**
819
+ * Creates a left-oriented triangle.
820
+ * o
821
+ * ooooooo
822
+ * ooooooooooooo
823
+ * ooooooo
824
+ * o
825
+ * @param {number} x x position of the triangle
826
+ * @param {number} y y position of the triangle
827
+ * @param {number} w width of the triangle
828
+ * @param {number} h height of the triangle
829
+ * @return {Array} Path array
830
+ */
831
+ H.SVGRenderer.prototype.symbols['triangle-left'] = function (x, y, w, h) {
832
+ return [
833
+ 'M', x + w, y,
834
+ 'L', x, y + h / 2,
835
+ 'L', x + w, y + h,
836
+ 'Z'
837
+ ];
838
+ };
839
+
840
+ /**
841
+ * Alias function for triangle-left.
842
+ * @param {number} x x position of the arrow
843
+ * @param {number} y y position of the arrow
844
+ * @param {number} w width of the arrow
845
+ * @param {number} h height of the arrow
846
+ * @return {Array} Path array
847
+ */
848
+ H.SVGRenderer.prototype.symbols['arrow-filled'] =
849
+ H.SVGRenderer.prototype.symbols['triangle-left'];
850
+
851
+ /**
852
+ * Creates a half-width, left-oriented triangle.
853
+ * o
854
+ * oooo
855
+ * ooooooo
856
+ * oooo
857
+ * o
858
+ * @param {number} x x position of the triangle
859
+ * @param {number} y y position of the triangle
860
+ * @param {number} w width of the triangle
861
+ * @param {number} h height of the triangle
862
+ * @return {Array} Path array
863
+ */
864
+ H.SVGRenderer.prototype.symbols['triangle-left-half'] = function (x, y, w, h) {
865
+ return H.SVGRenderer.prototype.symbols['triangle-left'](x, y, w / 2, h);
866
+ };
867
+
868
+ /**
869
+ * Alias function for triangle-left-half.
870
+ * @param {number} x x position of the arrow
871
+ * @param {number} y y position of the arrow
872
+ * @param {number} w width of the arrow
873
+ * @param {number} h height of the arrow
874
+ * @return {Array} Path array
875
+ */
876
+ H.SVGRenderer.prototype.symbols['arrow-filled-half'] =
877
+ H.SVGRenderer.prototype.symbols['triangle-left-half'];
878
+
879
+ }(Highcharts));
880
+ (function (H, pathfinderAlgorithms) {
881
+ /**
882
+ * (c) 2016 Highsoft AS
883
+ * Authors: Øystein Moseng, Lars A. V. Cabrera
884
+ *
885
+ * License: www.highcharts.com/license
886
+ */
887
+
888
+ var defined = H.defined,
889
+ deg2rad = H.deg2rad,
890
+ extend = H.extend,
891
+ each = H.each,
892
+ addEvent = H.addEvent,
893
+ merge = H.merge,
894
+ pick = H.pick,
895
+ max = Math.max,
896
+ min = Math.min;
897
+
898
+ /*
899
+ TODO:
900
+ - Test dynamics, hiding/adding/removing/updating chart/series/points/axes
901
+ - Test connecting to multiple points
902
+ - Add demos/samples
903
+ - Document how to write your own algorithms
904
+ - Consider adding a Point.pathTo method that wraps creating a connection
905
+ and rendering it
906
+ */
907
+
908
+
909
+ // Set default Pathfinder options
910
+ extend(H.defaultOptions, {
911
+ /**
912
+ * The Pathfinder allows you to define connections between any two points,
913
+ * represented as lines - optionally with markers for the start and/or end
914
+ * points. Multiple algorithms are available for calculating how the
915
+ * connecting lines are drawn.
916
+ *
917
+ * Pathfinder functionality requires Highcharts Gantt to be loaded. In Gantt
918
+ * charts, the Pathfinder is used to draw dependencies between tasks.
919
+ *
920
+ * @product gantt
921
+ * @see [dependency](series.gantt.data.dependency)
922
+ * @optionparent pathfinder
923
+ */
924
+ pathfinder: {
925
+ /**
926
+ * Enable the pathfinder for this chart. Requires Highcharts Gantt.
927
+ *
928
+ * @type {boolean}
929
+ * @default true
930
+ * @since 6.2.0
931
+ * @apioption pathfinder.enabled
932
+ */
933
+
934
+ /**
935
+ * Set the default dash style for this chart's Pathfinder connecting
936
+ * lines.
937
+ *
938
+ * @type {string}
939
+ * @default solid
940
+ * @since 6.2.0
941
+ * @apioption pathfinder.dashStyle
942
+ */
943
+
944
+ /**
945
+ * Set the default color for this chart's Pathfinder connecting lines.
946
+ * Defaults to the color of the point being connected.
947
+ *
948
+ * @type {Color}
949
+ * @default null
950
+ * @since 6.2.0
951
+ * @apioption pathfinder.lineColor
952
+ */
953
+
954
+ /**
955
+ * Set the default pathfinder margin to use, in pixels. Some Pathfinder
956
+ * algorithms attempt to avoid obstacles, such as other points in the
957
+ * chart. These algorithms use this margin to determine how close lines
958
+ * can be to an obstacle. The default is to compute this automatically
959
+ * from the size of the obstacles in the chart.
960
+ *
961
+ * To draw connecting lines close to existing points, set this to a low
962
+ * number. For more space around existing points, set this number
963
+ * higher.
964
+ *
965
+ * @type {number}
966
+ * @default null
967
+ * @since 6.2.0
968
+ * @apioption pathfinder.algorithmMargin
969
+ */
970
+
971
+ /**
972
+ * Set the default pathfinder algorithm to use for this chart. It is
973
+ * possible to define your own algorithms by adding them to the
974
+ * Highcharts.Pathfinder.prototype.algorithms object after the chart
975
+ * has been created.
976
+ *
977
+ * The default algorithms are as follows:
978
+ *
979
+ * straight: Draws a straight line between the connecting points.
980
+ * Does not avoid other points when drawing.
981
+ *
982
+ * simpleConnect: Finds a path between the points using right angles
983
+ * only. Takes only starting/ending points into
984
+ * account, and will not avoid other points.
985
+ *
986
+ * fastAvoid: Finds a path between the points using right angles
987
+ * only. Will attempt to avoid other points, but its
988
+ * focus is performance over accuracy. Works well with
989
+ * less dense datasets.
990
+ *
991
+ * @type {string}
992
+ * @default straight
993
+ * @since 6.2.0
994
+ * @apioption pathfinder.type
995
+ */
996
+ type: 'straight',
997
+
998
+ /**
999
+ * Set the default pixel width for this chart's Pathfinder connecting
1000
+ * lines.
1001
+ *
1002
+ * @type {number}
1003
+ * @default 1
1004
+ * @since 6.2.0
1005
+ * @apioption pathfinder.lineWidth
1006
+ */
1007
+ lineWidth: 1,
1008
+
1009
+ /**
1010
+ * Marker options for this chart's Pathfinder connectors.
1011
+ *
1012
+ * @type {object}
1013
+ * @since 6.2.0
1014
+ * @apioption pathfinder.marker
1015
+ */
1016
+ marker: {
1017
+ /**
1018
+ * Set the radius of the pathfinder markers. The default is
1019
+ * automatically computed based on the algorithmMargin setting.
1020
+ *
1021
+ * Setting marker.width and marker.height will override this
1022
+ * setting.
1023
+ *
1024
+ * @type {number}
1025
+ * @default null
1026
+ * @since 6.2.0
1027
+ * @apioption pathfinder.marker.radius
1028
+ */
1029
+
1030
+ /**
1031
+ * Set the width of the pathfinder markers. If not supplied, this
1032
+ * is inferred from the marker radius.
1033
+ *
1034
+ * @type {number}
1035
+ * @default null
1036
+ * @since 6.2.0
1037
+ * @apioption pathfinder.marker.width
1038
+ */
1039
+
1040
+ /**
1041
+ * Set the height of the pathfinder markers. If not supplied, this
1042
+ * is inferred from the marker radius.
1043
+ *
1044
+ * @type {number}
1045
+ * @default null
1046
+ * @since 6.2.0
1047
+ * @apioption pathfinder.marker.height
1048
+ */
1049
+
1050
+ /**
1051
+ * Set the color of the pathfinder markers. By default this is the
1052
+ * same as the connector color.
1053
+ *
1054
+ * @type {Color}
1055
+ * @default null
1056
+ * @since 6.2.0
1057
+ * @apioption pathfinder.marker.color
1058
+ */
1059
+
1060
+ /**
1061
+ * Set the line/border color of the pathfinder markers. By default
1062
+ * this is the same as the marker color.
1063
+ *
1064
+ * @type {Color}
1065
+ * @default null
1066
+ * @since 6.2.0
1067
+ * @apioption pathfinder.marker.lineColor
1068
+ */
1069
+
1070
+ /**
1071
+ * Enable markers for the connectors.
1072
+ */
1073
+ enabled: false,
1074
+
1075
+ /**
1076
+ * Horizontal alignment of the markers relative to the points.
1077
+ */
1078
+ align: 'center',
1079
+
1080
+ /**
1081
+ * Vertical alignment of the markers relative to the points.
1082
+ */
1083
+ verticalAlign: 'middle',
1084
+
1085
+ /**
1086
+ * Whether or not to draw the markers inside the points.
1087
+ */
1088
+ inside: false,
1089
+
1090
+ /**
1091
+ * Set the line/border width of the pathfinder markers.
1092
+ */
1093
+ lineWidth: 1
1094
+ },
1095
+
1096
+ /**
1097
+ * Marker options specific to the start markers for this chart's
1098
+ * Pathfinder connectors. Overrides the generic marker options.
1099
+ *
1100
+ * @type {object}
1101
+ * @since 6.2.0
1102
+ * @extends pathfinder.marker
1103
+ * @apioption pathfinder.startMarker
1104
+ */
1105
+ startMarker: {
1106
+ /**
1107
+ * Set the symbol of the pathfinder start markers.
1108
+ */
1109
+ symbol: 'diamond'
1110
+ },
1111
+
1112
+ /**
1113
+ * Marker options specific to the end markers for this chart's
1114
+ * Pathfinder connectors. Overrides the generic marker options.
1115
+ *
1116
+ * @type {object}
1117
+ * @since 6.2.0
1118
+ * @extends pathfinder.marker
1119
+ * @apioption pathfinder.endMarker
1120
+ */
1121
+ endMarker: {
1122
+ /**
1123
+ * Set the symbol of the pathfinder end markers.
1124
+ */
1125
+ symbol: 'arrow-filled'
1126
+ }
1127
+ }
1128
+ });
1129
+
1130
+ /**
1131
+ * Override Pathfinder options for a series. Requires Highcharts Gantt or the
1132
+ * Pathfinder module.
1133
+ *
1134
+ * @since 6.2.0
1135
+ * @extends pathfinder
1136
+ * @product gantt
1137
+ * @apioption plotOptions.series.pathfinder
1138
+ * @excluding enabled,algorithmMargin
1139
+ */
1140
+
1141
+ /**
1142
+ * Connect to a point. Requires Highcharts Gantt to be loaded. This option can
1143
+ * be either a string, referring to the ID of another point, or an object.
1144
+ *
1145
+ * @type {string|object}
1146
+ * @since 6.2.0
1147
+ * @extends plotOptions.series.pathfinder
1148
+ * @product gantt
1149
+ * @apioption series.xrange.data.connect
1150
+ */
1151
+
1152
+ /**
1153
+ * The ID of the point to connect to.
1154
+ *
1155
+ * @type {string}
1156
+ * @since 6.2.0
1157
+ * @product gantt
1158
+ * @apioption series.xrange.data.connect.to
1159
+ */
1160
+
1161
+
1162
+ /**
1163
+ * Get point bounding box using plotX/plotY and shapeArgs. If using
1164
+ * graphic.getBBox() directly, the bbox will be affected by animation.
1165
+ *
1166
+ * @param {Highcharts.Point} point
1167
+ * The point to get BB of.
1168
+ *
1169
+ * @return {object}
1170
+ * Result xMax, xMin, yMax, yMin.
1171
+ */
1172
+ function getPointBB(point) {
1173
+ var shapeArgs = point.shapeArgs,
1174
+ bb;
1175
+
1176
+ // Prefer using shapeArgs (columns)
1177
+ if (shapeArgs) {
1178
+ return {
1179
+ xMin: shapeArgs.x,
1180
+ xMax: shapeArgs.x + shapeArgs.width,
1181
+ yMin: shapeArgs.y,
1182
+ yMax: shapeArgs.y + shapeArgs.height
1183
+ };
1184
+ }
1185
+
1186
+ // Otherwise use plotX/plotY and bb
1187
+ bb = point.graphic && point.graphic.getBBox();
1188
+ return bb ? {
1189
+ xMin: point.plotX - bb.width / 2,
1190
+ xMax: point.plotX + bb.width / 2,
1191
+ yMin: point.plotY - bb.height / 2,
1192
+ yMax: point.plotY + bb.height / 2
1193
+ } : null;
1194
+ }
1195
+
1196
+
1197
+ /**
1198
+ * Calculate margin to place around obstacles for the pathfinder in pixels.
1199
+ * Returns a minimum of 1 pixel margin.
1200
+ *
1201
+ * @param {Array} obstacles
1202
+ * Obstacles to calculate margin from.
1203
+ *
1204
+ * @return {number}
1205
+ * The calculated margin in pixels. At least 1.
1206
+ */
1207
+ function calculateObstacleMargin(obstacles) {
1208
+ var len = obstacles.length,
1209
+ i = 0,
1210
+ j,
1211
+ obstacleDistance,
1212
+ distances = [],
1213
+ // Compute smallest distance between two rectangles
1214
+ distance = function (a, b, bbMargin) {
1215
+ // Count the distance even if we are slightly off
1216
+ var margin = pick(bbMargin, 10),
1217
+ yOverlap = a.yMax + margin > b.yMin - margin &&
1218
+ a.yMin - margin < b.yMax + margin,
1219
+ xOverlap = a.xMax + margin > b.xMin - margin &&
1220
+ a.xMin - margin < b.xMax + margin,
1221
+ xDistance = yOverlap ? (
1222
+ a.xMin > b.xMax ? a.xMin - b.xMax : b.xMin - a.xMax
1223
+ ) : Infinity,
1224
+ yDistance = xOverlap ? (
1225
+ a.yMin > b.yMax ? a.yMin - b.yMax : b.yMin - a.yMax
1226
+ ) : Infinity;
1227
+
1228
+ // If the rectangles collide, try recomputing with smaller margin.
1229
+ // If they collide anyway, discard the obstacle.
1230
+ if (xOverlap && yOverlap) {
1231
+ return (
1232
+ margin ?
1233
+ distance(a, b, Math.floor(margin / 2)) :
1234
+ Infinity
1235
+ );
1236
+ }
1237
+
1238
+ return min(xDistance, yDistance);
1239
+ };
1240
+
1241
+ // Go over all obstacles and compare them to the others.
1242
+ for (; i < len; ++i) {
1243
+ // Compare to all obstacles ahead. We will already have compared this
1244
+ // obstacle to the ones before.
1245
+ for (j = i + 1; j < len; ++j) {
1246
+ obstacleDistance = distance(obstacles[i], obstacles[j]);
1247
+ // TODO: Magic number 80
1248
+ if (obstacleDistance < 80) { // Ignore large distances
1249
+ distances.push(obstacleDistance);
1250
+ }
1251
+ }
1252
+ }
1253
+ // Ensure we always have at least one value, even in very spaceous charts
1254
+ distances.push(80);
1255
+
1256
+ return max(
1257
+ Math.floor(
1258
+ distances.sort(function (a, b) {
1259
+ return a - b;
1260
+ })[
1261
+ // Discard first 10% of the relevant distances, and then grab
1262
+ // the smallest one.
1263
+ Math.floor(distances.length / 10)
1264
+ ] / 2 - 1 // Divide the distance by 2 and subtract 1.
1265
+ ),
1266
+ 1 // 1 is the minimum margin
1267
+ );
1268
+ }
1269
+
1270
+
1271
+ /**
1272
+ * The Connection class. Used internally to represent a connection between two
1273
+ * points.
1274
+ *
1275
+ * @private
1276
+ * @class Connection
1277
+ *
1278
+ * @param {Highcharts.Point} from
1279
+ * Connection runs from this Point.
1280
+ *
1281
+ * @param {Highcharts.Point} to
1282
+ * Connection runs to this Point.
1283
+ *
1284
+ * @param {object} [options]
1285
+ * Connection options.
1286
+ */
1287
+ function Connection(from, to, options) {
1288
+ this.init(from, to, options);
1289
+ }
1290
+ Connection.prototype = {
1291
+
1292
+ /**
1293
+ * Initialize the Connection object. Used as constructor only.
1294
+ *
1295
+ * @function Highcharts.Connection#init
1296
+ *
1297
+ * @param {Highcharts.Point} from
1298
+ * Connection runs from this Point.
1299
+ *
1300
+ * @param {Highcharts.Point} to
1301
+ * Connection runs to this Point.
1302
+ *
1303
+ * @param {object} [options]
1304
+ * Connection options.
1305
+ *
1306
+ * @return {void}
1307
+ */
1308
+ init: function (from, to, options) {
1309
+ this.fromPoint = from;
1310
+ this.toPoint = to;
1311
+ this.options = options;
1312
+ this.chart = from.series.chart;
1313
+ this.pathfinder = this.chart.pathfinder;
1314
+ },
1315
+
1316
+ /**
1317
+ * Add (or update) this connection's path on chart. Stores reference to the
1318
+ * created element on this.graphics.path.
1319
+ *
1320
+ * @function Highcharts.Connection#renderPath
1321
+ *
1322
+ * @param {Array} path
1323
+ * Path to render, in array format. E.g. ['M', 0, 0, 'L', 10, 10]
1324
+ *
1325
+ * @param {object} [attribs]
1326
+ * SVG attributes for the path.
1327
+ *
1328
+ * @param {object} [animation]
1329
+ * Animation options for the rendering.
1330
+ *
1331
+ * @param {Function} [complete]
1332
+ * Callback function when the path has been rendered and animation
1333
+ * is complete.
1334
+ *
1335
+ * @return {void}
1336
+ */
1337
+ renderPath: function (path, attribs, animation) {
1338
+ var connection = this,
1339
+ chart = this.chart,
1340
+ pathfinder = chart.pathfinder,
1341
+ animate = !chart.options.chart.forExport && animation !== false,
1342
+ pathGraphic = connection.graphics && connection.graphics.path;
1343
+
1344
+ // Add the SVG element of the pathfinder group if it doesn't exist
1345
+ if (!pathfinder.group) {
1346
+ pathfinder.group = chart.renderer.g()
1347
+ .addClass('highcharts-pathfinder-group')
1348
+ .attr({ zIndex: -1 })
1349
+ .add(chart.seriesGroup);
1350
+ }
1351
+
1352
+ // Shift the group to compensate for plot area.
1353
+ // Note: Do this always (even when redrawing a path) to avoid issues
1354
+ // when updating chart in a way that changes plot metrics.
1355
+ pathfinder.group.translate(chart.plotLeft, chart.plotTop);
1356
+
1357
+ // Create path if does not exist
1358
+ if (!(pathGraphic && pathGraphic.renderer)) {
1359
+ pathGraphic = chart.renderer.path()
1360
+
1361
+ .add(pathfinder.group);
1362
+ }
1363
+
1364
+ // Set path attribs and animate to the new path
1365
+ pathGraphic.attr(attribs);
1366
+ pathGraphic[animate ? 'animate' : 'attr']({
1367
+
1368
+ d: path
1369
+ }, animation);
1370
+
1371
+ // Store reference on connection
1372
+ this.graphics = this.graphics || {};
1373
+ this.graphics.path = pathGraphic;
1374
+ },
1375
+
1376
+ /**
1377
+ * Calculate and add marker graphics for connection to the chart. The
1378
+ * created/updated elements are stored on this.graphics.start and
1379
+ * this.graphics.end.
1380
+ *
1381
+ * @function Highcharts.Connection#addMarker
1382
+ *
1383
+ * @param {string} type
1384
+ * Marker type, either 'start' or 'end'.
1385
+ *
1386
+ * @param {object} options
1387
+ * All options for this marker. Not calculated or merged with other
1388
+ * options.
1389
+ *
1390
+ * @param {Array} path
1391
+ * Connection path in array format. This is used to calculate the
1392
+ * rotation angle of the markers.
1393
+ *
1394
+ * @return {void}
1395
+ */
1396
+ addMarker: function (type, options, path) {
1397
+ var connection = this,
1398
+ chart = connection.fromPoint.series.chart,
1399
+ pathfinder = chart.pathfinder,
1400
+ renderer = chart.renderer,
1401
+ point = (
1402
+ type === 'start' ?
1403
+ connection.fromPoint :
1404
+ connection.toPoint
1405
+ ),
1406
+ anchor = point.getPathfinderAnchorPoint(options),
1407
+ markerVector,
1408
+ radians,
1409
+ rotation,
1410
+ box,
1411
+ width,
1412
+ height,
1413
+ pathVector;
1414
+
1415
+
1416
+ if (!options.enabled) {
1417
+ return;
1418
+ }
1419
+
1420
+ // Last vector before start/end of path, used to get angle
1421
+ if (type === 'start') {
1422
+ pathVector = {
1423
+ x: path[4],
1424
+ y: path[5]
1425
+ };
1426
+ } else { // 'end'
1427
+ pathVector = {
1428
+ x: path[path.length - 5],
1429
+ y: path[path.length - 4]
1430
+ };
1431
+ }
1432
+
1433
+ // Get angle between pathVector and anchor point and use it to create
1434
+ // marker position.
1435
+ radians = point.getRadiansToVector(pathVector, anchor);
1436
+ markerVector = point.getMarkerVector(
1437
+ radians,
1438
+ options.radius,
1439
+ anchor
1440
+ );
1441
+
1442
+ // Rotation of marker is calculated from angle between pathVector and
1443
+ // markerVector.
1444
+ // (Note:
1445
+ // Used to recalculate radians between markerVector and pathVector,
1446
+ // but this should be the same as between pathVector and anchor.)
1447
+ rotation = -radians / deg2rad;
1448
+
1449
+ if (options.width && options.height) {
1450
+ width = options.width;
1451
+ height = options.height;
1452
+ } else {
1453
+ width = height = options.radius * 2;
1454
+ }
1455
+
1456
+ // Add graphics object if it does not exist
1457
+ connection.graphics = connection.graphics || {};
1458
+ box = {
1459
+ x: markerVector.x - (width / 2),
1460
+ y: markerVector.y - (height / 2),
1461
+ width: width,
1462
+ height: height,
1463
+ rotation: rotation,
1464
+ rotationOriginX: markerVector.x,
1465
+ rotationOriginY: markerVector.y
1466
+ };
1467
+
1468
+ if (!connection.graphics[type]) {
1469
+
1470
+ // Create new marker element
1471
+ connection.graphics[type] = renderer.symbol(
1472
+ options.symbol
1473
+ )
1474
+ .addClass(
1475
+ 'highcharts-point-connecting-path-' + type + '-marker'
1476
+ )
1477
+ .attr(box)
1478
+
1479
+
1480
+ .add(pathfinder.group);
1481
+ } else {
1482
+ connection.graphics[type].animate(box);
1483
+ }
1484
+ },
1485
+
1486
+ /**
1487
+ * Calculate and return connection path.
1488
+ * Note: Recalculates chart obstacles on demand if they aren't calculated.
1489
+ *
1490
+ * @function Highcharts.Connection#getPath
1491
+ *
1492
+ * @param {object} options
1493
+ * Pathfinder options. Not calculated or merged with other options.
1494
+ *
1495
+ * @return {Array}
1496
+ * Calculated SVG path data in array format.
1497
+ */
1498
+ getPath: function (options) {
1499
+ var pathfinder = this.pathfinder,
1500
+ chart = this.chart,
1501
+ algorithm = pathfinder.algorithms[options.type],
1502
+ chartObstacles = pathfinder.chartObstacles;
1503
+
1504
+ if (typeof algorithm !== 'function') {
1505
+ H.error(
1506
+ '"' + options.type + '" is not a Pathfinder algorithm.'
1507
+ );
1508
+ return;
1509
+ }
1510
+
1511
+ // This function calculates obstacles on demand if they don't exist
1512
+ if (algorithm.requiresObstacles && !chartObstacles) {
1513
+ chartObstacles =
1514
+ pathfinder.chartObstacles =
1515
+ pathfinder.getChartObstacles(options);
1516
+
1517
+ // If the algorithmMargin was computed, store the result in default
1518
+ // options.
1519
+ chart.options.pathfinder.algorithmMargin = options.algorithmMargin;
1520
+
1521
+ // Cache some metrics too
1522
+ pathfinder.chartObstacleMetrics =
1523
+ pathfinder.getObstacleMetrics(chartObstacles);
1524
+ }
1525
+
1526
+ // Get the SVG path
1527
+ return algorithm(
1528
+ // From
1529
+ this.fromPoint.getPathfinderAnchorPoint(options.startMarker),
1530
+ // To
1531
+ this.toPoint.getPathfinderAnchorPoint(options.endMarker),
1532
+ merge({
1533
+ chartObstacles: chartObstacles,
1534
+ lineObstacles: pathfinder.lineObstacles || [],
1535
+ obstacleMetrics: pathfinder.chartObstacleMetrics,
1536
+ hardBounds: {
1537
+ xMin: 0,
1538
+ xMax: chart.plotWidth,
1539
+ yMin: 0,
1540
+ yMax: chart.plotHeight
1541
+ },
1542
+ obstacleOptions: {
1543
+ margin: options.algorithmMargin
1544
+ },
1545
+ startDirectionX: pathfinder.getAlgorithmStartDirection(
1546
+ options.startMarker
1547
+ )
1548
+ }, options)
1549
+ );
1550
+ },
1551
+
1552
+ /**
1553
+ * (re)Calculate and (re)draw the connection.
1554
+ *
1555
+ * @function Highcharts.Connection#render
1556
+ */
1557
+ render: function () {
1558
+ var connection = this,
1559
+ fromPoint = connection.fromPoint,
1560
+ series = fromPoint.series,
1561
+ chart = series.chart,
1562
+ pathfinder = chart.pathfinder,
1563
+ pathResult,
1564
+ path,
1565
+ options = merge(
1566
+ chart.options.pathfinder, series.options.pathfinder,
1567
+ fromPoint.options.pathfinder, connection.options
1568
+ ),
1569
+ attribs = {};
1570
+
1571
+ // Set path attribs
1572
+
1573
+
1574
+ attribs.class = 'highcharts-point-connecting-path ' +
1575
+ 'highcharts-color-' + fromPoint.colorIndex;
1576
+ options = merge(attribs, options);
1577
+
1578
+ // Set common marker options
1579
+ if (!defined(options.marker.radius)) {
1580
+ options.marker.radius = min(max(
1581
+ Math.ceil((options.algorithmMargin || 8) / 2) - 1, 1
1582
+ ), 5);
1583
+ }
1584
+ // Get the path
1585
+ pathResult = connection.getPath(options);
1586
+ path = pathResult.path;
1587
+
1588
+ // Always update obstacle storage with obstacles from this path.
1589
+ // We don't know if future calls will need this for their algorithm.
1590
+ if (pathResult.obstacles) {
1591
+ pathfinder.lineObstacles = pathfinder.lineObstacles || [];
1592
+ pathfinder.lineObstacles =
1593
+ pathfinder.lineObstacles.concat(pathResult.obstacles);
1594
+ }
1595
+
1596
+ // Add the calculated path to the pathfinder group
1597
+ connection.renderPath(path, attribs, series.options.animation);
1598
+
1599
+ // Render the markers
1600
+ connection.addMarker(
1601
+ 'start',
1602
+ merge(options.marker, options.startMarker),
1603
+ path
1604
+ );
1605
+ connection.addMarker(
1606
+ 'end',
1607
+ merge(options.marker, options.endMarker),
1608
+ path
1609
+ );
1610
+ },
1611
+
1612
+ /**
1613
+ * Destroy connection by destroying the added graphics elements.
1614
+ *
1615
+ * @function Highcharts.Connection#destroy
1616
+ */
1617
+ destroy: function () {
1618
+ if (this.graphics) {
1619
+ H.objectEach(this.graphics, function (val) {
1620
+ val.destroy();
1621
+ });
1622
+ delete this.graphics;
1623
+ }
1624
+ }
1625
+ };
1626
+
1627
+
1628
+ /**
1629
+ * The Pathfinder class.
1630
+ *
1631
+ * @private
1632
+ * @class Pathfinder
1633
+ *
1634
+ * @param {Highcharts.Chart} chart
1635
+ * The chart to operate on.
1636
+ */
1637
+ function Pathfinder(chart) {
1638
+ this.init(chart);
1639
+ }
1640
+ Pathfinder.prototype = {
1641
+
1642
+ algorithms: pathfinderAlgorithms,
1643
+
1644
+ /**
1645
+ * Initialize the Pathfinder object.
1646
+ *
1647
+ * @function Highcharts.Pathfinder#init
1648
+ *
1649
+ * @param {Highcharts.Chart} chart
1650
+ * The chart context.
1651
+ *
1652
+ * @return {void}
1653
+ */
1654
+ init: function (chart) {
1655
+ // Initialize pathfinder with chart context
1656
+ this.chart = chart;
1657
+
1658
+ // Init connection reference list
1659
+ this.connections = [];
1660
+
1661
+ // Recalculate paths/obstacles on chart redraw
1662
+ addEvent(chart, 'redraw', function () {
1663
+ this.pathfinder.update();
1664
+ });
1665
+ },
1666
+
1667
+ /**
1668
+ * Update Pathfinder connections from scratch.
1669
+ *
1670
+ * @function Highcharts.Pathfinder#update
1671
+ *
1672
+ * @param {boolean} deferRender Whether or not to defer rendering of
1673
+ * connections until series.afterAnimate event has fired. Used on first
1674
+ * render.
1675
+ */
1676
+ update: function (deferRender) {
1677
+ var chart = this.chart,
1678
+ pathfinder = this,
1679
+ oldConnections = pathfinder.connections;
1680
+
1681
+ // Rebuild pathfinder connections from options
1682
+ pathfinder.connections = [];
1683
+ each(chart.series, function (series) {
1684
+ if (series.visible) {
1685
+ each(series.points, function (point) {
1686
+ var to,
1687
+ connects = (
1688
+ point.options &&
1689
+ point.options.connect &&
1690
+ H.splat(point.options.connect)
1691
+ );
1692
+ if (point.visible && point.isInside !== false && connects) {
1693
+ each(connects, function (connect) {
1694
+ to = chart.get(typeof connect === 'string' ?
1695
+ connect : connect.to
1696
+ );
1697
+ if (
1698
+ to instanceof H.Point &&
1699
+ to.series.visible &&
1700
+ to.visible &&
1701
+ to.isInside !== false
1702
+ ) {
1703
+ // Add new connection
1704
+ pathfinder.connections.push(new Connection(
1705
+ point, // from
1706
+ to,
1707
+ typeof connect === 'string' ? {} : connect
1708
+ ));
1709
+ }
1710
+ });
1711
+ }
1712
+ });
1713
+ }
1714
+ });
1715
+
1716
+ // Clear connections that should not be updated, and move old info over
1717
+ // to new connections.
1718
+ for (
1719
+ var j = 0, k, found, lenOld = oldConnections.length,
1720
+ lenNew = pathfinder.connections.length;
1721
+ j < lenOld;
1722
+ ++j
1723
+ ) {
1724
+ found = false;
1725
+ for (k = 0; k < lenNew; ++k) {
1726
+ if (
1727
+ oldConnections[j].fromPoint ===
1728
+ pathfinder.connections[k].fromPoint &&
1729
+ oldConnections[j].toPoint ===
1730
+ pathfinder.connections[k].toPoint
1731
+ ) {
1732
+ pathfinder.connections[k].graphics =
1733
+ oldConnections[j].graphics;
1734
+ found = true;
1735
+ break;
1736
+ }
1737
+ }
1738
+ if (!found) {
1739
+ oldConnections[j].destroy();
1740
+ }
1741
+ }
1742
+
1743
+ // Clear obstacles to force recalculation. This must be done on every
1744
+ // redraw in case positions have changed. Recalculation is handled in
1745
+ // Connection.getPath on demand.
1746
+ delete this.chartObstacles;
1747
+ delete this.lineObstacles;
1748
+
1749
+ // Draw the pending connections
1750
+ pathfinder.renderConnections(deferRender);
1751
+ },
1752
+
1753
+ /**
1754
+ * Draw the chart's connecting paths.
1755
+ *
1756
+ * @function Highcharts.Pathfinder#renderConnections
1757
+ *
1758
+ * @param {boolean} deferRender Whether or not to defer render until series
1759
+ * animation is finished. Used on first render.
1760
+ */
1761
+ renderConnections: function (deferRender) {
1762
+ if (deferRender) {
1763
+ // Render after series are done animating
1764
+ each(this.chart.series, function (series) {
1765
+ var render = function () {
1766
+ // Find pathfinder connections belonging to this series
1767
+ // that haven't rendered, and render them now.
1768
+ var pathfinder = series.chart.pathfinder,
1769
+ conns = pathfinder && pathfinder.connections || [];
1770
+ each(conns, function (connection) {
1771
+ if (
1772
+ connection.fromPoint &&
1773
+ connection.fromPoint.series === series
1774
+ ) {
1775
+ connection.render();
1776
+ }
1777
+ });
1778
+ if (series.pathfinderRemoveRenderEvent) {
1779
+ series.pathfinderRemoveRenderEvent();
1780
+ delete series.pathfinderRemoveRenderEvent;
1781
+ }
1782
+ };
1783
+ if (series.options.animation === false) {
1784
+ render();
1785
+ } else {
1786
+ series.pathfinderRemoveRenderEvent = addEvent(
1787
+ series, 'afterAnimate', render
1788
+ );
1789
+ }
1790
+ });
1791
+ } else {
1792
+ // Go through connections and render them
1793
+ each(this.connections, function (connection) {
1794
+ connection.render();
1795
+ });
1796
+ }
1797
+ },
1798
+
1799
+ /**
1800
+ * Get obstacles for the points in the chart. Does not include connecting
1801
+ * lines from Pathfinder. Applies algorithmMargin to the obstacles.
1802
+ *
1803
+ * @function Highcharts.Pathfinder#getChartObstacles
1804
+ *
1805
+ * @param {object} options
1806
+ * Options for the calculation. Currenlty only
1807
+ * options.algorithmMargin.
1808
+ *
1809
+ * @return {Array}
1810
+ * An array of calculated obstacles. Each obstacle is defined as
1811
+ * an object with xMin, xMax, yMin and yMax properties.
1812
+ */
1813
+ getChartObstacles: function (options) {
1814
+ var obstacles = [],
1815
+ series = this.chart.series,
1816
+ margin = pick(options.algorithmMargin, 0),
1817
+ calculatedMargin;
1818
+ for (var i = 0, sLen = series.length; i < sLen; ++i) {
1819
+ if (series[i].visible) {
1820
+ for (
1821
+ var j = 0, pLen = series[i].points.length, bb, point;
1822
+ j < pLen;
1823
+ ++j
1824
+ ) {
1825
+ point = series[i].points[j];
1826
+ if (point.visible) {
1827
+ bb = getPointBB(point);
1828
+ if (bb) {
1829
+ obstacles.push({
1830
+ xMin: bb.xMin - margin,
1831
+ xMax: bb.xMax + margin,
1832
+ yMin: bb.yMin - margin,
1833
+ yMax: bb.yMax + margin
1834
+ });
1835
+ }
1836
+ }
1837
+ }
1838
+ }
1839
+ }
1840
+
1841
+ // Sort obstacles by xMin for optimization
1842
+ obstacles = obstacles.sort(function (a, b) {
1843
+ return a.xMin - b.xMin;
1844
+ });
1845
+
1846
+ // Add auto-calculated margin if the option is not defined
1847
+ if (!defined(options.algorithmMargin)) {
1848
+ calculatedMargin =
1849
+ options.algorithmMargin =
1850
+ calculateObstacleMargin(obstacles);
1851
+ each(obstacles, function (obstacle) {
1852
+ obstacle.xMin -= calculatedMargin;
1853
+ obstacle.xMax += calculatedMargin;
1854
+ obstacle.yMin -= calculatedMargin;
1855
+ obstacle.yMax += calculatedMargin;
1856
+ });
1857
+ }
1858
+
1859
+ return obstacles;
1860
+ },
1861
+
1862
+ /**
1863
+ * Utility function to get metrics for obstacles:
1864
+ * - Widest obstacle width
1865
+ * - Tallest obstacle height
1866
+ *
1867
+ * @function Highcharts.Pathfinder#getObstacleMetrics
1868
+ *
1869
+ * @param {Array} obstacles
1870
+ * An array of obstacles to inspect.
1871
+ *
1872
+ * @return {object}
1873
+ * The calculated metrics, as an object with maxHeight and maxWidth
1874
+ * properties.
1875
+ */
1876
+ getObstacleMetrics: function (obstacles) {
1877
+ var maxWidth = 0,
1878
+ maxHeight = 0,
1879
+ width,
1880
+ height,
1881
+ i = obstacles.length;
1882
+
1883
+ while (i--) {
1884
+ width = obstacles[i].xMax - obstacles[i].xMin;
1885
+ height = obstacles[i].yMax - obstacles[i].yMin;
1886
+ if (maxWidth < width) {
1887
+ maxWidth = width;
1888
+ }
1889
+ if (maxHeight < height) {
1890
+ maxHeight = height;
1891
+ }
1892
+ }
1893
+
1894
+ return {
1895
+ maxHeight: maxHeight,
1896
+ maxWidth: maxWidth
1897
+ };
1898
+ },
1899
+
1900
+ /**
1901
+ * Utility to get which direction to start the pathfinding algorithm
1902
+ * (X vs Y), calculated from a set of marker options.
1903
+ *
1904
+ * @function Highcharts.Pathfinder#getAlgorithmStartDirection
1905
+ *
1906
+ * @param {object} markerOptions
1907
+ * Marker options to calculate from.
1908
+ *
1909
+ * @return {boolean}
1910
+ * Returns true for X, false for Y, and undefined for
1911
+ * autocalculate.
1912
+ */
1913
+ getAlgorithmStartDirection: function (markerOptions) {
1914
+ var xCenter = markerOptions.align !== 'left' &&
1915
+ markerOptions.align !== 'right',
1916
+ yCenter = markerOptions.verticalAlign !== 'top' &&
1917
+ markerOptions.verticalAlign !== 'bottom',
1918
+ undef;
1919
+
1920
+ return xCenter ?
1921
+ (yCenter ? undef : false) : // x is centered
1922
+ (yCenter ? true : undef); // x is off-center
1923
+ }
1924
+ };
1925
+
1926
+ // Add to Highcharts namespace
1927
+ H.Connection = Connection;
1928
+ H.Pathfinder = Pathfinder;
1929
+
1930
+
1931
+ // Add pathfinding capabilities to Points
1932
+ extend(H.Point.prototype, /** @lends Point.prototype */ {
1933
+
1934
+ /**
1935
+ * Get coordinates of anchor point for pathfinder connection.
1936
+ *
1937
+ * @private
1938
+ * @function Highcharts.Point#getPathfinderAnchorPoint
1939
+ *
1940
+ * @param {object} markerOptions
1941
+ * Connection options for position on point.
1942
+ *
1943
+ * @return {object}
1944
+ * An object with x/y properties for the position. Coordinates are
1945
+ * in plot values, not relative to point.
1946
+ */
1947
+ getPathfinderAnchorPoint: function (markerOptions) {
1948
+ var bb = getPointBB(this),
1949
+ x,
1950
+ y;
1951
+
1952
+ switch (markerOptions.align) { // eslint-disable-line default-case
1953
+ case 'right':
1954
+ x = 'xMax';
1955
+ break;
1956
+ case 'left':
1957
+ x = 'xMin';
1958
+ }
1959
+
1960
+ switch (markerOptions.verticalAlign) { // eslint-disable-line default-case
1961
+ case 'top':
1962
+ y = 'yMin';
1963
+ break;
1964
+ case 'bottom':
1965
+ y = 'yMax';
1966
+ }
1967
+
1968
+ return {
1969
+ x: x ? bb[x] : (bb.xMin + bb.xMax) / 2,
1970
+ y: y ? bb[y] : (bb.yMin + bb.yMax) / 2
1971
+ };
1972
+ },
1973
+
1974
+ /**
1975
+ * Utility to get the angle from one point to another.
1976
+ *
1977
+ * @private
1978
+ * @function Highcharts.Point#getRadiansToVector
1979
+ *
1980
+ * @param {object} v1
1981
+ * The first vector, as an object with x/y properties.
1982
+ *
1983
+ * @param {object} v2
1984
+ * The second vector, as an object with x/y properties.
1985
+ *
1986
+ * @return {number}
1987
+ * The angle in degrees
1988
+ */
1989
+ getRadiansToVector: function (v1, v2) {
1990
+ var box;
1991
+ if (!defined(v2)) {
1992
+ box = getPointBB(this);
1993
+ v2 = {
1994
+ x: (box.xMin + box.xMax) / 2,
1995
+ y: (box.yMin + box.yMax) / 2
1996
+ };
1997
+ }
1998
+ return Math.atan2(v2.y - v1.y, v1.x - v2.x);
1999
+ },
2000
+
2001
+ /**
2002
+ * Utility to get the position of the marker, based on the path angle and
2003
+ * the marker's radius.
2004
+ *
2005
+ * @private
2006
+ * @function Highcharts.Point#getMarkerVector
2007
+ *
2008
+ * @param {number} radians
2009
+ * The angle in radians from the point center to another vector.
2010
+ *
2011
+ * @param {number} markerRadius
2012
+ * The radius of the marker, to calculate the additional distance
2013
+ * to the center of the marker.
2014
+ *
2015
+ * @param {object} anchor
2016
+ * The anchor point of the path and marker as an object with x/y
2017
+ * properties.
2018
+ *
2019
+ * @return {object}
2020
+ * The marker vector as an object with x/y properties.
2021
+ */
2022
+ getMarkerVector: function (radians, markerRadius, anchor) {
2023
+ var twoPI = Math.PI * 2.0,
2024
+ theta = radians,
2025
+ bb = getPointBB(this),
2026
+ rectWidth = bb.xMax - bb.xMin,
2027
+ rectHeight = bb.yMax - bb.yMin,
2028
+ rAtan = Math.atan2(rectHeight, rectWidth),
2029
+ tanTheta = 1,
2030
+ leftOrRightRegion = false,
2031
+ rectHalfWidth = rectWidth / 2.0,
2032
+ rectHalfHeight = rectHeight / 2.0,
2033
+ rectHorizontalCenter = bb.xMin + rectHalfWidth,
2034
+ rectVerticalCenter = bb.yMin + rectHalfHeight,
2035
+ edgePoint = {
2036
+ x: rectHorizontalCenter,
2037
+ y: rectVerticalCenter
2038
+ },
2039
+ markerPoint = {},
2040
+ xFactor = 1,
2041
+ yFactor = 1;
2042
+
2043
+ while (theta < -Math.PI) {
2044
+ theta += twoPI;
2045
+ }
2046
+
2047
+ while (theta > Math.PI) {
2048
+ theta -= twoPI;
2049
+ }
2050
+
2051
+ tanTheta = Math.tan(theta);
2052
+
2053
+ if ((theta > -rAtan) && (theta <= rAtan)) {
2054
+ // Right side
2055
+ yFactor = -1;
2056
+ leftOrRightRegion = true;
2057
+ } else if (theta > rAtan && theta <= (Math.PI - rAtan)) {
2058
+ // Top side
2059
+ yFactor = -1;
2060
+ } else if (theta > (Math.PI - rAtan) || theta <= -(Math.PI - rAtan)) {
2061
+ // Left side
2062
+ xFactor = -1;
2063
+ leftOrRightRegion = true;
2064
+ } else {
2065
+ // Bottom side
2066
+ xFactor = -1;
2067
+ }
2068
+
2069
+ // Correct the edgePoint according to the placement of the marker
2070
+ if (leftOrRightRegion) {
2071
+ edgePoint.x += xFactor * (rectHalfWidth);
2072
+ edgePoint.y += yFactor * (rectHalfWidth) * tanTheta;
2073
+ } else {
2074
+ edgePoint.x += xFactor * (rectHeight / (2.0 * tanTheta));
2075
+ edgePoint.y += yFactor * (rectHalfHeight);
2076
+ }
2077
+
2078
+ if (anchor.x !== rectHorizontalCenter) {
2079
+ edgePoint.x = anchor.x;
2080
+ }
2081
+ if (anchor.y !== rectVerticalCenter) {
2082
+ edgePoint.y = anchor.y;
2083
+ }
2084
+
2085
+ markerPoint.x = edgePoint.x + (markerRadius * Math.cos(theta));
2086
+ markerPoint.y = edgePoint.y - (markerRadius * Math.sin(theta));
2087
+
2088
+ return markerPoint;
2089
+ }
2090
+ });
2091
+
2092
+ // Initialize Pathfinder for charts
2093
+ H.Chart.prototype.callbacks.push(function (chart) {
2094
+ var options = chart.options;
2095
+ if (options.pathfinder.enabled !== false) {
2096
+ this.pathfinder = new Pathfinder(this);
2097
+ this.pathfinder.update(true); // First draw, defer render
2098
+ }
2099
+ });
2100
+
2101
+ }(Highcharts, algorithms));
2102
+ return (function () {
2103
+
2104
+
2105
+ }());
2106
+ }));