highcharts 11.3.0 → 11.4.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 (773) hide show
  1. package/README.md +1 -1
  2. package/bower.json +1 -1
  3. package/css/annotations/popup.css +27 -19
  4. package/css/stocktools/gui.css +19 -7
  5. package/es-modules/Accessibility/A11yI18n.js +4 -6
  6. package/es-modules/Accessibility/Accessibility.js +8 -6
  7. package/es-modules/Accessibility/Components/InfoRegionsComponent.js +11 -6
  8. package/es-modules/Accessibility/Components/LegendComponent.js +4 -4
  9. package/es-modules/Accessibility/Components/MenuComponent.js +3 -6
  10. package/es-modules/Accessibility/Components/NavigatorComponent.js +6 -3
  11. package/es-modules/Accessibility/Components/RangeSelectorComponent.js +4 -7
  12. package/es-modules/Accessibility/Components/SeriesComponent/ForcedMarkers.js +18 -3
  13. package/es-modules/Accessibility/Components/SeriesComponent/NewDataAnnouncer.js +5 -3
  14. package/es-modules/Accessibility/Components/SeriesComponent/SeriesKeyboardNavigation.js +4 -4
  15. package/es-modules/Accessibility/FocusBorder.js +5 -5
  16. package/es-modules/Accessibility/HighContrastMode.js +22 -13
  17. package/es-modules/Accessibility/HighContrastTheme.js +2 -6
  18. package/es-modules/Accessibility/KeyboardNavigation.js +17 -8
  19. package/es-modules/Accessibility/Options/A11yDefaults.js +11 -1
  20. package/es-modules/Accessibility/ProxyElement.js +4 -4
  21. package/es-modules/Accessibility/ProxyProvider.js +8 -2
  22. package/es-modules/Accessibility/Utils/DOMElementProvider.js +8 -0
  23. package/es-modules/Accessibility/Utils/EventProvider.js +9 -0
  24. package/es-modules/Core/Animation/Fx.js +3 -3
  25. package/es-modules/Core/Axis/Axis.js +43 -97
  26. package/es-modules/Core/Axis/Axis3DComposition.js +5 -5
  27. package/es-modules/Core/Axis/Axis3DDefaults.js +1 -1
  28. package/es-modules/Core/Axis/AxisDefaults.js +18 -7
  29. package/es-modules/Core/Axis/BrokenAxis.js +4 -6
  30. package/es-modules/Core/Axis/Color/ColorAxis.js +2 -1
  31. package/es-modules/Core/Axis/Color/ColorAxisComposition.js +3 -5
  32. package/es-modules/Core/Axis/DateTimeAxis.js +3 -5
  33. package/es-modules/Core/Axis/GridAxis.js +7 -7
  34. package/es-modules/Core/Axis/LogarithmicAxis.js +2 -4
  35. package/es-modules/Core/Axis/NavigatorAxisComposition.js +26 -22
  36. package/es-modules/Core/Axis/OrdinalAxis.js +97 -53
  37. package/es-modules/Core/Axis/PlotLineOrBand/PlotLineOrBand.js +3 -3
  38. package/es-modules/Core/Axis/PlotLineOrBand/PlotLineOrBandAxis.js +4 -5
  39. package/es-modules/Core/Axis/RadialAxis.js +5 -5
  40. package/es-modules/Core/Axis/ScrollbarAxis.js +2 -2
  41. package/es-modules/Core/Axis/Stacking/StackItem.js +8 -4
  42. package/es-modules/Core/Axis/Stacking/StackingAxis.js +3 -5
  43. package/es-modules/Core/Axis/Tick.js +16 -7
  44. package/es-modules/Core/Axis/Tick3DComposition.js +2 -2
  45. package/es-modules/Core/Axis/TreeGrid/TreeGridAxis.js +4 -8
  46. package/es-modules/Core/Axis/TreeGrid/TreeGridTick.js +3 -6
  47. package/es-modules/Core/Axis/WaterfallAxis.js +3 -3
  48. package/es-modules/Core/Axis/ZAxis.js +6 -11
  49. package/es-modules/Core/Chart/Chart.js +201 -176
  50. package/es-modules/Core/Chart/Chart3D.js +1 -1
  51. package/es-modules/Core/Chart/ChartDefaults.js +7 -0
  52. package/es-modules/Core/Chart/GanttChart.js +2 -2
  53. package/es-modules/Core/Chart/MapChart.js +12 -2
  54. package/es-modules/Core/Chart/StockChart.js +12 -11
  55. package/es-modules/Core/Color/Color.js +3 -3
  56. package/es-modules/Core/Color/Palettes.js +2 -2
  57. package/es-modules/Core/Defaults.js +18 -15
  58. package/es-modules/Core/Geometry/CircleUtilities.js +3 -3
  59. package/es-modules/Core/Globals.js +2 -2
  60. package/es-modules/Core/HttpUtilities.js +4 -4
  61. package/es-modules/Core/Legend/Legend.js +6 -6
  62. package/es-modules/Core/MSPointer.js +7 -7
  63. package/es-modules/Core/Pointer.js +230 -245
  64. package/es-modules/Core/Renderer/HTML/AST.js +1 -1
  65. package/es-modules/Core/Renderer/HTML/HTMLElement.js +213 -26
  66. package/es-modules/Core/Renderer/RendererUtilities.js +1 -1
  67. package/es-modules/Core/Renderer/SVG/SVGElement.js +85 -52
  68. package/es-modules/Core/Renderer/SVG/SVGLabel.js +14 -11
  69. package/es-modules/Core/Renderer/SVG/SVGRenderer.js +17 -14
  70. package/es-modules/Core/Renderer/SVG/SVGRenderer3D.js +8 -7
  71. package/es-modules/Core/Renderer/SVG/Symbols.js +1 -1
  72. package/es-modules/Core/Renderer/SVG/TextBuilder.js +2 -2
  73. package/es-modules/Core/Responsive.js +5 -6
  74. package/es-modules/Core/Series/DataLabel.js +70 -90
  75. package/es-modules/Core/Series/DataSeriesComposition.js +1 -1
  76. package/es-modules/Core/Series/DataSeriesConverter.js +2 -2
  77. package/es-modules/Core/Series/Point.js +48 -40
  78. package/es-modules/Core/Series/Series.js +61 -51
  79. package/es-modules/Core/Series/Series3D.js +2 -2
  80. package/es-modules/Core/Series/SeriesRegistry.js +10 -2
  81. package/es-modules/Core/Templating.js +1 -1
  82. package/es-modules/Core/Time.js +12 -7
  83. package/es-modules/Core/Tooltip.js +19 -17
  84. package/es-modules/Core/Utilities.js +54 -26
  85. package/es-modules/Data/Connectors/CSVConnector.js +2 -2
  86. package/es-modules/Data/Connectors/DataConnector.js +4 -2
  87. package/es-modules/Data/Connectors/GoogleSheetsConnector.js +2 -2
  88. package/es-modules/Data/Connectors/HTMLTableConnector.js +2 -2
  89. package/es-modules/Data/Connectors/JSONConnector.js +3 -5
  90. package/es-modules/Data/Converters/CSVConverter.js +1 -3
  91. package/es-modules/Data/Converters/DataConverter.js +8 -2
  92. package/es-modules/Data/Converters/HTMLTableConverter.js +1 -3
  93. package/es-modules/Data/Converters/JSONConverter.js +1 -0
  94. package/es-modules/Data/DataTable.js +1 -2
  95. package/es-modules/Data/Formula/FormulaProcessor.js +4 -2
  96. package/es-modules/Data/Modifiers/DataModifier.js +15 -3
  97. package/es-modules/Extensions/Annotations/Annotation.js +6 -7
  98. package/es-modules/Extensions/Annotations/AnnotationChart.js +4 -5
  99. package/es-modules/Extensions/Annotations/AnnotationDefaults.js +4 -4
  100. package/es-modules/Extensions/Annotations/ControlPoint.js +2 -2
  101. package/es-modules/Extensions/Annotations/ControlTarget.js +1 -1
  102. package/es-modules/Extensions/Annotations/Controllables/Controllable.js +7 -3
  103. package/es-modules/Extensions/Annotations/Controllables/ControllableEllipse.js +3 -3
  104. package/es-modules/Extensions/Annotations/Controllables/ControllableLabel.js +8 -9
  105. package/es-modules/Extensions/Annotations/Controllables/ControllablePath.js +3 -4
  106. package/es-modules/Extensions/Annotations/EventEmitter.js +6 -6
  107. package/es-modules/Extensions/Annotations/NavigationBindings.js +29 -18
  108. package/es-modules/Extensions/Annotations/NavigationBindingsDefaults.js +6 -6
  109. package/es-modules/Extensions/Annotations/Popup/Popup.js +1 -1
  110. package/es-modules/Extensions/Annotations/Popup/PopupAnnotations.js +10 -6
  111. package/es-modules/Extensions/Annotations/Popup/PopupComposition.js +2 -2
  112. package/es-modules/Extensions/Annotations/Popup/PopupIndicators.js +31 -31
  113. package/es-modules/Extensions/Annotations/Popup/PopupTabs.js +1 -1
  114. package/es-modules/Extensions/Annotations/Types/BasicAnnotation.js +14 -11
  115. package/es-modules/Extensions/Annotations/Types/FibonacciTimeZones.js +1 -1
  116. package/es-modules/Extensions/Annotations/Types/Measure.js +1 -1
  117. package/es-modules/Extensions/ArrowSymbols.js +7 -13
  118. package/es-modules/Extensions/Boost/Boost.js +39 -7
  119. package/es-modules/Extensions/Boost/BoostChart.js +4 -4
  120. package/es-modules/Extensions/Boost/BoostSeries.js +58 -13
  121. package/es-modules/Extensions/Boost/WGLRenderer.js +3 -3
  122. package/es-modules/Extensions/Boost/WGLVertexBuffer.js +1 -1
  123. package/es-modules/Extensions/BoostCanvas.js +5 -4
  124. package/es-modules/Extensions/BorderRadius.js +5 -4
  125. package/es-modules/Extensions/Breadcrumbs/Breadcrumbs.js +9 -9
  126. package/es-modules/Extensions/CurrentDateIndication.js +1 -1
  127. package/es-modules/Extensions/Data.js +11 -11
  128. package/es-modules/Extensions/DataGrouping/DataGrouping.js +1 -1
  129. package/es-modules/Extensions/DataGrouping/DataGroupingAxisComposition.js +8 -9
  130. package/es-modules/Extensions/DataGrouping/DataGroupingDefaults.js +1 -1
  131. package/es-modules/Extensions/DataGrouping/DataGroupingSeriesComposition.js +6 -7
  132. package/es-modules/Extensions/Debugger/Debugger.js +1 -1
  133. package/es-modules/Extensions/Debugger/ErrorMessages.js +2 -2
  134. package/es-modules/Extensions/DragPanes/AxisResizer.js +13 -16
  135. package/es-modules/Extensions/DragPanes/DragPanes.js +2 -4
  136. package/es-modules/Extensions/DraggablePoints/DragDropDefaults.js +2 -1
  137. package/es-modules/Extensions/DraggablePoints/DragDropUtilities.js +1 -1
  138. package/es-modules/Extensions/DraggablePoints/DraggableChart.js +4 -4
  139. package/es-modules/Extensions/DraggablePoints/DraggablePoints.js +8 -9
  140. package/es-modules/Extensions/Drilldown/Drilldown.js +11 -9
  141. package/es-modules/Extensions/Drilldown/DrilldownSeries.js +5 -6
  142. package/es-modules/Extensions/ExportData/ExportData.js +27 -18
  143. package/es-modules/Extensions/Exporting/Exporting.js +25 -20
  144. package/es-modules/Extensions/Exporting/ExportingDefaults.js +1 -1
  145. package/es-modules/Extensions/Exporting/Fullscreen.js +5 -10
  146. package/es-modules/Extensions/MarkerClusters/MarkerClusterScatter.js +26 -21
  147. package/es-modules/Extensions/MarkerClusters/MarkerClusterSymbols.js +2 -12
  148. package/es-modules/Extensions/MarkerClusters/MarkerClusters.js +3 -3
  149. package/es-modules/Extensions/MouseWheelZoom/MouseWheelZoom.js +51 -161
  150. package/es-modules/Extensions/NoDataToDisplay/NoDataToDisplay.js +3 -5
  151. package/es-modules/Extensions/OfflineExporting/OfflineExporting.js +5 -6
  152. package/es-modules/Extensions/OfflineExporting/OfflineExportingDefaults.js +1 -1
  153. package/es-modules/Extensions/OverlappingDataLabels.js +21 -49
  154. package/es-modules/Extensions/Pane/PaneComposition.js +3 -5
  155. package/es-modules/Extensions/ParallelCoordinates/ParallelAxis.js +2 -4
  156. package/es-modules/Extensions/ParallelCoordinates/ParallelCoordinates.js +5 -6
  157. package/es-modules/Extensions/ParallelCoordinates/ParallelSeries.js +1 -1
  158. package/es-modules/Extensions/PatternFill.js +19 -22
  159. package/es-modules/Extensions/PriceIndication.js +1 -1
  160. package/es-modules/Extensions/ScrollablePlotArea.js +218 -292
  161. package/es-modules/Extensions/SeriesLabel/SeriesLabel.js +26 -18
  162. package/es-modules/Extensions/Sonification/Options.js +1 -0
  163. package/es-modules/Extensions/Sonification/SonificationSpeaker.js +2 -2
  164. package/es-modules/Extensions/Sonification/SynthPatch.js +3 -3
  165. package/es-modules/Extensions/StaticScale.js +3 -5
  166. package/es-modules/Gantt/Legacy.js +1 -1
  167. package/es-modules/Gantt/Pathfinder.js +2 -2
  168. package/es-modules/Gantt/PathfinderComposition.js +3 -5
  169. package/es-modules/Gantt/Tree.js +3 -3
  170. package/es-modules/Maps/GeoJSONComposition.js +20 -13
  171. package/es-modules/Maps/MapNavigation.js +2 -2
  172. package/es-modules/Maps/MapPointer.js +3 -19
  173. package/es-modules/Maps/MapSymbols.js +3 -9
  174. package/es-modules/Maps/MapView.js +134 -74
  175. package/es-modules/Series/ArcDiagram/ArcDiagramSeries.js +5 -4
  176. package/es-modules/Series/Area/AreaSeries.js +2 -4
  177. package/es-modules/Series/Area3D/Area3DSeries.js +1 -1
  178. package/es-modules/Series/AreaRange/AreaRangePoint.js +2 -2
  179. package/es-modules/Series/AreaRange/AreaRangeSeries.js +2 -3
  180. package/es-modules/Series/AreaSpline/AreaSplineSeries.js +1 -1
  181. package/es-modules/Series/Bar/BarSeries.js +1 -1
  182. package/es-modules/Series/Bellcurve/BellcurveSeries.js +1 -1
  183. package/es-modules/Series/BoxPlot/BoxPlotSeriesDefaults.js +4 -0
  184. package/es-modules/Series/Bubble/BubbleLegendComposition.js +1 -1
  185. package/es-modules/Series/Bubble/BubbleLegendDefaults.js +2 -2
  186. package/es-modules/Series/Bubble/BubbleLegendItem.js +3 -3
  187. package/es-modules/Series/Bubble/BubbleSeries.js +1 -1
  188. package/es-modules/Series/Bullet/BulletSeriesDefaults.js +2 -2
  189. package/es-modules/Series/Candlestick/CandlestickSeries.js +2 -2
  190. package/es-modules/Series/Candlestick/CandlestickSeriesDefaults.js +1 -5
  191. package/es-modules/Series/ColorMapComposition.js +1 -1
  192. package/es-modules/Series/Column/ColumnDataLabel.js +2 -2
  193. package/es-modules/Series/Column/ColumnSeries.js +20 -22
  194. package/es-modules/Series/Column/ColumnSeriesDefaults.js +1 -1
  195. package/es-modules/Series/Column3D/Column3DComposition.js +1 -1
  196. package/es-modules/Series/ColumnRange/ColumnRangeSeries.js +2 -1
  197. package/es-modules/Series/Cylinder/CylinderComposition.js +9 -9
  198. package/es-modules/Series/DataModifyComposition.js +5 -5
  199. package/es-modules/Series/DependencyWheel/DependencyWheelSeries.js +3 -2
  200. package/es-modules/Series/DependencyWheel/DependencyWheelSeriesDefaults.js +1 -1
  201. package/es-modules/Series/DragNodesComposition.js +7 -7
  202. package/es-modules/Series/DrawPointUtilities.js +0 -2
  203. package/es-modules/Series/Dumbbell/DumbbellSeriesDefaults.js +1 -1
  204. package/es-modules/Series/Funnel/FunnelSeries.js +1 -1
  205. package/es-modules/Series/Funnel3D/Funnel3DComposition.js +6 -6
  206. package/es-modules/Series/Funnel3D/Funnel3DSeriesDefaults.js +2 -2
  207. package/es-modules/Series/Funnel3D/SVGElement3DFunnel.js +1 -1
  208. package/es-modules/Series/Gantt/GanttSeries.js +0 -1
  209. package/es-modules/Series/GeoHeatmap/GeoHeatmapSeries.js +5 -5
  210. package/es-modules/Series/GraphLayoutComposition.js +1 -1
  211. package/es-modules/Series/Heatmap/HeatmapSeries.js +2 -2
  212. package/es-modules/Series/Heatmap/HeatmapSeriesDefaults.js +1 -1
  213. package/es-modules/Series/HeikinAshi/HeikinAshiPoint.js +3 -1
  214. package/es-modules/Series/HeikinAshi/HeikinAshiSeries.js +3 -3
  215. package/es-modules/Series/HeikinAshi/HeikinAshiSeriesDefaults.js +1 -1
  216. package/es-modules/Series/HollowCandlestick/HollowCandlestickSeries.js +2 -2
  217. package/es-modules/Series/Item/ItemSeries.js +1 -1
  218. package/es-modules/Series/Line/LineSeries.js +1 -1
  219. package/es-modules/Series/Lollipop/LollipopSeries.js +3 -1
  220. package/es-modules/Series/Map/MapPoint.js +5 -1
  221. package/es-modules/Series/Map/MapSeries.js +32 -7
  222. package/es-modules/Series/Map/MapSeriesDefaults.js +5 -3
  223. package/es-modules/Series/Networkgraph/EulerIntegration.js +5 -5
  224. package/es-modules/Series/Networkgraph/NetworkgraphSeries.js +4 -4
  225. package/es-modules/Series/Networkgraph/NetworkgraphSeriesDefaults.js +5 -5
  226. package/es-modules/Series/Networkgraph/QuadTree.js +1 -1
  227. package/es-modules/Series/Networkgraph/QuadTreeNode.js +1 -1
  228. package/es-modules/Series/Networkgraph/VerletIntegration.js +9 -9
  229. package/es-modules/Series/NodesComposition.js +1 -1
  230. package/es-modules/Series/OHLC/OHLCSeries.js +1 -1
  231. package/es-modules/Series/OHLC/OHLCSeriesDefaults.js +1 -1
  232. package/es-modules/Series/OnSeriesComposition.js +1 -1
  233. package/es-modules/Series/Organization/OrganizationPoint.js +1 -1
  234. package/es-modules/Series/Organization/OrganizationSeries.js +22 -10
  235. package/es-modules/Series/Organization/OrganizationSeriesDefaults.js +15 -2
  236. package/es-modules/Series/PackedBubble/PackedBubbleLayout.js +3 -5
  237. package/es-modules/Series/PackedBubble/PackedBubblePoint.js +1 -1
  238. package/es-modules/Series/PackedBubble/PackedBubbleSeries.js +6 -10
  239. package/es-modules/Series/Pictorial/PictorialSeries.js +2 -2
  240. package/es-modules/Series/Pie/PieDataLabel.js +2 -2
  241. package/es-modules/Series/Pie/PiePoint.js +1 -1
  242. package/es-modules/Series/Pie/PieSeries.js +10 -1
  243. package/es-modules/Series/Pie/PieSeriesDefaults.js +1 -1
  244. package/es-modules/Series/Pie3D/Pie3DSeries.js +2 -2
  245. package/es-modules/Series/PolarComposition.js +22 -20
  246. package/es-modules/Series/Sankey/SankeyColumnComposition.js +1 -1
  247. package/es-modules/Series/Sankey/SankeySeries.js +8 -8
  248. package/es-modules/Series/Sankey/SankeySeriesDefaults.js +57 -13
  249. package/es-modules/Series/SeriesOnPointComposition.js +3 -3
  250. package/es-modules/Series/Spline/SplineSeries.js +1 -1
  251. package/es-modules/Series/Sunburst/SunburstPoint.js +1 -1
  252. package/es-modules/Series/Sunburst/SunburstSeries.js +2 -7
  253. package/es-modules/Series/Sunburst/SunburstSeriesDefaults.js +3 -3
  254. package/es-modules/Series/Sunburst/SunburstUtilities.js +1 -1
  255. package/es-modules/Series/TiledWebMap/TiledWebMapSeries.js +23 -25
  256. package/es-modules/Series/Tilemap/TilemapSeries.js +2 -2
  257. package/es-modules/Series/Timeline/TimelineSeries.js +2 -2
  258. package/es-modules/Series/TreeUtilities.js +23 -1
  259. package/es-modules/Series/Treegraph/TreegraphLayout.js +7 -11
  260. package/es-modules/Series/Treegraph/TreegraphPoint.js +1 -0
  261. package/es-modules/Series/Treegraph/TreegraphSeries.js +8 -8
  262. package/es-modules/Series/Treegraph/TreegraphSeriesDefaults.js +39 -2
  263. package/es-modules/Series/Treemap/TreemapSeries.js +4 -2
  264. package/es-modules/Series/Treemap/TreemapUtilities.js +0 -7
  265. package/es-modules/Series/Variwide/VariwideComposition.js +6 -2
  266. package/es-modules/Series/Variwide/VariwideSeries.js +1 -1
  267. package/es-modules/Series/Venn/VennSeries.js +4 -4
  268. package/es-modules/Series/Venn/VennUtils.js +5 -6
  269. package/es-modules/Series/Waterfall/WaterfallSeriesDefaults.js +1 -1
  270. package/es-modules/Series/Windbarb/WindbarbSeries.js +1 -1
  271. package/es-modules/Series/Wordcloud/WordcloudUtils.js +6 -4
  272. package/es-modules/Series/XRange/XRangePoint.js +2 -2
  273. package/es-modules/Series/XRange/XRangeSeries.js +1 -1
  274. package/es-modules/Shared/BaseForm.js +1 -1
  275. package/es-modules/Stock/Indicators/AD/ADIndicator.js +3 -1
  276. package/es-modules/Stock/Indicators/APO/APOIndicator.js +1 -1
  277. package/es-modules/Stock/Indicators/Aroon/AroonIndicator.js +1 -1
  278. package/es-modules/Stock/Indicators/CMF/CMFIndicator.js +1 -1
  279. package/es-modules/Stock/Indicators/CMO/CMOIndicator.js +2 -2
  280. package/es-modules/Stock/Indicators/Chaikin/ChaikinIndicator.js +1 -1
  281. package/es-modules/Stock/Indicators/DPO/DPOIndicator.js +1 -1
  282. package/es-modules/Stock/Indicators/Klinger/KlingerIndicator.js +1 -1
  283. package/es-modules/Stock/Indicators/LinearRegression/LinearRegressionIndicator.js +7 -7
  284. package/es-modules/Stock/Indicators/MultipleLinesComposition.js +9 -9
  285. package/es-modules/Stock/Indicators/OBV/OBVIndicator.js +1 -1
  286. package/es-modules/Stock/Indicators/PPO/PPOIndicator.js +1 -1
  287. package/es-modules/Stock/Indicators/PivotPoints/PivotPointsIndicator.js +2 -2
  288. package/es-modules/Stock/Indicators/SMA/SMAIndicator.js +1 -1
  289. package/es-modules/Stock/Indicators/Supertrend/SupertrendIndicator.js +16 -17
  290. package/es-modules/Stock/Indicators/VBP/VBPIndicator.js +4 -5
  291. package/es-modules/Stock/Indicators/WilliamsR/WilliamsRIndicator.js +1 -1
  292. package/es-modules/Stock/Indicators/Zigzag/ZigzagIndicator.js +5 -5
  293. package/es-modules/Stock/Navigator/ChartNavigatorComposition.js +188 -0
  294. package/es-modules/Stock/Navigator/Navigator.js +42 -27
  295. package/es-modules/Stock/Navigator/NavigatorComposition.js +10 -149
  296. package/es-modules/Stock/Navigator/NavigatorDefaults.js +16 -2
  297. package/es-modules/Stock/Navigator/StandaloneNavigator.js +334 -0
  298. package/es-modules/Stock/Navigator/StandaloneNavigatorDefaults.js +64 -0
  299. package/es-modules/Stock/RangeSelector/RangeSelector.js +28 -16
  300. package/es-modules/Stock/RangeSelector/RangeSelectorComposition.js +2 -2
  301. package/es-modules/Stock/Scrollbar/Scrollbar.js +10 -10
  302. package/es-modules/Stock/Scrollbar/ScrollbarDefaults.js +1 -3
  303. package/es-modules/Stock/StockTools/StockToolbar.js +6 -5
  304. package/es-modules/Stock/StockTools/StockTools.js +10 -13
  305. package/es-modules/Stock/StockTools/StockToolsBindings.js +35 -35
  306. package/es-modules/Stock/StockTools/StockToolsDefaults.js +2 -1
  307. package/es-modules/Stock/StockTools/StockToolsGui.js +7 -8
  308. package/es-modules/Stock/StockTools/StockToolsUtilities.js +8 -9
  309. package/es-modules/Stock/Utilities/StockUtilities.js +41 -0
  310. package/es-modules/masters/highcharts-3d.src.js +2 -1
  311. package/es-modules/masters/highcharts-gantt.src.js +1 -1
  312. package/es-modules/masters/highcharts-more.src.js +2 -1
  313. package/es-modules/masters/highcharts.src.js +41 -40
  314. package/es-modules/masters/highmaps.src.js +1 -1
  315. package/es-modules/masters/highstock.src.js +1 -1
  316. package/es-modules/masters/indicators/acceleration-bands.src.js +3 -1
  317. package/es-modules/masters/indicators/accumulation-distribution.src.js +3 -1
  318. package/es-modules/masters/indicators/ao.src.js +3 -1
  319. package/es-modules/masters/indicators/apo.src.js +3 -1
  320. package/es-modules/masters/indicators/aroon-oscillator.src.js +3 -1
  321. package/es-modules/masters/indicators/aroon.src.js +3 -1
  322. package/es-modules/masters/indicators/atr.src.js +3 -1
  323. package/es-modules/masters/indicators/bollinger-bands.src.js +3 -1
  324. package/es-modules/masters/indicators/cci.src.js +3 -1
  325. package/es-modules/masters/indicators/chaikin.src.js +3 -1
  326. package/es-modules/masters/indicators/cmf.src.js +3 -1
  327. package/es-modules/masters/indicators/cmo.src.js +3 -1
  328. package/es-modules/masters/indicators/dema.src.js +3 -1
  329. package/es-modules/masters/indicators/disparity-index.src.js +3 -1
  330. package/es-modules/masters/indicators/dmi.src.js +3 -1
  331. package/es-modules/masters/indicators/dpo.src.js +3 -1
  332. package/es-modules/masters/indicators/ema.src.js +2 -0
  333. package/es-modules/masters/indicators/ichimoku-kinko-hyo.src.js +3 -1
  334. package/es-modules/masters/indicators/indicators-all.src.js +3 -1
  335. package/es-modules/masters/indicators/indicators.src.js +7 -1
  336. package/es-modules/masters/indicators/keltner-channels.src.js +3 -1
  337. package/es-modules/masters/indicators/klinger.src.js +3 -1
  338. package/es-modules/masters/indicators/macd.src.js +3 -1
  339. package/es-modules/masters/indicators/mfi.src.js +3 -1
  340. package/es-modules/masters/indicators/momentum.src.js +3 -1
  341. package/es-modules/masters/indicators/natr.src.js +3 -1
  342. package/es-modules/masters/indicators/obv.src.js +3 -1
  343. package/es-modules/masters/indicators/pivot-points.src.js +3 -1
  344. package/es-modules/masters/indicators/ppo.src.js +3 -1
  345. package/es-modules/masters/indicators/price-channel.src.js +3 -1
  346. package/es-modules/masters/indicators/price-envelopes.src.js +3 -1
  347. package/es-modules/masters/indicators/psar.src.js +3 -1
  348. package/es-modules/masters/indicators/regressions.src.js +3 -1
  349. package/es-modules/masters/indicators/roc.src.js +3 -1
  350. package/es-modules/masters/indicators/rsi.src.js +3 -1
  351. package/es-modules/masters/indicators/slow-stochastic.src.js +3 -1
  352. package/es-modules/masters/indicators/stochastic.src.js +3 -1
  353. package/es-modules/masters/indicators/supertrend.src.js +3 -1
  354. package/es-modules/masters/indicators/tema.src.js +3 -1
  355. package/es-modules/masters/indicators/trendline.src.js +3 -1
  356. package/es-modules/masters/indicators/trix.src.js +3 -1
  357. package/es-modules/masters/indicators/volume-by-price.src.js +3 -1
  358. package/es-modules/masters/indicators/vwap.src.js +3 -1
  359. package/es-modules/masters/indicators/williams-r.src.js +3 -1
  360. package/es-modules/masters/indicators/wma.src.js +3 -1
  361. package/es-modules/masters/indicators/zigzag.src.js +3 -1
  362. package/es-modules/masters/modules/accessibility.src.js +4 -1
  363. package/es-modules/masters/modules/annotations-advanced.src.js +3 -5
  364. package/es-modules/masters/modules/annotations.src.js +6 -3
  365. package/es-modules/masters/modules/arc-diagram.src.js +3 -1
  366. package/es-modules/masters/modules/arrow-symbols.src.js +2 -1
  367. package/es-modules/masters/modules/boost-canvas.src.js +2 -1
  368. package/es-modules/masters/modules/boost.src.js +3 -2
  369. package/es-modules/masters/modules/broken-axis.src.js +4 -3
  370. package/es-modules/masters/modules/bullet.src.js +3 -1
  371. package/es-modules/masters/modules/coloraxis.src.js +4 -3
  372. package/es-modules/masters/modules/current-date-indicator.src.js +2 -1
  373. package/es-modules/masters/modules/cylinder.src.js +3 -1
  374. package/es-modules/masters/modules/data-tools.src.js +9 -8
  375. package/es-modules/masters/modules/data.src.js +9 -8
  376. package/es-modules/masters/modules/datagrouping.src.js +7 -5
  377. package/es-modules/masters/modules/debugger.src.js +3 -2
  378. package/es-modules/masters/modules/dependency-wheel.src.js +3 -1
  379. package/es-modules/masters/modules/dotplot.src.js +3 -1
  380. package/es-modules/masters/modules/drag-panes.src.js +2 -1
  381. package/es-modules/masters/modules/draggable-points.src.js +2 -1
  382. package/es-modules/masters/modules/drilldown.src.js +3 -2
  383. package/es-modules/masters/modules/dumbbell.src.js +3 -1
  384. package/es-modules/masters/modules/export-data.src.js +5 -4
  385. package/es-modules/masters/modules/exporting.src.js +6 -5
  386. package/es-modules/masters/modules/flowmap.src.js +3 -1
  387. package/es-modules/masters/modules/full-screen.src.js +4 -3
  388. package/es-modules/masters/modules/funnel.src.js +2 -1
  389. package/es-modules/masters/modules/funnel3d.src.js +4 -3
  390. package/es-modules/masters/modules/gantt.src.js +15 -17
  391. package/es-modules/masters/modules/geoheatmap.src.js +3 -1
  392. package/es-modules/masters/modules/grid-axis.src.js +2 -1
  393. package/es-modules/masters/modules/heatmap.src.js +3 -5
  394. package/es-modules/masters/modules/heikinashi.src.js +2 -1
  395. package/es-modules/masters/modules/histogram-bellcurve.src.js +3 -1
  396. package/es-modules/masters/modules/hollowcandlestick.src.js +3 -1
  397. package/es-modules/masters/modules/item-series.src.js +3 -1
  398. package/es-modules/masters/modules/lollipop.src.js +3 -1
  399. package/es-modules/masters/modules/map.src.js +15 -10
  400. package/es-modules/masters/modules/marker-clusters.src.js +2 -1
  401. package/es-modules/masters/modules/mouse-wheel-zoom.src.js +4 -2
  402. package/es-modules/masters/modules/navigator.src.d.ts +1 -0
  403. package/es-modules/masters/modules/navigator.src.js +19 -0
  404. package/es-modules/masters/modules/networkgraph.src.js +2 -1
  405. package/es-modules/masters/modules/no-data-to-display.src.js +2 -1
  406. package/es-modules/masters/modules/offline-exporting.src.js +4 -3
  407. package/es-modules/masters/modules/organization.src.js +3 -1
  408. package/es-modules/masters/modules/overlapping-datalabels.src.js +4 -2
  409. package/es-modules/masters/modules/parallel-coordinates.src.js +2 -1
  410. package/es-modules/masters/modules/pareto.src.js +3 -1
  411. package/es-modules/masters/modules/pathfinder.src.js +4 -3
  412. package/es-modules/masters/modules/pattern-fill.src.js +2 -1
  413. package/es-modules/masters/modules/pictorial.src.js +3 -1
  414. package/es-modules/masters/modules/price-indicator.src.js +2 -1
  415. package/es-modules/masters/modules/pyramid3d.src.js +3 -1
  416. package/es-modules/masters/modules/sankey.src.js +3 -1
  417. package/es-modules/masters/modules/series-label.src.js +2 -1
  418. package/es-modules/masters/modules/series-on-point.src.js +2 -1
  419. package/es-modules/masters/modules/solid-gauge.src.js +3 -1
  420. package/es-modules/masters/modules/sonification.src.js +2 -1
  421. package/es-modules/masters/modules/static-scale.src.js +2 -1
  422. package/es-modules/masters/modules/stock-tools.src.js +5 -3
  423. package/es-modules/masters/modules/stock.src.js +20 -15
  424. package/es-modules/masters/modules/streamgraph.src.js +3 -1
  425. package/es-modules/masters/modules/sunburst.src.js +4 -3
  426. package/es-modules/masters/modules/tiledwebmap.src.js +5 -4
  427. package/es-modules/masters/modules/tilemap.src.js +2 -1
  428. package/es-modules/masters/modules/timeline.src.js +3 -1
  429. package/es-modules/masters/modules/treegraph.src.js +3 -1
  430. package/es-modules/masters/modules/treegrid.src.js +2 -2
  431. package/es-modules/masters/modules/treemap.src.js +5 -4
  432. package/es-modules/masters/modules/variable-pie.src.js +3 -1
  433. package/es-modules/masters/modules/variwide.src.js +2 -1
  434. package/es-modules/masters/modules/vector.src.js +3 -1
  435. package/es-modules/masters/modules/venn.src.js +3 -1
  436. package/es-modules/masters/modules/windbarb.src.js +3 -1
  437. package/es-modules/masters/modules/wordcloud.src.js +3 -1
  438. package/es-modules/masters/modules/xrange.src.js +2 -1
  439. package/es-modules/masters/standalone-navigator.src.js +13 -0
  440. package/es-modules/masters/themes/avocado.src.js +2 -1
  441. package/es-modules/masters/themes/brand-dark.src.js +2 -1
  442. package/es-modules/masters/themes/brand-light.src.js +2 -1
  443. package/es-modules/masters/themes/dark-blue.src.js +2 -1
  444. package/es-modules/masters/themes/dark-green.src.js +2 -1
  445. package/es-modules/masters/themes/dark-unica.src.js +2 -1
  446. package/es-modules/masters/themes/gray.src.js +2 -1
  447. package/es-modules/masters/themes/grid-light.src.js +2 -1
  448. package/es-modules/masters/themes/grid.src.js +2 -1
  449. package/es-modules/masters/themes/high-contrast-dark.src.js +2 -1
  450. package/es-modules/masters/themes/high-contrast-light.src.js +2 -1
  451. package/es-modules/masters/themes/sand-signika.src.js +2 -1
  452. package/es-modules/masters/themes/skies.src.js +2 -1
  453. package/es-modules/masters/themes/sunset.src.js +2 -1
  454. package/es-modules/tsconfig.tsbuildinfo +1 -0
  455. package/globals.d.ts +9 -0
  456. package/globals.src.d.ts +9 -0
  457. package/highcharts-3d.js +3 -3
  458. package/highcharts-3d.src.js +32 -33
  459. package/highcharts-gantt.js +4 -4
  460. package/highcharts-gantt.src.js +5703 -5639
  461. package/highcharts-more.d.ts +4 -0
  462. package/highcharts-more.js +3 -3
  463. package/highcharts-more.src.d.ts +4 -0
  464. package/highcharts-more.src.js +88 -87
  465. package/highcharts.d.ts +834 -5365
  466. package/highcharts.js +4 -4
  467. package/highcharts.src.d.ts +834 -5365
  468. package/highcharts.src.js +1583 -1682
  469. package/highmaps.js +4 -4
  470. package/highmaps.src.js +1837 -1835
  471. package/highstock.js +4 -4
  472. package/highstock.src.js +12488 -12510
  473. package/indicators/acceleration-bands.js +3 -3
  474. package/indicators/acceleration-bands.src.js +12 -11
  475. package/indicators/accumulation-distribution.js +3 -3
  476. package/indicators/accumulation-distribution.src.js +6 -3
  477. package/indicators/ao.js +3 -3
  478. package/indicators/ao.src.js +3 -2
  479. package/indicators/apo.js +3 -3
  480. package/indicators/apo.src.js +4 -3
  481. package/indicators/aroon-oscillator.js +3 -3
  482. package/indicators/aroon-oscillator.src.js +12 -11
  483. package/indicators/aroon.js +3 -3
  484. package/indicators/aroon.src.js +13 -12
  485. package/indicators/atr.js +3 -3
  486. package/indicators/atr.src.js +3 -2
  487. package/indicators/bollinger-bands.js +3 -3
  488. package/indicators/bollinger-bands.src.js +12 -11
  489. package/indicators/cci.js +3 -3
  490. package/indicators/cci.src.js +3 -2
  491. package/indicators/chaikin.js +3 -3
  492. package/indicators/chaikin.src.js +7 -4
  493. package/indicators/cmf.js +3 -3
  494. package/indicators/cmf.src.js +4 -3
  495. package/indicators/cmo.js +3 -3
  496. package/indicators/cmo.src.js +5 -4
  497. package/indicators/dema.js +3 -3
  498. package/indicators/dema.src.js +3 -2
  499. package/indicators/disparity-index.js +3 -3
  500. package/indicators/disparity-index.src.js +3 -2
  501. package/indicators/dmi.js +3 -3
  502. package/indicators/dmi.src.js +12 -11
  503. package/indicators/dpo.js +3 -3
  504. package/indicators/dpo.src.js +4 -3
  505. package/indicators/ema.js +1 -1
  506. package/indicators/ema.src.js +2 -1
  507. package/indicators/ichimoku-kinko-hyo.js +3 -3
  508. package/indicators/ichimoku-kinko-hyo.src.js +3 -2
  509. package/indicators/indicators-all.js +3 -3
  510. package/indicators/indicators-all.src.js +63 -60
  511. package/indicators/indicators.js +3 -3
  512. package/indicators/indicators.src.js +286 -3
  513. package/indicators/keltner-channels.js +3 -3
  514. package/indicators/keltner-channels.src.js +12 -11
  515. package/indicators/klinger.js +3 -3
  516. package/indicators/klinger.src.js +13 -12
  517. package/indicators/macd.js +3 -3
  518. package/indicators/macd.src.js +3 -2
  519. package/indicators/mfi.js +3 -3
  520. package/indicators/mfi.src.js +3 -2
  521. package/indicators/momentum.js +3 -3
  522. package/indicators/momentum.src.js +3 -2
  523. package/indicators/natr.js +3 -3
  524. package/indicators/natr.src.js +3 -2
  525. package/indicators/obv.js +3 -3
  526. package/indicators/obv.src.js +4 -3
  527. package/indicators/pivot-points.js +3 -3
  528. package/indicators/pivot-points.src.js +5 -4
  529. package/indicators/ppo.js +3 -3
  530. package/indicators/ppo.src.js +4 -3
  531. package/indicators/price-channel.js +3 -3
  532. package/indicators/price-channel.src.js +12 -11
  533. package/indicators/price-envelopes.js +3 -3
  534. package/indicators/price-envelopes.src.js +12 -11
  535. package/indicators/psar.js +3 -3
  536. package/indicators/psar.src.js +3 -2
  537. package/indicators/regressions.js +3 -3
  538. package/indicators/regressions.src.js +10 -9
  539. package/indicators/roc.js +3 -3
  540. package/indicators/roc.src.js +3 -2
  541. package/indicators/rsi.js +3 -3
  542. package/indicators/rsi.src.js +3 -2
  543. package/indicators/slow-stochastic.js +3 -3
  544. package/indicators/slow-stochastic.src.js +3 -2
  545. package/indicators/stochastic.js +3 -3
  546. package/indicators/stochastic.src.js +12 -11
  547. package/indicators/supertrend.js +3 -3
  548. package/indicators/supertrend.src.js +20 -19
  549. package/indicators/tema.js +3 -3
  550. package/indicators/tema.src.js +3 -2
  551. package/indicators/trendline.js +3 -3
  552. package/indicators/trendline.src.js +3 -2
  553. package/indicators/trix.js +3 -3
  554. package/indicators/trix.src.js +3 -2
  555. package/indicators/volume-by-price.js +3 -3
  556. package/indicators/volume-by-price.src.js +8 -7
  557. package/indicators/vwap.js +3 -3
  558. package/indicators/vwap.src.js +3 -2
  559. package/indicators/williams-r.js +3 -3
  560. package/indicators/williams-r.src.js +4 -3
  561. package/indicators/wma.js +3 -3
  562. package/indicators/wma.src.js +3 -2
  563. package/indicators/zigzag.js +3 -3
  564. package/indicators/zigzag.src.js +8 -7
  565. package/lib/svg2pdf.js +7 -7
  566. package/lib/svg2pdf.src.js +185 -150
  567. package/modules/accessibility.js +3 -3
  568. package/modules/accessibility.src.js +664 -2793
  569. package/modules/annotations-advanced.d.ts +3 -0
  570. package/modules/annotations-advanced.js +3 -3
  571. package/modules/annotations-advanced.src.d.ts +3 -0
  572. package/modules/annotations-advanced.src.js +2949 -2920
  573. package/modules/annotations.d.ts +0 -3
  574. package/modules/annotations.js +3 -3
  575. package/modules/annotations.src.d.ts +0 -3
  576. package/modules/annotations.src.js +2926 -2905
  577. package/modules/arc-diagram.js +3 -3
  578. package/modules/arc-diagram.src.js +8 -6
  579. package/modules/arrow-symbols.js +3 -3
  580. package/modules/arrow-symbols.src.js +10 -13
  581. package/modules/boost-canvas.js +3 -3
  582. package/modules/boost-canvas.src.js +73 -26
  583. package/modules/boost.js +3 -3
  584. package/modules/boost.src.js +108 -30
  585. package/modules/broken-axis.js +3 -3
  586. package/modules/broken-axis.src.js +9 -9
  587. package/modules/bullet.js +3 -3
  588. package/modules/bullet.src.js +5 -4
  589. package/modules/coloraxis.js +3 -3
  590. package/modules/coloraxis.src.js +10 -9
  591. package/modules/current-date-indicator.js +3 -3
  592. package/modules/current-date-indicator.src.js +3 -2
  593. package/modules/cylinder.js +3 -3
  594. package/modules/cylinder.src.js +12 -11
  595. package/modules/data-tools.js +3 -3
  596. package/modules/data-tools.src.js +53 -36
  597. package/modules/data.d.ts +2 -2
  598. package/modules/data.js +3 -3
  599. package/modules/data.src.d.ts +2 -2
  600. package/modules/data.src.js +24 -23
  601. package/modules/datagrouping.js +3 -3
  602. package/modules/datagrouping.src.js +25 -23
  603. package/modules/debugger.js +3 -3
  604. package/modules/debugger.src.js +6 -5
  605. package/modules/dependency-wheel.js +3 -3
  606. package/modules/dependency-wheel.src.js +7 -5
  607. package/modules/dotplot.js +3 -3
  608. package/modules/dotplot.src.js +3 -2
  609. package/modules/drag-panes.js +3 -3
  610. package/modules/drag-panes.src.js +19 -21
  611. package/modules/draggable-points.js +3 -3
  612. package/modules/draggable-points.src.js +18 -16
  613. package/modules/drilldown.js +3 -3
  614. package/modules/drilldown.src.js +29 -26
  615. package/modules/dumbbell.js +3 -3
  616. package/modules/dumbbell.src.js +5 -4
  617. package/modules/export-data.js +3 -3
  618. package/modules/export-data.src.js +33 -22
  619. package/modules/exporting.d.ts +1 -1
  620. package/modules/exporting.js +3 -3
  621. package/modules/exporting.src.d.ts +1 -1
  622. package/modules/exporting.src.js +40 -39
  623. package/modules/flowmap.js +3 -3
  624. package/modules/flowmap.src.js +3 -2
  625. package/modules/full-screen.js +3 -3
  626. package/modules/full-screen.src.js +9 -13
  627. package/modules/funnel.js +3 -3
  628. package/modules/funnel.src.js +3 -2
  629. package/modules/funnel3d.js +3 -3
  630. package/modules/funnel3d.src.js +12 -12
  631. package/modules/gantt.d.ts +3 -4
  632. package/modules/gantt.js +3 -3
  633. package/modules/gantt.src.d.ts +3 -4
  634. package/modules/gantt.src.js +4165 -4002
  635. package/modules/geoheatmap.js +3 -3
  636. package/modules/geoheatmap.src.js +8 -7
  637. package/modules/grid-axis.js +3 -3
  638. package/modules/grid-axis.src.js +9 -8
  639. package/modules/heatmap.d.ts +2 -2
  640. package/modules/heatmap.js +3 -3
  641. package/modules/heatmap.src.d.ts +2 -2
  642. package/modules/heatmap.src.js +21 -15
  643. package/modules/heikinashi.js +3 -3
  644. package/modules/heikinashi.src.js +9 -6
  645. package/modules/histogram-bellcurve.js +3 -3
  646. package/modules/histogram-bellcurve.src.js +4 -3
  647. package/modules/hollowcandlestick.js +3 -3
  648. package/modules/hollowcandlestick.src.js +5 -4
  649. package/modules/item-series.js +3 -3
  650. package/modules/item-series.src.js +4 -3
  651. package/modules/lollipop.js +3 -3
  652. package/modules/lollipop.src.js +6 -3
  653. package/modules/map.d.ts +22 -1
  654. package/modules/map.js +3 -3
  655. package/modules/map.src.d.ts +22 -1
  656. package/modules/map.src.js +256 -155
  657. package/modules/marker-clusters.js +3 -3
  658. package/modules/marker-clusters.src.js +35 -37
  659. package/modules/mouse-wheel-zoom.js +3 -3
  660. package/modules/mouse-wheel-zoom.src.js +55 -163
  661. package/modules/navigator.d.ts +148 -0
  662. package/modules/navigator.js +9 -0
  663. package/modules/navigator.src.d.ts +148 -0
  664. package/modules/navigator.src.js +3921 -0
  665. package/modules/networkgraph.d.ts +2 -2
  666. package/modules/networkgraph.js +3 -3
  667. package/modules/networkgraph.src.d.ts +2 -2
  668. package/modules/networkgraph.src.js +36 -35
  669. package/modules/no-data-to-display.js +3 -3
  670. package/modules/no-data-to-display.src.js +6 -6
  671. package/modules/offline-exporting.js +3 -3
  672. package/modules/offline-exporting.src.js +10 -10
  673. package/modules/organization.js +3 -3
  674. package/modules/organization.src.js +41 -15
  675. package/modules/overlapping-datalabels.js +3 -3
  676. package/modules/overlapping-datalabels.src.js +4 -2
  677. package/modules/parallel-coordinates.js +3 -3
  678. package/modules/parallel-coordinates.src.js +12 -12
  679. package/modules/pareto.js +3 -3
  680. package/modules/pareto.src.js +3 -2
  681. package/modules/pathfinder.js +3 -3
  682. package/modules/pathfinder.src.js +18 -22
  683. package/modules/pattern-fill.js +3 -3
  684. package/modules/pattern-fill.src.js +22 -23
  685. package/modules/pictorial.js +3 -3
  686. package/modules/pictorial.src.js +25 -26
  687. package/modules/price-indicator.js +3 -3
  688. package/modules/price-indicator.src.js +3 -2
  689. package/modules/pyramid3d.js +3 -3
  690. package/modules/pyramid3d.src.js +3 -2
  691. package/modules/sankey.js +3 -3
  692. package/modules/sankey.src.js +93 -26
  693. package/modules/series-label.js +3 -3
  694. package/modules/series-label.src.js +28 -19
  695. package/modules/series-on-point.js +3 -3
  696. package/modules/series-on-point.src.js +5 -4
  697. package/modules/solid-gauge.js +3 -3
  698. package/modules/solid-gauge.src.js +3 -2
  699. package/modules/sonification.d.ts +2 -2
  700. package/modules/sonification.js +3 -3
  701. package/modules/sonification.src.d.ts +2 -2
  702. package/modules/sonification.src.js +8 -6
  703. package/modules/static-scale.js +3 -3
  704. package/modules/static-scale.src.js +6 -6
  705. package/modules/stock-tools.js +3 -3
  706. package/modules/stock-tools.src.js +109 -96
  707. package/modules/stock.d.ts +1 -1
  708. package/modules/stock.js +3 -3
  709. package/modules/stock.src.d.ts +1 -1
  710. package/modules/stock.src.js +10762 -10685
  711. package/modules/streamgraph.js +3 -3
  712. package/modules/streamgraph.src.js +3 -2
  713. package/modules/sunburst.js +3 -3
  714. package/modules/sunburst.src.js +50 -37
  715. package/modules/tiledwebmap.js +4 -4
  716. package/modules/tiledwebmap.src.js +28 -29
  717. package/modules/tilemap.js +3 -3
  718. package/modules/tilemap.src.js +4 -3
  719. package/modules/timeline.js +3 -3
  720. package/modules/timeline.src.js +5 -4
  721. package/modules/treegraph.js +3 -3
  722. package/modules/treegraph.src.js +58 -23
  723. package/modules/treegrid.js +3 -3
  724. package/modules/treegrid.src.js +49 -33
  725. package/modules/treemap.js +3 -3
  726. package/modules/treemap.src.js +44 -26
  727. package/modules/variable-pie.js +3 -3
  728. package/modules/variable-pie.src.js +3 -2
  729. package/modules/variwide.js +3 -3
  730. package/modules/variwide.src.js +9 -4
  731. package/modules/vector.js +3 -3
  732. package/modules/vector.src.js +3 -2
  733. package/modules/venn.js +3 -3
  734. package/modules/venn.src.js +16 -17
  735. package/modules/windbarb.js +3 -3
  736. package/modules/windbarb.src.js +5 -4
  737. package/modules/wordcloud.js +3 -3
  738. package/modules/wordcloud.src.js +10 -8
  739. package/modules/xrange.js +3 -3
  740. package/modules/xrange.src.js +5 -4
  741. package/package.json +1 -1
  742. package/standalone-navigator.js +2 -0
  743. package/standalone-navigator.src.js +49402 -0
  744. package/themes/avocado.js +3 -3
  745. package/themes/avocado.src.js +2 -1
  746. package/themes/brand-dark.js +3 -3
  747. package/themes/brand-dark.src.js +2 -1
  748. package/themes/brand-light.js +3 -3
  749. package/themes/brand-light.src.js +2 -1
  750. package/themes/dark-blue.js +3 -3
  751. package/themes/dark-blue.src.js +2 -1
  752. package/themes/dark-green.js +3 -3
  753. package/themes/dark-green.src.js +2 -1
  754. package/themes/dark-unica.js +3 -3
  755. package/themes/dark-unica.src.js +2 -1
  756. package/themes/gray.js +3 -3
  757. package/themes/gray.src.js +2 -1
  758. package/themes/grid-light.js +3 -3
  759. package/themes/grid-light.src.js +2 -1
  760. package/themes/grid.js +3 -3
  761. package/themes/grid.src.js +2 -1
  762. package/themes/high-contrast-dark.js +3 -3
  763. package/themes/high-contrast-dark.src.js +2 -1
  764. package/themes/high-contrast-light.js +3 -3
  765. package/themes/high-contrast-light.src.js +2 -1
  766. package/themes/sand-signika.js +3 -3
  767. package/themes/sand-signika.src.js +2 -1
  768. package/themes/skies.js +3 -3
  769. package/themes/skies.src.js +2 -1
  770. package/themes/sunset.js +3 -3
  771. package/themes/sunset.src.js +2 -1
  772. package/es-modules/Core/Renderer/HTML/HTMLRenderer.js +0 -259
  773. package/lib/canvg.js +0 -8
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Highcharts JS v11.3.0 (2024-01-10)
2
+ * @license Highcharts JS v11.4.0 (2024-03-05)
3
3
  *
4
4
  * Accessibility module
5
5
  *
@@ -355,7 +355,7 @@
355
355
 
356
356
  return HTMLUtilities;
357
357
  });
358
- _registerModule(_modules, 'Accessibility/A11yI18n.js', [_modules['Core/Templating.js'], _modules['Core/Globals.js'], _modules['Core/Utilities.js']], function (F, H, U) {
358
+ _registerModule(_modules, 'Accessibility/A11yI18n.js', [_modules['Core/Templating.js'], _modules['Core/Utilities.js']], function (F, U) {
359
359
  /* *
360
360
  *
361
361
  * Accessibility module - internationalization support
@@ -369,8 +369,7 @@
369
369
  *
370
370
  * */
371
371
  const { format } = F;
372
- const { composed } = H;
373
- const { getNestedProperty, pick, pushUnique } = U;
372
+ const { getNestedProperty, pick } = U;
374
373
  /* *
375
374
  *
376
375
  * Composition
@@ -392,8 +391,8 @@
392
391
  * @private
393
392
  */
394
393
  function compose(ChartClass) {
395
- if (pushUnique(composed, compose)) {
396
- const chartProto = ChartClass.prototype;
394
+ const chartProto = ChartClass.prototype;
395
+ if (!chartProto.langFormat) {
397
396
  chartProto.langFormat = langFormat;
398
397
  }
399
398
  }
@@ -985,6 +984,14 @@
985
984
  this.elements.push(el);
986
985
  return el;
987
986
  }
987
+ /**
988
+ * Destroy created element, removing it from the DOM.
989
+ * @private
990
+ */
991
+ removeElement(element) {
992
+ removeElement(element);
993
+ this.elements.splice(this.elements.indexOf(element), 1);
994
+ }
988
995
  /**
989
996
  * Destroy all created elements, removing them from the DOM.
990
997
  * @private
@@ -1044,6 +1051,15 @@
1044
1051
  this.eventRemovers.push(remover);
1045
1052
  return remover;
1046
1053
  }
1054
+ /**
1055
+ * Remove added event.
1056
+ * @private
1057
+ */
1058
+ removeEvent(event) {
1059
+ const pos = this.eventRemovers.indexOf(event);
1060
+ this.eventRemovers[pos]();
1061
+ this.eventRemovers.splice(pos, 1);
1062
+ }
1047
1063
  /**
1048
1064
  * Remove all added events.
1049
1065
  * @private
@@ -1463,7 +1479,7 @@
1463
1479
 
1464
1480
  return ContainerComponent;
1465
1481
  });
1466
- _registerModule(_modules, 'Accessibility/FocusBorder.js', [_modules['Core/Globals.js'], _modules['Core/Utilities.js']], function (H, U) {
1482
+ _registerModule(_modules, 'Accessibility/FocusBorder.js', [_modules['Core/Utilities.js']], function (U) {
1467
1483
  /* *
1468
1484
  *
1469
1485
  * (c) 2009-2024 Øystein Moseng
@@ -1475,8 +1491,7 @@
1475
1491
  * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
1476
1492
  *
1477
1493
  * */
1478
- const { composed } = H;
1479
- const { addEvent, pick, pushUnique } = U;
1494
+ const { addEvent, pick } = U;
1480
1495
  /* *
1481
1496
  *
1482
1497
  * Composition
@@ -1507,10 +1522,12 @@
1507
1522
  * @private
1508
1523
  */
1509
1524
  function compose(ChartClass, SVGElementClass) {
1510
- if (pushUnique(composed, compose)) {
1511
- const chartProto = ChartClass.prototype, svgElementProto = SVGElementClass.prototype;
1525
+ const chartProto = ChartClass.prototype, svgElementProto = SVGElementClass.prototype;
1526
+ if (!chartProto.renderFocusBorder) {
1512
1527
  chartProto.renderFocusBorder = chartRenderFocusBorder;
1513
1528
  chartProto.setFocusToElement = chartSetFocusToElement;
1529
+ }
1530
+ if (!svgElementProto.addFocusBorder) {
1514
1531
  svgElementProto.addFocusBorder = svgElementAddFocusBorder;
1515
1532
  svgElementProto.removeFocusBorder = svgElementRemoveFocusBorder;
1516
1533
  }
@@ -2021,7 +2038,7 @@
2021
2038
  const { format } = F;
2022
2039
  const { doc } = H;
2023
2040
  const { addClass, getElement, getHeadingTagNameForElement, stripHTMLTagsFromString, visuallyHideElement } = HU;
2024
- const { attr, pick } = U;
2041
+ const { attr, pick, replaceNested } = U;
2025
2042
  /* *
2026
2043
  *
2027
2044
  * Functions
@@ -2058,13 +2075,13 @@
2058
2075
  * @private
2059
2076
  */
2060
2077
  function buildTypeDescriptionFromSeries(chart, types, context) {
2061
- const firstType = types[0], typeExplaination = chart.langFormat('accessibility.seriesTypeDescriptions.' + firstType, context), multi = chart.series && chart.series.length < 2 ? 'Single' : 'Multiple';
2078
+ const firstType = types[0], typeExplanation = chart.langFormat('accessibility.seriesTypeDescriptions.' + firstType, context), multi = chart.series && chart.series.length < 2 ? 'Single' : 'Multiple';
2062
2079
  return (chart.langFormat('accessibility.chartTypes.' + firstType + multi, context) ||
2063
- chart.langFormat('accessibility.chartTypes.default' + multi, context)) + (typeExplaination ? ' ' + typeExplaination : '');
2080
+ chart.langFormat('accessibility.chartTypes.default' + multi, context)) + (typeExplanation ? ' ' + typeExplanation : '');
2064
2081
  }
2065
2082
  /**
2066
- * Return simplified explaination of chart type. Some types will not be
2067
- * familiar to most users, but in those cases we try to add an explaination
2083
+ * Return simplified explanation of chart type. Some types will not be
2084
+ * familiar to most users, but in those cases we try to add an explanation
2068
2085
  * of the type.
2069
2086
  *
2070
2087
  * @private
@@ -2095,7 +2112,8 @@
2095
2112
  * @private
2096
2113
  */
2097
2114
  function stripEmptyHTMLTags(str) {
2098
- return str.replace(/<(\w+)[^>]*?>\s*<\/\1>/g, '');
2115
+ // Scan alert #[71]: Loop for nested patterns
2116
+ return replaceNested(str, [/<([\w\-.:!]+)\b[^<>]*>\s*<\/\1>/g, '']);
2099
2117
  }
2100
2118
  /* *
2101
2119
  *
@@ -2396,6 +2414,10 @@
2396
2414
  * @private
2397
2415
  */
2398
2416
  getEndOfChartMarkerText() {
2417
+ const endMarkerId = `highcharts-end-of-chart-marker-${this.chart.index}`, endMarker = getElement(endMarkerId);
2418
+ if (endMarker) {
2419
+ return endMarker.outerHTML;
2420
+ }
2399
2421
  const chart = this.chart, markerText = chart.langFormat('accessibility.screenReaderSection.endOfChartMarker', { chart: chart }), id = 'highcharts-end-of-chart-marker-' + chart.index;
2400
2422
  return '<div id="' + id + '">' + markerText + '</div>';
2401
2423
  }
@@ -2535,7 +2557,7 @@
2535
2557
 
2536
2558
  return InfoRegionsComponent;
2537
2559
  });
2538
- _registerModule(_modules, 'Accessibility/Components/MenuComponent.js', [_modules['Core/Chart/Chart.js'], _modules['Core/Globals.js'], _modules['Core/Utilities.js'], _modules['Accessibility/AccessibilityComponent.js'], _modules['Accessibility/KeyboardNavigationHandler.js'], _modules['Accessibility/Utils/ChartUtilities.js'], _modules['Accessibility/Utils/HTMLUtilities.js']], function (Chart, H, U, AccessibilityComponent, KeyboardNavigationHandler, ChartUtilities, HTMLUtilities) {
2560
+ _registerModule(_modules, 'Accessibility/Components/MenuComponent.js', [_modules['Core/Utilities.js'], _modules['Accessibility/AccessibilityComponent.js'], _modules['Accessibility/KeyboardNavigationHandler.js'], _modules['Accessibility/Utils/ChartUtilities.js'], _modules['Accessibility/Utils/HTMLUtilities.js']], function (U, AccessibilityComponent, KeyboardNavigationHandler, ChartUtilities, HTMLUtilities) {
2539
2561
  /* *
2540
2562
  *
2541
2563
  * (c) 2009-2024 Øystein Moseng
@@ -2547,8 +2569,7 @@
2547
2569
  * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
2548
2570
  *
2549
2571
  * */
2550
- const { composed } = H;
2551
- const { attr, pushUnique } = U;
2572
+ const { attr } = U;
2552
2573
  const { getChartTitle, unhideChartElementFromAT } = ChartUtilities;
2553
2574
  const { getFakeMouseEvent } = HTMLUtilities;
2554
2575
  /* *
@@ -2851,8 +2872,8 @@
2851
2872
  * @private
2852
2873
  */
2853
2874
  function compose(ChartClass) {
2854
- if (pushUnique(composed, compose)) {
2855
- const chartProto = Chart.prototype;
2875
+ const chartProto = ChartClass.prototype;
2876
+ if (!chartProto.hideExportMenu) {
2856
2877
  chartProto.hideExportMenu = chartHideExportMenu;
2857
2878
  chartProto.highlightExportItem = chartHighlightExportItem;
2858
2879
  chartProto.highlightLastExportItem = chartHighlightLastExportItem;
@@ -2967,8 +2988,8 @@
2967
2988
  * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
2968
2989
  *
2969
2990
  * */
2970
- const { composed, doc, win } = H;
2971
- const { addEvent, fireEvent, pushUnique } = U;
2991
+ const { doc, win } = H;
2992
+ const { addEvent, defined, fireEvent } = U;
2972
2993
  const { getElement, simulatedEventTarget } = HTMLUtilities;
2973
2994
  /* *
2974
2995
  *
@@ -3250,8 +3271,16 @@
3250
3271
  * @private
3251
3272
  */
3252
3273
  removeExitAnchor() {
3253
- if (this.exitAnchor && this.exitAnchor.parentNode) {
3254
- this.exitAnchor.parentNode.removeChild(this.exitAnchor);
3274
+ // Remove event from element and from eventRemovers array to prevent
3275
+ // memory leak (#20329).
3276
+ if (this.exitAnchor) {
3277
+ if (defined(this.exitAnchor.focusEventRemover)) {
3278
+ this.eventProvider.removeEvent(this.exitAnchor.focusEventRemover);
3279
+ delete this.exitAnchor.focusEventRemover;
3280
+ }
3281
+ if (this.exitAnchor.parentNode) {
3282
+ this.exitAnchor.parentNode.removeChild(this.exitAnchor);
3283
+ }
3255
3284
  delete this.exitAnchor;
3256
3285
  }
3257
3286
  }
@@ -3261,7 +3290,7 @@
3261
3290
  */
3262
3291
  addExitAnchorEventsToEl(element) {
3263
3292
  const chart = this.chart, keyboardNavigation = this;
3264
- this.eventProvider.addEvent(element, 'focus', function (ev) {
3293
+ element.focusEventRemover = this.eventProvider.addEvent(element, 'focus', function (ev) {
3265
3294
  const e = ev || win.event, focusComesFromChart = (e.relatedTarget &&
3266
3295
  chart.container.contains(e.relatedTarget)), comingInBackwards = !(focusComesFromChart || keyboardNavigation.exiting);
3267
3296
  if (chart.focusElement) {
@@ -3283,7 +3312,8 @@
3283
3312
  // Validate the module
3284
3313
  if (curModule &&
3285
3314
  curModule.validate && !curModule.validate()) {
3286
- // Invalid. Try moving backwards to find next valid.
3315
+ // Invalid.
3316
+ // Try moving backwards to find next valid.
3287
3317
  keyboardNavigation.move(-1);
3288
3318
  }
3289
3319
  else if (curModule) {
@@ -3345,8 +3375,8 @@
3345
3375
  */
3346
3376
  function compose(ChartClass) {
3347
3377
  MenuComponent.compose(ChartClass);
3348
- if (pushUnique(composed, compose)) {
3349
- const chartProto = ChartClass.prototype;
3378
+ const chartProto = ChartClass.prototype;
3379
+ if (!chartProto.dismissPopupContent) {
3350
3380
  chartProto.dismissPopupContent = chartDismissPopupContent;
3351
3381
  addEvent(doc, 'keydown', documentOnKeydown);
3352
3382
  }
@@ -3404,8 +3434,8 @@
3404
3434
  *
3405
3435
  * */
3406
3436
  const { animObject } = A;
3407
- const { composed, doc } = H;
3408
- const { addEvent, fireEvent, isNumber, pick, pushUnique, syncTimeout } = U;
3437
+ const { doc } = H;
3438
+ const { addEvent, fireEvent, isNumber, pick, syncTimeout } = U;
3409
3439
  const { getChartTitle } = CU;
3410
3440
  const { stripHTMLTagsFromString: stripHTMLTags, addClass, removeClass } = HU;
3411
3441
  /* *
@@ -3824,8 +3854,8 @@
3824
3854
  * @private
3825
3855
  */
3826
3856
  function compose(ChartClass, LegendClass) {
3827
- if (pushUnique(composed, compose)) {
3828
- const chartProto = ChartClass.prototype;
3857
+ const chartProto = ChartClass.prototype;
3858
+ if (!chartProto.highlightLegendItem) {
3829
3859
  chartProto.highlightLegendItem = chartHighlightLegendItem;
3830
3860
  addEvent(LegendClass, 'afterColorizeItem', legendOnAfterColorizeItem);
3831
3861
  }
@@ -3850,6 +3880,194 @@
3850
3880
 
3851
3881
  return LegendComponent;
3852
3882
  });
3883
+ _registerModule(_modules, 'Stock/Navigator/ChartNavigatorComposition.js', [_modules['Core/Globals.js'], _modules['Core/Utilities.js']], function (H, U) {
3884
+ /* *
3885
+ *
3886
+ * (c) 2010-2024 Torstein Honsi
3887
+ *
3888
+ * License: www.highcharts.com/license
3889
+ *
3890
+ * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
3891
+ *
3892
+ * */
3893
+ const { isTouchDevice } = H;
3894
+ const { addEvent, merge, pick } = U;
3895
+ /* *
3896
+ *
3897
+ * Constants
3898
+ *
3899
+ * */
3900
+ const composedMembers = [];
3901
+ /* *
3902
+ *
3903
+ * Variables
3904
+ *
3905
+ * */
3906
+ let NavigatorConstructor;
3907
+ /* *
3908
+ *
3909
+ * Functions
3910
+ *
3911
+ * */
3912
+ /**
3913
+ * @private
3914
+ */
3915
+ function compose(ChartClass, NavigatorClass) {
3916
+ if (U.pushUnique(composedMembers, ChartClass)) {
3917
+ const chartProto = ChartClass.prototype;
3918
+ NavigatorConstructor = NavigatorClass;
3919
+ chartProto.callbacks.push(onChartCallback);
3920
+ addEvent(ChartClass, 'afterAddSeries', onChartAfterAddSeries);
3921
+ addEvent(ChartClass, 'afterSetChartSize', onChartAfterSetChartSize);
3922
+ addEvent(ChartClass, 'afterUpdate', onChartAfterUpdate);
3923
+ addEvent(ChartClass, 'beforeRender', onChartBeforeRender);
3924
+ addEvent(ChartClass, 'beforeShowResetZoom', onChartBeforeShowResetZoom);
3925
+ addEvent(ChartClass, 'update', onChartUpdate);
3926
+ }
3927
+ }
3928
+ /**
3929
+ * Handle adding new series.
3930
+ * @private
3931
+ */
3932
+ function onChartAfterAddSeries() {
3933
+ if (this.navigator) {
3934
+ // Recompute which series should be shown in navigator, and add them
3935
+ this.navigator.setBaseSeries(null, false);
3936
+ }
3937
+ }
3938
+ /**
3939
+ * For stock charts, extend the Chart.setChartSize method so that we can set the
3940
+ * final top position of the navigator once the height of the chart, including
3941
+ * the legend, is determined. #367. We can't use Chart.getMargins, because
3942
+ * labels offsets are not calculated yet.
3943
+ * @private
3944
+ */
3945
+ function onChartAfterSetChartSize() {
3946
+ const legend = this.legend, navigator = this.navigator;
3947
+ let legendOptions, xAxis, yAxis;
3948
+ if (navigator) {
3949
+ legendOptions = legend && legend.options;
3950
+ xAxis = navigator.xAxis;
3951
+ yAxis = navigator.yAxis;
3952
+ const { scrollbarHeight, scrollButtonSize } = navigator;
3953
+ // Compute the top position
3954
+ if (this.inverted) {
3955
+ navigator.left = navigator.opposite ?
3956
+ this.chartWidth - scrollbarHeight -
3957
+ navigator.height :
3958
+ this.spacing[3] + scrollbarHeight;
3959
+ navigator.top = this.plotTop + scrollButtonSize;
3960
+ }
3961
+ else {
3962
+ navigator.left = pick(xAxis.left, this.plotLeft + scrollButtonSize);
3963
+ navigator.top = navigator.navigatorOptions.top ||
3964
+ this.chartHeight -
3965
+ navigator.height -
3966
+ scrollbarHeight -
3967
+ (this.scrollbar?.options.margin || 0) -
3968
+ this.spacing[2] -
3969
+ (this.rangeSelector && this.extraBottomMargin ?
3970
+ this.rangeSelector.getHeight() :
3971
+ 0) -
3972
+ ((legendOptions &&
3973
+ legendOptions.verticalAlign === 'bottom' &&
3974
+ legendOptions.layout !== 'proximate' && // #13392
3975
+ legendOptions.enabled &&
3976
+ !legendOptions.floating) ?
3977
+ legend.legendHeight +
3978
+ pick(legendOptions.margin, 10) :
3979
+ 0) -
3980
+ (this.titleOffset ? this.titleOffset[2] : 0);
3981
+ }
3982
+ if (xAxis && yAxis) { // false if navigator is disabled (#904)
3983
+ if (this.inverted) {
3984
+ xAxis.options.left = yAxis.options.left = navigator.left;
3985
+ }
3986
+ else {
3987
+ xAxis.options.top = yAxis.options.top = navigator.top;
3988
+ }
3989
+ xAxis.setAxisSize();
3990
+ yAxis.setAxisSize();
3991
+ }
3992
+ }
3993
+ }
3994
+ /**
3995
+ * Initialize navigator, if no scrolling exists yet.
3996
+ * @private
3997
+ */
3998
+ function onChartAfterUpdate(event) {
3999
+ if (!this.navigator && !this.scroller &&
4000
+ (this.options.navigator.enabled ||
4001
+ this.options.scrollbar.enabled)) {
4002
+ this.scroller = this.navigator = new NavigatorConstructor(this);
4003
+ if (pick(event.redraw, true)) {
4004
+ this.redraw(event.animation); // #7067
4005
+ }
4006
+ }
4007
+ }
4008
+ /**
4009
+ * Initialize navigator for stock charts
4010
+ * @private
4011
+ */
4012
+ function onChartBeforeRender() {
4013
+ const options = this.options;
4014
+ if (options.navigator.enabled ||
4015
+ options.scrollbar.enabled) {
4016
+ this.scroller = this.navigator = new NavigatorConstructor(this);
4017
+ }
4018
+ }
4019
+ /**
4020
+ * For Stock charts. For x only zooming, do not to create the zoom button
4021
+ * because X axis zooming is already allowed by the Navigator and Range
4022
+ * selector. (#9285)
4023
+ * @private
4024
+ */
4025
+ function onChartBeforeShowResetZoom() {
4026
+ const chartOptions = this.options, navigator = chartOptions.navigator, rangeSelector = chartOptions.rangeSelector;
4027
+ if (((navigator && navigator.enabled) ||
4028
+ (rangeSelector && rangeSelector.enabled)) &&
4029
+ ((!isTouchDevice &&
4030
+ this.zooming.type === 'x') ||
4031
+ (isTouchDevice && this.zooming.pinchType === 'x'))) {
4032
+ return false;
4033
+ }
4034
+ }
4035
+ /**
4036
+ * @private
4037
+ */
4038
+ function onChartCallback(chart) {
4039
+ const navigator = chart.navigator;
4040
+ // Initialize the navigator
4041
+ if (navigator && chart.xAxis[0]) {
4042
+ const extremes = chart.xAxis[0].getExtremes();
4043
+ navigator.render(extremes.min, extremes.max);
4044
+ }
4045
+ }
4046
+ /**
4047
+ * Merge options, if no scrolling exists yet
4048
+ * @private
4049
+ */
4050
+ function onChartUpdate(e) {
4051
+ const navigatorOptions = (e.options.navigator || {}), scrollbarOptions = (e.options.scrollbar || {});
4052
+ if (!this.navigator && !this.scroller &&
4053
+ (navigatorOptions.enabled || scrollbarOptions.enabled)) {
4054
+ merge(true, this.options.navigator, navigatorOptions);
4055
+ merge(true, this.options.scrollbar, scrollbarOptions);
4056
+ delete e.options.navigator;
4057
+ delete e.options.scrollbar;
4058
+ }
4059
+ }
4060
+ /* *
4061
+ *
4062
+ * Default Export
4063
+ *
4064
+ * */
4065
+ const ChartNavigatorComposition = {
4066
+ compose
4067
+ };
4068
+
4069
+ return ChartNavigatorComposition;
4070
+ });
3853
4071
  _registerModule(_modules, 'Core/Axis/NavigatorAxisComposition.js', [_modules['Core/Globals.js'], _modules['Core/Utilities.js']], function (H, U) {
3854
4072
  /* *
3855
4073
  *
@@ -3860,8 +4078,8 @@
3860
4078
  * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
3861
4079
  *
3862
4080
  * */
3863
- const { composed, isTouchDevice } = H;
3864
- const { addEvent, correctFloat, defined, isNumber, pick, pushUnique } = U;
4081
+ const { isTouchDevice } = H;
4082
+ const { addEvent, correctFloat, defined, isNumber, pick } = U;
3865
4083
  /* *
3866
4084
  *
3867
4085
  * Functions
@@ -3882,34 +4100,36 @@
3882
4100
  * selector.
3883
4101
  * @private
3884
4102
  */
3885
- function onAxisZoom(e) {
4103
+ function onAxisSetExtremes(e) {
3886
4104
  const axis = this, chart = axis.chart, chartOptions = chart.options, navigator = chartOptions.navigator, navigatorAxis = axis.navigatorAxis, pinchType = chart.zooming.pinchType, rangeSelector = chartOptions.rangeSelector, zoomType = chart.zooming.type;
3887
- if (axis.isXAxis && ((navigator && navigator.enabled) ||
3888
- (rangeSelector && rangeSelector.enabled))) {
4105
+ let zoomed;
4106
+ if (axis.isXAxis &&
4107
+ (navigator?.enabled || rangeSelector?.enabled)) {
3889
4108
  // For y only zooming, ignore the X axis completely
3890
- if (zoomType === 'y') {
3891
- e.zoomed = false;
3892
- // For xy zooming, record the state of the zoom before zoom
3893
- // selection, then when the reset button is pressed, revert to
3894
- // this state. This should apply only if the chart is
3895
- // initialized with a range (#6612), otherwise zoom all the way
3896
- // out.
3897
- }
3898
- else if (((!isTouchDevice && zoomType === 'xy') ||
4109
+ if (zoomType === 'y' && e.trigger === 'zoom') {
4110
+ zoomed = false;
4111
+ // For xy zooming, record the state of the zoom before zoom selection,
4112
+ // then when the reset button is pressed, revert to this state. This
4113
+ // should apply only if the chart is initialized with a range (#6612),
4114
+ // otherwise zoom all the way out.
4115
+ }
4116
+ else if (((e.trigger === 'zoom' && zoomType === 'xy') ||
3899
4117
  (isTouchDevice && pinchType === 'xy')) &&
3900
4118
  axis.options.range) {
3901
4119
  const previousZoom = navigatorAxis.previousZoom;
3902
- if (defined(e.newMin)) {
4120
+ // Minimum defined, zooming in
4121
+ if (defined(e.min)) {
3903
4122
  navigatorAxis.previousZoom = [axis.min, axis.max];
4123
+ // Minimum undefined, resetting zoom
3904
4124
  }
3905
4125
  else if (previousZoom) {
3906
- e.newMin = previousZoom[0];
3907
- e.newMax = previousZoom[1];
4126
+ e.min = previousZoom[0];
4127
+ e.max = previousZoom[1];
3908
4128
  navigatorAxis.previousZoom = void 0;
3909
4129
  }
3910
4130
  }
3911
4131
  }
3912
- if (typeof e.zoomed !== 'undefined') {
4132
+ if (typeof zoomed !== 'undefined') {
3913
4133
  e.preventDefault();
3914
4134
  }
3915
4135
  }
@@ -3932,10 +4152,10 @@
3932
4152
  * @private
3933
4153
  */
3934
4154
  static compose(AxisClass) {
3935
- if (pushUnique(composed, this.compose)) {
4155
+ if (!AxisClass.keepProps.includes('navigatorAxis')) {
3936
4156
  AxisClass.keepProps.push('navigatorAxis');
3937
4157
  addEvent(AxisClass, 'init', onAxisInit);
3938
- addEvent(AxisClass, 'zoom', onAxisZoom);
4158
+ addEvent(AxisClass, 'setExtremes', onAxisSetExtremes);
3939
4159
  }
3940
4160
  }
3941
4161
  /* *
@@ -3965,7 +4185,7 @@
3965
4185
  * @function Highcharts.Axis#toFixedRange
3966
4186
  */
3967
4187
  toFixedRange(pxMin, pxMax, fixedMin, fixedMax) {
3968
- const axis = this.axis, chart = axis.chart;
4188
+ const axis = this.axis, chart = axis.chart, overscroll = pick(axis.ordinal?.convertOverscroll(axis.options.overscroll), 0);
3969
4189
  let newMin = pick(fixedMin, axis.translate(pxMin, true, !axis.horiz)), newMax = pick(fixedMax, axis.translate(pxMax, true, !axis.horiz));
3970
4190
  const fixedRange = chart && chart.fixedRange, halfPointRange = (axis.pointRange || 0) / 2;
3971
4191
  // Add/remove half point range to/from the extremes (#1172)
@@ -3977,8 +4197,10 @@
3977
4197
  }
3978
4198
  // Make sure panning to the edges does not decrease the zoomed range
3979
4199
  if (fixedRange && axis.dataMin && axis.dataMax) {
3980
- if (newMax >= axis.dataMax) {
3981
- newMin = correctFloat(axis.dataMax - fixedRange);
4200
+ const maxWithOverscroll = axis.dataMax + overscroll;
4201
+ if (newMax >= maxWithOverscroll) {
4202
+ newMin = correctFloat(maxWithOverscroll - fixedRange);
4203
+ newMax = correctFloat(maxWithOverscroll);
3982
4204
  }
3983
4205
  if (newMin <= axis.dataMin) {
3984
4206
  newMax = correctFloat(axis.dataMin + fixedRange);
@@ -4402,12 +4624,26 @@
4402
4624
  xAxis: {
4403
4625
  /**
4404
4626
  * Additional range on the right side of the xAxis. Works similar to
4405
- * xAxis.maxPadding, but value is set in milliseconds.
4627
+ * `xAxis.maxPadding`, but the value is set in terms of axis values,
4628
+ * percentage or pixels.
4629
+ *
4630
+ * If it's a number, it is interpreted as axis values, which in a
4631
+ * datetime axis equals milliseconds.
4632
+ *
4633
+ * If it's a percentage string, is interpreted as percentages of the
4634
+ * axis length. An overscroll of 50% will make a 100px axis 50px longer.
4635
+ *
4636
+ * If it's a pixel string, it is interpreted as a fixed pixel value, but
4637
+ * limited to 90% of the axis length.
4638
+ *
4639
+ * If it's undefined, the value is inherited from `xAxis.overscroll`.
4640
+ *
4406
4641
  * Can be set for both, main xAxis and navigator's xAxis.
4407
4642
  *
4643
+ * @type {number | string | undefined}
4408
4644
  * @since 6.0.0
4645
+ * @apioption navigator.xAxis.overscroll
4409
4646
  */
4410
- overscroll: 0,
4411
4647
  className: 'highcharts-navigator-xaxis',
4412
4648
  tickLength: 0,
4413
4649
  lineWidth: 0,
@@ -4548,7 +4784,49 @@
4548
4784
 
4549
4785
  return NavigatorSymbols;
4550
4786
  });
4551
- _registerModule(_modules, 'Stock/Navigator/NavigatorComposition.js', [_modules['Core/Defaults.js'], _modules['Core/Globals.js'], _modules['Core/Axis/NavigatorAxisComposition.js'], _modules['Stock/Navigator/NavigatorDefaults.js'], _modules['Stock/Navigator/NavigatorSymbols.js'], _modules['Core/Renderer/RendererRegistry.js'], _modules['Core/Utilities.js']], function (D, H, NavigatorAxisAdditions, NavigatorDefaults, NavigatorSymbols, RendererRegistry, U) {
4787
+ _registerModule(_modules, 'Stock/Utilities/StockUtilities.js', [_modules['Core/Utilities.js']], function (U) {
4788
+ /* *
4789
+ *
4790
+ * (c) 2010-2024 Torstein Honsi
4791
+ *
4792
+ * License: www.highcharts.com/license
4793
+ *
4794
+ * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
4795
+ *
4796
+ * */
4797
+ const { defined } = U;
4798
+ /* *
4799
+ *
4800
+ * Functions
4801
+ *
4802
+ * */
4803
+ /**
4804
+ * Sets the chart.fixedRange to the specified value. If the value is larger
4805
+ * than actual range, sets it to the maximum possible range. (#20327)
4806
+ *
4807
+ * @private
4808
+ * @function Highcharts.StockChart#setFixedRange
4809
+ * @param {number|undefined} range
4810
+ * Range to set in axis units.
4811
+ */
4812
+ function setFixedRange(range) {
4813
+ const xAxis = this.xAxis[0];
4814
+ if (defined(xAxis.dataMax) &&
4815
+ defined(xAxis.dataMin) &&
4816
+ range) {
4817
+ this.fixedRange = Math.min(range, xAxis.dataMax - xAxis.dataMin);
4818
+ }
4819
+ else {
4820
+ this.fixedRange = range;
4821
+ }
4822
+ }
4823
+ const StockUtilities = {
4824
+ setFixedRange
4825
+ };
4826
+
4827
+ return StockUtilities;
4828
+ });
4829
+ _registerModule(_modules, 'Stock/Navigator/NavigatorComposition.js', [_modules['Core/Defaults.js'], _modules['Core/Globals.js'], _modules['Core/Axis/NavigatorAxisComposition.js'], _modules['Stock/Navigator/NavigatorDefaults.js'], _modules['Stock/Navigator/NavigatorSymbols.js'], _modules['Core/Renderer/RendererRegistry.js'], _modules['Stock/Utilities/StockUtilities.js'], _modules['Core/Utilities.js']], function (D, H, NavigatorAxisAdditions, NavigatorDefaults, NavigatorSymbols, RendererRegistry, StockUtilities, U) {
4552
4830
  /* *
4553
4831
  *
4554
4832
  * (c) 2010-2024 Torstein Honsi
@@ -4558,16 +4836,16 @@
4558
4836
  * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
4559
4837
  *
4560
4838
  * */
4561
- const { defaultOptions, setOptions } = D;
4562
- const { composed, isTouchDevice } = H;
4839
+ const { setOptions } = D;
4840
+ const { composed } = H;
4563
4841
  const { getRendererType } = RendererRegistry;
4564
- const { addEvent, extend, merge, pick, pushUnique } = U;
4842
+ const { setFixedRange } = StockUtilities;
4843
+ const { addEvent, extend, pushUnique } = U;
4565
4844
  /* *
4566
4845
  *
4567
4846
  * Variables
4568
4847
  *
4569
4848
  * */
4570
- let NavigatorConstructor;
4571
4849
  /* *
4572
4850
  *
4573
4851
  * Functions
@@ -4576,157 +4854,17 @@
4576
4854
  /**
4577
4855
  * @private
4578
4856
  */
4579
- function compose(AxisClass, ChartClass, NavigatorClass, SeriesClass) {
4857
+ function compose(ChartClass, AxisClass, SeriesClass) {
4580
4858
  NavigatorAxisAdditions.compose(AxisClass);
4581
- NavigatorConstructor = NavigatorClass;
4582
- if (pushUnique(composed, compose)) {
4583
- const chartProto = ChartClass.prototype;
4584
- chartProto.callbacks.push(onChartCallback);
4585
- addEvent(ChartClass, 'afterAddSeries', onChartAfterAddSeries);
4586
- addEvent(ChartClass, 'afterSetChartSize', onChartAfterSetChartSize);
4587
- addEvent(ChartClass, 'afterUpdate', onChartAfterUpdate);
4588
- addEvent(ChartClass, 'beforeRender', onChartBeforeRender);
4589
- addEvent(ChartClass, 'beforeShowResetZoom', onChartBeforeShowResetZoom);
4590
- addEvent(ChartClass, 'update', onChartUpdate);
4591
- addEvent(SeriesClass, 'afterUpdate', onSeriesAfterUpdate);
4859
+ if (pushUnique(composed, 'Navigator')) {
4860
+ ChartClass.prototype.setFixedRange = setFixedRange;
4592
4861
  extend(getRendererType().prototype.symbols, NavigatorSymbols);
4593
- extend(defaultOptions, { navigator: NavigatorDefaults });
4862
+ addEvent(SeriesClass, 'afterUpdate', onSeriesAfterUpdate);
4863
+ setOptions({ navigator: NavigatorDefaults });
4594
4864
  }
4595
4865
  }
4596
4866
  /**
4597
- * Handle adding new series.
4598
- * @private
4599
- */
4600
- function onChartAfterAddSeries() {
4601
- if (this.navigator) {
4602
- // Recompute which series should be shown in navigator, and add them
4603
- this.navigator.setBaseSeries(null, false);
4604
- }
4605
- }
4606
- /**
4607
- * For stock charts, extend the Chart.setChartSize method so that we can set the
4608
- * final top position of the navigator once the height of the chart, including
4609
- * the legend, is determined. #367. We can't use Chart.getMargins, because
4610
- * labels offsets are not calculated yet.
4611
- * @private
4612
- */
4613
- function onChartAfterSetChartSize() {
4614
- const legend = this.legend, navigator = this.navigator;
4615
- let legendOptions, xAxis, yAxis;
4616
- if (navigator) {
4617
- legendOptions = legend && legend.options;
4618
- xAxis = navigator.xAxis;
4619
- yAxis = navigator.yAxis;
4620
- const { scrollbarHeight, scrollButtonSize } = navigator;
4621
- // Compute the top position
4622
- if (this.inverted) {
4623
- navigator.left = navigator.opposite ?
4624
- this.chartWidth - scrollbarHeight -
4625
- navigator.height :
4626
- this.spacing[3] + scrollbarHeight;
4627
- navigator.top = this.plotTop + scrollButtonSize;
4628
- }
4629
- else {
4630
- navigator.left = pick(xAxis.left, this.plotLeft + scrollButtonSize);
4631
- navigator.top = navigator.navigatorOptions.top ||
4632
- this.chartHeight -
4633
- navigator.height -
4634
- scrollbarHeight -
4635
- (this.scrollbar?.options.margin || 0) -
4636
- this.spacing[2] -
4637
- (this.rangeSelector && this.extraBottomMargin ?
4638
- this.rangeSelector.getHeight() :
4639
- 0) -
4640
- ((legendOptions &&
4641
- legendOptions.verticalAlign === 'bottom' &&
4642
- legendOptions.layout !== 'proximate' && // #13392
4643
- legendOptions.enabled &&
4644
- !legendOptions.floating) ?
4645
- legend.legendHeight +
4646
- pick(legendOptions.margin, 10) :
4647
- 0) -
4648
- (this.titleOffset ? this.titleOffset[2] : 0);
4649
- }
4650
- if (xAxis && yAxis) { // false if navigator is disabled (#904)
4651
- if (this.inverted) {
4652
- xAxis.options.left = yAxis.options.left = navigator.left;
4653
- }
4654
- else {
4655
- xAxis.options.top = yAxis.options.top = navigator.top;
4656
- }
4657
- xAxis.setAxisSize();
4658
- yAxis.setAxisSize();
4659
- }
4660
- }
4661
- }
4662
- /**
4663
- * Initialize navigator, if no scrolling exists yet.
4664
- * @private
4665
- */
4666
- function onChartAfterUpdate(event) {
4667
- if (!this.navigator && !this.scroller &&
4668
- (this.options.navigator.enabled ||
4669
- this.options.scrollbar.enabled)) {
4670
- this.scroller = this.navigator = new NavigatorConstructor(this);
4671
- if (pick(event.redraw, true)) {
4672
- this.redraw(event.animation); // #7067
4673
- }
4674
- }
4675
- }
4676
- /**
4677
- * Initialize navigator for stock charts
4678
- * @private
4679
- */
4680
- function onChartBeforeRender() {
4681
- const options = this.options;
4682
- if (options.navigator.enabled ||
4683
- options.scrollbar.enabled) {
4684
- this.scroller = this.navigator = new NavigatorConstructor(this);
4685
- }
4686
- }
4687
- /**
4688
- * For Stock charts. For x only zooming, do not to create the zoom button
4689
- * because X axis zooming is already allowed by the Navigator and Range
4690
- * selector. (#9285)
4691
- * @private
4692
- */
4693
- function onChartBeforeShowResetZoom() {
4694
- const chartOptions = this.options, navigator = chartOptions.navigator, rangeSelector = chartOptions.rangeSelector;
4695
- if (((navigator && navigator.enabled) ||
4696
- (rangeSelector && rangeSelector.enabled)) &&
4697
- ((!isTouchDevice &&
4698
- this.zooming.type === 'x') ||
4699
- (isTouchDevice && this.zooming.pinchType === 'x'))) {
4700
- return false;
4701
- }
4702
- }
4703
- /**
4704
- * @private
4705
- */
4706
- function onChartCallback(chart) {
4707
- const navigator = chart.navigator;
4708
- // Initialize the navigator
4709
- if (navigator && chart.xAxis[0]) {
4710
- const extremes = chart.xAxis[0].getExtremes();
4711
- navigator.render(extremes.min, extremes.max);
4712
- }
4713
- }
4714
- /**
4715
- * Merge options, if no scrolling exists yet
4716
- * @private
4717
- */
4718
- function onChartUpdate(e) {
4719
- const navigatorOptions = (e.options.navigator || {}), scrollbarOptions = (e.options.scrollbar || {});
4720
- if (!this.navigator && !this.scroller &&
4721
- (navigatorOptions.enabled || scrollbarOptions.enabled)) {
4722
- merge(true, this.options.navigator, navigatorOptions);
4723
- merge(true, this.options.scrollbar, scrollbarOptions);
4724
- delete e.options.navigator;
4725
- delete e.options.scrollbar;
4726
- }
4727
- }
4728
- /**
4729
- * Handle updating series
4867
+ * Handle updating series
4730
4868
  * @private
4731
4869
  */
4732
4870
  function onSeriesAfterUpdate() {
@@ -4787,7 +4925,7 @@
4787
4925
  * Scrollbar class to use.
4788
4926
  */
4789
4927
  function compose(AxisClass, ScrollbarClass) {
4790
- if (pushUnique(composed, compose)) {
4928
+ if (pushUnique(composed, 'Axis.Scrollbar')) {
4791
4929
  Scrollbar = ScrollbarClass;
4792
4930
  addEvent(AxisClass, 'afterGetOffset', onAxisAfterGetOffset);
4793
4931
  addEvent(AxisClass, 'afterInit', onAxisAfterInit);
@@ -4860,7 +4998,7 @@
4860
4998
  }
4861
4999
  else {
4862
5000
  // When live redraw is disabled, don't change extremes
4863
- // Only change the position of the scollbar thumb
5001
+ // Only change the position of the scrollbar thumb
4864
5002
  this.setRange(this.from, this.to);
4865
5003
  }
4866
5004
  });
@@ -4951,7 +5089,7 @@
4951
5089
 
4952
5090
  return ScrollbarAxis;
4953
5091
  });
4954
- _registerModule(_modules, 'Stock/Scrollbar/ScrollbarDefaults.js', [_modules['Core/Globals.js']], function (H) {
5092
+ _registerModule(_modules, 'Stock/Scrollbar/ScrollbarDefaults.js', [], function () {
4955
5093
  /* *
4956
5094
  *
4957
5095
  * (c) 2010-2024 Torstein Honsi
@@ -4961,7 +5099,6 @@
4961
5099
  * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
4962
5100
  *
4963
5101
  * */
4964
- const { isTouchDevice } = H;
4965
5102
  /* *
4966
5103
  *
4967
5104
  * Constant
@@ -4970,7 +5107,7 @@
4970
5107
  /**
4971
5108
  *
4972
5109
  * The scrollbar is a means of panning over the X axis of a stock chart.
4973
- * Scrollbars can also be applied to other types of axes.
5110
+ * Scrollbars can also be applied to other types of axes.
4974
5111
  *
4975
5112
  * Another approach to scrollable charts is the [chart.scrollablePlotArea](
4976
5113
  * https://api.highcharts.com/highcharts/chart.scrollablePlotArea) option that
@@ -5285,8 +5422,8 @@
5285
5422
  */
5286
5423
  addEvents() {
5287
5424
  const buttonsOrder = this.options.inverted ? [1, 0] : [0, 1], buttons = this.scrollbarButtons, bar = this.scrollbarGroup.element, track = this.track.element, mouseDownHandler = this.mouseDownHandler.bind(this), mouseMoveHandler = this.mouseMoveHandler.bind(this), mouseUpHandler = this.mouseUpHandler.bind(this);
5288
- // Mouse events
5289
5425
  const _events = [
5426
+ // Mouse events
5290
5427
  [
5291
5428
  buttons[buttonsOrder[0]].element,
5292
5429
  'click',
@@ -5300,12 +5437,12 @@
5300
5437
  [track, 'click', this.trackClick.bind(this)],
5301
5438
  [bar, 'mousedown', mouseDownHandler],
5302
5439
  [bar.ownerDocument, 'mousemove', mouseMoveHandler],
5303
- [bar.ownerDocument, 'mouseup', mouseUpHandler]
5440
+ [bar.ownerDocument, 'mouseup', mouseUpHandler],
5441
+ // Touch events
5442
+ [bar, 'touchstart', mouseDownHandler],
5443
+ [bar.ownerDocument, 'touchmove', mouseMoveHandler],
5444
+ [bar.ownerDocument, 'touchend', mouseUpHandler]
5304
5445
  ];
5305
- // Touch events
5306
- if (H.hasTouch) {
5307
- _events.push([bar, 'touchstart', mouseDownHandler], [bar.ownerDocument, 'touchmove', mouseMoveHandler], [bar.ownerDocument, 'touchend', mouseUpHandler]);
5308
- }
5309
5446
  // Add them all
5310
5447
  _events.forEach(function (args) {
5311
5448
  addEvent.apply(null, args);
@@ -5471,7 +5608,7 @@
5471
5608
  }
5472
5609
  }
5473
5610
  mouseDownHandler(e) {
5474
- const scroller = this, normalizedEvent = scroller.chart.pointer.normalize(e), mousePosition = scroller.cursorToScrollbarPosition(normalizedEvent);
5611
+ const scroller = this, normalizedEvent = scroller.chart.pointer?.normalize(e) || e, mousePosition = scroller.cursorToScrollbarPosition(normalizedEvent);
5475
5612
  scroller.chartX = mousePosition.chartX;
5476
5613
  scroller.chartY = mousePosition.chartY;
5477
5614
  scroller.initPositions = [scroller.from, scroller.to];
@@ -5482,7 +5619,7 @@
5482
5619
  * @private
5483
5620
  */
5484
5621
  mouseMoveHandler(e) {
5485
- const scroller = this, normalizedEvent = scroller.chart.pointer.normalize(e), options = scroller.options, direction = options.vertical ?
5622
+ const scroller = this, normalizedEvent = scroller.chart.pointer?.normalize(e) || e, options = scroller.options, direction = options.vertical ?
5486
5623
  'chartY' : 'chartX', initPositions = scroller.initPositions || [];
5487
5624
  let scrollPosition, chartPosition, change;
5488
5625
  // In iOS, a mousemove event with e.pageX === 0 is fired when
@@ -5540,7 +5677,7 @@
5540
5677
  * @param {number} width
5541
5678
  * width of the scrollbar
5542
5679
  * @param {number} height
5543
- * height of the scorllbar
5680
+ * height of the scrollbar
5544
5681
  */
5545
5682
  position(x, y, width, height) {
5546
5683
  const scroller = this, options = scroller.options, { buttonsEnabled, margin = 0, vertical } = options, method = scroller.rendered ? 'animate' : 'attr';
@@ -5764,7 +5901,7 @@
5764
5901
  }
5765
5902
  trackClick(e) {
5766
5903
  const scroller = this;
5767
- const normalizedEvent = scroller.chart.pointer.normalize(e), range = scroller.to - scroller.from, top = scroller.y + scroller.scrollbarTop, left = scroller.x + scroller.scrollbarLeft;
5904
+ const normalizedEvent = scroller.chart.pointer?.normalize(e) || e, range = scroller.to - scroller.from, top = scroller.y + scroller.scrollbarTop, left = scroller.x + scroller.scrollbarLeft;
5768
5905
  if ((scroller.options.vertical && normalizedEvent.chartY > top) ||
5769
5906
  (!scroller.options.vertical && normalizedEvent.chartX > left)) {
5770
5907
  // On the top or on the left side of the track:
@@ -5833,7 +5970,7 @@
5833
5970
 
5834
5971
  return Scrollbar;
5835
5972
  });
5836
- _registerModule(_modules, 'Stock/Navigator/Navigator.js', [_modules['Core/Axis/Axis.js'], _modules['Core/Defaults.js'], _modules['Core/Globals.js'], _modules['Core/Axis/NavigatorAxisComposition.js'], _modules['Stock/Navigator/NavigatorComposition.js'], _modules['Stock/Scrollbar/Scrollbar.js'], _modules['Core/Utilities.js']], function (Axis, D, H, NavigatorAxisAdditions, NavigatorComposition, Scrollbar, U) {
5973
+ _registerModule(_modules, 'Stock/Navigator/Navigator.js', [_modules['Core/Axis/Axis.js'], _modules['Stock/Navigator/ChartNavigatorComposition.js'], _modules['Core/Defaults.js'], _modules['Core/Globals.js'], _modules['Core/Axis/NavigatorAxisComposition.js'], _modules['Stock/Navigator/NavigatorComposition.js'], _modules['Stock/Scrollbar/Scrollbar.js'], _modules['Core/Utilities.js']], function (Axis, ChartNavigatorComposition, D, H, NavigatorAxisAdditions, NavigatorComposition, Scrollbar, U) {
5837
5974
  /* *
5838
5975
  *
5839
5976
  * (c) 2010-2024 Torstein Honsi
@@ -5844,7 +5981,7 @@
5844
5981
  *
5845
5982
  * */
5846
5983
  const { defaultOptions } = D;
5847
- const { hasTouch, isTouchDevice } = H;
5984
+ const { isTouchDevice } = H;
5848
5985
  const { addEvent, clamp, correctFloat, defined, destroyObjectProperties, erase, extend, find, fireEvent, isArray, isNumber, merge, pick, removeEvent, splat } = U;
5849
5986
  /* *
5850
5987
  *
@@ -5881,11 +6018,12 @@
5881
6018
  class Navigator {
5882
6019
  /* *
5883
6020
  *
5884
- * Static Functions
6021
+ * Static Properties
5885
6022
  *
5886
6023
  * */
5887
- static compose(AxisClass, ChartClass, SeriesClass) {
5888
- NavigatorComposition.compose(AxisClass, ChartClass, Navigator, SeriesClass);
6024
+ static compose(ChartClass, AxisClass, SeriesClass) {
6025
+ ChartNavigatorComposition.compose(ChartClass, Navigator);
6026
+ NavigatorComposition.compose(ChartClass, AxisClass, SeriesClass);
5889
6027
  }
5890
6028
  /* *
5891
6029
  *
@@ -6324,15 +6462,14 @@
6324
6462
  };
6325
6463
  // Add shades and handles mousedown events
6326
6464
  eventsToUnbind = navigator.getPartsEvents('mousedown');
6327
- // Add mouse move and mouseup events. These are bind to doc/container,
6465
+ eventsToUnbind.push(
6466
+ // Add mouse move and mouseup events. These are bind to doc/div,
6328
6467
  // because Navigator.grabbedSomething flags are stored in mousedown
6329
6468
  // events
6330
- eventsToUnbind.push(addEvent(chart.renderTo, 'mousemove', mouseMoveHandler), addEvent(container.ownerDocument, 'mouseup', mouseUpHandler));
6469
+ addEvent(chart.renderTo, 'mousemove', mouseMoveHandler), addEvent(container.ownerDocument, 'mouseup', mouseUpHandler),
6331
6470
  // Touch events
6332
- if (hasTouch) {
6333
- eventsToUnbind.push(addEvent(chart.renderTo, 'touchmove', mouseMoveHandler), addEvent(container.ownerDocument, 'touchend', mouseUpHandler));
6334
- eventsToUnbind.concat(navigator.getPartsEvents('touchstart'));
6335
- }
6471
+ addEvent(chart.renderTo, 'touchmove', mouseMoveHandler), addEvent(container.ownerDocument, 'touchend', mouseUpHandler));
6472
+ eventsToUnbind.concat(navigator.getPartsEvents('touchstart'));
6336
6473
  navigator.eventsToUnbind = eventsToUnbind;
6337
6474
  // Data events
6338
6475
  if (navigator.series && navigator.series[0]) {
@@ -6382,7 +6519,7 @@
6382
6519
  * Index of a mask in Navigator.shades array
6383
6520
  */
6384
6521
  shadesMousedown(e, index) {
6385
- e = this.chart.pointer.normalize(e);
6522
+ e = this.chart.pointer?.normalize(e) || e;
6386
6523
  const navigator = this, chart = navigator.chart, xAxis = navigator.xAxis, zoomedMin = navigator.zoomedMin, navigatorSize = navigator.size, range = navigator.range;
6387
6524
  let navigatorPosition = navigator.left, chartX = e.chartX, fixedMax, fixedMin, ext, left;
6388
6525
  // For inverted chart, swap some options:
@@ -6418,8 +6555,14 @@
6418
6555
  navigator.fixedWidth = range; // #1370
6419
6556
  ext = xAxis.navigatorAxis.toFixedRange(left, left + range, fixedMin, fixedMax);
6420
6557
  if (defined(ext.min)) { // #7411
6421
- chart.xAxis[0].setExtremes(Math.min(ext.min, ext.max), Math.max(ext.min, ext.max), true, null, // auto animation
6422
- { trigger: 'navigator' });
6558
+ fireEvent(this, 'setRange', {
6559
+ min: Math.min(ext.min, ext.max),
6560
+ max: Math.max(ext.min, ext.max),
6561
+ redraw: true,
6562
+ eventArguments: {
6563
+ trigger: 'navigator'
6564
+ }
6565
+ });
6423
6566
  }
6424
6567
  }
6425
6568
  }
@@ -6436,7 +6579,7 @@
6436
6579
  * Index of a handle in Navigator.handles array
6437
6580
  */
6438
6581
  handlesMousedown(e, index) {
6439
- e = this.chart.pointer.normalize(e);
6582
+ e = this.chart.pointer?.normalize(e) || e;
6440
6583
  const navigator = this, chart = navigator.chart, baseXAxis = chart.xAxis[0],
6441
6584
  // For reversed axes, min and max are changed,
6442
6585
  // so the other extreme should be stored
@@ -6453,7 +6596,7 @@
6453
6596
  navigator.otherHandlePos = navigator.zoomedMin;
6454
6597
  navigator.fixedExtreme = reverse ? baseXAxis.max : baseXAxis.min;
6455
6598
  }
6456
- chart.fixedRange = null;
6599
+ chart.setFixedRange(void 0);
6457
6600
  }
6458
6601
  /**
6459
6602
  * Mouse move event based on x/y mouse position.
@@ -6471,7 +6614,7 @@
6471
6614
  // the finger down in the center of the scrollbar. This should be
6472
6615
  // ignored.
6473
6616
  if (!e.touches || e.touches[0].pageX !== 0) { // #4696
6474
- e = chart.pointer.normalize(e);
6617
+ e = chart.pointer?.normalize(e) || e;
6475
6618
  chartX = e.chartX;
6476
6619
  // Swap some options for inverted chart
6477
6620
  if (inverted) {
@@ -6555,13 +6698,16 @@
6555
6698
  }
6556
6699
  ext = xAxis.navigatorAxis.toFixedRange(navigator.zoomedMin, navigator.zoomedMax, fixedMin, fixedMax);
6557
6700
  if (defined(ext.min)) {
6558
- chart.xAxis[0].setExtremes(Math.min(ext.min, ext.max), Math.max(ext.min, ext.max), true,
6559
- // Run animation when clicking buttons, scrollbar track etc,
6560
- // but not when dragging handles or scrollbar
6561
- navigator.hasDragged ? false : null, {
6562
- trigger: 'navigator',
6563
- triggerOp: 'navigator-drag',
6564
- DOMEvent: DOMEvent // #1838
6701
+ fireEvent(this, 'setRange', {
6702
+ min: Math.min(ext.min, ext.max),
6703
+ max: Math.max(ext.min, ext.max),
6704
+ redraw: true,
6705
+ animation: navigator.hasDragged ? false : null,
6706
+ eventArguments: {
6707
+ trigger: 'navigator',
6708
+ triggerOp: 'navigator-drag',
6709
+ DOMEvent: DOMEvent // #1838
6710
+ }
6565
6711
  });
6566
6712
  }
6567
6713
  }
@@ -6653,9 +6799,10 @@
6653
6799
  if (navigator.navigatorEnabled) {
6654
6800
  // an x axis is required for scrollbar also
6655
6801
  navigator.xAxis = new Axis(chart, merge({
6656
- // inherit base xAxis' break and ordinal options
6802
+ // inherit base xAxis' break, ordinal options and overscroll
6657
6803
  breaks: baseXaxis.options.breaks,
6658
- ordinal: baseXaxis.options.ordinal
6804
+ ordinal: baseXaxis.options.ordinal,
6805
+ overscroll: baseXaxis.options.overscroll
6659
6806
  }, navigatorOptions.xAxis, {
6660
6807
  id: 'navigator-x-axis',
6661
6808
  yAxis: 'navigator-y-axis',
@@ -6906,6 +7053,8 @@
6906
7053
  }
6907
7054
  else {
6908
7055
  base.navigatorSeries = chart.initSeries(mergedNavSeriesOptions);
7056
+ // Set data on initial run with dataSorting enabled (#20318)
7057
+ chart.setSortedData();
6909
7058
  base.navigatorSeries.baseSeries = base; // Store ref
6910
7059
  navigatorSeries.push(base.navigatorSeries);
6911
7060
  }
@@ -6976,7 +7125,7 @@
6976
7125
  this.navigatorSeries.setVisible(false, false);
6977
7126
  }
6978
7127
  }));
6979
- // Respond to updated data in the base series, unless explicitily
7128
+ // Respond to updated data in the base series, unless explicitly
6980
7129
  // not adapting to data changes.
6981
7130
  if (this.navigatorOptions.adaptToUpdatedData !== false) {
6982
7131
  if (base.xAxis) {
@@ -7037,7 +7186,7 @@
7037
7186
  * @function Highcharts.Navigator#modifyBaseAxisExtremes
7038
7187
  */
7039
7188
  modifyBaseAxisExtremes() {
7040
- const baseXAxis = this, navigator = baseXAxis.chart.navigator, baseExtremes = baseXAxis.getExtremes(), baseMin = baseExtremes.min, baseMax = baseExtremes.max, baseDataMin = baseExtremes.dataMin, baseDataMax = baseExtremes.dataMax, range = baseMax - baseMin, stickToMin = navigator.stickToMin, stickToMax = navigator.stickToMax, overscroll = pick(baseXAxis.options.overscroll, 0), navigatorSeries = navigator.series && navigator.series[0], hasSetExtremes = !!baseXAxis.setExtremes,
7189
+ const baseXAxis = this, navigator = baseXAxis.chart.navigator, baseExtremes = baseXAxis.getExtremes(), baseMin = baseExtremes.min, baseMax = baseExtremes.max, baseDataMin = baseExtremes.dataMin, baseDataMax = baseExtremes.dataMax, range = baseMax - baseMin, stickToMin = navigator.stickToMin, stickToMax = navigator.stickToMax, overscroll = pick(baseXAxis.ordinal?.convertOverscroll(baseXAxis.options.overscroll), 0), navigatorSeries = navigator.series && navigator.series[0], hasSetExtremes = !!baseXAxis.setExtremes,
7041
7190
  // When the extremes have been set by range selector button, don't
7042
7191
  // stick to min or max. The range selector buttons will handle the
7043
7192
  // extremes. (#5489)
@@ -7158,6 +7307,8 @@
7158
7307
  (chart[marginName] || 0) + (navigator.navigatorEnabled || !chart.inverted ?
7159
7308
  navigator.height + navigator.scrollbarHeight :
7160
7309
  0) + navigator.navigatorOptions.margin;
7310
+ }), addEvent(Navigator, 'setRange', function (e) {
7311
+ this.chart.xAxis[0].setExtremes(e.min, e.max, e.redraw, e.animation, e.eventArguments);
7161
7312
  }));
7162
7313
  }
7163
7314
  /**
@@ -7382,9 +7533,12 @@
7382
7533
  */
7383
7534
  updateNavigator(beforeAnnounce) {
7384
7535
  const performUpdate = (beforeAnnounce) => {
7385
- const chart = this.chart, navigator = chart.navigator;
7386
- if (navigator && this.minHandleProxy && this.maxHandleProxy) {
7387
- const chartPos = chart.pointer.getChartPosition(), minNewX = parseFloat(this.minHandleProxy.value) /
7536
+ const chart = this.chart, { navigator, pointer } = chart;
7537
+ if (navigator &&
7538
+ pointer &&
7539
+ this.minHandleProxy &&
7540
+ this.maxHandleProxy) {
7541
+ const chartPos = pointer.getChartPosition(), minNewX = parseFloat(this.minHandleProxy.value) /
7388
7542
  100 * navigator.size, maxNewX = parseFloat(this.maxHandleProxy.value) /
7389
7543
  100 * navigator.size;
7390
7544
  // Fire fake events in order for each handle.
@@ -8098,7 +8252,7 @@
8098
8252
  * @private
8099
8253
  */
8100
8254
  function compose(SeriesClass) {
8101
- if (pushUnique(composed, compose)) {
8255
+ if (pushUnique(composed, 'A11y.NDA')) {
8102
8256
  addEvent(SeriesClass, 'addPoint', seriesOnAddPoint);
8103
8257
  addEvent(SeriesClass, 'updatedData', seriesOnUpdatedData);
8104
8258
  }
@@ -8110,7 +8264,8 @@
8110
8264
  * @param {Highcharts.Point} point
8111
8265
  */
8112
8266
  function seriesOnAddPoint(e) {
8113
- const chart = this.chart, newDataAnnouncer = this.newDataAnnouncer;
8267
+ const chart = this.chart, newDataAnnouncer = chart.accessibility?.components
8268
+ .series.newDataAnnouncer;
8114
8269
  if (newDataAnnouncer &&
8115
8270
  newDataAnnouncer.chart === chart &&
8116
8271
  chartHasAnnounceEnabled(chart)) {
@@ -8126,7 +8281,8 @@
8126
8281
  * @param {Highcharts.Series} series
8127
8282
  */
8128
8283
  function seriesOnUpdatedData() {
8129
- const chart = this.chart, newDataAnnouncer = this.newDataAnnouncer;
8284
+ const chart = this.chart, newDataAnnouncer = chart.accessibility?.components
8285
+ .series.newDataAnnouncer;
8130
8286
  if (newDataAnnouncer &&
8131
8287
  newDataAnnouncer.chart === chart &&
8132
8288
  chartHasAnnounceEnabled(chart)) {
@@ -8290,7 +8446,7 @@
8290
8446
  fireEventOnWrappedOrUnwrappedElement(target, clonedEvent);
8291
8447
  }
8292
8448
  e.stopPropagation();
8293
- // #9682, #15318: Touch scrolling didnt work when touching
8449
+ // #9682, #15318: Touch scrolling didn't work when touching
8294
8450
  // proxy
8295
8451
  if (!isTouchEvent) {
8296
8452
  e.preventDefault();
@@ -8328,9 +8484,9 @@
8328
8484
  clickTarget.element :
8329
8485
  clickTarget;
8330
8486
  const posElement = this.target.visual || clickTargetElement;
8331
- const chartDiv = this.chart.renderTo;
8332
- if (chartDiv && posElement && posElement.getBoundingClientRect) {
8333
- const rectEl = posElement.getBoundingClientRect(), chartPos = this.chart.pointer.getChartPosition();
8487
+ const chartDiv = this.chart.renderTo, pointer = this.chart.pointer;
8488
+ if (chartDiv && posElement?.getBoundingClientRect && pointer) {
8489
+ const rectEl = posElement.getBoundingClientRect(), chartPos = pointer.getChartPosition();
8334
8490
  return {
8335
8491
  x: (rectEl.left - chartPos.left) / chartPos.scaleX,
8336
8492
  y: (rectEl.top - chartPos.top) / chartPos.scaleY,
@@ -8379,7 +8535,7 @@
8379
8535
  const { doc } = H;
8380
8536
  const { attr, css } = U;
8381
8537
  const { unhideChartElementFromAT } = CU;
8382
- const { removeElement, removeChildNodes } = HU;
8538
+ const { removeChildNodes } = HU;
8383
8539
  /* *
8384
8540
  *
8385
8541
  * Class
@@ -8453,2544 +8609,225 @@
8453
8609
  groupElement.className = 'highcharts-a11y-proxy-group highcharts-a11y-proxy-group-' +
8454
8610
  groupKey.replace(/\W/g, '-');
8455
8611
  this.groups[groupKey] = {
8456
- proxyContainerElement: proxyContainer,
8457
- groupElement,
8458
- type: groupElementType,
8459
- proxyElements: []
8460
- };
8461
- attr(groupElement, attributes || {});
8462
- if (groupElementType === 'ul') {
8463
- proxyContainer.setAttribute('role', 'list'); // Needed for webkit
8464
- }
8465
- // Add the group to the end by default, and perhaps then we
8466
- // won't have to reorder the whole set of groups.
8467
- this.afterChartProxyPosContainer.appendChild(groupElement);
8468
- this.updateGroupOrder(this.groupOrder);
8469
- return groupElement;
8470
- }
8471
- /**
8472
- * Update HTML attributes of a group.
8473
- */
8474
- updateGroupAttrs(groupKey, attributes) {
8475
- const group = this.groups[groupKey];
8476
- if (!group) {
8477
- throw new Error('ProxyProvider.updateGroupAttrs: Invalid group key ' + groupKey);
8478
- }
8479
- attr(group.groupElement, attributes);
8480
- }
8481
- /**
8482
- * Reorder the proxy groups.
8483
- *
8484
- * The group key "series" refers to the chart's data points / <svg> element.
8485
- * This is so that the keyboardNavigation.order option can be used to
8486
- * determine the proxy group order.
8487
- */
8488
- updateGroupOrder(groupKeys) {
8489
- // Store so that we can update order when a new group is created
8490
- this.groupOrder = groupKeys.slice();
8491
- // Don't unnecessarily reorder, because keyboard focus is lost
8492
- if (this.isDOMOrderGroupOrder()) {
8493
- return;
8494
- }
8495
- const seriesIx = groupKeys.indexOf('series');
8496
- const beforeKeys = seriesIx > -1 ? groupKeys.slice(0, seriesIx) : groupKeys;
8497
- const afterKeys = seriesIx > -1 ? groupKeys.slice(seriesIx + 1) : [];
8498
- // Store focused element since it will be lost when reordering
8499
- const activeElement = doc.activeElement;
8500
- // Add groups to correct container
8501
- ['before', 'after'].forEach((pos) => {
8502
- const posContainer = this[pos === 'before' ?
8503
- 'beforeChartProxyPosContainer' :
8504
- 'afterChartProxyPosContainer'];
8505
- const keys = pos === 'before' ? beforeKeys : afterKeys;
8506
- removeChildNodes(posContainer);
8507
- keys.forEach((groupKey) => {
8508
- const group = this.groups[groupKey];
8509
- if (group) {
8510
- posContainer.appendChild(group.groupElement);
8511
- }
8512
- });
8513
- });
8514
- // Attempt to restore focus after reordering, but note that this may
8515
- // cause screen readers re-announcing the button.
8516
- if ((this.beforeChartProxyPosContainer.contains(activeElement) ||
8517
- this.afterChartProxyPosContainer.contains(activeElement)) &&
8518
- activeElement && activeElement.focus) {
8519
- activeElement.focus();
8520
- }
8521
- }
8522
- /**
8523
- * Remove all proxy elements in a group
8524
- */
8525
- clearGroup(groupKey) {
8526
- const group = this.groups[groupKey];
8527
- if (!group) {
8528
- throw new Error('ProxyProvider.clearGroup: Invalid group key ' + groupKey);
8529
- }
8530
- removeChildNodes(group.proxyContainerElement);
8531
- }
8532
- /**
8533
- * Remove a group from the DOM and from the proxy provider's group list.
8534
- * All child elements are removed.
8535
- * If the group does not exist, nothing happens.
8536
- */
8537
- removeGroup(groupKey) {
8538
- const group = this.groups[groupKey];
8539
- if (group) {
8540
- removeElement(group.groupElement);
8541
- delete this.groups[groupKey];
8542
- }
8543
- }
8544
- /**
8545
- * Update the position and order of all proxy groups and elements
8546
- */
8547
- update() {
8548
- this.updatePosContainerPositions();
8549
- this.updateGroupOrder(this.groupOrder);
8550
- this.updateProxyElementPositions();
8551
- }
8552
- /**
8553
- * Update all proxy element positions
8554
- */
8555
- updateProxyElementPositions() {
8556
- Object.keys(this.groups).forEach(this.updateGroupProxyElementPositions.bind(this));
8557
- }
8558
- /**
8559
- * Update a group's proxy elements' positions.
8560
- * If the group does not exist, nothing happens.
8561
- */
8562
- updateGroupProxyElementPositions(groupKey) {
8563
- const group = this.groups[groupKey];
8564
- if (group) {
8565
- group.proxyElements.forEach((el) => el.refreshPosition());
8566
- }
8567
- }
8568
- /**
8569
- * Remove all added elements
8570
- */
8571
- destroy() {
8572
- this.domElementProvider.destroyCreatedElements();
8573
- }
8574
- // -------------------------- private ------------------------------------
8575
- /**
8576
- * Create and return a pos container element (the overall containers for
8577
- * the proxy groups).
8578
- */
8579
- createProxyPosContainer(classNamePostfix) {
8580
- const el = this.domElementProvider.createElement('div');
8581
- el.setAttribute('aria-hidden', 'false');
8582
- el.className = 'highcharts-a11y-proxy-container' + (classNamePostfix ? '-' + classNamePostfix : '');
8583
- css(el, {
8584
- top: '0',
8585
- left: '0'
8586
- });
8587
- if (!this.chart.styledMode) {
8588
- el.style.whiteSpace = 'nowrap';
8589
- el.style.position = 'absolute';
8590
- }
8591
- return el;
8592
- }
8593
- /**
8594
- * Get an array of group keys that corresponds to the current group order
8595
- * in the DOM.
8596
- */
8597
- getCurrentGroupOrderInDOM() {
8598
- const getGroupKeyFromElement = (el) => {
8599
- const allGroups = Object.keys(this.groups);
8600
- let i = allGroups.length;
8601
- while (i--) {
8602
- const groupKey = allGroups[i];
8603
- const group = this.groups[groupKey];
8604
- if (group && el === group.groupElement) {
8605
- return groupKey;
8606
- }
8607
- }
8608
- };
8609
- const getChildrenGroupOrder = (el) => {
8610
- const childrenOrder = [];
8611
- const children = el.children;
8612
- for (let i = 0; i < children.length; ++i) {
8613
- const groupKey = getGroupKeyFromElement(children[i]);
8614
- if (groupKey) {
8615
- childrenOrder.push(groupKey);
8616
- }
8617
- }
8618
- return childrenOrder;
8619
- };
8620
- const before = getChildrenGroupOrder(this.beforeChartProxyPosContainer);
8621
- const after = getChildrenGroupOrder(this.afterChartProxyPosContainer);
8622
- before.push('series');
8623
- return before.concat(after);
8624
- }
8625
- /**
8626
- * Check if the current DOM order matches the current group order, so that
8627
- * a reordering/update is unnecessary.
8628
- */
8629
- isDOMOrderGroupOrder() {
8630
- const domOrder = this.getCurrentGroupOrderInDOM();
8631
- const groupOrderWithGroups = this.groupOrder.filter((x) => x === 'series' || !!this.groups[x]);
8632
- let i = domOrder.length;
8633
- if (i !== groupOrderWithGroups.length) {
8634
- return false;
8635
- }
8636
- while (i--) {
8637
- if (domOrder[i] !== groupOrderWithGroups[i]) {
8638
- return false;
8639
- }
8640
- }
8641
- return true;
8642
- }
8643
- /**
8644
- * Update the DOM positions of the before/after proxy
8645
- * positioning containers for the groups.
8646
- */
8647
- updatePosContainerPositions() {
8648
- const chart = this.chart;
8649
- // If exporting, don't add these containers to the DOM.
8650
- if (chart.renderer.forExport) {
8651
- return;
8652
- }
8653
- const rendererSVGEl = chart.renderer.box;
8654
- chart.container.insertBefore(this.afterChartProxyPosContainer, rendererSVGEl.nextSibling);
8655
- chart.container.insertBefore(this.beforeChartProxyPosContainer, rendererSVGEl);
8656
- unhideChartElementFromAT(this.chart, this.afterChartProxyPosContainer);
8657
- unhideChartElementFromAT(this.chart, this.beforeChartProxyPosContainer);
8658
- }
8659
- }
8660
- /* *
8661
- *
8662
- * Export Default
8663
- *
8664
- * */
8665
-
8666
- return ProxyProvider;
8667
- });
8668
- _registerModule(_modules, 'Stock/RangeSelector/RangeSelectorDefaults.js', [], function () {
8669
- /* *
8670
- *
8671
- * (c) 2010-2024 Torstein Honsi
8672
- *
8673
- * License: www.highcharts.com/license
8674
- *
8675
- * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
8676
- *
8677
- * */
8678
- /* *
8679
- *
8680
- * Declarations
8681
- *
8682
- * */
8683
- /**
8684
- * Language object. The language object is global and it can't be set
8685
- * on each chart initialization. Instead, use `Highcharts.setOptions` to
8686
- * set it before any chart is initialized.
8687
- *
8688
- * ```js
8689
- * Highcharts.setOptions({
8690
- * lang: {
8691
- * months: [
8692
- * 'Janvier', 'Février', 'Mars', 'Avril',
8693
- * 'Mai', 'Juin', 'Juillet', 'Août',
8694
- * 'Septembre', 'Octobre', 'Novembre', 'Décembre'
8695
- * ],
8696
- * weekdays: [
8697
- * 'Dimanche', 'Lundi', 'Mardi', 'Mercredi',
8698
- * 'Jeudi', 'Vendredi', 'Samedi'
8699
- * ]
8700
- * }
8701
- * });
8702
- * ```
8703
- *
8704
- * @optionparent lang
8705
- */
8706
- const lang = {
8707
- /**
8708
- * The text for the label for the range selector buttons.
8709
- *
8710
- * @product highstock gantt
8711
- */
8712
- rangeSelectorZoom: 'Zoom',
8713
- /**
8714
- * The text for the label for the "from" input box in the range
8715
- * selector. Since v9.0, this string is empty as the label is not
8716
- * rendered by default.
8717
- *
8718
- * @product highstock gantt
8719
- */
8720
- rangeSelectorFrom: '',
8721
- /**
8722
- * The text for the label for the "to" input box in the range selector.
8723
- *
8724
- * @product highstock gantt
8725
- */
8726
- rangeSelectorTo: '→'
8727
- };
8728
- /**
8729
- * The range selector is a tool for selecting ranges to display within
8730
- * the chart. It provides buttons to select preconfigured ranges in
8731
- * the chart, like 1 day, 1 week, 1 month etc. It also provides input
8732
- * boxes where min and max dates can be manually input.
8733
- *
8734
- * @product highstock gantt
8735
- * @optionparent rangeSelector
8736
- */
8737
- const rangeSelector = {
8738
- /**
8739
- * Whether to enable all buttons from the start. By default buttons are
8740
- * only enabled if the corresponding time range exists on the X axis,
8741
- * but enabling all buttons allows for dynamically loading different
8742
- * time ranges.
8743
- *
8744
- * @sample {highstock} stock/rangeselector/allbuttonsenabled-true/
8745
- * All buttons enabled
8746
- *
8747
- * @since 2.0.3
8748
- */
8749
- allButtonsEnabled: false,
8750
- /**
8751
- * An array of configuration objects for the buttons.
8752
- *
8753
- * Defaults to:
8754
- * ```js
8755
- * buttons: [{
8756
- * type: 'month',
8757
- * count: 1,
8758
- * text: '1m',
8759
- * title: 'View 1 month'
8760
- * }, {
8761
- * type: 'month',
8762
- * count: 3,
8763
- * text: '3m',
8764
- * title: 'View 3 months'
8765
- * }, {
8766
- * type: 'month',
8767
- * count: 6,
8768
- * text: '6m',
8769
- * title: 'View 6 months'
8770
- * }, {
8771
- * type: 'ytd',
8772
- * text: 'YTD',
8773
- * title: 'View year to date'
8774
- * }, {
8775
- * type: 'year',
8776
- * count: 1,
8777
- * text: '1y',
8778
- * title: 'View 1 year'
8779
- * }, {
8780
- * type: 'all',
8781
- * text: 'All',
8782
- * title: 'View all'
8783
- * }]
8784
- * ```
8785
- *
8786
- * @sample {highstock} stock/demo/rangeselector-datagrouping/
8787
- * Data grouping by buttons
8788
- *
8789
- * @type {Array<*>}
8790
- */
8791
- buttons: void 0,
8792
- /**
8793
- * How many units of the defined type the button should span. If `type`
8794
- * is "month" and `count` is 3, the button spans three months.
8795
- *
8796
- * @type {number}
8797
- * @default 1
8798
- * @apioption rangeSelector.buttons.count
8799
- */
8800
- /**
8801
- * Fires when clicking on the rangeSelector button. One parameter,
8802
- * event, is passed to the function, containing common event
8803
- * information.
8804
- *
8805
- * ```js
8806
- * click: function(e) {
8807
- * console.log(this);
8808
- * }
8809
- * ```
8810
- *
8811
- * Return false to stop default button's click action.
8812
- *
8813
- * @sample {highstock} stock/rangeselector/button-click/
8814
- * Click event on the button
8815
- *
8816
- * @type {Highcharts.RangeSelectorClickCallbackFunction}
8817
- * @apioption rangeSelector.buttons.events.click
8818
- */
8819
- /**
8820
- * Additional range (in milliseconds) added to the end of the calculated
8821
- * time span.
8822
- *
8823
- * @sample {highstock} stock/rangeselector/min-max-offsets/
8824
- * Button offsets
8825
- *
8826
- * @type {number}
8827
- * @default 0
8828
- * @since 6.0.0
8829
- * @apioption rangeSelector.buttons.offsetMax
8830
- */
8831
- /**
8832
- * Additional range (in milliseconds) added to the start of the
8833
- * calculated time span.
8834
- *
8835
- * @sample {highstock} stock/rangeselector/min-max-offsets/
8836
- * Button offsets
8837
- *
8838
- * @type {number}
8839
- * @default 0
8840
- * @since 6.0.0
8841
- * @apioption rangeSelector.buttons.offsetMin
8842
- */
8843
- /**
8844
- * When buttons apply dataGrouping on a series, by default zooming
8845
- * in/out will deselect buttons and unset dataGrouping. Enable this
8846
- * option to keep buttons selected when extremes change.
8847
- *
8848
- * @sample {highstock} stock/rangeselector/preserve-datagrouping/
8849
- * Different preserveDataGrouping settings
8850
- *
8851
- * @type {boolean}
8852
- * @default false
8853
- * @since 6.1.2
8854
- * @apioption rangeSelector.buttons.preserveDataGrouping
8855
- */
8856
- /**
8857
- * A custom data grouping object for each button.
8858
- *
8859
- * @see [series.dataGrouping](#plotOptions.series.dataGrouping)
8860
- *
8861
- * @sample {highstock} stock/demo/rangeselector-datagrouping/
8862
- * Data grouping by range selector buttons
8863
- *
8864
- * @type {*}
8865
- * @extends plotOptions.series.dataGrouping
8866
- * @apioption rangeSelector.buttons.dataGrouping
8867
- */
8868
- /**
8869
- * The text for the button itself.
8870
- *
8871
- * @type {string}
8872
- * @apioption rangeSelector.buttons.text
8873
- */
8874
- /**
8875
- * Explanation for the button, shown as a tooltip on hover, and used by
8876
- * assistive technology.
8877
- *
8878
- * @type {string}
8879
- * @apioption rangeSelector.buttons.title
8880
- */
8881
- /**
8882
- * Defined the time span for the button. Can be one of `millisecond`,
8883
- * `second`, `minute`, `hour`, `day`, `week`, `month`, `year`, `ytd`,
8884
- * and `all`.
8885
- *
8886
- * @type {Highcharts.RangeSelectorButtonTypeValue}
8887
- * @apioption rangeSelector.buttons.type
8888
- */
8889
- /**
8890
- * The space in pixels between the buttons in the range selector.
8891
- */
8892
- buttonSpacing: 5,
8893
- /**
8894
- * Whether to collapse the range selector buttons into a dropdown when
8895
- * there is not enough room to show everything in a single row, instead
8896
- * of dividing the range selector into multiple rows.
8897
- * Can be one of the following:
8898
- * - `always`: Always collapse
8899
- * - `responsive`: Only collapse when there is not enough room
8900
- * - `never`: Never collapse
8901
- *
8902
- * @sample {highstock} stock/rangeselector/dropdown/
8903
- * Dropdown option
8904
- *
8905
- * @validvalue ["always", "responsive", "never"]
8906
- * @since 9.0.0
8907
- */
8908
- dropdown: 'responsive',
8909
- /**
8910
- * Enable or disable the range selector. Default to `true` for stock
8911
- * charts, using the `stockChart` factory.
8912
- *
8913
- * @sample {highstock} stock/rangeselector/enabled/
8914
- * Disable the range selector
8915
- *
8916
- * @type {boolean|undefined}
8917
- * @default {highstock} true
8918
- */
8919
- enabled: void 0,
8920
- /**
8921
- * The vertical alignment of the rangeselector box. Allowed properties
8922
- * are `top`, `middle`, `bottom`.
8923
- *
8924
- * @sample {highstock} stock/rangeselector/vertical-align-middle/
8925
- * Middle
8926
- * @sample {highstock} stock/rangeselector/vertical-align-bottom/
8927
- * Bottom
8928
- *
8929
- * @type {Highcharts.VerticalAlignValue}
8930
- * @since 6.0.0
8931
- */
8932
- verticalAlign: 'top',
8933
- /**
8934
- * A collection of attributes for the buttons. The object takes SVG
8935
- * attributes like `fill`, `stroke`, `stroke-width`, as well as `style`,
8936
- * a collection of CSS properties for the text.
8937
- *
8938
- * The object can also be extended with states, so you can set
8939
- * presentational options for `hover`, `select` or `disabled` button
8940
- * states.
8941
- *
8942
- * CSS styles for the text label.
8943
- *
8944
- * In styled mode, the buttons are styled by the
8945
- * `.highcharts-range-selector-buttons .highcharts-button` rule with its
8946
- * different states.
8947
- *
8948
- * @sample {highstock} stock/rangeselector/styling/
8949
- * Styling the buttons and inputs
8950
- *
8951
- * @type {Highcharts.SVGAttributes}
8952
- */
8953
- buttonTheme: {
8954
- /** @ignore */
8955
- width: 28,
8956
- /** @ignore */
8957
- height: 18,
8958
- /** @ignore */
8959
- padding: 2,
8960
- /** @ignore */
8961
- zIndex: 7 // #484, #852
8962
- },
8963
- /**
8964
- * When the rangeselector is floating, the plot area does not reserve
8965
- * space for it. This opens for positioning anywhere on the chart.
8966
- *
8967
- * @sample {highstock} stock/rangeselector/floating/
8968
- * Placing the range selector between the plot area and the
8969
- * navigator
8970
- *
8971
- * @since 6.0.0
8972
- */
8973
- floating: false,
8974
- /**
8975
- * The x offset of the range selector relative to its horizontal
8976
- * alignment within `chart.spacingLeft` and `chart.spacingRight`.
8977
- *
8978
- * @since 6.0.0
8979
- */
8980
- x: 0,
8981
- /**
8982
- * The y offset of the range selector relative to its horizontal
8983
- * alignment within `chart.spacingLeft` and `chart.spacingRight`.
8984
- *
8985
- * @since 6.0.0
8986
- */
8987
- y: 0,
8988
- /**
8989
- * Deprecated. The height of the range selector. Currently it is
8990
- * calculated dynamically.
8991
- *
8992
- * @deprecated
8993
- * @type {number|undefined}
8994
- * @since 2.1.9
8995
- */
8996
- height: void 0,
8997
- /**
8998
- * The border color of the date input boxes.
8999
- *
9000
- * @sample {highstock} stock/rangeselector/styling/
9001
- * Styling the buttons and inputs
9002
- *
9003
- * @type {Highcharts.ColorString}
9004
- * @since 1.3.7
9005
- */
9006
- inputBoxBorderColor: 'none',
9007
- /**
9008
- * The pixel height of the date input boxes.
9009
- *
9010
- * @sample {highstock} stock/rangeselector/styling/
9011
- * Styling the buttons and inputs
9012
- *
9013
- * @since 1.3.7
9014
- */
9015
- inputBoxHeight: 17,
9016
- /**
9017
- * The pixel width of the date input boxes. When `undefined`, the width
9018
- * is fitted to the rendered content.
9019
- *
9020
- * @sample {highstock} stock/rangeselector/styling/
9021
- * Styling the buttons and inputs
9022
- *
9023
- * @type {number|undefined}
9024
- * @since 1.3.7
9025
- */
9026
- inputBoxWidth: void 0,
9027
- /**
9028
- * The date format in the input boxes when not selected for editing.
9029
- * Defaults to `%e %b %Y`.
9030
- *
9031
- * This is used to determine which type of input to show,
9032
- * `datetime-local`, `date` or `time` and falling back to `text` when
9033
- * the browser does not support the input type or the format contains
9034
- * milliseconds.
9035
- *
9036
- * @sample {highstock} stock/rangeselector/input-type/
9037
- * Input types
9038
- * @sample {highstock} stock/rangeselector/input-format/
9039
- * Milliseconds in the range selector
9040
- *
9041
- */
9042
- inputDateFormat: '%e %b %Y',
9043
- /**
9044
- * A custom callback function to parse values entered in the input boxes
9045
- * and return a valid JavaScript time as milliseconds since 1970.
9046
- * The first argument passed is a value to parse,
9047
- * second is a boolean indicating use of the UTC time.
9048
- *
9049
- * This will only get called for inputs of type `text`. Since v8.2.3,
9050
- * the input type is dynamically determined based on the granularity
9051
- * of the `inputDateFormat` and the browser support.
9052
- *
9053
- * @sample {highstock} stock/rangeselector/input-format/
9054
- * Milliseconds in the range selector
9055
- *
9056
- * @type {Highcharts.RangeSelectorParseCallbackFunction}
9057
- * @since 1.3.3
9058
- */
9059
- inputDateParser: void 0,
9060
- /**
9061
- * The date format in the input boxes when they are selected for
9062
- * editing. This must be a format that is recognized by JavaScript
9063
- * Date.parse.
9064
- *
9065
- * This will only be used for inputs of type `text`. Since v8.2.3,
9066
- * the input type is dynamically determined based on the granularity
9067
- * of the `inputDateFormat` and the browser support.
9068
- *
9069
- * @sample {highstock} stock/rangeselector/input-format/
9070
- * Milliseconds in the range selector
9071
- *
9072
- */
9073
- inputEditDateFormat: '%Y-%m-%d',
9074
- /**
9075
- * Enable or disable the date input boxes.
9076
- */
9077
- inputEnabled: true,
9078
- /**
9079
- * Positioning for the input boxes. Allowed properties are `align`,
9080
- * `x` and `y`.
9081
- *
9082
- * @since 1.2.4
9083
- */
9084
- inputPosition: {
9085
- /**
9086
- * The alignment of the input box. Allowed properties are `left`,
9087
- * `center`, `right`.
9088
- *
9089
- * @sample {highstock} stock/rangeselector/input-button-position/
9090
- * Alignment
9091
- *
9092
- * @type {Highcharts.AlignValue}
9093
- * @since 6.0.0
9094
- */
9095
- align: 'right',
9096
- /**
9097
- * X offset of the input row.
9098
- */
9099
- x: 0,
9100
- /**
9101
- * Y offset of the input row.
9102
- */
9103
- y: 0
9104
- },
9105
- /**
9106
- * The space in pixels between the labels and the date input boxes in
9107
- * the range selector.
9108
- *
9109
- * @since 9.0.0
9110
- */
9111
- inputSpacing: 5,
9112
- /**
9113
- * The index of the button to appear pre-selected. If the selected range
9114
- * exceeds the total data range and the 'all' option is available,
9115
- * the 'all' option, showing the full range, is automatically selected.
9116
- *
9117
- * @type {number}
9118
- */
9119
- selected: void 0,
9120
- /**
9121
- * Positioning for the button row.
9122
- *
9123
- * @since 1.2.4
9124
- */
9125
- buttonPosition: {
9126
- /**
9127
- * The alignment of the input box. Allowed properties are `left`,
9128
- * `center`, `right`.
9129
- *
9130
- * @sample {highstock} stock/rangeselector/input-button-position/
9131
- * Alignment
9132
- *
9133
- * @type {Highcharts.AlignValue}
9134
- * @since 6.0.0
9135
- */
9136
- align: 'left',
9137
- /**
9138
- * X offset of the button row.
9139
- */
9140
- x: 0,
9141
- /**
9142
- * Y offset of the button row.
9143
- */
9144
- y: 0
9145
- },
9146
- /**
9147
- * CSS for the HTML inputs in the range selector.
9148
- *
9149
- * In styled mode, the inputs are styled by the
9150
- * `.highcharts-range-input text` rule in SVG mode, and
9151
- * `input.highcharts-range-selector` when active.
9152
- *
9153
- * @sample {highstock} stock/rangeselector/styling/
9154
- * Styling the buttons and inputs
9155
- *
9156
- * @type {Highcharts.CSSObject}
9157
- * @apioption rangeSelector.inputStyle
9158
- */
9159
- inputStyle: {
9160
- /** @ignore */
9161
- color: "#334eff" /* Palette.highlightColor80 */,
9162
- /** @ignore */
9163
- cursor: 'pointer',
9164
- /** @ignore */
9165
- fontSize: '0.8em'
9166
- },
9167
- /**
9168
- * CSS styles for the labels - the Zoom, From and To texts.
9169
- *
9170
- * In styled mode, the labels are styled by the
9171
- * `.highcharts-range-label` class.
9172
- *
9173
- * @sample {highstock} stock/rangeselector/styling/
9174
- * Styling the buttons and inputs
9175
- *
9176
- * @type {Highcharts.CSSObject}
9177
- */
9178
- labelStyle: {
9179
- /** @ignore */
9180
- color: "#666666" /* Palette.neutralColor60 */,
9181
- /** @ignore */
9182
- fontSize: '0.8em'
9183
- }
9184
- };
9185
- /* *
9186
- *
9187
- * Default Export
9188
- *
9189
- * */
9190
- const RangeSelectorDefaults = {
9191
- lang,
9192
- rangeSelector
9193
- };
9194
-
9195
- return RangeSelectorDefaults;
9196
- });
9197
- _registerModule(_modules, 'Stock/RangeSelector/RangeSelectorComposition.js', [_modules['Core/Defaults.js'], _modules['Core/Globals.js'], _modules['Stock/RangeSelector/RangeSelectorDefaults.js'], _modules['Core/Utilities.js']], function (D, H, RangeSelectorDefaults, U) {
9198
- /* *
9199
- *
9200
- * (c) 2010-2024 Torstein Honsi
9201
- *
9202
- * License: www.highcharts.com/license
9203
- *
9204
- * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
9205
- *
9206
- * */
9207
- const { defaultOptions } = D;
9208
- const { composed } = H;
9209
- const { addEvent, defined, extend, find, isNumber, merge, pick, pushUnique } = U;
9210
- /* *
9211
- *
9212
- * Constants
9213
- *
9214
- * */
9215
- const chartDestroyEvents = [];
9216
- /* *
9217
- *
9218
- * Variables
9219
- *
9220
- * */
9221
- let RangeSelectorConstructor;
9222
- /* *
9223
- *
9224
- * Functions
9225
- *
9226
- * */
9227
- /**
9228
- * Get the axis min value based on the range option and the current max. For
9229
- * stock charts this is extended via the {@link RangeSelector} so that if the
9230
- * selected range is a multiple of months or years, it is compensated for
9231
- * various month lengths.
9232
- *
9233
- * @private
9234
- * @function Highcharts.Axis#minFromRange
9235
- * @return {number|undefined}
9236
- * The new minimum value.
9237
- */
9238
- function axisMinFromRange() {
9239
- const rangeOptions = this.range, type = rangeOptions.type, max = this.max, time = this.chart.time,
9240
- // Get the true range from a start date
9241
- getTrueRange = function (base, count) {
9242
- const timeName = type === 'year' ?
9243
- 'FullYear' : 'Month';
9244
- const date = new time.Date(base);
9245
- const basePeriod = time.get(timeName, date);
9246
- time.set(timeName, date, basePeriod + count);
9247
- if (basePeriod === time.get(timeName, date)) {
9248
- time.set('Date', date, 0); // #6537
9249
- }
9250
- return date.getTime() - base;
9251
- };
9252
- let min, range;
9253
- if (isNumber(rangeOptions)) {
9254
- min = max - rangeOptions;
9255
- range = rangeOptions;
9256
- }
9257
- else if (rangeOptions) {
9258
- min = max + getTrueRange(max, -(rangeOptions.count || 1));
9259
- // Let the fixedRange reflect initial settings (#5930)
9260
- if (this.chart) {
9261
- this.chart.fixedRange = max - min;
9262
- }
9263
- }
9264
- const dataMin = pick(this.dataMin, Number.MIN_VALUE);
9265
- if (!isNumber(min)) {
9266
- min = dataMin;
9267
- }
9268
- if (min <= dataMin) {
9269
- min = dataMin;
9270
- if (typeof range === 'undefined') { // #4501
9271
- range = getTrueRange(min, rangeOptions.count);
9272
- }
9273
- this.newMax = Math.min(min + range, pick(this.dataMax, Number.MAX_VALUE));
9274
- }
9275
- if (!isNumber(max)) {
9276
- min = void 0;
9277
- }
9278
- else if (!isNumber(rangeOptions) &&
9279
- rangeOptions &&
9280
- rangeOptions._offsetMin) {
9281
- min += rangeOptions._offsetMin;
9282
- }
9283
- return min;
9284
- }
9285
- /**
9286
- * @private
9287
- */
9288
- function compose(AxisClass, ChartClass, RangeSelectorClass) {
9289
- RangeSelectorConstructor = RangeSelectorClass;
9290
- if (pushUnique(composed, compose)) {
9291
- const chartProto = ChartClass.prototype;
9292
- AxisClass.prototype.minFromRange = axisMinFromRange;
9293
- addEvent(ChartClass, 'afterGetContainer', onChartAfterGetContainer);
9294
- addEvent(ChartClass, 'beforeRender', onChartBeforeRender);
9295
- addEvent(ChartClass, 'destroy', onChartDestroy);
9296
- addEvent(ChartClass, 'getMargins', onChartGetMargins);
9297
- addEvent(ChartClass, 'render', onChartRender);
9298
- addEvent(ChartClass, 'update', onChartUpdate);
9299
- chartProto.callbacks.push(onChartCallback);
9300
- extend(defaultOptions, { rangeSelector: RangeSelectorDefaults.rangeSelector });
9301
- extend(defaultOptions.lang, RangeSelectorDefaults.lang);
9302
- }
9303
- }
9304
- /**
9305
- * Initialize rangeselector for stock charts
9306
- * @private
9307
- */
9308
- function onChartAfterGetContainer() {
9309
- if (this.options.rangeSelector &&
9310
- this.options.rangeSelector.enabled) {
9311
- this.rangeSelector = new RangeSelectorConstructor(this);
9312
- }
9313
- }
9314
- /**
9315
- * @private
9316
- */
9317
- function onChartBeforeRender() {
9318
- const chart = this, axes = chart.axes, rangeSelector = chart.rangeSelector;
9319
- if (rangeSelector) {
9320
- if (isNumber(rangeSelector.deferredYTDClick)) {
9321
- rangeSelector.clickButton(rangeSelector.deferredYTDClick);
9322
- delete rangeSelector.deferredYTDClick;
9323
- }
9324
- axes.forEach((axis) => {
9325
- axis.updateNames();
9326
- axis.setScale();
9327
- });
9328
- chart.getAxisMargins();
9329
- rangeSelector.render();
9330
- const verticalAlign = rangeSelector.options.verticalAlign;
9331
- if (!rangeSelector.options.floating) {
9332
- if (verticalAlign === 'bottom') {
9333
- this.extraBottomMargin = true;
9334
- }
9335
- else if (verticalAlign !== 'middle') {
9336
- this.extraTopMargin = true;
9337
- }
9338
- }
9339
- }
9340
- }
9341
- /**
9342
- * @private
9343
- */
9344
- function onChartCallback(chart) {
9345
- let extremes, legend, alignTo, verticalAlign;
9346
- const rangeSelector = chart.rangeSelector, redraw = () => {
9347
- if (rangeSelector) {
9348
- extremes = chart.xAxis[0].getExtremes();
9349
- legend = chart.legend;
9350
- verticalAlign = (rangeSelector &&
9351
- rangeSelector.options.verticalAlign);
9352
- if (isNumber(extremes.min)) {
9353
- rangeSelector.render(extremes.min, extremes.max);
9354
- }
9355
- // Re-align the legend so that it's below the rangeselector
9356
- if (legend.display &&
9357
- verticalAlign === 'top' &&
9358
- verticalAlign === legend.options.verticalAlign) {
9359
- // Create a new alignment box for the legend.
9360
- alignTo = merge(chart.spacingBox);
9361
- if (legend.options.layout === 'vertical') {
9362
- alignTo.y = chart.plotTop;
9363
- }
9364
- else {
9365
- alignTo.y += rangeSelector.getHeight();
9366
- }
9367
- legend.group.placed = false; // Don't animate the alignment.
9368
- legend.align(alignTo);
9369
- }
9370
- }
9371
- };
9372
- if (rangeSelector) {
9373
- const events = find(chartDestroyEvents, (e) => e[0] === chart);
9374
- if (!events) {
9375
- chartDestroyEvents.push([chart, [
9376
- // redraw the scroller on setExtremes
9377
- addEvent(chart.xAxis[0], 'afterSetExtremes', function (e) {
9378
- if (rangeSelector) {
9379
- rangeSelector.render(e.min, e.max);
9380
- }
9381
- }),
9382
- // redraw the scroller chart resize
9383
- addEvent(chart, 'redraw', redraw)
9384
- ]]);
9385
- }
9386
- // do it now
9387
- redraw();
9388
- }
9389
- }
9390
- /**
9391
- * Remove resize/afterSetExtremes at chart destroy.
9392
- * @private
9393
- */
9394
- function onChartDestroy() {
9395
- for (let i = 0, iEnd = chartDestroyEvents.length; i < iEnd; ++i) {
9396
- const events = chartDestroyEvents[i];
9397
- if (events[0] === this) {
9398
- events[1].forEach((unbind) => unbind());
9399
- chartDestroyEvents.splice(i, 1);
9400
- return;
9401
- }
9402
- }
9403
- }
9404
- function onChartGetMargins() {
9405
- const rangeSelector = this.rangeSelector;
9406
- if (rangeSelector) {
9407
- const rangeSelectorHeight = rangeSelector.getHeight();
9408
- if (this.extraTopMargin) {
9409
- this.plotTop += rangeSelectorHeight;
9410
- }
9411
- if (this.extraBottomMargin) {
9412
- this.marginBottom += rangeSelectorHeight;
9413
- }
9414
- }
9415
- }
9416
- /**
9417
- * @private
9418
- */
9419
- function onChartRender() {
9420
- const chart = this, rangeSelector = chart.rangeSelector;
9421
- if (rangeSelector && !rangeSelector.options.floating) {
9422
- rangeSelector.render();
9423
- const verticalAlign = rangeSelector.options.verticalAlign;
9424
- if (verticalAlign === 'bottom') {
9425
- this.extraBottomMargin = true;
9426
- }
9427
- else if (verticalAlign !== 'middle') {
9428
- this.extraTopMargin = true;
9429
- }
9430
- }
9431
- }
9432
- /**
9433
- * @private
9434
- */
9435
- function onChartUpdate(e) {
9436
- const chart = this, options = e.options, optionsRangeSelector = options.rangeSelector, extraBottomMarginWas = this.extraBottomMargin, extraTopMarginWas = this.extraTopMargin;
9437
- let rangeSelector = chart.rangeSelector;
9438
- if (optionsRangeSelector &&
9439
- optionsRangeSelector.enabled &&
9440
- !defined(rangeSelector) &&
9441
- this.options.rangeSelector) {
9442
- this.options.rangeSelector.enabled = true;
9443
- this.rangeSelector = rangeSelector = new RangeSelectorConstructor(this);
9444
- }
9445
- this.extraBottomMargin = false;
9446
- this.extraTopMargin = false;
9447
- if (rangeSelector) {
9448
- onChartCallback(this);
9449
- const verticalAlign = (optionsRangeSelector &&
9450
- optionsRangeSelector.verticalAlign) || (rangeSelector.options && rangeSelector.options.verticalAlign);
9451
- if (!rangeSelector.options.floating) {
9452
- if (verticalAlign === 'bottom') {
9453
- this.extraBottomMargin = true;
9454
- }
9455
- else if (verticalAlign !== 'middle') {
9456
- this.extraTopMargin = true;
9457
- }
9458
- }
9459
- if (this.extraBottomMargin !== extraBottomMarginWas ||
9460
- this.extraTopMargin !== extraTopMarginWas) {
9461
- this.isDirtyBox = true;
9462
- }
9463
- }
9464
- }
9465
- /* *
9466
- *
9467
- * Default Export
9468
- *
9469
- * */
9470
- const RangeSelectorComposition = {
9471
- compose
9472
- };
9473
-
9474
- return RangeSelectorComposition;
9475
- });
9476
- _registerModule(_modules, 'Stock/RangeSelector/RangeSelector.js', [_modules['Core/Axis/Axis.js'], _modules['Core/Defaults.js'], _modules['Core/Globals.js'], _modules['Stock/RangeSelector/RangeSelectorComposition.js'], _modules['Core/Renderer/SVG/SVGElement.js'], _modules['Core/Utilities.js']], function (Axis, D, H, RangeSelectorComposition, SVGElement, U) {
9477
- /* *
9478
- *
9479
- * (c) 2010-2024 Torstein Honsi
9480
- *
9481
- * License: www.highcharts.com/license
9482
- *
9483
- * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
9484
- *
9485
- * */
9486
- const { defaultOptions } = D;
9487
- const { addEvent, createElement, css, defined, destroyObjectProperties, discardElement, extend, fireEvent, isNumber, merge, objectEach, pad, pick, pInt, splat } = U;
9488
- /* *
9489
- *
9490
- * Functions
9491
- *
9492
- * */
9493
- /**
9494
- * Get the preferred input type based on a date format string.
9495
- *
9496
- * @private
9497
- * @function preferredInputType
9498
- */
9499
- function preferredInputType(format) {
9500
- const ms = format.indexOf('%L') !== -1;
9501
- if (ms) {
9502
- return 'text';
9503
- }
9504
- const date = ['a', 'A', 'd', 'e', 'w', 'b', 'B', 'm', 'o', 'y', 'Y']
9505
- .some((char) => format.indexOf('%' + char) !== -1);
9506
- const time = ['H', 'k', 'I', 'l', 'M', 'S']
9507
- .some((char) => format.indexOf('%' + char) !== -1);
9508
- if (date && time) {
9509
- return 'datetime-local';
9510
- }
9511
- if (date) {
9512
- return 'date';
9513
- }
9514
- if (time) {
9515
- return 'time';
9516
- }
9517
- return 'text';
9518
- }
9519
- /* *
9520
- *
9521
- * Class
9522
- *
9523
- * */
9524
- /**
9525
- * The range selector.
9526
- *
9527
- * @private
9528
- * @class
9529
- * @name Highcharts.RangeSelector
9530
- * @param {Highcharts.Chart} chart
9531
- */
9532
- class RangeSelector {
9533
- /* *
9534
- *
9535
- * Static Functions
9536
- *
9537
- * */
9538
- /**
9539
- * @private
9540
- */
9541
- static compose(AxisClass, ChartClass) {
9542
- RangeSelectorComposition.compose(AxisClass, ChartClass, RangeSelector);
9543
- }
9544
- /* *
9545
- *
9546
- * Constructor
9547
- *
9548
- * */
9549
- constructor(chart) {
9550
- this.buttonOptions = RangeSelector.prototype.defaultButtons;
9551
- this.initialButtonGroupWidth = 0;
9552
- this.chart = chart;
9553
- this.init(chart);
9554
- }
9555
- /* *
9556
- *
9557
- * Functions
9558
- *
9559
- * */
9560
- /**
9561
- * The method to run when one of the buttons in the range selectors is
9562
- * clicked
9563
- *
9564
- * @private
9565
- * @function Highcharts.RangeSelector#clickButton
9566
- * @param {number} i
9567
- * The index of the button
9568
- * @param {boolean} [redraw]
9569
- */
9570
- clickButton(i, redraw) {
9571
- const rangeSelector = this, chart = rangeSelector.chart, rangeOptions = rangeSelector.buttonOptions[i], baseAxis = chart.xAxis[0], unionExtremes = (chart.scroller && chart.scroller.getUnionExtremes()) || baseAxis || {}, type = rangeOptions.type, dataGrouping = rangeOptions.dataGrouping;
9572
- let dataMin = unionExtremes.dataMin, dataMax = unionExtremes.dataMax, newMin, newMax = baseAxis && Math.round(Math.min(baseAxis.max, pick(dataMax, baseAxis.max))), // #1568
9573
- baseXAxisOptions, range = rangeOptions._range, rangeMin, minSetting, rangeSetting, ctx, ytdExtremes, addOffsetMin = true;
9574
- // chart has no data, base series is removed
9575
- if (dataMin === null || dataMax === null) {
9576
- return;
9577
- }
9578
- // Set the fixed range before range is altered
9579
- chart.fixedRange = range;
9580
- rangeSelector.setSelected(i);
9581
- // Apply dataGrouping associated to button
9582
- if (dataGrouping) {
9583
- this.forcedDataGrouping = true;
9584
- Axis.prototype.setDataGrouping.call(baseAxis || { chart: this.chart }, dataGrouping, false);
9585
- this.frozenStates = rangeOptions.preserveDataGrouping;
9586
- }
9587
- // Apply range
9588
- if (type === 'month' || type === 'year') {
9589
- if (!baseAxis) {
9590
- // This is set to the user options and picked up later when the
9591
- // axis is instantiated so that we know the min and max.
9592
- range = rangeOptions;
9593
- }
9594
- else {
9595
- ctx = {
9596
- range: rangeOptions,
9597
- max: newMax,
9598
- chart: chart,
9599
- dataMin: dataMin,
9600
- dataMax: dataMax
9601
- };
9602
- newMin = baseAxis.minFromRange.call(ctx);
9603
- if (isNumber(ctx.newMax)) {
9604
- newMax = ctx.newMax;
9605
- }
9606
- // #15799: offsetMin is added in minFromRange so that it works
9607
- // with pre-selected buttons as well
9608
- addOffsetMin = false;
9609
- }
9610
- // Fixed times like minutes, hours, days
9611
- }
9612
- else if (range) {
9613
- newMin = Math.max(newMax - range, dataMin);
9614
- newMax = Math.min(newMin + range, dataMax);
9615
- addOffsetMin = false;
9616
- }
9617
- else if (type === 'ytd') {
9618
- // On user clicks on the buttons, or a delayed action running from
9619
- // the beforeRender event (below), the baseAxis is defined.
9620
- if (baseAxis) {
9621
- // When "ytd" is the pre-selected button for the initial view,
9622
- // its calculation is delayed and rerun in the beforeRender
9623
- // event (below). When the series are initialized, but before
9624
- // the chart is rendered, we have access to the xData array
9625
- // (#942).
9626
- if (typeof dataMax === 'undefined' ||
9627
- typeof dataMin === 'undefined') {
9628
- dataMin = Number.MAX_VALUE;
9629
- dataMax = Number.MIN_VALUE;
9630
- chart.series.forEach((series) => {
9631
- // reassign it to the last item
9632
- const xData = series.xData;
9633
- if (xData) {
9634
- dataMin = Math.min(xData[0], dataMin);
9635
- dataMax = Math.max(xData[xData.length - 1], dataMax);
9636
- }
9637
- });
9638
- redraw = false;
9639
- }
9640
- ytdExtremes = rangeSelector.getYTDExtremes(dataMax, dataMin, chart.time.useUTC);
9641
- newMin = rangeMin = ytdExtremes.min;
9642
- newMax = ytdExtremes.max;
9643
- // "ytd" is pre-selected. We don't yet have access to processed
9644
- // point and extremes data (things like pointStart and pointInterval
9645
- // are missing), so we delay the process (#942)
9646
- }
9647
- else {
9648
- rangeSelector.deferredYTDClick = i;
9649
- return;
9650
- }
9651
- }
9652
- else if (type === 'all' && baseAxis) {
9653
- // If the navigator exist and the axis range is declared reset that
9654
- // range and from now on only use the range set by a user, #14742.
9655
- if (chart.navigator && chart.navigator.baseSeries[0]) {
9656
- chart.navigator.baseSeries[0].xAxis.options.range = void 0;
9657
- }
9658
- newMin = dataMin;
9659
- newMax = dataMax;
9660
- }
9661
- if (addOffsetMin && rangeOptions._offsetMin && defined(newMin)) {
9662
- newMin += rangeOptions._offsetMin;
9663
- }
9664
- if (rangeOptions._offsetMax && defined(newMax)) {
9665
- newMax += rangeOptions._offsetMax;
9666
- }
9667
- if (this.dropdown) {
9668
- this.dropdown.selectedIndex = i + 1;
9669
- }
9670
- // Update the chart
9671
- if (!baseAxis) {
9672
- // Axis not yet instanciated. Temporarily set min and range
9673
- // options and remove them on chart load (#4317).
9674
- baseXAxisOptions = splat(chart.options.xAxis)[0];
9675
- rangeSetting = baseXAxisOptions.range;
9676
- baseXAxisOptions.range = range;
9677
- minSetting = baseXAxisOptions.min;
9678
- baseXAxisOptions.min = rangeMin;
9679
- addEvent(chart, 'load', function resetMinAndRange() {
9680
- baseXAxisOptions.range = rangeSetting;
9681
- baseXAxisOptions.min = minSetting;
9682
- });
9683
- }
9684
- else {
9685
- // Existing axis object. Set extremes after render time.
9686
- baseAxis.setExtremes(newMin, newMax, pick(redraw, true), void 0, // auto animation
9687
- {
9688
- trigger: 'rangeSelectorButton',
9689
- rangeSelectorButton: rangeOptions
9690
- });
9691
- }
9692
- fireEvent(this, 'afterBtnClick');
9693
- }
9694
- /**
9695
- * Set the selected option. This method only sets the internal flag, it
9696
- * doesn't update the buttons or the actual zoomed range.
9697
- *
9698
- * @private
9699
- * @function Highcharts.RangeSelector#setSelected
9700
- * @param {number} [selected]
9701
- */
9702
- setSelected(selected) {
9703
- this.selected = this.options.selected = selected;
9704
- }
9705
- /**
9706
- * Initialize the range selector
9707
- *
9708
- * @private
9709
- * @function Highcharts.RangeSelector#init
9710
- * @param {Highcharts.Chart} chart
9711
- */
9712
- init(chart) {
9713
- const rangeSelector = this, options = chart.options.rangeSelector, buttonOptions = (options.buttons || rangeSelector.defaultButtons.slice()), selectedOption = options.selected, blurInputs = function () {
9714
- const minInput = rangeSelector.minInput, maxInput = rangeSelector.maxInput;
9715
- // #3274 in some case blur is not defined
9716
- if (minInput && !!minInput.blur) {
9717
- fireEvent(minInput, 'blur');
9718
- }
9719
- if (maxInput && !!maxInput.blur) {
9720
- fireEvent(maxInput, 'blur');
9721
- }
9722
- };
9723
- rangeSelector.chart = chart;
9724
- rangeSelector.options = options;
9725
- rangeSelector.buttons = [];
9726
- rangeSelector.buttonOptions = buttonOptions;
9727
- this.eventsToUnbind = [];
9728
- this.eventsToUnbind.push(addEvent(chart.container, 'mousedown', blurInputs));
9729
- this.eventsToUnbind.push(addEvent(chart, 'resize', blurInputs));
9730
- // Extend the buttonOptions with actual range
9731
- buttonOptions.forEach(rangeSelector.computeButtonRange);
9732
- // zoomed range based on a pre-selected button index
9733
- if (typeof selectedOption !== 'undefined' &&
9734
- buttonOptions[selectedOption]) {
9735
- this.clickButton(selectedOption, false);
9736
- }
9737
- this.eventsToUnbind.push(addEvent(chart, 'load', function () {
9738
- // If a data grouping is applied to the current button, release it
9739
- // when extremes change
9740
- if (chart.xAxis && chart.xAxis[0]) {
9741
- addEvent(chart.xAxis[0], 'setExtremes', function (e) {
9742
- if (this.max - this.min !==
9743
- chart.fixedRange &&
9744
- e.trigger !== 'rangeSelectorButton' &&
9745
- e.trigger !== 'updatedData' &&
9746
- rangeSelector.forcedDataGrouping &&
9747
- !rangeSelector.frozenStates) {
9748
- this.setDataGrouping(false, false);
9749
- }
9750
- });
9751
- }
9752
- }));
9753
- }
9754
- /**
9755
- * Dynamically update the range selector buttons after a new range has been
9756
- * set
9757
- *
9758
- * @private
9759
- * @function Highcharts.RangeSelector#updateButtonStates
9760
- */
9761
- updateButtonStates() {
9762
- const rangeSelector = this, chart = this.chart, dropdown = this.dropdown, baseAxis = chart.xAxis[0], actualRange = Math.round(baseAxis.max - baseAxis.min), hasNoData = !baseAxis.hasVisibleSeries, day = 24 * 36e5, // A single day in milliseconds
9763
- unionExtremes = (chart.scroller &&
9764
- chart.scroller.getUnionExtremes()) || baseAxis, dataMin = unionExtremes.dataMin, dataMax = unionExtremes.dataMax, ytdExtremes = rangeSelector.getYTDExtremes(dataMax, dataMin, chart.time.useUTC), ytdMin = ytdExtremes.min, ytdMax = ytdExtremes.max, selected = rangeSelector.selected, allButtonsEnabled = rangeSelector.options.allButtonsEnabled, buttons = rangeSelector.buttons;
9765
- let selectedExists = isNumber(selected), isSelectedTooGreat = false;
9766
- rangeSelector.buttonOptions.forEach((rangeOptions, i) => {
9767
- const range = rangeOptions._range, type = rangeOptions.type, count = rangeOptions.count || 1, button = buttons[i], offsetRange = rangeOptions._offsetMax -
9768
- rangeOptions._offsetMin, isSelected = i === selected,
9769
- // Disable buttons where the range exceeds what is allowed in
9770
- // the current view
9771
- isTooGreatRange = range >
9772
- dataMax - dataMin,
9773
- // Disable buttons where the range is smaller than the minimum
9774
- // range
9775
- isTooSmallRange = range < baseAxis.minRange;
9776
- let state = 0,
9777
- // Do not select the YTD button if not explicitly told so
9778
- isYTDButNotSelected = false,
9779
- // Disable the All button if we're already showing all
9780
- isAllButAlreadyShowingAll = false, isSameRange = range === actualRange;
9781
- if (isSelected && isTooGreatRange) {
9782
- isSelectedTooGreat = true;
9783
- }
9784
- // Months and years have a variable range so we check the extremes
9785
- if ((type === 'month' || type === 'year') &&
9786
- (actualRange + 36e5 >=
9787
- { month: 28, year: 365 }[type] * day * count - offsetRange) &&
9788
- (actualRange - 36e5 <=
9789
- { month: 31, year: 366 }[type] * day * count + offsetRange)) {
9790
- isSameRange = true;
9791
- }
9792
- else if (type === 'ytd') {
9793
- isSameRange = (ytdMax - ytdMin + offsetRange) === actualRange;
9794
- isYTDButNotSelected = !isSelected;
9795
- }
9796
- else if (type === 'all') {
9797
- isSameRange = (baseAxis.max - baseAxis.min >=
9798
- dataMax - dataMin);
9799
- isAllButAlreadyShowingAll = (!isSelected &&
9800
- selectedExists &&
9801
- isSameRange);
9802
- }
9803
- // The new zoom area happens to match the range for a button - mark
9804
- // it selected. This happens when scrolling across an ordinal gap.
9805
- // It can be seen in the intraday demos when selecting 1h and scroll
9806
- // across the night gap.
9807
- const disable = (!allButtonsEnabled &&
9808
- !(isSelectedTooGreat && type === 'all') &&
9809
- (isTooGreatRange ||
9810
- isTooSmallRange ||
9811
- isAllButAlreadyShowingAll ||
9812
- hasNoData));
9813
- const select = ((isSelectedTooGreat && type === 'all') ||
9814
- (isSelected && isSameRange) ||
9815
- (isSameRange && !selectedExists && !isYTDButNotSelected) ||
9816
- (isSelected && rangeSelector.frozenStates));
9817
- if (disable) {
9818
- state = 3;
9819
- }
9820
- else if (select) {
9821
- selectedExists = true; // Only one button can be selected
9822
- state = 2;
9823
- }
9824
- // If state has changed, update the button
9825
- if (button.state !== state) {
9826
- button.setState(state);
9827
- if (dropdown) {
9828
- dropdown.options[i + 1].disabled = disable;
9829
- if (state === 2) {
9830
- dropdown.selectedIndex = i + 1;
9831
- }
9832
- }
9833
- // Reset (#9209)
9834
- if (state === 0 && selected === i) {
9835
- rangeSelector.setSelected();
9836
- }
9837
- else if ((state === 2 && !defined(selected)) ||
9838
- isSelectedTooGreat) {
9839
- rangeSelector.setSelected(i);
9840
- }
9841
- }
9842
- });
9843
- }
9844
- /**
9845
- * Compute and cache the range for an individual button
9846
- *
9847
- * @private
9848
- * @function Highcharts.RangeSelector#computeButtonRange
9849
- * @param {Highcharts.RangeSelectorButtonsOptions} rangeOptions
9850
- */
9851
- computeButtonRange(rangeOptions) {
9852
- const type = rangeOptions.type, count = rangeOptions.count || 1,
9853
- // these time intervals have a fixed number of milliseconds, as
9854
- // opposed to month, ytd and year
9855
- fixedTimes = {
9856
- millisecond: 1,
9857
- second: 1000,
9858
- minute: 60 * 1000,
9859
- hour: 3600 * 1000,
9860
- day: 24 * 3600 * 1000,
9861
- week: 7 * 24 * 3600 * 1000
9862
- };
9863
- // Store the range on the button object
9864
- if (fixedTimes[type]) {
9865
- rangeOptions._range = fixedTimes[type] * count;
9866
- }
9867
- else if (type === 'month' || type === 'year') {
9868
- rangeOptions._range = {
9869
- month: 30,
9870
- year: 365
9871
- }[type] * 24 * 36e5 * count;
9872
- }
9873
- rangeOptions._offsetMin = pick(rangeOptions.offsetMin, 0);
9874
- rangeOptions._offsetMax = pick(rangeOptions.offsetMax, 0);
9875
- rangeOptions._range +=
9876
- rangeOptions._offsetMax - rangeOptions._offsetMin;
9877
- }
9878
- /**
9879
- * Get the unix timestamp of a HTML input for the dates
9880
- *
9881
- * @private
9882
- * @function Highcharts.RangeSelector#getInputValue
9883
- */
9884
- getInputValue(name) {
9885
- const input = name === 'min' ? this.minInput : this.maxInput;
9886
- const options = this.chart.options
9887
- .rangeSelector;
9888
- const time = this.chart.time;
9889
- if (input) {
9890
- return ((input.type === 'text' && options.inputDateParser) ||
9891
- this.defaultInputDateParser)(input.value, time.useUTC, time);
9892
- }
9893
- return 0;
9894
- }
9895
- /**
9896
- * Set the internal and displayed value of a HTML input for the dates
9897
- *
9898
- * @private
9899
- * @function Highcharts.RangeSelector#setInputValue
9900
- */
9901
- setInputValue(name, inputTime) {
9902
- const options = this.options, time = this.chart.time, input = name === 'min' ? this.minInput : this.maxInput, dateBox = name === 'min' ? this.minDateBox : this.maxDateBox;
9903
- if (input) {
9904
- const hcTimeAttr = input.getAttribute('data-hc-time');
9905
- let updatedTime = defined(hcTimeAttr) ? Number(hcTimeAttr) : void 0;
9906
- if (defined(inputTime)) {
9907
- const previousTime = updatedTime;
9908
- if (defined(previousTime)) {
9909
- input.setAttribute('data-hc-time-previous', previousTime);
9910
- }
9911
- input.setAttribute('data-hc-time', inputTime);
9912
- updatedTime = inputTime;
9913
- }
9914
- input.value = time.dateFormat((this.inputTypeFormats[input.type] ||
9915
- options.inputEditDateFormat), updatedTime);
9916
- if (dateBox) {
9917
- dateBox.attr({
9918
- text: time.dateFormat(options.inputDateFormat, updatedTime)
9919
- });
9920
- }
9921
- }
9922
- }
9923
- /**
9924
- * Set the min and max value of a HTML input for the dates
9925
- *
9926
- * @private
9927
- * @function Highcharts.RangeSelector#setInputExtremes
9928
- */
9929
- setInputExtremes(name, min, max) {
9930
- const input = name === 'min' ? this.minInput : this.maxInput;
9931
- if (input) {
9932
- const format = this.inputTypeFormats[input.type];
9933
- const time = this.chart.time;
9934
- if (format) {
9935
- const newMin = time.dateFormat(format, min);
9936
- if (input.min !== newMin) {
9937
- input.min = newMin;
9938
- }
9939
- const newMax = time.dateFormat(format, max);
9940
- if (input.max !== newMax) {
9941
- input.max = newMax;
9942
- }
9943
- }
9944
- }
9945
- }
9946
- /**
9947
- * @private
9948
- * @function Highcharts.RangeSelector#showInput
9949
- * @param {string} name
9950
- */
9951
- showInput(name) {
9952
- const dateBox = name === 'min' ? this.minDateBox : this.maxDateBox, input = name === 'min' ? this.minInput : this.maxInput;
9953
- if (input && dateBox && this.inputGroup) {
9954
- const isTextInput = input.type === 'text', { translateX = 0, translateY = 0 } = this.inputGroup, { x = 0, width = 0, height = 0 } = dateBox, { inputBoxWidth } = this.options;
9955
- css(input, {
9956
- width: isTextInput ?
9957
- ((width + (inputBoxWidth ? -2 : 20)) + 'px') :
9958
- 'auto',
9959
- height: (height - 2) + 'px',
9960
- border: '2px solid silver'
9961
- });
9962
- if (isTextInput && inputBoxWidth) {
9963
- css(input, {
9964
- left: (translateX + x) + 'px',
9965
- top: translateY + 'px'
9966
- });
9967
- // Inputs of types date, time or datetime-local should be centered
9968
- // on top of the dateBox
9969
- }
9970
- else {
9971
- css(input, {
9972
- left: Math.min(Math.round(x +
9973
- translateX -
9974
- (input.offsetWidth - width) / 2), this.chart.chartWidth - input.offsetWidth) + 'px',
9975
- top: (translateY - (input.offsetHeight - height) / 2) + 'px'
9976
- });
9977
- }
9978
- }
9979
- }
9980
- /**
9981
- * @private
9982
- * @function Highcharts.RangeSelector#hideInput
9983
- * @param {string} name
9984
- */
9985
- hideInput(name) {
9986
- const input = name === 'min' ? this.minInput : this.maxInput;
9987
- if (input) {
9988
- css(input, {
9989
- top: '-9999em',
9990
- border: 0,
9991
- width: '1px',
9992
- height: '1px'
9993
- });
9994
- }
9995
- }
9996
- /**
9997
- * @private
9998
- * @function Highcharts.RangeSelector#defaultInputDateParser
9999
- */
10000
- defaultInputDateParser(inputDate, useUTC, time) {
10001
- const hasTimezone = (str) => str.length > 6 &&
10002
- (str.lastIndexOf('-') === str.length - 6 ||
10003
- str.lastIndexOf('+') === str.length - 6);
10004
- let input = inputDate.split('/').join('-').split(' ').join('T');
10005
- if (input.indexOf('T') === -1) {
10006
- input += 'T00:00';
10007
- }
10008
- if (useUTC) {
10009
- input += 'Z';
10010
- }
10011
- else if (H.isSafari && !hasTimezone(input)) {
10012
- const offset = new Date(input).getTimezoneOffset() / 60;
10013
- input += offset <= 0 ? `+${pad(-offset)}:00` : `-${pad(offset)}:00`;
10014
- }
10015
- let date = Date.parse(input);
10016
- // If the value isn't parsed directly to a value by the
10017
- // browser's Date.parse method, try
10018
- // parsing it a different way
10019
- if (!isNumber(date)) {
10020
- const parts = inputDate.split('-');
10021
- date = Date.UTC(pInt(parts[0]), pInt(parts[1]) - 1, pInt(parts[2]));
10022
- }
10023
- if (time && useUTC && isNumber(date)) {
10024
- date += time.getTimezoneOffset(date);
10025
- }
10026
- return date;
10027
- }
10028
- /**
10029
- * Draw either the 'from' or the 'to' HTML input box of the range selector
10030
- *
10031
- * @private
10032
- * @function Highcharts.RangeSelector#drawInput
10033
- */
10034
- drawInput(name) {
10035
- const { chart, div, inputGroup } = this;
10036
- const rangeSelector = this, chartStyle = chart.renderer.style || {}, renderer = chart.renderer, options = chart.options.rangeSelector, lang = defaultOptions.lang, isMin = name === 'min';
10037
- /**
10038
- * @private
10039
- */
10040
- function updateExtremes() {
10041
- const { maxInput, minInput } = rangeSelector, chartAxis = chart.xAxis[0], unionExtremes = (chart.scroller && chart.scroller.getUnionExtremes()) || chartAxis, dataMin = unionExtremes.dataMin, dataMax = unionExtremes.dataMax;
10042
- let value = rangeSelector.getInputValue(name);
10043
- if (value !== Number(input.getAttribute('data-hc-time-previous')) &&
10044
- isNumber(value)) {
10045
- input.setAttribute('data-hc-time-previous', value);
10046
- // Validate the extremes. If it goes beyound the data min or
10047
- // max, use the actual data extreme (#2438).
10048
- if (isMin && maxInput && isNumber(dataMin)) {
10049
- if (value > Number(maxInput.getAttribute('data-hc-time'))) {
10050
- value = void 0;
10051
- }
10052
- else if (value < dataMin) {
10053
- value = dataMin;
10054
- }
10055
- }
10056
- else if (minInput && isNumber(dataMax)) {
10057
- if (value < Number(minInput.getAttribute('data-hc-time'))) {
10058
- value = void 0;
10059
- }
10060
- else if (value > dataMax) {
10061
- value = dataMax;
10062
- }
10063
- }
10064
- // Set the extremes
10065
- if (typeof value !== 'undefined') { // @todo typof undefined
10066
- chartAxis.setExtremes(isMin ? value : chartAxis.min, isMin ? chartAxis.max : value, void 0, void 0, { trigger: 'rangeSelectorInput' });
10067
- }
10068
- }
10069
- }
10070
- // Create the text label
10071
- const text = lang[isMin ? 'rangeSelectorFrom' : 'rangeSelectorTo'] || '';
10072
- const label = renderer
10073
- .label(text, 0)
10074
- .addClass('highcharts-range-label')
10075
- .attr({
10076
- padding: text ? 2 : 0,
10077
- height: text ? options.inputBoxHeight : 0
10078
- })
10079
- .add(inputGroup);
10080
- // Create an SVG label that shows updated date ranges and and records
10081
- // click events that bring in the HTML input.
10082
- const dateBox = renderer
10083
- .label('', 0)
10084
- .addClass('highcharts-range-input')
10085
- .attr({
10086
- padding: 2,
10087
- width: options.inputBoxWidth,
10088
- height: options.inputBoxHeight,
10089
- 'text-align': 'center'
10090
- })
10091
- .on('click', function () {
10092
- // If it is already focused, the onfocus event doesn't fire
10093
- // (#3713)
10094
- rangeSelector.showInput(name);
10095
- rangeSelector[name + 'Input'].focus();
10096
- });
10097
- if (!chart.styledMode) {
10098
- dateBox.attr({
10099
- stroke: options.inputBoxBorderColor,
10100
- 'stroke-width': 1
10101
- });
10102
- }
10103
- dateBox.add(inputGroup);
10104
- // Create the HTML input element. This is rendered as 1x1 pixel then set
10105
- // to the right size when focused.
10106
- const input = createElement('input', {
10107
- name: name,
10108
- className: 'highcharts-range-selector'
10109
- }, void 0, div);
10110
- // #14788: Setting input.type to an unsupported type throws in IE, so
10111
- // we need to use setAttribute instead
10112
- input.setAttribute('type', preferredInputType(options.inputDateFormat || '%e %b %Y'));
10113
- if (!chart.styledMode) {
10114
- // Styles
10115
- label.css(merge(chartStyle, options.labelStyle));
10116
- dateBox.css(merge({
10117
- color: "#333333" /* Palette.neutralColor80 */
10118
- }, chartStyle, options.inputStyle));
10119
- css(input, extend({
10120
- position: 'absolute',
10121
- border: 0,
10122
- boxShadow: '0 0 15px rgba(0,0,0,0.3)',
10123
- width: '1px',
10124
- height: '1px',
10125
- padding: 0,
10126
- textAlign: 'center',
10127
- fontSize: chartStyle.fontSize,
10128
- fontFamily: chartStyle.fontFamily,
10129
- top: '-9999em' // #4798
10130
- }, options.inputStyle));
10131
- }
10132
- // Blow up the input box
10133
- input.onfocus = () => {
10134
- rangeSelector.showInput(name);
10135
- };
10136
- // Hide away the input box
10137
- input.onblur = () => {
10138
- // update extermes only when inputs are active
10139
- if (input === H.doc.activeElement) { // Only when focused
10140
- // Update also when no `change` event is triggered, like when
10141
- // clicking inside the SVG (#4710)
10142
- updateExtremes();
10143
- }
10144
- // #10404 - move hide and blur outside focus
10145
- rangeSelector.hideInput(name);
10146
- rangeSelector.setInputValue(name);
10147
- input.blur(); // #4606
10148
- };
10149
- let keyDown = false;
10150
- // handle changes in the input boxes
10151
- input.onchange = () => {
10152
- // Update extremes and blur input when clicking date input calendar
10153
- if (!keyDown) {
10154
- updateExtremes();
10155
- rangeSelector.hideInput(name);
10156
- input.blur();
10157
- }
10158
- };
10159
- input.onkeypress = (event) => {
10160
- // IE does not fire onchange on enter
10161
- if (event.keyCode === 13) {
10162
- updateExtremes();
10163
- }
10164
- };
10165
- input.onkeydown = (event) => {
10166
- keyDown = true;
10167
- // Arrow keys
10168
- if (event.keyCode === 38 || event.keyCode === 40) {
10169
- updateExtremes();
10170
- }
10171
- };
10172
- input.onkeyup = () => {
10173
- keyDown = false;
10174
- };
10175
- return { dateBox, input, label };
10176
- }
10177
- /**
10178
- * Get the position of the range selector buttons and inputs. This can be
10179
- * overridden from outside for custom positioning.
10180
- *
10181
- * @private
10182
- * @function Highcharts.RangeSelector#getPosition
10183
- */
10184
- getPosition() {
10185
- const chart = this.chart, options = chart.options.rangeSelector, top = options.verticalAlign === 'top' ?
10186
- chart.plotTop - chart.axisOffset[0] :
10187
- 0; // set offset only for varticalAlign top
10188
- return {
10189
- buttonTop: top + options.buttonPosition.y,
10190
- inputTop: top + options.inputPosition.y - 10
10191
- };
10192
- }
10193
- /**
10194
- * Get the extremes of YTD. Will choose dataMax if its value is lower than
10195
- * the current timestamp. Will choose dataMin if its value is higher than
10196
- * the timestamp for the start of current year.
10197
- *
10198
- * @private
10199
- * @function Highcharts.RangeSelector#getYTDExtremes
10200
- * @return {*}
10201
- * Returns min and max for the YTD
10202
- */
10203
- getYTDExtremes(dataMax, dataMin, useUTC) {
10204
- const time = this.chart.time, now = new time.Date(dataMax), year = time.get('FullYear', now), startOfYear = useUTC ?
10205
- time.Date.UTC(year, 0, 1) : // eslint-disable-line new-cap
10206
- +new time.Date(year, 0, 1), min = Math.max(dataMin, startOfYear), ts = now.getTime();
10207
- return {
10208
- max: Math.min(dataMax || ts, ts),
10209
- min
10210
- };
10211
- }
10212
- /**
10213
- * Render the range selector including the buttons and the inputs. The first
10214
- * time render is called, the elements are created and positioned. On
10215
- * subsequent calls, they are moved and updated.
10216
- *
10217
- * @private
10218
- * @function Highcharts.RangeSelector#render
10219
- * @param {number} [min]
10220
- * X axis minimum
10221
- * @param {number} [max]
10222
- * X axis maximum
10223
- */
10224
- render(min, max) {
10225
- const chart = this.chart, renderer = chart.renderer, container = chart.container, chartOptions = chart.options, options = chartOptions.rangeSelector,
10226
- // Place inputs above the container
10227
- inputsZIndex = pick(chartOptions.chart.style &&
10228
- chartOptions.chart.style.zIndex, 0) + 1, inputEnabled = options.inputEnabled, rendered = this.rendered;
10229
- if (options.enabled === false) {
10230
- return;
10231
- }
10232
- // create the elements
10233
- if (!rendered) {
10234
- this.group = renderer.g('range-selector-group')
10235
- .attr({
10236
- zIndex: 7
10237
- })
10238
- .add();
10239
- this.div = createElement('div', void 0, {
10240
- position: 'relative',
10241
- height: 0,
10242
- zIndex: inputsZIndex
10243
- });
10244
- if (this.buttonOptions.length) {
10245
- this.renderButtons();
10246
- }
10247
- // First create a wrapper outside the container in order to make
10248
- // the inputs work and make export correct
10249
- if (container.parentNode) {
10250
- container.parentNode.insertBefore(this.div, container);
10251
- }
10252
- if (inputEnabled) {
10253
- // Create the group to keep the inputs
10254
- this.inputGroup = renderer.g('input-group').add(this.group);
10255
- const minElems = this.drawInput('min');
10256
- this.minDateBox = minElems.dateBox;
10257
- this.minLabel = minElems.label;
10258
- this.minInput = minElems.input;
10259
- const maxElems = this.drawInput('max');
10260
- this.maxDateBox = maxElems.dateBox;
10261
- this.maxLabel = maxElems.label;
10262
- this.maxInput = maxElems.input;
10263
- }
10264
- }
10265
- if (inputEnabled) {
10266
- // Set or reset the input values
10267
- this.setInputValue('min', min);
10268
- this.setInputValue('max', max);
10269
- const unionExtremes = (chart.scroller && chart.scroller.getUnionExtremes()) || chart.xAxis[0] || {};
10270
- if (defined(unionExtremes.dataMin) &&
10271
- defined(unionExtremes.dataMax)) {
10272
- const minRange = chart.xAxis[0].minRange || 0;
10273
- this.setInputExtremes('min', unionExtremes.dataMin, Math.min(unionExtremes.dataMax, this.getInputValue('max')) - minRange);
10274
- this.setInputExtremes('max', Math.max(unionExtremes.dataMin, this.getInputValue('min')) + minRange, unionExtremes.dataMax);
10275
- }
10276
- // Reflow
10277
- if (this.inputGroup) {
10278
- let x = 0;
10279
- [
10280
- this.minLabel,
10281
- this.minDateBox,
10282
- this.maxLabel,
10283
- this.maxDateBox
10284
- ].forEach((label) => {
10285
- if (label) {
10286
- const { width } = label.getBBox();
10287
- if (width) {
10288
- label.attr({ x });
10289
- x += width + options.inputSpacing;
10290
- }
10291
- }
10292
- });
10293
- }
10294
- }
10295
- this.alignElements();
10296
- this.rendered = true;
10297
- }
10298
- /**
10299
- * Render the range buttons. This only runs the first time, later the
10300
- * positioning is laid out in alignElements.
10301
- *
10302
- * @private
10303
- * @function Highcharts.RangeSelector#renderButtons
10304
- */
10305
- renderButtons() {
10306
- const { buttons, chart, options } = this;
10307
- const lang = defaultOptions.lang;
10308
- const renderer = chart.renderer;
10309
- const buttonTheme = merge(options.buttonTheme);
10310
- const states = buttonTheme && buttonTheme.states;
10311
- // Prevent the button from resetting the width when the button state
10312
- // changes since we need more control over the width when collapsing
10313
- // the buttons
10314
- const width = buttonTheme.width || 28;
10315
- delete buttonTheme.width;
10316
- delete buttonTheme.states;
10317
- this.buttonGroup = renderer.g('range-selector-buttons').add(this.group);
10318
- const dropdown = this.dropdown = createElement('select', void 0, {
10319
- position: 'absolute',
10320
- width: '1px',
10321
- height: '1px',
10322
- padding: 0,
10323
- border: 0,
10324
- top: '-9999em',
10325
- cursor: 'pointer',
10326
- opacity: 0.0001
10327
- }, this.div);
10328
- // Prevent page zoom on iPhone
10329
- addEvent(dropdown, 'touchstart', () => {
10330
- dropdown.style.fontSize = '16px';
10331
- });
10332
- // Forward events from select to button
10333
- [
10334
- [H.isMS ? 'mouseover' : 'mouseenter'],
10335
- [H.isMS ? 'mouseout' : 'mouseleave'],
10336
- ['change', 'click']
10337
- ].forEach(([from, to]) => {
10338
- addEvent(dropdown, from, () => {
10339
- const button = buttons[this.currentButtonIndex()];
10340
- if (button) {
10341
- fireEvent(button.element, to || from);
10342
- }
10343
- });
10344
- });
10345
- this.zoomText = renderer
10346
- .label((lang && lang.rangeSelectorZoom) || '', 0)
10347
- .attr({
10348
- padding: options.buttonTheme.padding,
10349
- height: options.buttonTheme.height,
10350
- paddingLeft: 0,
10351
- paddingRight: 0
10352
- })
10353
- .add(this.buttonGroup);
10354
- if (!this.chart.styledMode) {
10355
- this.zoomText.css(options.labelStyle);
10356
- buttonTheme['stroke-width'] = pick(buttonTheme['stroke-width'], 0);
10357
- }
10358
- createElement('option', {
10359
- textContent: this.zoomText.textStr,
10360
- disabled: true
10361
- }, void 0, dropdown);
10362
- this.buttonOptions.forEach((rangeOptions, i) => {
10363
- createElement('option', {
10364
- textContent: rangeOptions.title || rangeOptions.text
10365
- }, void 0, dropdown);
10366
- buttons[i] = renderer
10367
- .button(rangeOptions.text, 0, 0, (e) => {
10368
- // extract events from button object and call
10369
- const buttonEvents = (rangeOptions.events && rangeOptions.events.click);
10370
- let callDefaultEvent;
10371
- if (buttonEvents) {
10372
- callDefaultEvent =
10373
- buttonEvents.call(rangeOptions, e);
10374
- }
10375
- if (callDefaultEvent !== false) {
10376
- this.clickButton(i);
10377
- }
10378
- this.isActive = true;
10379
- }, buttonTheme, states && states.hover, states && states.select, states && states.disabled)
10380
- .attr({
10381
- 'text-align': 'center',
10382
- width
10383
- })
10384
- .add(this.buttonGroup);
10385
- if (rangeOptions.title) {
10386
- buttons[i].attr('title', rangeOptions.title);
10387
- }
10388
- });
10389
- }
10390
- /**
10391
- * Align the elements horizontally and vertically.
10392
- *
10393
- * @private
10394
- * @function Highcharts.RangeSelector#alignElements
10395
- */
10396
- alignElements() {
10397
- const { buttonGroup, buttons, chart, group, inputGroup, options, zoomText } = this;
10398
- const chartOptions = chart.options;
10399
- const navButtonOptions = (chartOptions.exporting &&
10400
- chartOptions.exporting.enabled !== false &&
10401
- chartOptions.navigation &&
10402
- chartOptions.navigation.buttonOptions);
10403
- const { buttonPosition, inputPosition, verticalAlign } = options;
10404
- // Get the X offset required to avoid overlapping with the exporting
10405
- // button. This is is used both by the buttonGroup and the inputGroup.
10406
- const getXOffsetForExportButton = (group, position) => {
10407
- if (navButtonOptions &&
10408
- this.titleCollision(chart) &&
10409
- verticalAlign === 'top' &&
10410
- position.align === 'right' && ((position.y -
10411
- group.getBBox().height - 12) <
10412
- ((navButtonOptions.y || 0) +
10413
- (navButtonOptions.height || 0) +
10414
- chart.spacing[0]))) {
10415
- return -40;
10416
- }
10417
- return 0;
10418
- };
10419
- let plotLeft = chart.plotLeft;
10420
- if (group && buttonPosition && inputPosition) {
10421
- let translateX = buttonPosition.x - chart.spacing[3];
10422
- if (buttonGroup) {
10423
- this.positionButtons();
10424
- if (!this.initialButtonGroupWidth) {
10425
- let width = 0;
10426
- if (zoomText) {
10427
- width += zoomText.getBBox().width + 5;
10428
- }
10429
- buttons.forEach((button, i) => {
10430
- width += button.width || 0;
10431
- if (i !== buttons.length - 1) {
10432
- width += options.buttonSpacing;
10433
- }
10434
- });
10435
- this.initialButtonGroupWidth = width;
10436
- }
10437
- plotLeft -= chart.spacing[3];
10438
- this.updateButtonStates();
10439
- // Detect collision between button group and exporting
10440
- const xOffsetForExportButton = getXOffsetForExportButton(buttonGroup, buttonPosition);
10441
- this.alignButtonGroup(xOffsetForExportButton);
10442
- // Skip animation
10443
- group.placed = buttonGroup.placed = chart.hasLoaded;
10444
- }
10445
- let xOffsetForExportButton = 0;
10446
- if (inputGroup) {
10447
- // Detect collision between the input group and exporting button
10448
- xOffsetForExportButton = getXOffsetForExportButton(inputGroup, inputPosition);
10449
- if (inputPosition.align === 'left') {
10450
- translateX = plotLeft;
10451
- }
10452
- else if (inputPosition.align === 'right') {
10453
- translateX = -Math.max(chart.axisOffset[1], -xOffsetForExportButton);
10454
- }
10455
- // Update the alignment to the updated spacing box
10456
- inputGroup.align({
10457
- y: inputPosition.y,
10458
- width: inputGroup.getBBox().width,
10459
- align: inputPosition.align,
10460
- // fix wrong getBBox() value on right align
10461
- x: inputPosition.x + translateX - 2
10462
- }, true, chart.spacingBox);
10463
- // Skip animation
10464
- inputGroup.placed = chart.hasLoaded;
10465
- }
10466
- this.handleCollision(xOffsetForExportButton);
10467
- // Vertical align
10468
- group.align({
10469
- verticalAlign
10470
- }, true, chart.spacingBox);
10471
- const alignTranslateY = group.alignAttr.translateY;
10472
- // Set position
10473
- let groupHeight = group.getBBox().height + 20; // # 20 padding
10474
- let translateY = 0;
10475
- // Calculate bottom position
10476
- if (verticalAlign === 'bottom') {
10477
- const legendOptions = chart.legend && chart.legend.options;
10478
- const legendHeight = (legendOptions &&
10479
- legendOptions.verticalAlign === 'bottom' &&
10480
- legendOptions.enabled &&
10481
- !legendOptions.floating ?
10482
- (chart.legend.legendHeight +
10483
- pick(legendOptions.margin, 10)) :
10484
- 0);
10485
- groupHeight = groupHeight + legendHeight - 20;
10486
- translateY = (alignTranslateY -
10487
- groupHeight -
10488
- (options.floating ? 0 : options.y) -
10489
- (chart.titleOffset ? chart.titleOffset[2] : 0) -
10490
- 10 // 10 spacing
10491
- );
10492
- }
10493
- if (verticalAlign === 'top') {
10494
- if (options.floating) {
10495
- translateY = 0;
10496
- }
10497
- if (chart.titleOffset && chart.titleOffset[0]) {
10498
- translateY = chart.titleOffset[0];
10499
- }
10500
- translateY += ((chart.margin[0] - chart.spacing[0]) || 0);
10501
- }
10502
- else if (verticalAlign === 'middle') {
10503
- if (inputPosition.y === buttonPosition.y) {
10504
- translateY = alignTranslateY;
10505
- }
10506
- else if (inputPosition.y || buttonPosition.y) {
10507
- if (inputPosition.y < 0 ||
10508
- buttonPosition.y < 0) {
10509
- translateY -= Math.min(inputPosition.y, buttonPosition.y);
10510
- }
10511
- else {
10512
- translateY = alignTranslateY - groupHeight;
10513
- }
10514
- }
10515
- }
10516
- group.translate(options.x, options.y + Math.floor(translateY));
10517
- // Translate HTML inputs
10518
- const { minInput, maxInput, dropdown } = this;
10519
- if (options.inputEnabled && minInput && maxInput) {
10520
- minInput.style.marginTop = group.translateY + 'px';
10521
- maxInput.style.marginTop = group.translateY + 'px';
10522
- }
10523
- if (dropdown) {
10524
- dropdown.style.marginTop = group.translateY + 'px';
10525
- }
10526
- }
10527
- }
10528
- /**
10529
- * Align the button group horizontally and vertically.
10530
- *
10531
- * @private
10532
- * @function Highcharts.RangeSelector#alignButtonGroup
10533
- * @param {number} xOffsetForExportButton
10534
- * @param {number} [width]
10535
- */
10536
- alignButtonGroup(xOffsetForExportButton, width) {
10537
- const { chart, options, buttonGroup, buttons } = this;
10538
- const { buttonPosition } = options;
10539
- const plotLeft = chart.plotLeft - chart.spacing[3];
10540
- let translateX = buttonPosition.x - chart.spacing[3];
10541
- if (buttonPosition.align === 'right') {
10542
- translateX += xOffsetForExportButton - plotLeft; // #13014
10543
- }
10544
- else if (buttonPosition.align === 'center') {
10545
- translateX -= plotLeft / 2;
10546
- }
10547
- if (buttonGroup) {
10548
- // Align button group
10549
- buttonGroup.align({
10550
- y: buttonPosition.y,
10551
- width: pick(width, this.initialButtonGroupWidth),
10552
- align: buttonPosition.align,
10553
- x: translateX
10554
- }, true, chart.spacingBox);
10555
- }
10556
- }
10557
- /**
10558
- * @private
10559
- * @function Highcharts.RangeSelector#positionButtons
10560
- */
10561
- positionButtons() {
10562
- const { buttons, chart, options, zoomText } = this;
10563
- const verb = chart.hasLoaded ? 'animate' : 'attr';
10564
- const { buttonPosition } = options;
10565
- const plotLeft = chart.plotLeft;
10566
- let buttonLeft = plotLeft;
10567
- if (zoomText && zoomText.visibility !== 'hidden') {
10568
- // #8769, allow dynamically updating margins
10569
- zoomText[verb]({
10570
- x: pick(plotLeft + buttonPosition.x, plotLeft)
10571
- });
10572
- // Button start position
10573
- buttonLeft += buttonPosition.x +
10574
- zoomText.getBBox().width + 5;
10575
- }
10576
- for (let i = 0, iEnd = this.buttonOptions.length; i < iEnd; ++i) {
10577
- if (buttons[i].visibility !== 'hidden') {
10578
- buttons[i][verb]({ x: buttonLeft });
10579
- // Increase the button position for the next button
10580
- buttonLeft += (buttons[i].width || 0) + options.buttonSpacing;
10581
- }
10582
- else {
10583
- buttons[i][verb]({ x: plotLeft });
10584
- }
10585
- }
10586
- }
10587
- /**
10588
- * Handle collision between the button group and the input group
10589
- *
10590
- * @private
10591
- * @function Highcharts.RangeSelector#handleCollision
10592
- *
10593
- * @param {number} xOffsetForExportButton
10594
- * The X offset of the group required to make room for the
10595
- * exporting button
10596
- */
10597
- handleCollision(xOffsetForExportButton) {
10598
- const { chart, buttonGroup, inputGroup } = this;
10599
- const { buttonPosition, dropdown, inputPosition } = this.options;
10600
- const maxButtonWidth = () => {
10601
- let buttonWidth = 0;
10602
- this.buttons.forEach((button) => {
10603
- const bBox = button.getBBox();
10604
- if (bBox.width > buttonWidth) {
10605
- buttonWidth = bBox.width;
10606
- }
10607
- });
10608
- return buttonWidth;
10609
- };
10610
- const groupsOverlap = (buttonGroupWidth) => {
10611
- if (inputGroup && buttonGroup) {
10612
- const inputGroupX = (inputGroup.alignAttr.translateX +
10613
- inputGroup.alignOptions.x -
10614
- xOffsetForExportButton +
10615
- // getBBox for detecing left margin
10616
- inputGroup.getBBox().x +
10617
- // 2px padding to not overlap input and label
10618
- 2);
10619
- const inputGroupWidth = inputGroup.alignOptions.width;
10620
- const buttonGroupX = buttonGroup.alignAttr.translateX +
10621
- buttonGroup.getBBox().x;
10622
- return (buttonGroupX + buttonGroupWidth > inputGroupX) &&
10623
- (inputGroupX + inputGroupWidth > buttonGroupX) &&
10624
- (buttonPosition.y <
10625
- (inputPosition.y +
10626
- inputGroup.getBBox().height));
10627
- }
10628
- return false;
10629
- };
10630
- const moveInputsDown = () => {
10631
- if (inputGroup && buttonGroup) {
10632
- inputGroup.attr({
10633
- translateX: inputGroup.alignAttr.translateX + (chart.axisOffset[1] >= -xOffsetForExportButton ?
10634
- 0 :
10635
- -xOffsetForExportButton),
10636
- translateY: inputGroup.alignAttr.translateY +
10637
- buttonGroup.getBBox().height + 10
10638
- });
10639
- }
10640
- };
10641
- if (buttonGroup) {
10642
- if (dropdown === 'always') {
10643
- this.collapseButtons(xOffsetForExportButton);
10644
- if (groupsOverlap(maxButtonWidth())) {
10645
- // Move the inputs down if there is still a collision
10646
- // after collapsing the buttons
10647
- moveInputsDown();
10648
- }
10649
- return;
10650
- }
10651
- if (dropdown === 'never') {
10652
- this.expandButtons();
10653
- }
10654
- }
10655
- // Detect collision
10656
- if (inputGroup && buttonGroup) {
10657
- if ((inputPosition.align === buttonPosition.align) ||
10658
- // 20 is minimal spacing between elements
10659
- groupsOverlap(this.initialButtonGroupWidth + 20)) {
10660
- if (dropdown === 'responsive') {
10661
- this.collapseButtons(xOffsetForExportButton);
10662
- if (groupsOverlap(maxButtonWidth())) {
10663
- moveInputsDown();
10664
- }
10665
- }
10666
- else {
10667
- moveInputsDown();
10668
- }
10669
- }
10670
- else if (dropdown === 'responsive') {
10671
- this.expandButtons();
10672
- }
10673
- }
10674
- else if (buttonGroup && dropdown === 'responsive') {
10675
- if (this.initialButtonGroupWidth > chart.plotWidth) {
10676
- this.collapseButtons(xOffsetForExportButton);
10677
- }
10678
- else {
10679
- this.expandButtons();
10680
- }
8612
+ proxyContainerElement: proxyContainer,
8613
+ groupElement,
8614
+ type: groupElementType,
8615
+ proxyElements: []
8616
+ };
8617
+ attr(groupElement, attributes || {});
8618
+ if (groupElementType === 'ul') {
8619
+ proxyContainer.setAttribute('role', 'list'); // Needed for webkit
10681
8620
  }
8621
+ // Add the group to the end by default, and perhaps then we
8622
+ // won't have to reorder the whole set of groups.
8623
+ this.afterChartProxyPosContainer.appendChild(groupElement);
8624
+ this.updateGroupOrder(this.groupOrder);
8625
+ return groupElement;
10682
8626
  }
10683
8627
  /**
10684
- * Collapse the buttons and put the select element on top.
10685
- *
10686
- * @private
10687
- * @function Highcharts.RangeSelector#collapseButtons
10688
- * @param {number} xOffsetForExportButton
8628
+ * Update HTML attributes of a group.
10689
8629
  */
10690
- collapseButtons(xOffsetForExportButton) {
10691
- const { buttons, buttonOptions, chart, dropdown, options, zoomText } = this;
10692
- // If the buttons are already collapsed do nothing.
10693
- if (this.isCollapsed === true) {
10694
- return;
10695
- }
10696
- this.isCollapsed = true;
10697
- const userButtonTheme = (chart.userOptions.rangeSelector &&
10698
- chart.userOptions.rangeSelector.buttonTheme) || {};
10699
- const getAttribs = (text) => ({
10700
- text: text ? `${text} ▾` : '▾',
10701
- width: 'auto',
10702
- paddingLeft: pick(options.buttonTheme.paddingLeft, userButtonTheme.padding, 8),
10703
- paddingRight: pick(options.buttonTheme.paddingRight, userButtonTheme.padding, 8)
10704
- });
10705
- if (zoomText) {
10706
- zoomText.hide();
10707
- }
10708
- let hasActiveButton = false;
10709
- buttonOptions.forEach((rangeOptions, i) => {
10710
- const button = buttons[i];
10711
- if (button.state !== 2) {
10712
- button.hide();
10713
- }
10714
- else {
10715
- button.show();
10716
- button.attr(getAttribs(rangeOptions.text));
10717
- hasActiveButton = true;
10718
- }
10719
- });
10720
- if (!hasActiveButton) {
10721
- if (dropdown) {
10722
- dropdown.selectedIndex = 0;
10723
- }
10724
- buttons[0].show();
10725
- buttons[0].attr(getAttribs(this.zoomText && this.zoomText.textStr));
10726
- }
10727
- const { align } = options.buttonPosition;
10728
- this.positionButtons();
10729
- if (align === 'right' || align === 'center') {
10730
- this.alignButtonGroup(xOffsetForExportButton, buttons[this.currentButtonIndex()].getBBox().width);
8630
+ updateGroupAttrs(groupKey, attributes) {
8631
+ const group = this.groups[groupKey];
8632
+ if (!group) {
8633
+ throw new Error('ProxyProvider.updateGroupAttrs: Invalid group key ' + groupKey);
10731
8634
  }
10732
- this.showDropdown();
8635
+ attr(group.groupElement, attributes);
10733
8636
  }
10734
8637
  /**
10735
- * Show all the buttons and hide the select element.
8638
+ * Reorder the proxy groups.
10736
8639
  *
10737
- * @private
10738
- * @function Highcharts.RangeSelector#expandButtons
8640
+ * The group key "series" refers to the chart's data points / <svg> element.
8641
+ * This is so that the keyboardNavigation.order option can be used to
8642
+ * determine the proxy group order.
10739
8643
  */
10740
- expandButtons() {
10741
- const { buttons, buttonOptions, options, zoomText } = this;
10742
- this.hideDropdown();
10743
- // If buttons are already not collapsed, do nothing.
10744
- if (this.isCollapsed === false) {
8644
+ updateGroupOrder(groupKeys) {
8645
+ // Store so that we can update order when a new group is created
8646
+ this.groupOrder = groupKeys.slice();
8647
+ // Don't unnecessarily reorder, because keyboard focus is lost
8648
+ if (this.isDOMOrderGroupOrder()) {
10745
8649
  return;
10746
8650
  }
10747
- this.isCollapsed = false;
10748
- if (zoomText) {
10749
- zoomText.show();
10750
- }
10751
- buttonOptions.forEach((rangeOptions, i) => {
10752
- const button = buttons[i];
10753
- button.show();
10754
- button.attr({
10755
- text: rangeOptions.text,
10756
- width: options.buttonTheme.width || 28,
10757
- paddingLeft: pick(options.buttonTheme.paddingLeft, 'unset'),
10758
- paddingRight: pick(options.buttonTheme.paddingRight, 'unset')
8651
+ const seriesIx = groupKeys.indexOf('series');
8652
+ const beforeKeys = seriesIx > -1 ? groupKeys.slice(0, seriesIx) : groupKeys;
8653
+ const afterKeys = seriesIx > -1 ? groupKeys.slice(seriesIx + 1) : [];
8654
+ // Store focused element since it will be lost when reordering
8655
+ const activeElement = doc.activeElement;
8656
+ // Add groups to correct container
8657
+ ['before', 'after'].forEach((pos) => {
8658
+ const posContainer = this[pos === 'before' ?
8659
+ 'beforeChartProxyPosContainer' :
8660
+ 'afterChartProxyPosContainer'];
8661
+ const keys = pos === 'before' ? beforeKeys : afterKeys;
8662
+ removeChildNodes(posContainer);
8663
+ keys.forEach((groupKey) => {
8664
+ const group = this.groups[groupKey];
8665
+ if (group) {
8666
+ posContainer.appendChild(group.groupElement);
8667
+ }
10759
8668
  });
10760
- if (button.state < 2) {
10761
- button.setState(0);
10762
- }
10763
8669
  });
10764
- this.positionButtons();
8670
+ // Attempt to restore focus after reordering, but note that this may
8671
+ // cause screen readers re-announcing the button.
8672
+ if ((this.beforeChartProxyPosContainer.contains(activeElement) ||
8673
+ this.afterChartProxyPosContainer.contains(activeElement)) &&
8674
+ activeElement && activeElement.focus) {
8675
+ activeElement.focus();
8676
+ }
10765
8677
  }
10766
8678
  /**
10767
- * Get the index of the visible button when the buttons are collapsed.
10768
- *
10769
- * @private
10770
- * @function Highcharts.RangeSelector#currentButtonIndex
8679
+ * Remove all proxy elements in a group
10771
8680
  */
10772
- currentButtonIndex() {
10773
- const { dropdown } = this;
10774
- if (dropdown && dropdown.selectedIndex > 0) {
10775
- return dropdown.selectedIndex - 1;
8681
+ clearGroup(groupKey) {
8682
+ const group = this.groups[groupKey];
8683
+ if (!group) {
8684
+ throw new Error('ProxyProvider.clearGroup: Invalid group key ' + groupKey);
10776
8685
  }
10777
- return 0;
8686
+ removeChildNodes(group.proxyContainerElement);
10778
8687
  }
10779
8688
  /**
10780
- * Position the select element on top of the button.
10781
- *
10782
- * @private
10783
- * @function Highcharts.RangeSelector#showDropdown
8689
+ * Remove a group from the DOM and from the proxy provider's group list.
8690
+ * All child elements are removed.
8691
+ * If the group does not exist, nothing happens.
10784
8692
  */
10785
- showDropdown() {
10786
- const { buttonGroup, buttons, chart, dropdown } = this;
10787
- if (buttonGroup && dropdown) {
10788
- const { translateX = 0, translateY = 0 } = buttonGroup, bBox = buttons[this.currentButtonIndex()].getBBox();
10789
- css(dropdown, {
10790
- left: (chart.plotLeft + translateX) + 'px',
10791
- top: (translateY + 0.5) + 'px',
10792
- width: bBox.width + 'px',
10793
- height: bBox.height + 'px'
10794
- });
10795
- this.hasVisibleDropdown = true;
8693
+ removeGroup(groupKey) {
8694
+ const group = this.groups[groupKey];
8695
+ if (group) {
8696
+ // Remove detached HTML elements to prevent memory leak (#20329).
8697
+ this.domElementProvider.removeElement(group.groupElement);
8698
+ // Sometimes groupElement is a wrapper around the proxyContainer, so
8699
+ // the real one proxyContainer needs to be removed also.
8700
+ if (group.groupElement !== group.proxyContainerElement) {
8701
+ this.domElementProvider.removeElement(group.proxyContainerElement);
8702
+ }
8703
+ delete this.groups[groupKey];
10796
8704
  }
10797
8705
  }
10798
8706
  /**
10799
- * @private
10800
- * @function Highcharts.RangeSelector#hideDropdown
8707
+ * Update the position and order of all proxy groups and elements
10801
8708
  */
10802
- hideDropdown() {
10803
- const { dropdown } = this;
10804
- if (dropdown) {
10805
- css(dropdown, {
10806
- top: '-9999em',
10807
- width: '1px',
10808
- height: '1px'
10809
- });
10810
- this.hasVisibleDropdown = false;
10811
- }
8709
+ update() {
8710
+ this.updatePosContainerPositions();
8711
+ this.updateGroupOrder(this.groupOrder);
8712
+ this.updateProxyElementPositions();
10812
8713
  }
10813
8714
  /**
10814
- * Extracts height of range selector
10815
- *
10816
- * @private
10817
- * @function Highcharts.RangeSelector#getHeight
10818
- * @return {number}
10819
- * Returns rangeSelector height
8715
+ * Update all proxy element positions
10820
8716
  */
10821
- getHeight() {
10822
- const rangeSelector = this, options = rangeSelector.options, rangeSelectorGroup = rangeSelector.group, inputPosition = options.inputPosition, buttonPosition = options.buttonPosition, yPosition = options.y, buttonPositionY = buttonPosition.y, inputPositionY = inputPosition.y;
10823
- let rangeSelectorHeight = 0;
10824
- if (options.height) {
10825
- return options.height;
10826
- }
10827
- // Align the elements before we read the height in case we're switching
10828
- // between wrapped and non-wrapped layout
10829
- this.alignElements();
10830
- rangeSelectorHeight = rangeSelectorGroup ?
10831
- // 13px to keep back compatibility
10832
- (rangeSelectorGroup.getBBox(true).height) + 13 +
10833
- yPosition :
10834
- 0;
10835
- const minPosition = Math.min(inputPositionY, buttonPositionY);
10836
- if ((inputPositionY < 0 && buttonPositionY < 0) ||
10837
- (inputPositionY > 0 && buttonPositionY > 0)) {
10838
- rangeSelectorHeight += Math.abs(minPosition);
8717
+ updateProxyElementPositions() {
8718
+ Object.keys(this.groups).forEach(this.updateGroupProxyElementPositions.bind(this));
8719
+ }
8720
+ /**
8721
+ * Update a group's proxy elements' positions.
8722
+ * If the group does not exist, nothing happens.
8723
+ */
8724
+ updateGroupProxyElementPositions(groupKey) {
8725
+ const group = this.groups[groupKey];
8726
+ if (group) {
8727
+ group.proxyElements.forEach((el) => el.refreshPosition());
10839
8728
  }
10840
- return rangeSelectorHeight;
10841
8729
  }
10842
8730
  /**
10843
- * Detect collision with title or subtitle
10844
- *
10845
- * @private
10846
- * @function Highcharts.RangeSelector#titleCollision
10847
- * @return {boolean}
10848
- * Returns collision status
8731
+ * Remove all added elements
10849
8732
  */
10850
- titleCollision(chart) {
10851
- return !(chart.options.title.text ||
10852
- chart.options.subtitle.text);
8733
+ destroy() {
8734
+ this.domElementProvider.destroyCreatedElements();
10853
8735
  }
8736
+ // -------------------------- private ------------------------------------
10854
8737
  /**
10855
- * Update the range selector with new options
10856
- *
10857
- * @private
10858
- * @function Highcharts.RangeSelector#update
10859
- * @param {Highcharts.RangeSelectorOptions} options
8738
+ * Create and return a pos container element (the overall containers for
8739
+ * the proxy groups).
10860
8740
  */
10861
- update(options) {
10862
- const chart = this.chart;
10863
- merge(true, chart.options.rangeSelector, options);
10864
- this.destroy();
10865
- this.init(chart);
10866
- this.render();
8741
+ createProxyPosContainer(classNamePostfix) {
8742
+ const el = this.domElementProvider.createElement('div');
8743
+ el.setAttribute('aria-hidden', 'false');
8744
+ el.className = 'highcharts-a11y-proxy-container' + (classNamePostfix ? '-' + classNamePostfix : '');
8745
+ css(el, {
8746
+ top: '0',
8747
+ left: '0'
8748
+ });
8749
+ if (!this.chart.styledMode) {
8750
+ el.style.whiteSpace = 'nowrap';
8751
+ el.style.position = 'absolute';
8752
+ }
8753
+ return el;
10867
8754
  }
10868
8755
  /**
10869
- * Destroys allocated elements.
10870
- *
10871
- * @private
10872
- * @function Highcharts.RangeSelector#destroy
8756
+ * Get an array of group keys that corresponds to the current group order
8757
+ * in the DOM.
10873
8758
  */
10874
- destroy() {
10875
- const rSelector = this, minInput = rSelector.minInput, maxInput = rSelector.maxInput;
10876
- if (rSelector.eventsToUnbind) {
10877
- rSelector.eventsToUnbind.forEach((unbind) => unbind());
10878
- rSelector.eventsToUnbind = void 0;
10879
- }
10880
- // Destroy elements in collections
10881
- destroyObjectProperties(rSelector.buttons);
10882
- // Clear input element events
10883
- if (minInput) {
10884
- minInput.onfocus = minInput.onblur = minInput.onchange = null;
10885
- }
10886
- if (maxInput) {
10887
- maxInput.onfocus = maxInput.onblur = maxInput.onchange = null;
10888
- }
10889
- // Destroy HTML and SVG elements
10890
- objectEach(rSelector, function (val, key) {
10891
- if (val && key !== 'chart') {
10892
- if (val instanceof SVGElement) {
10893
- // SVGElement
10894
- val.destroy();
8759
+ getCurrentGroupOrderInDOM() {
8760
+ const getGroupKeyFromElement = (el) => {
8761
+ const allGroups = Object.keys(this.groups);
8762
+ let i = allGroups.length;
8763
+ while (i--) {
8764
+ const groupKey = allGroups[i];
8765
+ const group = this.groups[groupKey];
8766
+ if (group && el === group.groupElement) {
8767
+ return groupKey;
10895
8768
  }
10896
- else if (val instanceof window.HTMLElement) {
10897
- // HTML element
10898
- discardElement(val);
8769
+ }
8770
+ };
8771
+ const getChildrenGroupOrder = (el) => {
8772
+ const childrenOrder = [];
8773
+ const children = el.children;
8774
+ for (let i = 0; i < children.length; ++i) {
8775
+ const groupKey = getGroupKeyFromElement(children[i]);
8776
+ if (groupKey) {
8777
+ childrenOrder.push(groupKey);
10899
8778
  }
10900
8779
  }
10901
- if (val !== RangeSelector.prototype[key]) {
10902
- rSelector[key] = null;
10903
- }
10904
- }, this);
10905
- }
10906
- }
10907
- extend(RangeSelector.prototype, {
10908
- /**
10909
- * The default buttons for pre-selecting time frames.
10910
- * @private
10911
- */
10912
- defaultButtons: [{
10913
- type: 'month',
10914
- count: 1,
10915
- text: '1m',
10916
- title: 'View 1 month'
10917
- }, {
10918
- type: 'month',
10919
- count: 3,
10920
- text: '3m',
10921
- title: 'View 3 months'
10922
- }, {
10923
- type: 'month',
10924
- count: 6,
10925
- text: '6m',
10926
- title: 'View 6 months'
10927
- }, {
10928
- type: 'ytd',
10929
- text: 'YTD',
10930
- title: 'View year to date'
10931
- }, {
10932
- type: 'year',
10933
- count: 1,
10934
- text: '1y',
10935
- title: 'View 1 year'
10936
- }, {
10937
- type: 'all',
10938
- text: 'All',
10939
- title: 'View all'
10940
- }],
10941
- /**
10942
- * The date formats to use when setting min, max and value on date inputs.
10943
- * @private
10944
- */
10945
- inputTypeFormats: {
10946
- 'datetime-local': '%Y-%m-%dT%H:%M:%S',
10947
- 'date': '%Y-%m-%d',
10948
- 'time': '%H:%M:%S'
8780
+ return childrenOrder;
8781
+ };
8782
+ const before = getChildrenGroupOrder(this.beforeChartProxyPosContainer);
8783
+ const after = getChildrenGroupOrder(this.afterChartProxyPosContainer);
8784
+ before.push('series');
8785
+ return before.concat(after);
10949
8786
  }
10950
- });
10951
- /* *
10952
- *
10953
- * Default Export
10954
- *
10955
- * */
8787
+ /**
8788
+ * Check if the current DOM order matches the current group order, so that
8789
+ * a reordering/update is unnecessary.
8790
+ */
8791
+ isDOMOrderGroupOrder() {
8792
+ const domOrder = this.getCurrentGroupOrderInDOM();
8793
+ const groupOrderWithGroups = this.groupOrder.filter((x) => x === 'series' || !!this.groups[x]);
8794
+ let i = domOrder.length;
8795
+ if (i !== groupOrderWithGroups.length) {
8796
+ return false;
8797
+ }
8798
+ while (i--) {
8799
+ if (domOrder[i] !== groupOrderWithGroups[i]) {
8800
+ return false;
8801
+ }
8802
+ }
8803
+ return true;
8804
+ }
8805
+ /**
8806
+ * Update the DOM positions of the before/after proxy
8807
+ * positioning containers for the groups.
8808
+ */
8809
+ updatePosContainerPositions() {
8810
+ const chart = this.chart;
8811
+ // If exporting, don't add these containers to the DOM.
8812
+ if (chart.renderer.forExport) {
8813
+ return;
8814
+ }
8815
+ const rendererSVGEl = chart.renderer.box;
8816
+ chart.container.insertBefore(this.afterChartProxyPosContainer, rendererSVGEl.nextSibling);
8817
+ chart.container.insertBefore(this.beforeChartProxyPosContainer, rendererSVGEl);
8818
+ unhideChartElementFromAT(this.chart, this.afterChartProxyPosContainer);
8819
+ unhideChartElementFromAT(this.chart, this.beforeChartProxyPosContainer);
8820
+ }
8821
+ }
10956
8822
  /* *
10957
8823
  *
10958
- * API Options
8824
+ * Export Default
10959
8825
  *
10960
8826
  * */
10961
- /**
10962
- * Define the time span for the button
10963
- *
10964
- * @typedef {"all"|"day"|"hour"|"millisecond"|"minute"|"month"|"second"|"week"|"year"|"ytd"} Highcharts.RangeSelectorButtonTypeValue
10965
- */
10966
- /**
10967
- * Callback function to react on button clicks.
10968
- *
10969
- * @callback Highcharts.RangeSelectorClickCallbackFunction
10970
- *
10971
- * @param {global.Event} e
10972
- * Event arguments.
10973
- *
10974
- * @param {boolean|undefined}
10975
- * Return false to cancel the default button event.
10976
- */
10977
- /**
10978
- * Callback function to parse values entered in the input boxes and return a
10979
- * valid JavaScript time as milliseconds since 1970.
10980
- *
10981
- * @callback Highcharts.RangeSelectorParseCallbackFunction
10982
- *
10983
- * @param {string} value
10984
- * Input value to parse.
10985
- *
10986
- * @return {number}
10987
- * Parsed JavaScript time value.
10988
- */
10989
- (''); // keeps doclets above in JS file
10990
8827
 
10991
- return RangeSelector;
8828
+ return ProxyProvider;
10992
8829
  });
10993
- _registerModule(_modules, 'Accessibility/Components/RangeSelectorComponent.js', [_modules['Accessibility/AccessibilityComponent.js'], _modules['Accessibility/Utils/Announcer.js'], _modules['Accessibility/Utils/ChartUtilities.js'], _modules['Core/Globals.js'], _modules['Accessibility/KeyboardNavigationHandler.js'], _modules['Stock/RangeSelector/RangeSelector.js'], _modules['Core/Utilities.js']], function (AccessibilityComponent, Announcer, ChartUtilities, H, KeyboardNavigationHandler, RangeSelector, U) {
8830
+ _registerModule(_modules, 'Accessibility/Components/RangeSelectorComponent.js', [_modules['Accessibility/AccessibilityComponent.js'], _modules['Accessibility/Utils/Announcer.js'], _modules['Accessibility/Utils/ChartUtilities.js'], _modules['Accessibility/KeyboardNavigationHandler.js'], _modules['Core/Utilities.js']], function (AccessibilityComponent, Announcer, ChartUtilities, KeyboardNavigationHandler, U) {
10994
8831
  /* *
10995
8832
  *
10996
8833
  * (c) 2009-2024 Øystein Moseng
@@ -11003,8 +8840,7 @@
11003
8840
  *
11004
8841
  * */
11005
8842
  const { unhideChartElementFromAT, getAxisRangeDescription } = ChartUtilities;
11006
- const { composed } = H;
11007
- const { addEvent, attr, pushUnique } = U;
8843
+ const { addEvent, attr } = U;
11008
8844
  /* *
11009
8845
  *
11010
8846
  * Functions
@@ -11435,10 +9271,10 @@
11435
9271
  * @private
11436
9272
  */
11437
9273
  function compose(ChartClass, RangeSelectorClass) {
11438
- if (pushUnique(composed, compose)) {
11439
- const chartProto = ChartClass.prototype;
9274
+ const chartProto = ChartClass.prototype;
9275
+ if (!chartProto.highlightRangeSelectorButton) {
11440
9276
  chartProto.highlightRangeSelectorButton = (chartHighlightRangeSelectorButton);
11441
- addEvent(RangeSelector, 'afterBtnClick', rangeSelectorAfterBtnClick);
9277
+ addEvent(RangeSelectorClass, 'afterBtnClick', rangeSelectorAfterBtnClick);
11442
9278
  }
11443
9279
  }
11444
9280
  RangeSelectorComponent.compose = compose;
@@ -11497,10 +9333,11 @@
11497
9333
  * @private
11498
9334
  */
11499
9335
  function compose(SeriesClass) {
11500
- if (pushUnique(composed, compose)) {
9336
+ if (pushUnique(composed, 'A11y.FM')) {
11501
9337
  addEvent(SeriesClass, 'afterSetOptions', seriesOnAfterSetOptions);
11502
9338
  addEvent(SeriesClass, 'render', seriesOnRender);
11503
9339
  addEvent(SeriesClass, 'afterRender', seriesOnAfterRender);
9340
+ addEvent(SeriesClass, 'renderCanvas', seriesOnRenderCanvas);
11504
9341
  }
11505
9342
  }
11506
9343
  ForcedMarkersComposition.compose = compose;
@@ -11652,7 +9489,7 @@
11652
9489
  function unforceSeriesMarkerOptions(series) {
11653
9490
  const resetMarkerOptions = series.resetA11yMarkerOptions;
11654
9491
  if (resetMarkerOptions) {
11655
- const originalOpactiy = resetMarkerOptions.states &&
9492
+ const originalOpacity = resetMarkerOptions.states &&
11656
9493
  resetMarkerOptions.states.normal &&
11657
9494
  resetMarkerOptions.states.normal.opacity;
11658
9495
  // Temporarily set the old marker options to enabled in order to
@@ -11664,12 +9501,26 @@
11664
9501
  marker: {
11665
9502
  enabled: resetMarkerOptions.enabled,
11666
9503
  states: {
11667
- normal: { opacity: originalOpactiy }
9504
+ normal: { opacity: originalOpacity }
11668
9505
  }
11669
9506
  }
11670
9507
  });
11671
9508
  }
11672
9509
  }
9510
+ /**
9511
+ * Reset markers if series is boosted and had forced markers (#17320).
9512
+ * @private
9513
+ */
9514
+ function seriesOnRenderCanvas() {
9515
+ if (this.boosted && this.a11yMarkersForced) {
9516
+ merge(true, this.options, {
9517
+ marker: {
9518
+ enabled: false
9519
+ }
9520
+ });
9521
+ delete this.a11yMarkersForced;
9522
+ }
9523
+ }
11673
9524
  })(ForcedMarkersComposition || (ForcedMarkersComposition = {}));
11674
9525
  /* *
11675
9526
  *
@@ -11692,8 +9543,8 @@
11692
9543
  *
11693
9544
  * */
11694
9545
  const { seriesTypes } = SeriesRegistry;
11695
- const { composed, doc } = H;
11696
- const { defined, fireEvent, pushUnique } = U;
9546
+ const { doc } = H;
9547
+ const { defined, fireEvent } = U;
11697
9548
  const { getPointFromXY, getSeriesFromName, scrollAxisToPoint } = ChartUtilities;
11698
9549
  /* *
11699
9550
  *
@@ -12240,8 +10091,8 @@
12240
10091
  * @private
12241
10092
  */
12242
10093
  function compose(ChartClass, PointClass, SeriesClass) {
12243
- if (pushUnique(composed, compose)) {
12244
- const chartProto = ChartClass.prototype, pointProto = PointClass.prototype, seriesProto = SeriesClass.prototype;
10094
+ const chartProto = ChartClass.prototype, pointProto = PointClass.prototype, seriesProto = SeriesClass.prototype;
10095
+ if (!chartProto.highlightAdjacentPoint) {
12245
10096
  chartProto.highlightAdjacentPoint = chartHighlightAdjacentPoint;
12246
10097
  chartProto.highlightAdjacentPointVertical = (chartHighlightAdjacentPointVertical);
12247
10098
  chartProto.highlightAdjacentSeries = chartHighlightAdjacentSeries;
@@ -12874,23 +10725,32 @@
12874
10725
  // Apply theme to chart
12875
10726
  const theme = (chart.options.accessibility.highContrastTheme);
12876
10727
  chart.update(theme, false);
10728
+ const hasCustomColors = theme.colors?.length > 1;
12877
10729
  // Force series colors (plotOptions is not enough)
12878
10730
  chart.series.forEach(function (s) {
12879
10731
  const plotOpts = theme.plotOptions[s.type] || {};
12880
- s.update({
10732
+ const fillColor = hasCustomColors && s.colorIndex !== void 0 ?
10733
+ theme.colors[s.colorIndex] :
10734
+ plotOpts.color || 'window';
10735
+ const seriesOptions = {
12881
10736
  color: plotOpts.color || 'windowText',
12882
- colors: [plotOpts.color || 'windowText'],
12883
- borderColor: plotOpts.borderColor || 'window'
12884
- });
12885
- // Force point colors if existing
12886
- s.points.forEach(function (p) {
12887
- if (p.options && p.options.color) {
12888
- p.update({
12889
- color: plotOpts.color || 'windowText',
12890
- borderColor: plotOpts.borderColor || 'window'
12891
- }, false);
12892
- }
12893
- });
10737
+ colors: hasCustomColors ?
10738
+ theme.colors : [plotOpts.color || 'windowText'],
10739
+ borderColor: plotOpts.borderColor || 'window',
10740
+ fillColor
10741
+ };
10742
+ s.update(seriesOptions, false);
10743
+ if (s.points) {
10744
+ // Force point colors if existing
10745
+ s.points.forEach(function (p) {
10746
+ if (p.options && p.options.color) {
10747
+ p.update({
10748
+ color: plotOpts.color || 'windowText',
10749
+ borderColor: plotOpts.borderColor || 'window'
10750
+ }, false);
10751
+ }
10752
+ });
10753
+ }
12894
10754
  });
12895
10755
  // The redraw for each series and after is required for 3D pie
12896
10756
  // (workaround)
@@ -12920,11 +10780,6 @@
12920
10780
  * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
12921
10781
  *
12922
10782
  * */
12923
- /* *
12924
- *
12925
- * Theme
12926
- *
12927
- * */
12928
10783
  const theme = {
12929
10784
  chart: {
12930
10785
  backgroundColor: 'window'
@@ -12942,7 +10797,8 @@
12942
10797
  colorAxis: {
12943
10798
  minColor: 'windowText',
12944
10799
  maxColor: 'windowText',
12945
- stops: []
10800
+ stops: [],
10801
+ dataClasses: []
12946
10802
  },
12947
10803
  colors: ['windowText'],
12948
10804
  xAxis: {
@@ -13600,12 +11456,22 @@
13600
11456
  /**
13601
11457
  * Theme to apply to the chart when Windows High Contrast Mode is
13602
11458
  * detected. By default, a high contrast theme matching the high
13603
- * contrast system system colors is used.
11459
+ * contrast system colors is used.
13604
11460
  *
13605
11461
  * @type {*}
13606
11462
  * @since 7.1.3
13607
11463
  * @apioption accessibility.highContrastTheme
13608
11464
  */
11465
+ /**
11466
+ * Controls how [highContrastTheme](#accessibility.highContrastTheme)
11467
+ * is applied.
11468
+ *
11469
+ * The default option is `auto`, which applies the high contrast theme
11470
+ * the user's system has a high contrast theme active.
11471
+ *
11472
+ * @since 11.4.0
11473
+ */
11474
+ highContrastMode: 'auto',
13609
11475
  /**
13610
11476
  * A text description of the chart.
13611
11477
  *
@@ -14787,8 +12653,8 @@
14787
12653
  *
14788
12654
  * */
14789
12655
  const { defaultOptions } = D;
14790
- const { composed, doc } = H;
14791
- const { addEvent, extend, fireEvent, merge, pushUnique } = U;
12656
+ const { doc } = H;
12657
+ const { addEvent, extend, fireEvent, merge } = U;
14792
12658
  const { removeElement } = HU;
14793
12659
  /* *
14794
12660
  *
@@ -14909,8 +12775,10 @@
14909
12775
  // Update keyboard navigation
14910
12776
  this.keyboardNavigation.update(kbdNavOrder);
14911
12777
  // Handle high contrast mode
14912
- if (!chart.highContrastModeActive && // Only do this once
14913
- whcm.isHighContrastModeActive()) {
12778
+ // Should only be applied once, and not if explicitly disabled
12779
+ if (!chart.highContrastModeActive &&
12780
+ a11yOptions.highContrastMode !== false && (whcm.isHighContrastModeActive() ||
12781
+ a11yOptions.highContrastMode === true)) {
14914
12782
  whcm.setHighContrastTheme(chart);
14915
12783
  }
14916
12784
  fireEvent(chart, 'afterA11yUpdate', {
@@ -15079,8 +12947,8 @@
15079
12947
  if (RangeSelectorClass) {
15080
12948
  RangeSelectorComponent.compose(ChartClass, RangeSelectorClass);
15081
12949
  }
15082
- if (pushUnique(composed, compose)) {
15083
- const chartProto = ChartClass.prototype;
12950
+ const chartProto = ChartClass.prototype;
12951
+ if (!chartProto.updateA11yEnabled) {
15084
12952
  chartProto.updateA11yEnabled = chartUpdateA11yEnabled;
15085
12953
  addEvent(ChartClass, 'destroy', chartOnDestroy);
15086
12954
  addEvent(ChartClass, 'render', chartOnRender);
@@ -15145,13 +13013,16 @@
15145
13013
  _registerModule(_modules, 'masters/modules/accessibility.src.js', [_modules['Core/Globals.js'], _modules['Accessibility/Accessibility.js'], _modules['Accessibility/AccessibilityComponent.js'], _modules['Accessibility/Utils/ChartUtilities.js'], _modules['Accessibility/Utils/HTMLUtilities.js'], _modules['Accessibility/KeyboardNavigationHandler.js'], _modules['Accessibility/Components/SeriesComponent/SeriesDescriber.js']], function (Highcharts, Accessibility, AccessibilityComponent, ChartUtilities, HTMLUtilities, KeyboardNavigationHandler, SeriesDescriber) {
15146
13014
 
15147
13015
  const G = Highcharts;
13016
+ // Classes
15148
13017
  G.i18nFormat = Accessibility.i18nFormat;
15149
13018
  G.A11yChartUtilities = ChartUtilities;
15150
13019
  G.A11yHTMLUtilities = HTMLUtilities;
15151
13020
  G.AccessibilityComponent = AccessibilityComponent;
15152
13021
  G.KeyboardNavigationHandler = KeyboardNavigationHandler;
15153
13022
  G.SeriesAccessibilityDescriber = SeriesDescriber;
13023
+ // Compositions
15154
13024
  Accessibility.compose(G.Chart, G.Legend, G.Point, G.Series, G.SVGElement, G.RangeSelector);
15155
13025
 
13026
+ return Highcharts;
15156
13027
  });
15157
13028
  }));