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.
- package/README.md +1 -1
- package/bower.json +1 -1
- package/css/annotations/popup.css +27 -19
- package/css/stocktools/gui.css +19 -7
- package/es-modules/Accessibility/A11yI18n.js +4 -6
- package/es-modules/Accessibility/Accessibility.js +8 -6
- package/es-modules/Accessibility/Components/InfoRegionsComponent.js +11 -6
- package/es-modules/Accessibility/Components/LegendComponent.js +4 -4
- package/es-modules/Accessibility/Components/MenuComponent.js +3 -6
- package/es-modules/Accessibility/Components/NavigatorComponent.js +6 -3
- package/es-modules/Accessibility/Components/RangeSelectorComponent.js +4 -7
- package/es-modules/Accessibility/Components/SeriesComponent/ForcedMarkers.js +18 -3
- package/es-modules/Accessibility/Components/SeriesComponent/NewDataAnnouncer.js +5 -3
- package/es-modules/Accessibility/Components/SeriesComponent/SeriesKeyboardNavigation.js +4 -4
- package/es-modules/Accessibility/FocusBorder.js +5 -5
- package/es-modules/Accessibility/HighContrastMode.js +22 -13
- package/es-modules/Accessibility/HighContrastTheme.js +2 -6
- package/es-modules/Accessibility/KeyboardNavigation.js +17 -8
- package/es-modules/Accessibility/Options/A11yDefaults.js +11 -1
- package/es-modules/Accessibility/ProxyElement.js +4 -4
- package/es-modules/Accessibility/ProxyProvider.js +8 -2
- package/es-modules/Accessibility/Utils/DOMElementProvider.js +8 -0
- package/es-modules/Accessibility/Utils/EventProvider.js +9 -0
- package/es-modules/Core/Animation/Fx.js +3 -3
- package/es-modules/Core/Axis/Axis.js +43 -97
- package/es-modules/Core/Axis/Axis3DComposition.js +5 -5
- package/es-modules/Core/Axis/Axis3DDefaults.js +1 -1
- package/es-modules/Core/Axis/AxisDefaults.js +18 -7
- package/es-modules/Core/Axis/BrokenAxis.js +4 -6
- package/es-modules/Core/Axis/Color/ColorAxis.js +2 -1
- package/es-modules/Core/Axis/Color/ColorAxisComposition.js +3 -5
- package/es-modules/Core/Axis/DateTimeAxis.js +3 -5
- package/es-modules/Core/Axis/GridAxis.js +7 -7
- package/es-modules/Core/Axis/LogarithmicAxis.js +2 -4
- package/es-modules/Core/Axis/NavigatorAxisComposition.js +26 -22
- package/es-modules/Core/Axis/OrdinalAxis.js +97 -53
- package/es-modules/Core/Axis/PlotLineOrBand/PlotLineOrBand.js +3 -3
- package/es-modules/Core/Axis/PlotLineOrBand/PlotLineOrBandAxis.js +4 -5
- package/es-modules/Core/Axis/RadialAxis.js +5 -5
- package/es-modules/Core/Axis/ScrollbarAxis.js +2 -2
- package/es-modules/Core/Axis/Stacking/StackItem.js +8 -4
- package/es-modules/Core/Axis/Stacking/StackingAxis.js +3 -5
- package/es-modules/Core/Axis/Tick.js +16 -7
- package/es-modules/Core/Axis/Tick3DComposition.js +2 -2
- package/es-modules/Core/Axis/TreeGrid/TreeGridAxis.js +4 -8
- package/es-modules/Core/Axis/TreeGrid/TreeGridTick.js +3 -6
- package/es-modules/Core/Axis/WaterfallAxis.js +3 -3
- package/es-modules/Core/Axis/ZAxis.js +6 -11
- package/es-modules/Core/Chart/Chart.js +201 -176
- package/es-modules/Core/Chart/Chart3D.js +1 -1
- package/es-modules/Core/Chart/ChartDefaults.js +7 -0
- package/es-modules/Core/Chart/GanttChart.js +2 -2
- package/es-modules/Core/Chart/MapChart.js +12 -2
- package/es-modules/Core/Chart/StockChart.js +12 -11
- package/es-modules/Core/Color/Color.js +3 -3
- package/es-modules/Core/Color/Palettes.js +2 -2
- package/es-modules/Core/Defaults.js +18 -15
- package/es-modules/Core/Geometry/CircleUtilities.js +3 -3
- package/es-modules/Core/Globals.js +2 -2
- package/es-modules/Core/HttpUtilities.js +4 -4
- package/es-modules/Core/Legend/Legend.js +6 -6
- package/es-modules/Core/MSPointer.js +7 -7
- package/es-modules/Core/Pointer.js +230 -245
- package/es-modules/Core/Renderer/HTML/AST.js +1 -1
- package/es-modules/Core/Renderer/HTML/HTMLElement.js +213 -26
- package/es-modules/Core/Renderer/RendererUtilities.js +1 -1
- package/es-modules/Core/Renderer/SVG/SVGElement.js +85 -52
- package/es-modules/Core/Renderer/SVG/SVGLabel.js +14 -11
- package/es-modules/Core/Renderer/SVG/SVGRenderer.js +17 -14
- package/es-modules/Core/Renderer/SVG/SVGRenderer3D.js +8 -7
- package/es-modules/Core/Renderer/SVG/Symbols.js +1 -1
- package/es-modules/Core/Renderer/SVG/TextBuilder.js +2 -2
- package/es-modules/Core/Responsive.js +5 -6
- package/es-modules/Core/Series/DataLabel.js +70 -90
- package/es-modules/Core/Series/DataSeriesComposition.js +1 -1
- package/es-modules/Core/Series/DataSeriesConverter.js +2 -2
- package/es-modules/Core/Series/Point.js +48 -40
- package/es-modules/Core/Series/Series.js +61 -51
- package/es-modules/Core/Series/Series3D.js +2 -2
- package/es-modules/Core/Series/SeriesRegistry.js +10 -2
- package/es-modules/Core/Templating.js +1 -1
- package/es-modules/Core/Time.js +12 -7
- package/es-modules/Core/Tooltip.js +19 -17
- package/es-modules/Core/Utilities.js +54 -26
- package/es-modules/Data/Connectors/CSVConnector.js +2 -2
- package/es-modules/Data/Connectors/DataConnector.js +4 -2
- package/es-modules/Data/Connectors/GoogleSheetsConnector.js +2 -2
- package/es-modules/Data/Connectors/HTMLTableConnector.js +2 -2
- package/es-modules/Data/Connectors/JSONConnector.js +3 -5
- package/es-modules/Data/Converters/CSVConverter.js +1 -3
- package/es-modules/Data/Converters/DataConverter.js +8 -2
- package/es-modules/Data/Converters/HTMLTableConverter.js +1 -3
- package/es-modules/Data/Converters/JSONConverter.js +1 -0
- package/es-modules/Data/DataTable.js +1 -2
- package/es-modules/Data/Formula/FormulaProcessor.js +4 -2
- package/es-modules/Data/Modifiers/DataModifier.js +15 -3
- package/es-modules/Extensions/Annotations/Annotation.js +6 -7
- package/es-modules/Extensions/Annotations/AnnotationChart.js +4 -5
- package/es-modules/Extensions/Annotations/AnnotationDefaults.js +4 -4
- package/es-modules/Extensions/Annotations/ControlPoint.js +2 -2
- package/es-modules/Extensions/Annotations/ControlTarget.js +1 -1
- package/es-modules/Extensions/Annotations/Controllables/Controllable.js +7 -3
- package/es-modules/Extensions/Annotations/Controllables/ControllableEllipse.js +3 -3
- package/es-modules/Extensions/Annotations/Controllables/ControllableLabel.js +8 -9
- package/es-modules/Extensions/Annotations/Controllables/ControllablePath.js +3 -4
- package/es-modules/Extensions/Annotations/EventEmitter.js +6 -6
- package/es-modules/Extensions/Annotations/NavigationBindings.js +29 -18
- package/es-modules/Extensions/Annotations/NavigationBindingsDefaults.js +6 -6
- package/es-modules/Extensions/Annotations/Popup/Popup.js +1 -1
- package/es-modules/Extensions/Annotations/Popup/PopupAnnotations.js +10 -6
- package/es-modules/Extensions/Annotations/Popup/PopupComposition.js +2 -2
- package/es-modules/Extensions/Annotations/Popup/PopupIndicators.js +31 -31
- package/es-modules/Extensions/Annotations/Popup/PopupTabs.js +1 -1
- package/es-modules/Extensions/Annotations/Types/BasicAnnotation.js +14 -11
- package/es-modules/Extensions/Annotations/Types/FibonacciTimeZones.js +1 -1
- package/es-modules/Extensions/Annotations/Types/Measure.js +1 -1
- package/es-modules/Extensions/ArrowSymbols.js +7 -13
- package/es-modules/Extensions/Boost/Boost.js +39 -7
- package/es-modules/Extensions/Boost/BoostChart.js +4 -4
- package/es-modules/Extensions/Boost/BoostSeries.js +58 -13
- package/es-modules/Extensions/Boost/WGLRenderer.js +3 -3
- package/es-modules/Extensions/Boost/WGLVertexBuffer.js +1 -1
- package/es-modules/Extensions/BoostCanvas.js +5 -4
- package/es-modules/Extensions/BorderRadius.js +5 -4
- package/es-modules/Extensions/Breadcrumbs/Breadcrumbs.js +9 -9
- package/es-modules/Extensions/CurrentDateIndication.js +1 -1
- package/es-modules/Extensions/Data.js +11 -11
- package/es-modules/Extensions/DataGrouping/DataGrouping.js +1 -1
- package/es-modules/Extensions/DataGrouping/DataGroupingAxisComposition.js +8 -9
- package/es-modules/Extensions/DataGrouping/DataGroupingDefaults.js +1 -1
- package/es-modules/Extensions/DataGrouping/DataGroupingSeriesComposition.js +6 -7
- package/es-modules/Extensions/Debugger/Debugger.js +1 -1
- package/es-modules/Extensions/Debugger/ErrorMessages.js +2 -2
- package/es-modules/Extensions/DragPanes/AxisResizer.js +13 -16
- package/es-modules/Extensions/DragPanes/DragPanes.js +2 -4
- package/es-modules/Extensions/DraggablePoints/DragDropDefaults.js +2 -1
- package/es-modules/Extensions/DraggablePoints/DragDropUtilities.js +1 -1
- package/es-modules/Extensions/DraggablePoints/DraggableChart.js +4 -4
- package/es-modules/Extensions/DraggablePoints/DraggablePoints.js +8 -9
- package/es-modules/Extensions/Drilldown/Drilldown.js +11 -9
- package/es-modules/Extensions/Drilldown/DrilldownSeries.js +5 -6
- package/es-modules/Extensions/ExportData/ExportData.js +27 -18
- package/es-modules/Extensions/Exporting/Exporting.js +25 -20
- package/es-modules/Extensions/Exporting/ExportingDefaults.js +1 -1
- package/es-modules/Extensions/Exporting/Fullscreen.js +5 -10
- package/es-modules/Extensions/MarkerClusters/MarkerClusterScatter.js +26 -21
- package/es-modules/Extensions/MarkerClusters/MarkerClusterSymbols.js +2 -12
- package/es-modules/Extensions/MarkerClusters/MarkerClusters.js +3 -3
- package/es-modules/Extensions/MouseWheelZoom/MouseWheelZoom.js +51 -161
- package/es-modules/Extensions/NoDataToDisplay/NoDataToDisplay.js +3 -5
- package/es-modules/Extensions/OfflineExporting/OfflineExporting.js +5 -6
- package/es-modules/Extensions/OfflineExporting/OfflineExportingDefaults.js +1 -1
- package/es-modules/Extensions/OverlappingDataLabels.js +21 -49
- package/es-modules/Extensions/Pane/PaneComposition.js +3 -5
- package/es-modules/Extensions/ParallelCoordinates/ParallelAxis.js +2 -4
- package/es-modules/Extensions/ParallelCoordinates/ParallelCoordinates.js +5 -6
- package/es-modules/Extensions/ParallelCoordinates/ParallelSeries.js +1 -1
- package/es-modules/Extensions/PatternFill.js +19 -22
- package/es-modules/Extensions/PriceIndication.js +1 -1
- package/es-modules/Extensions/ScrollablePlotArea.js +218 -292
- package/es-modules/Extensions/SeriesLabel/SeriesLabel.js +26 -18
- package/es-modules/Extensions/Sonification/Options.js +1 -0
- package/es-modules/Extensions/Sonification/SonificationSpeaker.js +2 -2
- package/es-modules/Extensions/Sonification/SynthPatch.js +3 -3
- package/es-modules/Extensions/StaticScale.js +3 -5
- package/es-modules/Gantt/Legacy.js +1 -1
- package/es-modules/Gantt/Pathfinder.js +2 -2
- package/es-modules/Gantt/PathfinderComposition.js +3 -5
- package/es-modules/Gantt/Tree.js +3 -3
- package/es-modules/Maps/GeoJSONComposition.js +20 -13
- package/es-modules/Maps/MapNavigation.js +2 -2
- package/es-modules/Maps/MapPointer.js +3 -19
- package/es-modules/Maps/MapSymbols.js +3 -9
- package/es-modules/Maps/MapView.js +134 -74
- package/es-modules/Series/ArcDiagram/ArcDiagramSeries.js +5 -4
- package/es-modules/Series/Area/AreaSeries.js +2 -4
- package/es-modules/Series/Area3D/Area3DSeries.js +1 -1
- package/es-modules/Series/AreaRange/AreaRangePoint.js +2 -2
- package/es-modules/Series/AreaRange/AreaRangeSeries.js +2 -3
- package/es-modules/Series/AreaSpline/AreaSplineSeries.js +1 -1
- package/es-modules/Series/Bar/BarSeries.js +1 -1
- package/es-modules/Series/Bellcurve/BellcurveSeries.js +1 -1
- package/es-modules/Series/BoxPlot/BoxPlotSeriesDefaults.js +4 -0
- package/es-modules/Series/Bubble/BubbleLegendComposition.js +1 -1
- package/es-modules/Series/Bubble/BubbleLegendDefaults.js +2 -2
- package/es-modules/Series/Bubble/BubbleLegendItem.js +3 -3
- package/es-modules/Series/Bubble/BubbleSeries.js +1 -1
- package/es-modules/Series/Bullet/BulletSeriesDefaults.js +2 -2
- package/es-modules/Series/Candlestick/CandlestickSeries.js +2 -2
- package/es-modules/Series/Candlestick/CandlestickSeriesDefaults.js +1 -5
- package/es-modules/Series/ColorMapComposition.js +1 -1
- package/es-modules/Series/Column/ColumnDataLabel.js +2 -2
- package/es-modules/Series/Column/ColumnSeries.js +20 -22
- package/es-modules/Series/Column/ColumnSeriesDefaults.js +1 -1
- package/es-modules/Series/Column3D/Column3DComposition.js +1 -1
- package/es-modules/Series/ColumnRange/ColumnRangeSeries.js +2 -1
- package/es-modules/Series/Cylinder/CylinderComposition.js +9 -9
- package/es-modules/Series/DataModifyComposition.js +5 -5
- package/es-modules/Series/DependencyWheel/DependencyWheelSeries.js +3 -2
- package/es-modules/Series/DependencyWheel/DependencyWheelSeriesDefaults.js +1 -1
- package/es-modules/Series/DragNodesComposition.js +7 -7
- package/es-modules/Series/DrawPointUtilities.js +0 -2
- package/es-modules/Series/Dumbbell/DumbbellSeriesDefaults.js +1 -1
- package/es-modules/Series/Funnel/FunnelSeries.js +1 -1
- package/es-modules/Series/Funnel3D/Funnel3DComposition.js +6 -6
- package/es-modules/Series/Funnel3D/Funnel3DSeriesDefaults.js +2 -2
- package/es-modules/Series/Funnel3D/SVGElement3DFunnel.js +1 -1
- package/es-modules/Series/Gantt/GanttSeries.js +0 -1
- package/es-modules/Series/GeoHeatmap/GeoHeatmapSeries.js +5 -5
- package/es-modules/Series/GraphLayoutComposition.js +1 -1
- package/es-modules/Series/Heatmap/HeatmapSeries.js +2 -2
- package/es-modules/Series/Heatmap/HeatmapSeriesDefaults.js +1 -1
- package/es-modules/Series/HeikinAshi/HeikinAshiPoint.js +3 -1
- package/es-modules/Series/HeikinAshi/HeikinAshiSeries.js +3 -3
- package/es-modules/Series/HeikinAshi/HeikinAshiSeriesDefaults.js +1 -1
- package/es-modules/Series/HollowCandlestick/HollowCandlestickSeries.js +2 -2
- package/es-modules/Series/Item/ItemSeries.js +1 -1
- package/es-modules/Series/Line/LineSeries.js +1 -1
- package/es-modules/Series/Lollipop/LollipopSeries.js +3 -1
- package/es-modules/Series/Map/MapPoint.js +5 -1
- package/es-modules/Series/Map/MapSeries.js +32 -7
- package/es-modules/Series/Map/MapSeriesDefaults.js +5 -3
- package/es-modules/Series/Networkgraph/EulerIntegration.js +5 -5
- package/es-modules/Series/Networkgraph/NetworkgraphSeries.js +4 -4
- package/es-modules/Series/Networkgraph/NetworkgraphSeriesDefaults.js +5 -5
- package/es-modules/Series/Networkgraph/QuadTree.js +1 -1
- package/es-modules/Series/Networkgraph/QuadTreeNode.js +1 -1
- package/es-modules/Series/Networkgraph/VerletIntegration.js +9 -9
- package/es-modules/Series/NodesComposition.js +1 -1
- package/es-modules/Series/OHLC/OHLCSeries.js +1 -1
- package/es-modules/Series/OHLC/OHLCSeriesDefaults.js +1 -1
- package/es-modules/Series/OnSeriesComposition.js +1 -1
- package/es-modules/Series/Organization/OrganizationPoint.js +1 -1
- package/es-modules/Series/Organization/OrganizationSeries.js +22 -10
- package/es-modules/Series/Organization/OrganizationSeriesDefaults.js +15 -2
- package/es-modules/Series/PackedBubble/PackedBubbleLayout.js +3 -5
- package/es-modules/Series/PackedBubble/PackedBubblePoint.js +1 -1
- package/es-modules/Series/PackedBubble/PackedBubbleSeries.js +6 -10
- package/es-modules/Series/Pictorial/PictorialSeries.js +2 -2
- package/es-modules/Series/Pie/PieDataLabel.js +2 -2
- package/es-modules/Series/Pie/PiePoint.js +1 -1
- package/es-modules/Series/Pie/PieSeries.js +10 -1
- package/es-modules/Series/Pie/PieSeriesDefaults.js +1 -1
- package/es-modules/Series/Pie3D/Pie3DSeries.js +2 -2
- package/es-modules/Series/PolarComposition.js +22 -20
- package/es-modules/Series/Sankey/SankeyColumnComposition.js +1 -1
- package/es-modules/Series/Sankey/SankeySeries.js +8 -8
- package/es-modules/Series/Sankey/SankeySeriesDefaults.js +57 -13
- package/es-modules/Series/SeriesOnPointComposition.js +3 -3
- package/es-modules/Series/Spline/SplineSeries.js +1 -1
- package/es-modules/Series/Sunburst/SunburstPoint.js +1 -1
- package/es-modules/Series/Sunburst/SunburstSeries.js +2 -7
- package/es-modules/Series/Sunburst/SunburstSeriesDefaults.js +3 -3
- package/es-modules/Series/Sunburst/SunburstUtilities.js +1 -1
- package/es-modules/Series/TiledWebMap/TiledWebMapSeries.js +23 -25
- package/es-modules/Series/Tilemap/TilemapSeries.js +2 -2
- package/es-modules/Series/Timeline/TimelineSeries.js +2 -2
- package/es-modules/Series/TreeUtilities.js +23 -1
- package/es-modules/Series/Treegraph/TreegraphLayout.js +7 -11
- package/es-modules/Series/Treegraph/TreegraphPoint.js +1 -0
- package/es-modules/Series/Treegraph/TreegraphSeries.js +8 -8
- package/es-modules/Series/Treegraph/TreegraphSeriesDefaults.js +39 -2
- package/es-modules/Series/Treemap/TreemapSeries.js +4 -2
- package/es-modules/Series/Treemap/TreemapUtilities.js +0 -7
- package/es-modules/Series/Variwide/VariwideComposition.js +6 -2
- package/es-modules/Series/Variwide/VariwideSeries.js +1 -1
- package/es-modules/Series/Venn/VennSeries.js +4 -4
- package/es-modules/Series/Venn/VennUtils.js +5 -6
- package/es-modules/Series/Waterfall/WaterfallSeriesDefaults.js +1 -1
- package/es-modules/Series/Windbarb/WindbarbSeries.js +1 -1
- package/es-modules/Series/Wordcloud/WordcloudUtils.js +6 -4
- package/es-modules/Series/XRange/XRangePoint.js +2 -2
- package/es-modules/Series/XRange/XRangeSeries.js +1 -1
- package/es-modules/Shared/BaseForm.js +1 -1
- package/es-modules/Stock/Indicators/AD/ADIndicator.js +3 -1
- package/es-modules/Stock/Indicators/APO/APOIndicator.js +1 -1
- package/es-modules/Stock/Indicators/Aroon/AroonIndicator.js +1 -1
- package/es-modules/Stock/Indicators/CMF/CMFIndicator.js +1 -1
- package/es-modules/Stock/Indicators/CMO/CMOIndicator.js +2 -2
- package/es-modules/Stock/Indicators/Chaikin/ChaikinIndicator.js +1 -1
- package/es-modules/Stock/Indicators/DPO/DPOIndicator.js +1 -1
- package/es-modules/Stock/Indicators/Klinger/KlingerIndicator.js +1 -1
- package/es-modules/Stock/Indicators/LinearRegression/LinearRegressionIndicator.js +7 -7
- package/es-modules/Stock/Indicators/MultipleLinesComposition.js +9 -9
- package/es-modules/Stock/Indicators/OBV/OBVIndicator.js +1 -1
- package/es-modules/Stock/Indicators/PPO/PPOIndicator.js +1 -1
- package/es-modules/Stock/Indicators/PivotPoints/PivotPointsIndicator.js +2 -2
- package/es-modules/Stock/Indicators/SMA/SMAIndicator.js +1 -1
- package/es-modules/Stock/Indicators/Supertrend/SupertrendIndicator.js +16 -17
- package/es-modules/Stock/Indicators/VBP/VBPIndicator.js +4 -5
- package/es-modules/Stock/Indicators/WilliamsR/WilliamsRIndicator.js +1 -1
- package/es-modules/Stock/Indicators/Zigzag/ZigzagIndicator.js +5 -5
- package/es-modules/Stock/Navigator/ChartNavigatorComposition.js +188 -0
- package/es-modules/Stock/Navigator/Navigator.js +42 -27
- package/es-modules/Stock/Navigator/NavigatorComposition.js +10 -149
- package/es-modules/Stock/Navigator/NavigatorDefaults.js +16 -2
- package/es-modules/Stock/Navigator/StandaloneNavigator.js +334 -0
- package/es-modules/Stock/Navigator/StandaloneNavigatorDefaults.js +64 -0
- package/es-modules/Stock/RangeSelector/RangeSelector.js +28 -16
- package/es-modules/Stock/RangeSelector/RangeSelectorComposition.js +2 -2
- package/es-modules/Stock/Scrollbar/Scrollbar.js +10 -10
- package/es-modules/Stock/Scrollbar/ScrollbarDefaults.js +1 -3
- package/es-modules/Stock/StockTools/StockToolbar.js +6 -5
- package/es-modules/Stock/StockTools/StockTools.js +10 -13
- package/es-modules/Stock/StockTools/StockToolsBindings.js +35 -35
- package/es-modules/Stock/StockTools/StockToolsDefaults.js +2 -1
- package/es-modules/Stock/StockTools/StockToolsGui.js +7 -8
- package/es-modules/Stock/StockTools/StockToolsUtilities.js +8 -9
- package/es-modules/Stock/Utilities/StockUtilities.js +41 -0
- package/es-modules/masters/highcharts-3d.src.js +2 -1
- package/es-modules/masters/highcharts-gantt.src.js +1 -1
- package/es-modules/masters/highcharts-more.src.js +2 -1
- package/es-modules/masters/highcharts.src.js +41 -40
- package/es-modules/masters/highmaps.src.js +1 -1
- package/es-modules/masters/highstock.src.js +1 -1
- package/es-modules/masters/indicators/acceleration-bands.src.js +3 -1
- package/es-modules/masters/indicators/accumulation-distribution.src.js +3 -1
- package/es-modules/masters/indicators/ao.src.js +3 -1
- package/es-modules/masters/indicators/apo.src.js +3 -1
- package/es-modules/masters/indicators/aroon-oscillator.src.js +3 -1
- package/es-modules/masters/indicators/aroon.src.js +3 -1
- package/es-modules/masters/indicators/atr.src.js +3 -1
- package/es-modules/masters/indicators/bollinger-bands.src.js +3 -1
- package/es-modules/masters/indicators/cci.src.js +3 -1
- package/es-modules/masters/indicators/chaikin.src.js +3 -1
- package/es-modules/masters/indicators/cmf.src.js +3 -1
- package/es-modules/masters/indicators/cmo.src.js +3 -1
- package/es-modules/masters/indicators/dema.src.js +3 -1
- package/es-modules/masters/indicators/disparity-index.src.js +3 -1
- package/es-modules/masters/indicators/dmi.src.js +3 -1
- package/es-modules/masters/indicators/dpo.src.js +3 -1
- package/es-modules/masters/indicators/ema.src.js +2 -0
- package/es-modules/masters/indicators/ichimoku-kinko-hyo.src.js +3 -1
- package/es-modules/masters/indicators/indicators-all.src.js +3 -1
- package/es-modules/masters/indicators/indicators.src.js +7 -1
- package/es-modules/masters/indicators/keltner-channels.src.js +3 -1
- package/es-modules/masters/indicators/klinger.src.js +3 -1
- package/es-modules/masters/indicators/macd.src.js +3 -1
- package/es-modules/masters/indicators/mfi.src.js +3 -1
- package/es-modules/masters/indicators/momentum.src.js +3 -1
- package/es-modules/masters/indicators/natr.src.js +3 -1
- package/es-modules/masters/indicators/obv.src.js +3 -1
- package/es-modules/masters/indicators/pivot-points.src.js +3 -1
- package/es-modules/masters/indicators/ppo.src.js +3 -1
- package/es-modules/masters/indicators/price-channel.src.js +3 -1
- package/es-modules/masters/indicators/price-envelopes.src.js +3 -1
- package/es-modules/masters/indicators/psar.src.js +3 -1
- package/es-modules/masters/indicators/regressions.src.js +3 -1
- package/es-modules/masters/indicators/roc.src.js +3 -1
- package/es-modules/masters/indicators/rsi.src.js +3 -1
- package/es-modules/masters/indicators/slow-stochastic.src.js +3 -1
- package/es-modules/masters/indicators/stochastic.src.js +3 -1
- package/es-modules/masters/indicators/supertrend.src.js +3 -1
- package/es-modules/masters/indicators/tema.src.js +3 -1
- package/es-modules/masters/indicators/trendline.src.js +3 -1
- package/es-modules/masters/indicators/trix.src.js +3 -1
- package/es-modules/masters/indicators/volume-by-price.src.js +3 -1
- package/es-modules/masters/indicators/vwap.src.js +3 -1
- package/es-modules/masters/indicators/williams-r.src.js +3 -1
- package/es-modules/masters/indicators/wma.src.js +3 -1
- package/es-modules/masters/indicators/zigzag.src.js +3 -1
- package/es-modules/masters/modules/accessibility.src.js +4 -1
- package/es-modules/masters/modules/annotations-advanced.src.js +3 -5
- package/es-modules/masters/modules/annotations.src.js +6 -3
- package/es-modules/masters/modules/arc-diagram.src.js +3 -1
- package/es-modules/masters/modules/arrow-symbols.src.js +2 -1
- package/es-modules/masters/modules/boost-canvas.src.js +2 -1
- package/es-modules/masters/modules/boost.src.js +3 -2
- package/es-modules/masters/modules/broken-axis.src.js +4 -3
- package/es-modules/masters/modules/bullet.src.js +3 -1
- package/es-modules/masters/modules/coloraxis.src.js +4 -3
- package/es-modules/masters/modules/current-date-indicator.src.js +2 -1
- package/es-modules/masters/modules/cylinder.src.js +3 -1
- package/es-modules/masters/modules/data-tools.src.js +9 -8
- package/es-modules/masters/modules/data.src.js +9 -8
- package/es-modules/masters/modules/datagrouping.src.js +7 -5
- package/es-modules/masters/modules/debugger.src.js +3 -2
- package/es-modules/masters/modules/dependency-wheel.src.js +3 -1
- package/es-modules/masters/modules/dotplot.src.js +3 -1
- package/es-modules/masters/modules/drag-panes.src.js +2 -1
- package/es-modules/masters/modules/draggable-points.src.js +2 -1
- package/es-modules/masters/modules/drilldown.src.js +3 -2
- package/es-modules/masters/modules/dumbbell.src.js +3 -1
- package/es-modules/masters/modules/export-data.src.js +5 -4
- package/es-modules/masters/modules/exporting.src.js +6 -5
- package/es-modules/masters/modules/flowmap.src.js +3 -1
- package/es-modules/masters/modules/full-screen.src.js +4 -3
- package/es-modules/masters/modules/funnel.src.js +2 -1
- package/es-modules/masters/modules/funnel3d.src.js +4 -3
- package/es-modules/masters/modules/gantt.src.js +15 -17
- package/es-modules/masters/modules/geoheatmap.src.js +3 -1
- package/es-modules/masters/modules/grid-axis.src.js +2 -1
- package/es-modules/masters/modules/heatmap.src.js +3 -5
- package/es-modules/masters/modules/heikinashi.src.js +2 -1
- package/es-modules/masters/modules/histogram-bellcurve.src.js +3 -1
- package/es-modules/masters/modules/hollowcandlestick.src.js +3 -1
- package/es-modules/masters/modules/item-series.src.js +3 -1
- package/es-modules/masters/modules/lollipop.src.js +3 -1
- package/es-modules/masters/modules/map.src.js +15 -10
- package/es-modules/masters/modules/marker-clusters.src.js +2 -1
- package/es-modules/masters/modules/mouse-wheel-zoom.src.js +4 -2
- package/es-modules/masters/modules/navigator.src.d.ts +1 -0
- package/es-modules/masters/modules/navigator.src.js +19 -0
- package/es-modules/masters/modules/networkgraph.src.js +2 -1
- package/es-modules/masters/modules/no-data-to-display.src.js +2 -1
- package/es-modules/masters/modules/offline-exporting.src.js +4 -3
- package/es-modules/masters/modules/organization.src.js +3 -1
- package/es-modules/masters/modules/overlapping-datalabels.src.js +4 -2
- package/es-modules/masters/modules/parallel-coordinates.src.js +2 -1
- package/es-modules/masters/modules/pareto.src.js +3 -1
- package/es-modules/masters/modules/pathfinder.src.js +4 -3
- package/es-modules/masters/modules/pattern-fill.src.js +2 -1
- package/es-modules/masters/modules/pictorial.src.js +3 -1
- package/es-modules/masters/modules/price-indicator.src.js +2 -1
- package/es-modules/masters/modules/pyramid3d.src.js +3 -1
- package/es-modules/masters/modules/sankey.src.js +3 -1
- package/es-modules/masters/modules/series-label.src.js +2 -1
- package/es-modules/masters/modules/series-on-point.src.js +2 -1
- package/es-modules/masters/modules/solid-gauge.src.js +3 -1
- package/es-modules/masters/modules/sonification.src.js +2 -1
- package/es-modules/masters/modules/static-scale.src.js +2 -1
- package/es-modules/masters/modules/stock-tools.src.js +5 -3
- package/es-modules/masters/modules/stock.src.js +20 -15
- package/es-modules/masters/modules/streamgraph.src.js +3 -1
- package/es-modules/masters/modules/sunburst.src.js +4 -3
- package/es-modules/masters/modules/tiledwebmap.src.js +5 -4
- package/es-modules/masters/modules/tilemap.src.js +2 -1
- package/es-modules/masters/modules/timeline.src.js +3 -1
- package/es-modules/masters/modules/treegraph.src.js +3 -1
- package/es-modules/masters/modules/treegrid.src.js +2 -2
- package/es-modules/masters/modules/treemap.src.js +5 -4
- package/es-modules/masters/modules/variable-pie.src.js +3 -1
- package/es-modules/masters/modules/variwide.src.js +2 -1
- package/es-modules/masters/modules/vector.src.js +3 -1
- package/es-modules/masters/modules/venn.src.js +3 -1
- package/es-modules/masters/modules/windbarb.src.js +3 -1
- package/es-modules/masters/modules/wordcloud.src.js +3 -1
- package/es-modules/masters/modules/xrange.src.js +2 -1
- package/es-modules/masters/standalone-navigator.src.js +13 -0
- package/es-modules/masters/themes/avocado.src.js +2 -1
- package/es-modules/masters/themes/brand-dark.src.js +2 -1
- package/es-modules/masters/themes/brand-light.src.js +2 -1
- package/es-modules/masters/themes/dark-blue.src.js +2 -1
- package/es-modules/masters/themes/dark-green.src.js +2 -1
- package/es-modules/masters/themes/dark-unica.src.js +2 -1
- package/es-modules/masters/themes/gray.src.js +2 -1
- package/es-modules/masters/themes/grid-light.src.js +2 -1
- package/es-modules/masters/themes/grid.src.js +2 -1
- package/es-modules/masters/themes/high-contrast-dark.src.js +2 -1
- package/es-modules/masters/themes/high-contrast-light.src.js +2 -1
- package/es-modules/masters/themes/sand-signika.src.js +2 -1
- package/es-modules/masters/themes/skies.src.js +2 -1
- package/es-modules/masters/themes/sunset.src.js +2 -1
- package/es-modules/tsconfig.tsbuildinfo +1 -0
- package/globals.d.ts +9 -0
- package/globals.src.d.ts +9 -0
- package/highcharts-3d.js +3 -3
- package/highcharts-3d.src.js +32 -33
- package/highcharts-gantt.js +4 -4
- package/highcharts-gantt.src.js +5703 -5639
- package/highcharts-more.d.ts +4 -0
- package/highcharts-more.js +3 -3
- package/highcharts-more.src.d.ts +4 -0
- package/highcharts-more.src.js +88 -87
- package/highcharts.d.ts +834 -5365
- package/highcharts.js +4 -4
- package/highcharts.src.d.ts +834 -5365
- package/highcharts.src.js +1583 -1682
- package/highmaps.js +4 -4
- package/highmaps.src.js +1837 -1835
- package/highstock.js +4 -4
- package/highstock.src.js +12488 -12510
- package/indicators/acceleration-bands.js +3 -3
- package/indicators/acceleration-bands.src.js +12 -11
- package/indicators/accumulation-distribution.js +3 -3
- package/indicators/accumulation-distribution.src.js +6 -3
- package/indicators/ao.js +3 -3
- package/indicators/ao.src.js +3 -2
- package/indicators/apo.js +3 -3
- package/indicators/apo.src.js +4 -3
- package/indicators/aroon-oscillator.js +3 -3
- package/indicators/aroon-oscillator.src.js +12 -11
- package/indicators/aroon.js +3 -3
- package/indicators/aroon.src.js +13 -12
- package/indicators/atr.js +3 -3
- package/indicators/atr.src.js +3 -2
- package/indicators/bollinger-bands.js +3 -3
- package/indicators/bollinger-bands.src.js +12 -11
- package/indicators/cci.js +3 -3
- package/indicators/cci.src.js +3 -2
- package/indicators/chaikin.js +3 -3
- package/indicators/chaikin.src.js +7 -4
- package/indicators/cmf.js +3 -3
- package/indicators/cmf.src.js +4 -3
- package/indicators/cmo.js +3 -3
- package/indicators/cmo.src.js +5 -4
- package/indicators/dema.js +3 -3
- package/indicators/dema.src.js +3 -2
- package/indicators/disparity-index.js +3 -3
- package/indicators/disparity-index.src.js +3 -2
- package/indicators/dmi.js +3 -3
- package/indicators/dmi.src.js +12 -11
- package/indicators/dpo.js +3 -3
- package/indicators/dpo.src.js +4 -3
- package/indicators/ema.js +1 -1
- package/indicators/ema.src.js +2 -1
- package/indicators/ichimoku-kinko-hyo.js +3 -3
- package/indicators/ichimoku-kinko-hyo.src.js +3 -2
- package/indicators/indicators-all.js +3 -3
- package/indicators/indicators-all.src.js +63 -60
- package/indicators/indicators.js +3 -3
- package/indicators/indicators.src.js +286 -3
- package/indicators/keltner-channels.js +3 -3
- package/indicators/keltner-channels.src.js +12 -11
- package/indicators/klinger.js +3 -3
- package/indicators/klinger.src.js +13 -12
- package/indicators/macd.js +3 -3
- package/indicators/macd.src.js +3 -2
- package/indicators/mfi.js +3 -3
- package/indicators/mfi.src.js +3 -2
- package/indicators/momentum.js +3 -3
- package/indicators/momentum.src.js +3 -2
- package/indicators/natr.js +3 -3
- package/indicators/natr.src.js +3 -2
- package/indicators/obv.js +3 -3
- package/indicators/obv.src.js +4 -3
- package/indicators/pivot-points.js +3 -3
- package/indicators/pivot-points.src.js +5 -4
- package/indicators/ppo.js +3 -3
- package/indicators/ppo.src.js +4 -3
- package/indicators/price-channel.js +3 -3
- package/indicators/price-channel.src.js +12 -11
- package/indicators/price-envelopes.js +3 -3
- package/indicators/price-envelopes.src.js +12 -11
- package/indicators/psar.js +3 -3
- package/indicators/psar.src.js +3 -2
- package/indicators/regressions.js +3 -3
- package/indicators/regressions.src.js +10 -9
- package/indicators/roc.js +3 -3
- package/indicators/roc.src.js +3 -2
- package/indicators/rsi.js +3 -3
- package/indicators/rsi.src.js +3 -2
- package/indicators/slow-stochastic.js +3 -3
- package/indicators/slow-stochastic.src.js +3 -2
- package/indicators/stochastic.js +3 -3
- package/indicators/stochastic.src.js +12 -11
- package/indicators/supertrend.js +3 -3
- package/indicators/supertrend.src.js +20 -19
- package/indicators/tema.js +3 -3
- package/indicators/tema.src.js +3 -2
- package/indicators/trendline.js +3 -3
- package/indicators/trendline.src.js +3 -2
- package/indicators/trix.js +3 -3
- package/indicators/trix.src.js +3 -2
- package/indicators/volume-by-price.js +3 -3
- package/indicators/volume-by-price.src.js +8 -7
- package/indicators/vwap.js +3 -3
- package/indicators/vwap.src.js +3 -2
- package/indicators/williams-r.js +3 -3
- package/indicators/williams-r.src.js +4 -3
- package/indicators/wma.js +3 -3
- package/indicators/wma.src.js +3 -2
- package/indicators/zigzag.js +3 -3
- package/indicators/zigzag.src.js +8 -7
- package/lib/svg2pdf.js +7 -7
- package/lib/svg2pdf.src.js +185 -150
- package/modules/accessibility.js +3 -3
- package/modules/accessibility.src.js +664 -2793
- package/modules/annotations-advanced.d.ts +3 -0
- package/modules/annotations-advanced.js +3 -3
- package/modules/annotations-advanced.src.d.ts +3 -0
- package/modules/annotations-advanced.src.js +2949 -2920
- package/modules/annotations.d.ts +0 -3
- package/modules/annotations.js +3 -3
- package/modules/annotations.src.d.ts +0 -3
- package/modules/annotations.src.js +2926 -2905
- package/modules/arc-diagram.js +3 -3
- package/modules/arc-diagram.src.js +8 -6
- package/modules/arrow-symbols.js +3 -3
- package/modules/arrow-symbols.src.js +10 -13
- package/modules/boost-canvas.js +3 -3
- package/modules/boost-canvas.src.js +73 -26
- package/modules/boost.js +3 -3
- package/modules/boost.src.js +108 -30
- package/modules/broken-axis.js +3 -3
- package/modules/broken-axis.src.js +9 -9
- package/modules/bullet.js +3 -3
- package/modules/bullet.src.js +5 -4
- package/modules/coloraxis.js +3 -3
- package/modules/coloraxis.src.js +10 -9
- package/modules/current-date-indicator.js +3 -3
- package/modules/current-date-indicator.src.js +3 -2
- package/modules/cylinder.js +3 -3
- package/modules/cylinder.src.js +12 -11
- package/modules/data-tools.js +3 -3
- package/modules/data-tools.src.js +53 -36
- package/modules/data.d.ts +2 -2
- package/modules/data.js +3 -3
- package/modules/data.src.d.ts +2 -2
- package/modules/data.src.js +24 -23
- package/modules/datagrouping.js +3 -3
- package/modules/datagrouping.src.js +25 -23
- package/modules/debugger.js +3 -3
- package/modules/debugger.src.js +6 -5
- package/modules/dependency-wheel.js +3 -3
- package/modules/dependency-wheel.src.js +7 -5
- package/modules/dotplot.js +3 -3
- package/modules/dotplot.src.js +3 -2
- package/modules/drag-panes.js +3 -3
- package/modules/drag-panes.src.js +19 -21
- package/modules/draggable-points.js +3 -3
- package/modules/draggable-points.src.js +18 -16
- package/modules/drilldown.js +3 -3
- package/modules/drilldown.src.js +29 -26
- package/modules/dumbbell.js +3 -3
- package/modules/dumbbell.src.js +5 -4
- package/modules/export-data.js +3 -3
- package/modules/export-data.src.js +33 -22
- package/modules/exporting.d.ts +1 -1
- package/modules/exporting.js +3 -3
- package/modules/exporting.src.d.ts +1 -1
- package/modules/exporting.src.js +40 -39
- package/modules/flowmap.js +3 -3
- package/modules/flowmap.src.js +3 -2
- package/modules/full-screen.js +3 -3
- package/modules/full-screen.src.js +9 -13
- package/modules/funnel.js +3 -3
- package/modules/funnel.src.js +3 -2
- package/modules/funnel3d.js +3 -3
- package/modules/funnel3d.src.js +12 -12
- package/modules/gantt.d.ts +3 -4
- package/modules/gantt.js +3 -3
- package/modules/gantt.src.d.ts +3 -4
- package/modules/gantt.src.js +4165 -4002
- package/modules/geoheatmap.js +3 -3
- package/modules/geoheatmap.src.js +8 -7
- package/modules/grid-axis.js +3 -3
- package/modules/grid-axis.src.js +9 -8
- package/modules/heatmap.d.ts +2 -2
- package/modules/heatmap.js +3 -3
- package/modules/heatmap.src.d.ts +2 -2
- package/modules/heatmap.src.js +21 -15
- package/modules/heikinashi.js +3 -3
- package/modules/heikinashi.src.js +9 -6
- package/modules/histogram-bellcurve.js +3 -3
- package/modules/histogram-bellcurve.src.js +4 -3
- package/modules/hollowcandlestick.js +3 -3
- package/modules/hollowcandlestick.src.js +5 -4
- package/modules/item-series.js +3 -3
- package/modules/item-series.src.js +4 -3
- package/modules/lollipop.js +3 -3
- package/modules/lollipop.src.js +6 -3
- package/modules/map.d.ts +22 -1
- package/modules/map.js +3 -3
- package/modules/map.src.d.ts +22 -1
- package/modules/map.src.js +256 -155
- package/modules/marker-clusters.js +3 -3
- package/modules/marker-clusters.src.js +35 -37
- package/modules/mouse-wheel-zoom.js +3 -3
- package/modules/mouse-wheel-zoom.src.js +55 -163
- package/modules/navigator.d.ts +148 -0
- package/modules/navigator.js +9 -0
- package/modules/navigator.src.d.ts +148 -0
- package/modules/navigator.src.js +3921 -0
- package/modules/networkgraph.d.ts +2 -2
- package/modules/networkgraph.js +3 -3
- package/modules/networkgraph.src.d.ts +2 -2
- package/modules/networkgraph.src.js +36 -35
- package/modules/no-data-to-display.js +3 -3
- package/modules/no-data-to-display.src.js +6 -6
- package/modules/offline-exporting.js +3 -3
- package/modules/offline-exporting.src.js +10 -10
- package/modules/organization.js +3 -3
- package/modules/organization.src.js +41 -15
- package/modules/overlapping-datalabels.js +3 -3
- package/modules/overlapping-datalabels.src.js +4 -2
- package/modules/parallel-coordinates.js +3 -3
- package/modules/parallel-coordinates.src.js +12 -12
- package/modules/pareto.js +3 -3
- package/modules/pareto.src.js +3 -2
- package/modules/pathfinder.js +3 -3
- package/modules/pathfinder.src.js +18 -22
- package/modules/pattern-fill.js +3 -3
- package/modules/pattern-fill.src.js +22 -23
- package/modules/pictorial.js +3 -3
- package/modules/pictorial.src.js +25 -26
- package/modules/price-indicator.js +3 -3
- package/modules/price-indicator.src.js +3 -2
- package/modules/pyramid3d.js +3 -3
- package/modules/pyramid3d.src.js +3 -2
- package/modules/sankey.js +3 -3
- package/modules/sankey.src.js +93 -26
- package/modules/series-label.js +3 -3
- package/modules/series-label.src.js +28 -19
- package/modules/series-on-point.js +3 -3
- package/modules/series-on-point.src.js +5 -4
- package/modules/solid-gauge.js +3 -3
- package/modules/solid-gauge.src.js +3 -2
- package/modules/sonification.d.ts +2 -2
- package/modules/sonification.js +3 -3
- package/modules/sonification.src.d.ts +2 -2
- package/modules/sonification.src.js +8 -6
- package/modules/static-scale.js +3 -3
- package/modules/static-scale.src.js +6 -6
- package/modules/stock-tools.js +3 -3
- package/modules/stock-tools.src.js +109 -96
- package/modules/stock.d.ts +1 -1
- package/modules/stock.js +3 -3
- package/modules/stock.src.d.ts +1 -1
- package/modules/stock.src.js +10762 -10685
- package/modules/streamgraph.js +3 -3
- package/modules/streamgraph.src.js +3 -2
- package/modules/sunburst.js +3 -3
- package/modules/sunburst.src.js +50 -37
- package/modules/tiledwebmap.js +4 -4
- package/modules/tiledwebmap.src.js +28 -29
- package/modules/tilemap.js +3 -3
- package/modules/tilemap.src.js +4 -3
- package/modules/timeline.js +3 -3
- package/modules/timeline.src.js +5 -4
- package/modules/treegraph.js +3 -3
- package/modules/treegraph.src.js +58 -23
- package/modules/treegrid.js +3 -3
- package/modules/treegrid.src.js +49 -33
- package/modules/treemap.js +3 -3
- package/modules/treemap.src.js +44 -26
- package/modules/variable-pie.js +3 -3
- package/modules/variable-pie.src.js +3 -2
- package/modules/variwide.js +3 -3
- package/modules/variwide.src.js +9 -4
- package/modules/vector.js +3 -3
- package/modules/vector.src.js +3 -2
- package/modules/venn.js +3 -3
- package/modules/venn.src.js +16 -17
- package/modules/windbarb.js +3 -3
- package/modules/windbarb.src.js +5 -4
- package/modules/wordcloud.js +3 -3
- package/modules/wordcloud.src.js +10 -8
- package/modules/xrange.js +3 -3
- package/modules/xrange.src.js +5 -4
- package/package.json +1 -1
- package/standalone-navigator.js +2 -0
- package/standalone-navigator.src.js +49402 -0
- package/themes/avocado.js +3 -3
- package/themes/avocado.src.js +2 -1
- package/themes/brand-dark.js +3 -3
- package/themes/brand-dark.src.js +2 -1
- package/themes/brand-light.js +3 -3
- package/themes/brand-light.src.js +2 -1
- package/themes/dark-blue.js +3 -3
- package/themes/dark-blue.src.js +2 -1
- package/themes/dark-green.js +3 -3
- package/themes/dark-green.src.js +2 -1
- package/themes/dark-unica.js +3 -3
- package/themes/dark-unica.src.js +2 -1
- package/themes/gray.js +3 -3
- package/themes/gray.src.js +2 -1
- package/themes/grid-light.js +3 -3
- package/themes/grid-light.src.js +2 -1
- package/themes/grid.js +3 -3
- package/themes/grid.src.js +2 -1
- package/themes/high-contrast-dark.js +3 -3
- package/themes/high-contrast-dark.src.js +2 -1
- package/themes/high-contrast-light.js +3 -3
- package/themes/high-contrast-light.src.js +2 -1
- package/themes/sand-signika.js +3 -3
- package/themes/sand-signika.src.js +2 -1
- package/themes/skies.js +3 -3
- package/themes/skies.src.js +2 -1
- package/themes/sunset.js +3 -3
- package/themes/sunset.src.js +2 -1
- package/es-modules/Core/Renderer/HTML/HTMLRenderer.js +0 -259
- package/lib/canvg.js +0 -8
|
@@ -0,0 +1,3921 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Highcharts JS v11.4.0 (2024-03-05)
|
|
3
|
+
*
|
|
4
|
+
* Standalone navigator module
|
|
5
|
+
*
|
|
6
|
+
* (c) 2009-2024 Mateusz Bernacik
|
|
7
|
+
*
|
|
8
|
+
* License: www.highcharts.com/license
|
|
9
|
+
*/
|
|
10
|
+
(function (factory) {
|
|
11
|
+
if (typeof module === 'object' && module.exports) {
|
|
12
|
+
factory['default'] = factory;
|
|
13
|
+
module.exports = factory;
|
|
14
|
+
} else if (typeof define === 'function' && define.amd) {
|
|
15
|
+
define('highcharts/modules/navigator', ['highcharts'], function (Highcharts) {
|
|
16
|
+
factory(Highcharts);
|
|
17
|
+
factory.Highcharts = Highcharts;
|
|
18
|
+
return factory;
|
|
19
|
+
});
|
|
20
|
+
} else {
|
|
21
|
+
factory(typeof Highcharts !== 'undefined' ? Highcharts : undefined);
|
|
22
|
+
}
|
|
23
|
+
}(function (Highcharts) {
|
|
24
|
+
'use strict';
|
|
25
|
+
var _modules = Highcharts ? Highcharts._modules : {};
|
|
26
|
+
function _registerModule(obj, path, args, fn) {
|
|
27
|
+
if (!obj.hasOwnProperty(path)) {
|
|
28
|
+
obj[path] = fn.apply(null, args);
|
|
29
|
+
|
|
30
|
+
if (typeof CustomEvent === 'function') {
|
|
31
|
+
window.dispatchEvent(new CustomEvent(
|
|
32
|
+
'HighchartsModuleLoaded',
|
|
33
|
+
{ detail: { path: path, module: obj[path] } }
|
|
34
|
+
));
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
_registerModule(_modules, 'Stock/Navigator/ChartNavigatorComposition.js', [_modules['Core/Globals.js'], _modules['Core/Utilities.js']], function (H, U) {
|
|
39
|
+
/* *
|
|
40
|
+
*
|
|
41
|
+
* (c) 2010-2024 Torstein Honsi
|
|
42
|
+
*
|
|
43
|
+
* License: www.highcharts.com/license
|
|
44
|
+
*
|
|
45
|
+
* !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
|
|
46
|
+
*
|
|
47
|
+
* */
|
|
48
|
+
const { isTouchDevice } = H;
|
|
49
|
+
const { addEvent, merge, pick } = U;
|
|
50
|
+
/* *
|
|
51
|
+
*
|
|
52
|
+
* Constants
|
|
53
|
+
*
|
|
54
|
+
* */
|
|
55
|
+
const composedMembers = [];
|
|
56
|
+
/* *
|
|
57
|
+
*
|
|
58
|
+
* Variables
|
|
59
|
+
*
|
|
60
|
+
* */
|
|
61
|
+
let NavigatorConstructor;
|
|
62
|
+
/* *
|
|
63
|
+
*
|
|
64
|
+
* Functions
|
|
65
|
+
*
|
|
66
|
+
* */
|
|
67
|
+
/**
|
|
68
|
+
* @private
|
|
69
|
+
*/
|
|
70
|
+
function compose(ChartClass, NavigatorClass) {
|
|
71
|
+
if (U.pushUnique(composedMembers, ChartClass)) {
|
|
72
|
+
const chartProto = ChartClass.prototype;
|
|
73
|
+
NavigatorConstructor = NavigatorClass;
|
|
74
|
+
chartProto.callbacks.push(onChartCallback);
|
|
75
|
+
addEvent(ChartClass, 'afterAddSeries', onChartAfterAddSeries);
|
|
76
|
+
addEvent(ChartClass, 'afterSetChartSize', onChartAfterSetChartSize);
|
|
77
|
+
addEvent(ChartClass, 'afterUpdate', onChartAfterUpdate);
|
|
78
|
+
addEvent(ChartClass, 'beforeRender', onChartBeforeRender);
|
|
79
|
+
addEvent(ChartClass, 'beforeShowResetZoom', onChartBeforeShowResetZoom);
|
|
80
|
+
addEvent(ChartClass, 'update', onChartUpdate);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Handle adding new series.
|
|
85
|
+
* @private
|
|
86
|
+
*/
|
|
87
|
+
function onChartAfterAddSeries() {
|
|
88
|
+
if (this.navigator) {
|
|
89
|
+
// Recompute which series should be shown in navigator, and add them
|
|
90
|
+
this.navigator.setBaseSeries(null, false);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* For stock charts, extend the Chart.setChartSize method so that we can set the
|
|
95
|
+
* final top position of the navigator once the height of the chart, including
|
|
96
|
+
* the legend, is determined. #367. We can't use Chart.getMargins, because
|
|
97
|
+
* labels offsets are not calculated yet.
|
|
98
|
+
* @private
|
|
99
|
+
*/
|
|
100
|
+
function onChartAfterSetChartSize() {
|
|
101
|
+
const legend = this.legend, navigator = this.navigator;
|
|
102
|
+
let legendOptions, xAxis, yAxis;
|
|
103
|
+
if (navigator) {
|
|
104
|
+
legendOptions = legend && legend.options;
|
|
105
|
+
xAxis = navigator.xAxis;
|
|
106
|
+
yAxis = navigator.yAxis;
|
|
107
|
+
const { scrollbarHeight, scrollButtonSize } = navigator;
|
|
108
|
+
// Compute the top position
|
|
109
|
+
if (this.inverted) {
|
|
110
|
+
navigator.left = navigator.opposite ?
|
|
111
|
+
this.chartWidth - scrollbarHeight -
|
|
112
|
+
navigator.height :
|
|
113
|
+
this.spacing[3] + scrollbarHeight;
|
|
114
|
+
navigator.top = this.plotTop + scrollButtonSize;
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
navigator.left = pick(xAxis.left, this.plotLeft + scrollButtonSize);
|
|
118
|
+
navigator.top = navigator.navigatorOptions.top ||
|
|
119
|
+
this.chartHeight -
|
|
120
|
+
navigator.height -
|
|
121
|
+
scrollbarHeight -
|
|
122
|
+
(this.scrollbar?.options.margin || 0) -
|
|
123
|
+
this.spacing[2] -
|
|
124
|
+
(this.rangeSelector && this.extraBottomMargin ?
|
|
125
|
+
this.rangeSelector.getHeight() :
|
|
126
|
+
0) -
|
|
127
|
+
((legendOptions &&
|
|
128
|
+
legendOptions.verticalAlign === 'bottom' &&
|
|
129
|
+
legendOptions.layout !== 'proximate' && // #13392
|
|
130
|
+
legendOptions.enabled &&
|
|
131
|
+
!legendOptions.floating) ?
|
|
132
|
+
legend.legendHeight +
|
|
133
|
+
pick(legendOptions.margin, 10) :
|
|
134
|
+
0) -
|
|
135
|
+
(this.titleOffset ? this.titleOffset[2] : 0);
|
|
136
|
+
}
|
|
137
|
+
if (xAxis && yAxis) { // false if navigator is disabled (#904)
|
|
138
|
+
if (this.inverted) {
|
|
139
|
+
xAxis.options.left = yAxis.options.left = navigator.left;
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
xAxis.options.top = yAxis.options.top = navigator.top;
|
|
143
|
+
}
|
|
144
|
+
xAxis.setAxisSize();
|
|
145
|
+
yAxis.setAxisSize();
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Initialize navigator, if no scrolling exists yet.
|
|
151
|
+
* @private
|
|
152
|
+
*/
|
|
153
|
+
function onChartAfterUpdate(event) {
|
|
154
|
+
if (!this.navigator && !this.scroller &&
|
|
155
|
+
(this.options.navigator.enabled ||
|
|
156
|
+
this.options.scrollbar.enabled)) {
|
|
157
|
+
this.scroller = this.navigator = new NavigatorConstructor(this);
|
|
158
|
+
if (pick(event.redraw, true)) {
|
|
159
|
+
this.redraw(event.animation); // #7067
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Initialize navigator for stock charts
|
|
165
|
+
* @private
|
|
166
|
+
*/
|
|
167
|
+
function onChartBeforeRender() {
|
|
168
|
+
const options = this.options;
|
|
169
|
+
if (options.navigator.enabled ||
|
|
170
|
+
options.scrollbar.enabled) {
|
|
171
|
+
this.scroller = this.navigator = new NavigatorConstructor(this);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* For Stock charts. For x only zooming, do not to create the zoom button
|
|
176
|
+
* because X axis zooming is already allowed by the Navigator and Range
|
|
177
|
+
* selector. (#9285)
|
|
178
|
+
* @private
|
|
179
|
+
*/
|
|
180
|
+
function onChartBeforeShowResetZoom() {
|
|
181
|
+
const chartOptions = this.options, navigator = chartOptions.navigator, rangeSelector = chartOptions.rangeSelector;
|
|
182
|
+
if (((navigator && navigator.enabled) ||
|
|
183
|
+
(rangeSelector && rangeSelector.enabled)) &&
|
|
184
|
+
((!isTouchDevice &&
|
|
185
|
+
this.zooming.type === 'x') ||
|
|
186
|
+
(isTouchDevice && this.zooming.pinchType === 'x'))) {
|
|
187
|
+
return false;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* @private
|
|
192
|
+
*/
|
|
193
|
+
function onChartCallback(chart) {
|
|
194
|
+
const navigator = chart.navigator;
|
|
195
|
+
// Initialize the navigator
|
|
196
|
+
if (navigator && chart.xAxis[0]) {
|
|
197
|
+
const extremes = chart.xAxis[0].getExtremes();
|
|
198
|
+
navigator.render(extremes.min, extremes.max);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Merge options, if no scrolling exists yet
|
|
203
|
+
* @private
|
|
204
|
+
*/
|
|
205
|
+
function onChartUpdate(e) {
|
|
206
|
+
const navigatorOptions = (e.options.navigator || {}), scrollbarOptions = (e.options.scrollbar || {});
|
|
207
|
+
if (!this.navigator && !this.scroller &&
|
|
208
|
+
(navigatorOptions.enabled || scrollbarOptions.enabled)) {
|
|
209
|
+
merge(true, this.options.navigator, navigatorOptions);
|
|
210
|
+
merge(true, this.options.scrollbar, scrollbarOptions);
|
|
211
|
+
delete e.options.navigator;
|
|
212
|
+
delete e.options.scrollbar;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
/* *
|
|
216
|
+
*
|
|
217
|
+
* Default Export
|
|
218
|
+
*
|
|
219
|
+
* */
|
|
220
|
+
const ChartNavigatorComposition = {
|
|
221
|
+
compose
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
return ChartNavigatorComposition;
|
|
225
|
+
});
|
|
226
|
+
_registerModule(_modules, 'Core/Axis/NavigatorAxisComposition.js', [_modules['Core/Globals.js'], _modules['Core/Utilities.js']], function (H, U) {
|
|
227
|
+
/* *
|
|
228
|
+
*
|
|
229
|
+
* (c) 2010-2024 Torstein Honsi
|
|
230
|
+
*
|
|
231
|
+
* License: www.highcharts.com/license
|
|
232
|
+
*
|
|
233
|
+
* !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
|
|
234
|
+
*
|
|
235
|
+
* */
|
|
236
|
+
const { isTouchDevice } = H;
|
|
237
|
+
const { addEvent, correctFloat, defined, isNumber, pick } = U;
|
|
238
|
+
/* *
|
|
239
|
+
*
|
|
240
|
+
* Functions
|
|
241
|
+
*
|
|
242
|
+
* */
|
|
243
|
+
/**
|
|
244
|
+
* @private
|
|
245
|
+
*/
|
|
246
|
+
function onAxisInit() {
|
|
247
|
+
const axis = this;
|
|
248
|
+
if (!axis.navigatorAxis) {
|
|
249
|
+
axis.navigatorAxis = new NavigatorAxisAdditions(axis);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* For Stock charts, override selection zooming with some special features
|
|
254
|
+
* because X axis zooming is already allowed by the Navigator and Range
|
|
255
|
+
* selector.
|
|
256
|
+
* @private
|
|
257
|
+
*/
|
|
258
|
+
function onAxisSetExtremes(e) {
|
|
259
|
+
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;
|
|
260
|
+
let zoomed;
|
|
261
|
+
if (axis.isXAxis &&
|
|
262
|
+
(navigator?.enabled || rangeSelector?.enabled)) {
|
|
263
|
+
// For y only zooming, ignore the X axis completely
|
|
264
|
+
if (zoomType === 'y' && e.trigger === 'zoom') {
|
|
265
|
+
zoomed = false;
|
|
266
|
+
// For xy zooming, record the state of the zoom before zoom selection,
|
|
267
|
+
// then when the reset button is pressed, revert to this state. This
|
|
268
|
+
// should apply only if the chart is initialized with a range (#6612),
|
|
269
|
+
// otherwise zoom all the way out.
|
|
270
|
+
}
|
|
271
|
+
else if (((e.trigger === 'zoom' && zoomType === 'xy') ||
|
|
272
|
+
(isTouchDevice && pinchType === 'xy')) &&
|
|
273
|
+
axis.options.range) {
|
|
274
|
+
const previousZoom = navigatorAxis.previousZoom;
|
|
275
|
+
// Minimum defined, zooming in
|
|
276
|
+
if (defined(e.min)) {
|
|
277
|
+
navigatorAxis.previousZoom = [axis.min, axis.max];
|
|
278
|
+
// Minimum undefined, resetting zoom
|
|
279
|
+
}
|
|
280
|
+
else if (previousZoom) {
|
|
281
|
+
e.min = previousZoom[0];
|
|
282
|
+
e.max = previousZoom[1];
|
|
283
|
+
navigatorAxis.previousZoom = void 0;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
if (typeof zoomed !== 'undefined') {
|
|
288
|
+
e.preventDefault();
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
/* *
|
|
292
|
+
*
|
|
293
|
+
* Class
|
|
294
|
+
*
|
|
295
|
+
* */
|
|
296
|
+
/**
|
|
297
|
+
* @private
|
|
298
|
+
* @class
|
|
299
|
+
*/
|
|
300
|
+
class NavigatorAxisAdditions {
|
|
301
|
+
/* *
|
|
302
|
+
*
|
|
303
|
+
* Static Functions
|
|
304
|
+
*
|
|
305
|
+
* */
|
|
306
|
+
/**
|
|
307
|
+
* @private
|
|
308
|
+
*/
|
|
309
|
+
static compose(AxisClass) {
|
|
310
|
+
if (!AxisClass.keepProps.includes('navigatorAxis')) {
|
|
311
|
+
AxisClass.keepProps.push('navigatorAxis');
|
|
312
|
+
addEvent(AxisClass, 'init', onAxisInit);
|
|
313
|
+
addEvent(AxisClass, 'setExtremes', onAxisSetExtremes);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
/* *
|
|
317
|
+
*
|
|
318
|
+
* Constructors
|
|
319
|
+
*
|
|
320
|
+
* */
|
|
321
|
+
constructor(axis) {
|
|
322
|
+
this.axis = axis;
|
|
323
|
+
}
|
|
324
|
+
/* *
|
|
325
|
+
*
|
|
326
|
+
* Functions
|
|
327
|
+
*
|
|
328
|
+
* */
|
|
329
|
+
/**
|
|
330
|
+
* @private
|
|
331
|
+
*/
|
|
332
|
+
destroy() {
|
|
333
|
+
this.axis = void 0;
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* Add logic to normalize the zoomed range in order to preserve the pressed
|
|
337
|
+
* state of range selector buttons
|
|
338
|
+
*
|
|
339
|
+
* @private
|
|
340
|
+
* @function Highcharts.Axis#toFixedRange
|
|
341
|
+
*/
|
|
342
|
+
toFixedRange(pxMin, pxMax, fixedMin, fixedMax) {
|
|
343
|
+
const axis = this.axis, chart = axis.chart, overscroll = pick(axis.ordinal?.convertOverscroll(axis.options.overscroll), 0);
|
|
344
|
+
let newMin = pick(fixedMin, axis.translate(pxMin, true, !axis.horiz)), newMax = pick(fixedMax, axis.translate(pxMax, true, !axis.horiz));
|
|
345
|
+
const fixedRange = chart && chart.fixedRange, halfPointRange = (axis.pointRange || 0) / 2;
|
|
346
|
+
// Add/remove half point range to/from the extremes (#1172)
|
|
347
|
+
if (!defined(fixedMin)) {
|
|
348
|
+
newMin = correctFloat(newMin + halfPointRange);
|
|
349
|
+
}
|
|
350
|
+
if (!defined(fixedMax)) {
|
|
351
|
+
newMax = correctFloat(newMax - halfPointRange);
|
|
352
|
+
}
|
|
353
|
+
// Make sure panning to the edges does not decrease the zoomed range
|
|
354
|
+
if (fixedRange && axis.dataMin && axis.dataMax) {
|
|
355
|
+
const maxWithOverscroll = axis.dataMax + overscroll;
|
|
356
|
+
if (newMax >= maxWithOverscroll) {
|
|
357
|
+
newMin = correctFloat(maxWithOverscroll - fixedRange);
|
|
358
|
+
newMax = correctFloat(maxWithOverscroll);
|
|
359
|
+
}
|
|
360
|
+
if (newMin <= axis.dataMin) {
|
|
361
|
+
newMax = correctFloat(axis.dataMin + fixedRange);
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
if (!isNumber(newMin) || !isNumber(newMax)) { // #1195, #7411
|
|
365
|
+
newMin = newMax = void 0;
|
|
366
|
+
}
|
|
367
|
+
return {
|
|
368
|
+
min: newMin,
|
|
369
|
+
max: newMax
|
|
370
|
+
};
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
/* *
|
|
374
|
+
*
|
|
375
|
+
* Default Export
|
|
376
|
+
*
|
|
377
|
+
* */
|
|
378
|
+
|
|
379
|
+
return NavigatorAxisAdditions;
|
|
380
|
+
});
|
|
381
|
+
_registerModule(_modules, 'Stock/Navigator/NavigatorDefaults.js', [_modules['Core/Color/Color.js'], _modules['Core/Series/SeriesRegistry.js']], function (Color, SeriesRegistry) {
|
|
382
|
+
/* *
|
|
383
|
+
*
|
|
384
|
+
* (c) 2010-2024 Torstein Honsi
|
|
385
|
+
*
|
|
386
|
+
* License: www.highcharts.com/license
|
|
387
|
+
*
|
|
388
|
+
* !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
|
|
389
|
+
*
|
|
390
|
+
* */
|
|
391
|
+
const { parse: color } = Color;
|
|
392
|
+
const { seriesTypes } = SeriesRegistry;
|
|
393
|
+
/* *
|
|
394
|
+
*
|
|
395
|
+
* Constants
|
|
396
|
+
*
|
|
397
|
+
* */
|
|
398
|
+
/**
|
|
399
|
+
* The navigator is a small series below the main series, displaying
|
|
400
|
+
* a view of the entire data set. It provides tools to zoom in and
|
|
401
|
+
* out on parts of the data as well as panning across the dataset.
|
|
402
|
+
*
|
|
403
|
+
* @product highstock gantt
|
|
404
|
+
* @optionparent navigator
|
|
405
|
+
*/
|
|
406
|
+
const NavigatorDefaults = {
|
|
407
|
+
/**
|
|
408
|
+
* Whether the navigator and scrollbar should adapt to updated data
|
|
409
|
+
* in the base X axis. When loading data async, as in the demo below,
|
|
410
|
+
* this should be `false`. Otherwise new data will trigger navigator
|
|
411
|
+
* redraw, which will cause unwanted looping. In the demo below, the
|
|
412
|
+
* data in the navigator is set only once. On navigating, only the main
|
|
413
|
+
* chart content is updated.
|
|
414
|
+
*
|
|
415
|
+
* @sample {highstock} stock/demo/lazy-loading/
|
|
416
|
+
* Set to false with async data loading
|
|
417
|
+
*
|
|
418
|
+
* @type {boolean}
|
|
419
|
+
* @default true
|
|
420
|
+
* @apioption navigator.adaptToUpdatedData
|
|
421
|
+
*/
|
|
422
|
+
/**
|
|
423
|
+
* An integer identifying the index to use for the base series, or a
|
|
424
|
+
* string representing the id of the series.
|
|
425
|
+
*
|
|
426
|
+
* **Note**: As of Highcharts 5.0, this is now a deprecated option.
|
|
427
|
+
* Prefer [series.showInNavigator](#plotOptions.series.showInNavigator).
|
|
428
|
+
*
|
|
429
|
+
* @see [series.showInNavigator](#plotOptions.series.showInNavigator)
|
|
430
|
+
*
|
|
431
|
+
* @deprecated
|
|
432
|
+
* @type {number|string}
|
|
433
|
+
* @default 0
|
|
434
|
+
* @apioption navigator.baseSeries
|
|
435
|
+
*/
|
|
436
|
+
/**
|
|
437
|
+
* Enable or disable the navigator.
|
|
438
|
+
*
|
|
439
|
+
* @sample {highstock} stock/navigator/enabled/
|
|
440
|
+
* Disable the navigator
|
|
441
|
+
*
|
|
442
|
+
* @type {boolean}
|
|
443
|
+
* @default true
|
|
444
|
+
* @apioption navigator.enabled
|
|
445
|
+
*/
|
|
446
|
+
/**
|
|
447
|
+
* When the chart is inverted, whether to draw the navigator on the
|
|
448
|
+
* opposite side.
|
|
449
|
+
*
|
|
450
|
+
* @type {boolean}
|
|
451
|
+
* @default false
|
|
452
|
+
* @since 5.0.8
|
|
453
|
+
* @apioption navigator.opposite
|
|
454
|
+
*/
|
|
455
|
+
/**
|
|
456
|
+
* The height of the navigator.
|
|
457
|
+
*
|
|
458
|
+
* @sample {highstock} stock/navigator/height/
|
|
459
|
+
* A higher navigator
|
|
460
|
+
*/
|
|
461
|
+
height: 40,
|
|
462
|
+
/**
|
|
463
|
+
* The distance from the nearest element, the X axis or X axis labels.
|
|
464
|
+
*
|
|
465
|
+
* @sample {highstock} stock/navigator/margin/
|
|
466
|
+
* A margin of 2 draws the navigator closer to the X axis labels
|
|
467
|
+
*/
|
|
468
|
+
margin: 25,
|
|
469
|
+
/**
|
|
470
|
+
* Whether the mask should be inside the range marking the zoomed
|
|
471
|
+
* range, or outside. In Highcharts Stock 1.x it was always `false`.
|
|
472
|
+
*
|
|
473
|
+
* @sample {highstock} stock/demo/maskinside-false/
|
|
474
|
+
* False, mask outside
|
|
475
|
+
*
|
|
476
|
+
* @since 2.0
|
|
477
|
+
*/
|
|
478
|
+
maskInside: true,
|
|
479
|
+
/**
|
|
480
|
+
* Options for the handles for dragging the zoomed area.
|
|
481
|
+
*
|
|
482
|
+
* @sample {highstock} stock/navigator/handles/
|
|
483
|
+
* Colored handles
|
|
484
|
+
*/
|
|
485
|
+
handles: {
|
|
486
|
+
/**
|
|
487
|
+
* Width for handles.
|
|
488
|
+
*
|
|
489
|
+
* @sample {highstock} stock/navigator/styled-handles/
|
|
490
|
+
* Styled handles
|
|
491
|
+
*
|
|
492
|
+
* @since 6.0.0
|
|
493
|
+
*/
|
|
494
|
+
width: 7,
|
|
495
|
+
/**
|
|
496
|
+
* Height for handles.
|
|
497
|
+
*
|
|
498
|
+
* @sample {highstock} stock/navigator/styled-handles/
|
|
499
|
+
* Styled handles
|
|
500
|
+
*
|
|
501
|
+
* @since 6.0.0
|
|
502
|
+
*/
|
|
503
|
+
height: 15,
|
|
504
|
+
/**
|
|
505
|
+
* Array to define shapes of handles. 0-index for left, 1-index for
|
|
506
|
+
* right.
|
|
507
|
+
*
|
|
508
|
+
* Additionally, the URL to a graphic can be given on this form:
|
|
509
|
+
* `url(graphic.png)`. Note that for the image to be applied to
|
|
510
|
+
* exported charts, its URL needs to be accessible by the export
|
|
511
|
+
* server.
|
|
512
|
+
*
|
|
513
|
+
* Custom callbacks for symbol path generation can also be added to
|
|
514
|
+
* `Highcharts.SVGRenderer.prototype.symbols`. The callback is then
|
|
515
|
+
* used by its method name, as shown in the demo.
|
|
516
|
+
*
|
|
517
|
+
* @sample {highstock} stock/navigator/styled-handles/
|
|
518
|
+
* Styled handles
|
|
519
|
+
*
|
|
520
|
+
* @type {Array<string>}
|
|
521
|
+
* @default ["navigator-handle", "navigator-handle"]
|
|
522
|
+
* @since 6.0.0
|
|
523
|
+
*/
|
|
524
|
+
symbols: ['navigator-handle', 'navigator-handle'],
|
|
525
|
+
/**
|
|
526
|
+
* Allows to enable/disable handles.
|
|
527
|
+
*
|
|
528
|
+
* @since 6.0.0
|
|
529
|
+
*/
|
|
530
|
+
enabled: true,
|
|
531
|
+
/**
|
|
532
|
+
* The width for the handle border and the stripes inside.
|
|
533
|
+
*
|
|
534
|
+
* @sample {highstock} stock/navigator/styled-handles/
|
|
535
|
+
* Styled handles
|
|
536
|
+
*
|
|
537
|
+
* @since 6.0.0
|
|
538
|
+
* @apioption navigator.handles.lineWidth
|
|
539
|
+
*/
|
|
540
|
+
lineWidth: 1,
|
|
541
|
+
/**
|
|
542
|
+
* The fill for the handle.
|
|
543
|
+
*
|
|
544
|
+
* @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
|
|
545
|
+
*/
|
|
546
|
+
backgroundColor: "#f2f2f2" /* Palette.neutralColor5 */,
|
|
547
|
+
/**
|
|
548
|
+
* The stroke for the handle border and the stripes inside.
|
|
549
|
+
*
|
|
550
|
+
* @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
|
|
551
|
+
*/
|
|
552
|
+
borderColor: "#999999" /* Palette.neutralColor40 */
|
|
553
|
+
},
|
|
554
|
+
/**
|
|
555
|
+
* The color of the mask covering the areas of the navigator series
|
|
556
|
+
* that are currently not visible in the main series. The default
|
|
557
|
+
* color is bluish with an opacity of 0.3 to see the series below.
|
|
558
|
+
*
|
|
559
|
+
* @see In styled mode, the mask is styled with the
|
|
560
|
+
* `.highcharts-navigator-mask` and
|
|
561
|
+
* `.highcharts-navigator-mask-inside` classes.
|
|
562
|
+
*
|
|
563
|
+
* @sample {highstock} stock/navigator/maskfill/
|
|
564
|
+
* Blue, semi transparent mask
|
|
565
|
+
*
|
|
566
|
+
* @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
|
|
567
|
+
* @default rgba(102,133,194,0.3)
|
|
568
|
+
*/
|
|
569
|
+
maskFill: color("#667aff" /* Palette.highlightColor60 */).setOpacity(0.3).get(),
|
|
570
|
+
/**
|
|
571
|
+
* The color of the line marking the currently zoomed area in the
|
|
572
|
+
* navigator.
|
|
573
|
+
*
|
|
574
|
+
* @sample {highstock} stock/navigator/outline/
|
|
575
|
+
* 2px blue outline
|
|
576
|
+
*
|
|
577
|
+
* @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
|
|
578
|
+
* @default #cccccc
|
|
579
|
+
*/
|
|
580
|
+
outlineColor: "#999999" /* Palette.neutralColor40 */,
|
|
581
|
+
/**
|
|
582
|
+
* The width of the line marking the currently zoomed area in the
|
|
583
|
+
* navigator.
|
|
584
|
+
*
|
|
585
|
+
* @see In styled mode, the outline stroke width is set with the
|
|
586
|
+
* `.highcharts-navigator-outline` class.
|
|
587
|
+
*
|
|
588
|
+
* @sample {highstock} stock/navigator/outline/
|
|
589
|
+
* 2px blue outline
|
|
590
|
+
*
|
|
591
|
+
* @type {number}
|
|
592
|
+
*/
|
|
593
|
+
outlineWidth: 1,
|
|
594
|
+
/**
|
|
595
|
+
* Options for the navigator series. Available options are the same
|
|
596
|
+
* as any series, documented at [plotOptions](#plotOptions.series)
|
|
597
|
+
* and [series](#series).
|
|
598
|
+
*
|
|
599
|
+
* Unless data is explicitly defined on navigator.series, the data
|
|
600
|
+
* is borrowed from the first series in the chart.
|
|
601
|
+
*
|
|
602
|
+
* Default series options for the navigator series are:
|
|
603
|
+
* ```js
|
|
604
|
+
* series: {
|
|
605
|
+
* type: 'areaspline',
|
|
606
|
+
* fillOpacity: 0.05,
|
|
607
|
+
* dataGrouping: {
|
|
608
|
+
* smoothed: true
|
|
609
|
+
* },
|
|
610
|
+
* lineWidth: 1,
|
|
611
|
+
* marker: {
|
|
612
|
+
* enabled: false
|
|
613
|
+
* }
|
|
614
|
+
* }
|
|
615
|
+
* ```
|
|
616
|
+
*
|
|
617
|
+
* @see In styled mode, the navigator series is styled with the
|
|
618
|
+
* `.highcharts-navigator-series` class.
|
|
619
|
+
*
|
|
620
|
+
* @sample {highstock} stock/navigator/series-data/
|
|
621
|
+
* Using a separate data set for the navigator
|
|
622
|
+
* @sample {highstock} stock/navigator/series/
|
|
623
|
+
* A green navigator series
|
|
624
|
+
*
|
|
625
|
+
* @type {*|Array<*>|Highcharts.SeriesOptionsType|Array<Highcharts.SeriesOptionsType>}
|
|
626
|
+
*/
|
|
627
|
+
series: {
|
|
628
|
+
/**
|
|
629
|
+
* The type of the navigator series.
|
|
630
|
+
*
|
|
631
|
+
* Heads up:
|
|
632
|
+
* In column-type navigator, zooming is limited to at least one
|
|
633
|
+
* point with its `pointRange`.
|
|
634
|
+
*
|
|
635
|
+
* @sample {highstock} stock/navigator/column/
|
|
636
|
+
* Column type navigator
|
|
637
|
+
*
|
|
638
|
+
* @type {string}
|
|
639
|
+
* @default {highstock} `areaspline` if defined, otherwise `line`
|
|
640
|
+
* @default {gantt} gantt
|
|
641
|
+
*/
|
|
642
|
+
type: (typeof seriesTypes.areaspline === 'undefined' ?
|
|
643
|
+
'line' :
|
|
644
|
+
'areaspline'),
|
|
645
|
+
/**
|
|
646
|
+
* The fill opacity of the navigator series.
|
|
647
|
+
*/
|
|
648
|
+
fillOpacity: 0.05,
|
|
649
|
+
/**
|
|
650
|
+
* The pixel line width of the navigator series.
|
|
651
|
+
*/
|
|
652
|
+
lineWidth: 1,
|
|
653
|
+
/**
|
|
654
|
+
* @ignore-option
|
|
655
|
+
*/
|
|
656
|
+
compare: null,
|
|
657
|
+
/**
|
|
658
|
+
* @ignore-option
|
|
659
|
+
*/
|
|
660
|
+
sonification: {
|
|
661
|
+
enabled: false
|
|
662
|
+
},
|
|
663
|
+
/**
|
|
664
|
+
* Unless data is explicitly defined, the data is borrowed from the
|
|
665
|
+
* first series in the chart.
|
|
666
|
+
*
|
|
667
|
+
* @type {Array<number|Array<number|string|null>|object|null>}
|
|
668
|
+
* @product highstock
|
|
669
|
+
* @apioption navigator.series.data
|
|
670
|
+
*/
|
|
671
|
+
/**
|
|
672
|
+
* Data grouping options for the navigator series.
|
|
673
|
+
*
|
|
674
|
+
* @extends plotOptions.series.dataGrouping
|
|
675
|
+
*/
|
|
676
|
+
dataGrouping: {
|
|
677
|
+
approximation: 'average',
|
|
678
|
+
enabled: true,
|
|
679
|
+
groupPixelWidth: 2,
|
|
680
|
+
// Replace smoothed property by anchors, #12455.
|
|
681
|
+
firstAnchor: 'firstPoint',
|
|
682
|
+
anchor: 'middle',
|
|
683
|
+
lastAnchor: 'lastPoint',
|
|
684
|
+
// Day and week differs from plotOptions.series.dataGrouping
|
|
685
|
+
units: [
|
|
686
|
+
['millisecond', [1, 2, 5, 10, 20, 25, 50, 100, 200, 500]],
|
|
687
|
+
['second', [1, 2, 5, 10, 15, 30]],
|
|
688
|
+
['minute', [1, 2, 5, 10, 15, 30]],
|
|
689
|
+
['hour', [1, 2, 3, 4, 6, 8, 12]],
|
|
690
|
+
['day', [1, 2, 3, 4]],
|
|
691
|
+
['week', [1, 2, 3]],
|
|
692
|
+
['month', [1, 3, 6]],
|
|
693
|
+
['year', null]
|
|
694
|
+
]
|
|
695
|
+
},
|
|
696
|
+
/**
|
|
697
|
+
* Data label options for the navigator series. Data labels are
|
|
698
|
+
* disabled by default on the navigator series.
|
|
699
|
+
*
|
|
700
|
+
* @extends plotOptions.series.dataLabels
|
|
701
|
+
*/
|
|
702
|
+
dataLabels: {
|
|
703
|
+
enabled: false,
|
|
704
|
+
zIndex: 2 // #1839
|
|
705
|
+
},
|
|
706
|
+
id: 'highcharts-navigator-series',
|
|
707
|
+
className: 'highcharts-navigator-series',
|
|
708
|
+
/**
|
|
709
|
+
* Sets the fill color of the navigator series.
|
|
710
|
+
*
|
|
711
|
+
* @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
|
|
712
|
+
* @apioption navigator.series.color
|
|
713
|
+
*/
|
|
714
|
+
/**
|
|
715
|
+
* Line color for the navigator series. Allows setting the color
|
|
716
|
+
* while disallowing the default candlestick setting.
|
|
717
|
+
*
|
|
718
|
+
* @type {Highcharts.ColorString|null}
|
|
719
|
+
*/
|
|
720
|
+
lineColor: null,
|
|
721
|
+
marker: {
|
|
722
|
+
enabled: false
|
|
723
|
+
},
|
|
724
|
+
/**
|
|
725
|
+
* Since Highcharts Stock v8, default value is the same as default
|
|
726
|
+
* `pointRange` defined for a specific type (e.g. `null` for
|
|
727
|
+
* column type).
|
|
728
|
+
*
|
|
729
|
+
* In Highcharts Stock version < 8, defaults to 0.
|
|
730
|
+
*
|
|
731
|
+
* @extends plotOptions.series.pointRange
|
|
732
|
+
* @type {number|null}
|
|
733
|
+
* @apioption navigator.series.pointRange
|
|
734
|
+
*/
|
|
735
|
+
/**
|
|
736
|
+
* The threshold option. Setting it to 0 will make the default
|
|
737
|
+
* navigator area series draw its area from the 0 value and up.
|
|
738
|
+
*
|
|
739
|
+
* @type {number|null}
|
|
740
|
+
*/
|
|
741
|
+
threshold: null
|
|
742
|
+
},
|
|
743
|
+
/**
|
|
744
|
+
* Enable or disable navigator sticking to right, while adding new
|
|
745
|
+
* points. If `undefined`, the navigator sticks to the axis maximum only
|
|
746
|
+
* if it was already at the maximum prior to adding points.
|
|
747
|
+
*
|
|
748
|
+
* @type {boolean}
|
|
749
|
+
* @default undefined
|
|
750
|
+
* @since 10.2.1
|
|
751
|
+
* @sample {highstock} stock/navigator/sticktomax-false/
|
|
752
|
+
* stickToMax set to false
|
|
753
|
+
* @apioption navigator.stickToMax
|
|
754
|
+
*/
|
|
755
|
+
/**
|
|
756
|
+
* Options for the navigator X axis. Default series options for the
|
|
757
|
+
* navigator xAxis are:
|
|
758
|
+
* ```js
|
|
759
|
+
* xAxis: {
|
|
760
|
+
* tickWidth: 0,
|
|
761
|
+
* lineWidth: 0,
|
|
762
|
+
* gridLineWidth: 1,
|
|
763
|
+
* tickPixelInterval: 200,
|
|
764
|
+
* labels: {
|
|
765
|
+
* align: 'left',
|
|
766
|
+
* style: {
|
|
767
|
+
* color: '#888'
|
|
768
|
+
* },
|
|
769
|
+
* x: 3,
|
|
770
|
+
* y: -4
|
|
771
|
+
* }
|
|
772
|
+
* }
|
|
773
|
+
* ```
|
|
774
|
+
*
|
|
775
|
+
* @extends xAxis
|
|
776
|
+
* @excluding linkedTo, maxZoom, minRange, opposite, range, scrollbar,
|
|
777
|
+
* showEmpty, maxRange
|
|
778
|
+
*/
|
|
779
|
+
xAxis: {
|
|
780
|
+
/**
|
|
781
|
+
* Additional range on the right side of the xAxis. Works similar to
|
|
782
|
+
* `xAxis.maxPadding`, but the value is set in terms of axis values,
|
|
783
|
+
* percentage or pixels.
|
|
784
|
+
*
|
|
785
|
+
* If it's a number, it is interpreted as axis values, which in a
|
|
786
|
+
* datetime axis equals milliseconds.
|
|
787
|
+
*
|
|
788
|
+
* If it's a percentage string, is interpreted as percentages of the
|
|
789
|
+
* axis length. An overscroll of 50% will make a 100px axis 50px longer.
|
|
790
|
+
*
|
|
791
|
+
* If it's a pixel string, it is interpreted as a fixed pixel value, but
|
|
792
|
+
* limited to 90% of the axis length.
|
|
793
|
+
*
|
|
794
|
+
* If it's undefined, the value is inherited from `xAxis.overscroll`.
|
|
795
|
+
*
|
|
796
|
+
* Can be set for both, main xAxis and navigator's xAxis.
|
|
797
|
+
*
|
|
798
|
+
* @type {number | string | undefined}
|
|
799
|
+
* @since 6.0.0
|
|
800
|
+
* @apioption navigator.xAxis.overscroll
|
|
801
|
+
*/
|
|
802
|
+
className: 'highcharts-navigator-xaxis',
|
|
803
|
+
tickLength: 0,
|
|
804
|
+
lineWidth: 0,
|
|
805
|
+
gridLineColor: "#e6e6e6" /* Palette.neutralColor10 */,
|
|
806
|
+
gridLineWidth: 1,
|
|
807
|
+
tickPixelInterval: 200,
|
|
808
|
+
labels: {
|
|
809
|
+
align: 'left',
|
|
810
|
+
/**
|
|
811
|
+
* @type {Highcharts.CSSObject}
|
|
812
|
+
*/
|
|
813
|
+
style: {
|
|
814
|
+
/** @ignore */
|
|
815
|
+
color: "#000000" /* Palette.neutralColor100 */,
|
|
816
|
+
/** @ignore */
|
|
817
|
+
fontSize: '0.7em',
|
|
818
|
+
/** @ignore */
|
|
819
|
+
opacity: 0.6,
|
|
820
|
+
/** @ignore */
|
|
821
|
+
textOutline: '2px contrast'
|
|
822
|
+
},
|
|
823
|
+
x: 3,
|
|
824
|
+
y: -4
|
|
825
|
+
},
|
|
826
|
+
crosshair: false
|
|
827
|
+
},
|
|
828
|
+
/**
|
|
829
|
+
* Options for the navigator Y axis. Default series options for the
|
|
830
|
+
* navigator yAxis are:
|
|
831
|
+
* ```js
|
|
832
|
+
* yAxis: {
|
|
833
|
+
* gridLineWidth: 0,
|
|
834
|
+
* startOnTick: false,
|
|
835
|
+
* endOnTick: false,
|
|
836
|
+
* minPadding: 0.1,
|
|
837
|
+
* maxPadding: 0.1,
|
|
838
|
+
* labels: {
|
|
839
|
+
* enabled: false
|
|
840
|
+
* },
|
|
841
|
+
* title: {
|
|
842
|
+
* text: null
|
|
843
|
+
* },
|
|
844
|
+
* tickWidth: 0
|
|
845
|
+
* }
|
|
846
|
+
* ```
|
|
847
|
+
*
|
|
848
|
+
* @extends yAxis
|
|
849
|
+
* @excluding height, linkedTo, maxZoom, minRange, ordinal, range,
|
|
850
|
+
* showEmpty, scrollbar, top, units, maxRange, minLength,
|
|
851
|
+
* maxLength, resize
|
|
852
|
+
*/
|
|
853
|
+
yAxis: {
|
|
854
|
+
className: 'highcharts-navigator-yaxis',
|
|
855
|
+
gridLineWidth: 0,
|
|
856
|
+
startOnTick: false,
|
|
857
|
+
endOnTick: false,
|
|
858
|
+
minPadding: 0.1,
|
|
859
|
+
maxPadding: 0.1,
|
|
860
|
+
labels: {
|
|
861
|
+
enabled: false
|
|
862
|
+
},
|
|
863
|
+
crosshair: false,
|
|
864
|
+
title: {
|
|
865
|
+
text: null
|
|
866
|
+
},
|
|
867
|
+
tickLength: 0,
|
|
868
|
+
tickWidth: 0
|
|
869
|
+
}
|
|
870
|
+
};
|
|
871
|
+
/* *
|
|
872
|
+
*
|
|
873
|
+
* Default Export
|
|
874
|
+
*
|
|
875
|
+
* */
|
|
876
|
+
/* *
|
|
877
|
+
*
|
|
878
|
+
* API Options
|
|
879
|
+
*
|
|
880
|
+
* */
|
|
881
|
+
/**
|
|
882
|
+
* Maximum range which can be set using the navigator's handles.
|
|
883
|
+
* Opposite of [xAxis.minRange](#xAxis.minRange).
|
|
884
|
+
*
|
|
885
|
+
* @sample {highstock} stock/navigator/maxrange/
|
|
886
|
+
* Defined max and min range
|
|
887
|
+
*
|
|
888
|
+
* @type {number}
|
|
889
|
+
* @since 6.0.0
|
|
890
|
+
* @product highstock gantt
|
|
891
|
+
* @apioption xAxis.maxRange
|
|
892
|
+
*/
|
|
893
|
+
(''); // keeps doclets above in JS file
|
|
894
|
+
|
|
895
|
+
return NavigatorDefaults;
|
|
896
|
+
});
|
|
897
|
+
_registerModule(_modules, 'Stock/Navigator/NavigatorSymbols.js', [], function () {
|
|
898
|
+
/* *
|
|
899
|
+
*
|
|
900
|
+
* (c) 2010-2024 Torstein Honsi
|
|
901
|
+
*
|
|
902
|
+
* License: www.highcharts.com/license
|
|
903
|
+
*
|
|
904
|
+
* !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
|
|
905
|
+
*
|
|
906
|
+
* */
|
|
907
|
+
/* *
|
|
908
|
+
*
|
|
909
|
+
* Constants
|
|
910
|
+
*
|
|
911
|
+
* */
|
|
912
|
+
/**
|
|
913
|
+
* Draw one of the handles on the side of the zoomed range in the navigator.
|
|
914
|
+
* @private
|
|
915
|
+
*/
|
|
916
|
+
function navigatorHandle(_x, _y, width, height, options = {}) {
|
|
917
|
+
const halfWidth = options.width ? options.width / 2 : width, markerPosition = Math.round(halfWidth / 3) + 0.5;
|
|
918
|
+
height = options.height || height;
|
|
919
|
+
return [
|
|
920
|
+
['M', -halfWidth - 1, 0.5],
|
|
921
|
+
['L', halfWidth, 0.5],
|
|
922
|
+
['L', halfWidth, height + 0.5],
|
|
923
|
+
['L', -halfWidth - 1, height + 0.5],
|
|
924
|
+
['L', -halfWidth - 1, 0.5],
|
|
925
|
+
['M', -markerPosition, 4],
|
|
926
|
+
['L', -markerPosition, height - 3],
|
|
927
|
+
['M', markerPosition - 1, 4],
|
|
928
|
+
['L', markerPosition - 1, height - 3]
|
|
929
|
+
];
|
|
930
|
+
}
|
|
931
|
+
/* *
|
|
932
|
+
*
|
|
933
|
+
* Default Export
|
|
934
|
+
*
|
|
935
|
+
* */
|
|
936
|
+
const NavigatorSymbols = {
|
|
937
|
+
'navigator-handle': navigatorHandle
|
|
938
|
+
};
|
|
939
|
+
|
|
940
|
+
return NavigatorSymbols;
|
|
941
|
+
});
|
|
942
|
+
_registerModule(_modules, 'Stock/Utilities/StockUtilities.js', [_modules['Core/Utilities.js']], function (U) {
|
|
943
|
+
/* *
|
|
944
|
+
*
|
|
945
|
+
* (c) 2010-2024 Torstein Honsi
|
|
946
|
+
*
|
|
947
|
+
* License: www.highcharts.com/license
|
|
948
|
+
*
|
|
949
|
+
* !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
|
|
950
|
+
*
|
|
951
|
+
* */
|
|
952
|
+
const { defined } = U;
|
|
953
|
+
/* *
|
|
954
|
+
*
|
|
955
|
+
* Functions
|
|
956
|
+
*
|
|
957
|
+
* */
|
|
958
|
+
/**
|
|
959
|
+
* Sets the chart.fixedRange to the specified value. If the value is larger
|
|
960
|
+
* than actual range, sets it to the maximum possible range. (#20327)
|
|
961
|
+
*
|
|
962
|
+
* @private
|
|
963
|
+
* @function Highcharts.StockChart#setFixedRange
|
|
964
|
+
* @param {number|undefined} range
|
|
965
|
+
* Range to set in axis units.
|
|
966
|
+
*/
|
|
967
|
+
function setFixedRange(range) {
|
|
968
|
+
const xAxis = this.xAxis[0];
|
|
969
|
+
if (defined(xAxis.dataMax) &&
|
|
970
|
+
defined(xAxis.dataMin) &&
|
|
971
|
+
range) {
|
|
972
|
+
this.fixedRange = Math.min(range, xAxis.dataMax - xAxis.dataMin);
|
|
973
|
+
}
|
|
974
|
+
else {
|
|
975
|
+
this.fixedRange = range;
|
|
976
|
+
}
|
|
977
|
+
}
|
|
978
|
+
const StockUtilities = {
|
|
979
|
+
setFixedRange
|
|
980
|
+
};
|
|
981
|
+
|
|
982
|
+
return StockUtilities;
|
|
983
|
+
});
|
|
984
|
+
_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) {
|
|
985
|
+
/* *
|
|
986
|
+
*
|
|
987
|
+
* (c) 2010-2024 Torstein Honsi
|
|
988
|
+
*
|
|
989
|
+
* License: www.highcharts.com/license
|
|
990
|
+
*
|
|
991
|
+
* !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
|
|
992
|
+
*
|
|
993
|
+
* */
|
|
994
|
+
const { setOptions } = D;
|
|
995
|
+
const { composed } = H;
|
|
996
|
+
const { getRendererType } = RendererRegistry;
|
|
997
|
+
const { setFixedRange } = StockUtilities;
|
|
998
|
+
const { addEvent, extend, pushUnique } = U;
|
|
999
|
+
/* *
|
|
1000
|
+
*
|
|
1001
|
+
* Variables
|
|
1002
|
+
*
|
|
1003
|
+
* */
|
|
1004
|
+
/* *
|
|
1005
|
+
*
|
|
1006
|
+
* Functions
|
|
1007
|
+
*
|
|
1008
|
+
* */
|
|
1009
|
+
/**
|
|
1010
|
+
* @private
|
|
1011
|
+
*/
|
|
1012
|
+
function compose(ChartClass, AxisClass, SeriesClass) {
|
|
1013
|
+
NavigatorAxisAdditions.compose(AxisClass);
|
|
1014
|
+
if (pushUnique(composed, 'Navigator')) {
|
|
1015
|
+
ChartClass.prototype.setFixedRange = setFixedRange;
|
|
1016
|
+
extend(getRendererType().prototype.symbols, NavigatorSymbols);
|
|
1017
|
+
addEvent(SeriesClass, 'afterUpdate', onSeriesAfterUpdate);
|
|
1018
|
+
setOptions({ navigator: NavigatorDefaults });
|
|
1019
|
+
}
|
|
1020
|
+
}
|
|
1021
|
+
/**
|
|
1022
|
+
* Handle updating series
|
|
1023
|
+
* @private
|
|
1024
|
+
*/
|
|
1025
|
+
function onSeriesAfterUpdate() {
|
|
1026
|
+
if (this.chart.navigator && !this.options.isInternal) {
|
|
1027
|
+
this.chart.navigator.setBaseSeries(null, false);
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1030
|
+
/* *
|
|
1031
|
+
*
|
|
1032
|
+
* Default Export
|
|
1033
|
+
*
|
|
1034
|
+
* */
|
|
1035
|
+
const NavigatorComposition = {
|
|
1036
|
+
compose
|
|
1037
|
+
};
|
|
1038
|
+
|
|
1039
|
+
return NavigatorComposition;
|
|
1040
|
+
});
|
|
1041
|
+
_registerModule(_modules, 'Core/Axis/ScrollbarAxis.js', [_modules['Core/Globals.js'], _modules['Core/Utilities.js']], function (H, U) {
|
|
1042
|
+
/* *
|
|
1043
|
+
*
|
|
1044
|
+
* (c) 2010-2024 Torstein Honsi
|
|
1045
|
+
*
|
|
1046
|
+
* License: www.highcharts.com/license
|
|
1047
|
+
*
|
|
1048
|
+
* !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
|
|
1049
|
+
*
|
|
1050
|
+
* */
|
|
1051
|
+
const { composed } = H;
|
|
1052
|
+
const { addEvent, defined, pick, pushUnique } = U;
|
|
1053
|
+
/* *
|
|
1054
|
+
*
|
|
1055
|
+
* Composition
|
|
1056
|
+
*
|
|
1057
|
+
* */
|
|
1058
|
+
var ScrollbarAxis;
|
|
1059
|
+
(function (ScrollbarAxis) {
|
|
1060
|
+
/* *
|
|
1061
|
+
*
|
|
1062
|
+
* Variables
|
|
1063
|
+
*
|
|
1064
|
+
* */
|
|
1065
|
+
let Scrollbar;
|
|
1066
|
+
/* *
|
|
1067
|
+
*
|
|
1068
|
+
* Functions
|
|
1069
|
+
*
|
|
1070
|
+
* */
|
|
1071
|
+
/**
|
|
1072
|
+
* Attaches to axis events to create scrollbars if enabled.
|
|
1073
|
+
*
|
|
1074
|
+
* @private
|
|
1075
|
+
*
|
|
1076
|
+
* @param {Highcharts.Axis} AxisClass
|
|
1077
|
+
* Axis class to extend.
|
|
1078
|
+
*
|
|
1079
|
+
* @param {Highcharts.Scrollbar} ScrollbarClass
|
|
1080
|
+
* Scrollbar class to use.
|
|
1081
|
+
*/
|
|
1082
|
+
function compose(AxisClass, ScrollbarClass) {
|
|
1083
|
+
if (pushUnique(composed, 'Axis.Scrollbar')) {
|
|
1084
|
+
Scrollbar = ScrollbarClass;
|
|
1085
|
+
addEvent(AxisClass, 'afterGetOffset', onAxisAfterGetOffset);
|
|
1086
|
+
addEvent(AxisClass, 'afterInit', onAxisAfterInit);
|
|
1087
|
+
addEvent(AxisClass, 'afterRender', onAxisAfterRender);
|
|
1088
|
+
}
|
|
1089
|
+
}
|
|
1090
|
+
ScrollbarAxis.compose = compose;
|
|
1091
|
+
/** @private */
|
|
1092
|
+
function getExtremes(axis) {
|
|
1093
|
+
const axisMin = pick(axis.options && axis.options.min, axis.min);
|
|
1094
|
+
const axisMax = pick(axis.options && axis.options.max, axis.max);
|
|
1095
|
+
return {
|
|
1096
|
+
axisMin,
|
|
1097
|
+
axisMax,
|
|
1098
|
+
scrollMin: defined(axis.dataMin) ?
|
|
1099
|
+
Math.min(axisMin, axis.min, axis.dataMin, pick(axis.threshold, Infinity)) : axisMin,
|
|
1100
|
+
scrollMax: defined(axis.dataMax) ?
|
|
1101
|
+
Math.max(axisMax, axis.max, axis.dataMax, pick(axis.threshold, -Infinity)) : axisMax
|
|
1102
|
+
};
|
|
1103
|
+
}
|
|
1104
|
+
/**
|
|
1105
|
+
* Make space for a scrollbar.
|
|
1106
|
+
* @private
|
|
1107
|
+
*/
|
|
1108
|
+
function onAxisAfterGetOffset() {
|
|
1109
|
+
const axis = this, scrollbar = axis.scrollbar, opposite = scrollbar && !scrollbar.options.opposite, index = axis.horiz ? 2 : opposite ? 3 : 1;
|
|
1110
|
+
if (scrollbar) {
|
|
1111
|
+
// Reset scrollbars offsets
|
|
1112
|
+
axis.chart.scrollbarsOffsets = [0, 0];
|
|
1113
|
+
axis.chart.axisOffset[index] +=
|
|
1114
|
+
scrollbar.size + (scrollbar.options.margin || 0);
|
|
1115
|
+
}
|
|
1116
|
+
}
|
|
1117
|
+
/**
|
|
1118
|
+
* Wrap axis initialization and create scrollbar if enabled.
|
|
1119
|
+
* @private
|
|
1120
|
+
*/
|
|
1121
|
+
function onAxisAfterInit() {
|
|
1122
|
+
const axis = this;
|
|
1123
|
+
if (axis.options &&
|
|
1124
|
+
axis.options.scrollbar &&
|
|
1125
|
+
axis.options.scrollbar.enabled) {
|
|
1126
|
+
// Predefined options:
|
|
1127
|
+
axis.options.scrollbar.vertical = !axis.horiz;
|
|
1128
|
+
axis.options.startOnTick = axis.options.endOnTick = false;
|
|
1129
|
+
axis.scrollbar = new Scrollbar(axis.chart.renderer, axis.options.scrollbar, axis.chart);
|
|
1130
|
+
addEvent(axis.scrollbar, 'changed', function (e) {
|
|
1131
|
+
const { axisMin, axisMax, scrollMin: unitedMin, scrollMax: unitedMax } = getExtremes(axis), range = unitedMax - unitedMin;
|
|
1132
|
+
let to, from;
|
|
1133
|
+
// #12834, scroll when show/hide series, wrong extremes
|
|
1134
|
+
if (!defined(axisMin) || !defined(axisMax)) {
|
|
1135
|
+
return;
|
|
1136
|
+
}
|
|
1137
|
+
if ((axis.horiz && !axis.reversed) ||
|
|
1138
|
+
(!axis.horiz && axis.reversed)) {
|
|
1139
|
+
to = unitedMin + range * this.to;
|
|
1140
|
+
from = unitedMin + range * this.from;
|
|
1141
|
+
}
|
|
1142
|
+
else {
|
|
1143
|
+
// Y-values in browser are reversed, but this also
|
|
1144
|
+
// applies for reversed horizontal axis:
|
|
1145
|
+
to = unitedMin + range * (1 - this.from);
|
|
1146
|
+
from = unitedMin + range * (1 - this.to);
|
|
1147
|
+
}
|
|
1148
|
+
if (this.shouldUpdateExtremes(e.DOMType)) {
|
|
1149
|
+
// #17977, set animation to undefined instead of true
|
|
1150
|
+
const animate = e.DOMType === 'mousemove' ||
|
|
1151
|
+
e.DOMType === 'touchmove' ? false : void 0;
|
|
1152
|
+
axis.setExtremes(from, to, true, animate, e);
|
|
1153
|
+
}
|
|
1154
|
+
else {
|
|
1155
|
+
// When live redraw is disabled, don't change extremes
|
|
1156
|
+
// Only change the position of the scrollbar thumb
|
|
1157
|
+
this.setRange(this.from, this.to);
|
|
1158
|
+
}
|
|
1159
|
+
});
|
|
1160
|
+
}
|
|
1161
|
+
}
|
|
1162
|
+
/**
|
|
1163
|
+
* Wrap rendering axis, and update scrollbar if one is created.
|
|
1164
|
+
* @private
|
|
1165
|
+
*/
|
|
1166
|
+
function onAxisAfterRender() {
|
|
1167
|
+
const axis = this, { scrollMin, scrollMax } = getExtremes(axis), scrollbar = axis.scrollbar, offset = (axis.axisTitleMargin + (axis.titleOffset || 0)), scrollbarsOffsets = axis.chart.scrollbarsOffsets, axisMargin = axis.options.margin || 0;
|
|
1168
|
+
let offsetsIndex, from, to;
|
|
1169
|
+
if (scrollbar && scrollbarsOffsets) {
|
|
1170
|
+
if (axis.horiz) {
|
|
1171
|
+
// Reserve space for labels/title
|
|
1172
|
+
if (!axis.opposite) {
|
|
1173
|
+
scrollbarsOffsets[1] += offset;
|
|
1174
|
+
}
|
|
1175
|
+
scrollbar.position(axis.left, (axis.top +
|
|
1176
|
+
axis.height +
|
|
1177
|
+
2 +
|
|
1178
|
+
scrollbarsOffsets[1] -
|
|
1179
|
+
(axis.opposite ? axisMargin : 0)), axis.width, axis.height);
|
|
1180
|
+
// Next scrollbar should reserve space for margin (if set)
|
|
1181
|
+
if (!axis.opposite) {
|
|
1182
|
+
scrollbarsOffsets[1] += axisMargin;
|
|
1183
|
+
}
|
|
1184
|
+
offsetsIndex = 1;
|
|
1185
|
+
}
|
|
1186
|
+
else {
|
|
1187
|
+
// Reserve space for labels/title
|
|
1188
|
+
if (axis.opposite) {
|
|
1189
|
+
scrollbarsOffsets[0] += offset;
|
|
1190
|
+
}
|
|
1191
|
+
let xPosition;
|
|
1192
|
+
if (!scrollbar.options.opposite) {
|
|
1193
|
+
xPosition = axis.opposite ? 0 : axisMargin;
|
|
1194
|
+
}
|
|
1195
|
+
else {
|
|
1196
|
+
xPosition = axis.left +
|
|
1197
|
+
axis.width +
|
|
1198
|
+
2 +
|
|
1199
|
+
scrollbarsOffsets[0] -
|
|
1200
|
+
(axis.opposite ? 0 : axisMargin);
|
|
1201
|
+
}
|
|
1202
|
+
scrollbar.position(xPosition, axis.top, axis.width, axis.height);
|
|
1203
|
+
// Next scrollbar should reserve space for margin (if set)
|
|
1204
|
+
if (axis.opposite) {
|
|
1205
|
+
scrollbarsOffsets[0] += axisMargin;
|
|
1206
|
+
}
|
|
1207
|
+
offsetsIndex = 0;
|
|
1208
|
+
}
|
|
1209
|
+
scrollbarsOffsets[offsetsIndex] += scrollbar.size +
|
|
1210
|
+
(scrollbar.options.margin || 0);
|
|
1211
|
+
if (isNaN(scrollMin) ||
|
|
1212
|
+
isNaN(scrollMax) ||
|
|
1213
|
+
!defined(axis.min) ||
|
|
1214
|
+
!defined(axis.max) ||
|
|
1215
|
+
axis.min === axis.max // #10733
|
|
1216
|
+
) {
|
|
1217
|
+
// Default action: when extremes are the same or there is
|
|
1218
|
+
// not extremes on the axis, but scrollbar exists, make it
|
|
1219
|
+
// full size
|
|
1220
|
+
scrollbar.setRange(0, 1);
|
|
1221
|
+
}
|
|
1222
|
+
else {
|
|
1223
|
+
from = ((axis.min - scrollMin) /
|
|
1224
|
+
(scrollMax - scrollMin));
|
|
1225
|
+
to = ((axis.max - scrollMin) /
|
|
1226
|
+
(scrollMax - scrollMin));
|
|
1227
|
+
if ((axis.horiz && !axis.reversed) ||
|
|
1228
|
+
(!axis.horiz && axis.reversed)) {
|
|
1229
|
+
scrollbar.setRange(from, to);
|
|
1230
|
+
}
|
|
1231
|
+
else {
|
|
1232
|
+
// Inverse vertical axis
|
|
1233
|
+
scrollbar.setRange(1 - to, 1 - from);
|
|
1234
|
+
}
|
|
1235
|
+
}
|
|
1236
|
+
}
|
|
1237
|
+
}
|
|
1238
|
+
})(ScrollbarAxis || (ScrollbarAxis = {}));
|
|
1239
|
+
/* *
|
|
1240
|
+
*
|
|
1241
|
+
* Default Export
|
|
1242
|
+
*
|
|
1243
|
+
* */
|
|
1244
|
+
|
|
1245
|
+
return ScrollbarAxis;
|
|
1246
|
+
});
|
|
1247
|
+
_registerModule(_modules, 'Stock/Scrollbar/ScrollbarDefaults.js', [], function () {
|
|
1248
|
+
/* *
|
|
1249
|
+
*
|
|
1250
|
+
* (c) 2010-2024 Torstein Honsi
|
|
1251
|
+
*
|
|
1252
|
+
* License: www.highcharts.com/license
|
|
1253
|
+
*
|
|
1254
|
+
* !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
|
|
1255
|
+
*
|
|
1256
|
+
* */
|
|
1257
|
+
/* *
|
|
1258
|
+
*
|
|
1259
|
+
* Constant
|
|
1260
|
+
*
|
|
1261
|
+
* */
|
|
1262
|
+
/**
|
|
1263
|
+
*
|
|
1264
|
+
* The scrollbar is a means of panning over the X axis of a stock chart.
|
|
1265
|
+
* Scrollbars can also be applied to other types of axes.
|
|
1266
|
+
*
|
|
1267
|
+
* Another approach to scrollable charts is the [chart.scrollablePlotArea](
|
|
1268
|
+
* https://api.highcharts.com/highcharts/chart.scrollablePlotArea) option that
|
|
1269
|
+
* is especially suitable for simpler cartesian charts on mobile.
|
|
1270
|
+
*
|
|
1271
|
+
* In styled mode, all the presentational options for the
|
|
1272
|
+
* scrollbar are replaced by the classes `.highcharts-scrollbar-thumb`,
|
|
1273
|
+
* `.highcharts-scrollbar-arrow`, `.highcharts-scrollbar-button`,
|
|
1274
|
+
* `.highcharts-scrollbar-rifles` and `.highcharts-scrollbar-track`.
|
|
1275
|
+
*
|
|
1276
|
+
* @sample stock/yaxis/inverted-bar-scrollbar/
|
|
1277
|
+
* A scrollbar on a simple bar chart
|
|
1278
|
+
*
|
|
1279
|
+
* @product highstock gantt
|
|
1280
|
+
* @optionparent scrollbar
|
|
1281
|
+
*
|
|
1282
|
+
* @private
|
|
1283
|
+
*/
|
|
1284
|
+
const ScrollbarDefaults = {
|
|
1285
|
+
/**
|
|
1286
|
+
* The height of the scrollbar. If `buttonsEnabled` is true , the height
|
|
1287
|
+
* also applies to the width of the scroll arrows so that they are always
|
|
1288
|
+
* squares.
|
|
1289
|
+
*
|
|
1290
|
+
* @sample stock/scrollbar/style/
|
|
1291
|
+
* Non-default height
|
|
1292
|
+
*
|
|
1293
|
+
* @type {number}
|
|
1294
|
+
*/
|
|
1295
|
+
height: 10,
|
|
1296
|
+
/**
|
|
1297
|
+
* The border rounding radius of the bar.
|
|
1298
|
+
*
|
|
1299
|
+
* @sample stock/scrollbar/style/
|
|
1300
|
+
* Scrollbar styling
|
|
1301
|
+
*/
|
|
1302
|
+
barBorderRadius: 5,
|
|
1303
|
+
/**
|
|
1304
|
+
* The corner radius of the scrollbar buttons.
|
|
1305
|
+
*
|
|
1306
|
+
* @sample stock/scrollbar/style/
|
|
1307
|
+
* Scrollbar styling
|
|
1308
|
+
*/
|
|
1309
|
+
buttonBorderRadius: 0,
|
|
1310
|
+
/**
|
|
1311
|
+
* Enable or disable the buttons at the end of the scrollbar.
|
|
1312
|
+
*
|
|
1313
|
+
* @since 11.0.0
|
|
1314
|
+
*/
|
|
1315
|
+
buttonsEnabled: false,
|
|
1316
|
+
/**
|
|
1317
|
+
* Enable or disable the scrollbar.
|
|
1318
|
+
*
|
|
1319
|
+
* @sample stock/scrollbar/enabled/
|
|
1320
|
+
* Disable the scrollbar, only use navigator
|
|
1321
|
+
*
|
|
1322
|
+
* @type {boolean}
|
|
1323
|
+
* @default true
|
|
1324
|
+
* @apioption scrollbar.enabled
|
|
1325
|
+
*/
|
|
1326
|
+
/**
|
|
1327
|
+
* Whether to redraw the main chart as the scrollbar or the navigator
|
|
1328
|
+
* zoomed window is moved. Defaults to `true` for modern browsers and
|
|
1329
|
+
* `false` for legacy IE browsers as well as mobile devices.
|
|
1330
|
+
*
|
|
1331
|
+
* @sample stock/scrollbar/liveredraw
|
|
1332
|
+
* Setting live redraw to false
|
|
1333
|
+
*
|
|
1334
|
+
* @type {boolean}
|
|
1335
|
+
* @since 1.3
|
|
1336
|
+
*/
|
|
1337
|
+
liveRedraw: void 0,
|
|
1338
|
+
/**
|
|
1339
|
+
* The margin between the scrollbar and its axis when the scrollbar is
|
|
1340
|
+
* applied directly to an axis, or the navigator in case that is enabled.
|
|
1341
|
+
* Defaults to 10 for axis, 0 for navigator.
|
|
1342
|
+
*
|
|
1343
|
+
* @type {number|undefined}
|
|
1344
|
+
*/
|
|
1345
|
+
margin: void 0,
|
|
1346
|
+
/**
|
|
1347
|
+
* The minimum width of the scrollbar.
|
|
1348
|
+
*
|
|
1349
|
+
* @since 1.2.5
|
|
1350
|
+
*/
|
|
1351
|
+
minWidth: 6,
|
|
1352
|
+
/** @ignore-option */
|
|
1353
|
+
opposite: true,
|
|
1354
|
+
/**
|
|
1355
|
+
* Whether to show or hide the scrollbar when the scrolled content is
|
|
1356
|
+
* zoomed out to it full extent.
|
|
1357
|
+
*
|
|
1358
|
+
* @type {boolean}
|
|
1359
|
+
* @default true
|
|
1360
|
+
* @apioption scrollbar.showFull
|
|
1361
|
+
*/
|
|
1362
|
+
step: 0.2,
|
|
1363
|
+
/**
|
|
1364
|
+
* The z index of the scrollbar group.
|
|
1365
|
+
*/
|
|
1366
|
+
zIndex: 3,
|
|
1367
|
+
/**
|
|
1368
|
+
* The background color of the scrollbar itself.
|
|
1369
|
+
*
|
|
1370
|
+
* @sample stock/scrollbar/style/
|
|
1371
|
+
* Scrollbar styling
|
|
1372
|
+
*
|
|
1373
|
+
* @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
|
|
1374
|
+
*/
|
|
1375
|
+
barBackgroundColor: "#cccccc" /* Palette.neutralColor20 */,
|
|
1376
|
+
/**
|
|
1377
|
+
* The width of the bar's border.
|
|
1378
|
+
*
|
|
1379
|
+
* @sample stock/scrollbar/style/
|
|
1380
|
+
* Scrollbar styling
|
|
1381
|
+
*/
|
|
1382
|
+
barBorderWidth: 0,
|
|
1383
|
+
/**
|
|
1384
|
+
* The color of the scrollbar's border.
|
|
1385
|
+
*
|
|
1386
|
+
* @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
|
|
1387
|
+
*/
|
|
1388
|
+
barBorderColor: "#cccccc" /* Palette.neutralColor20 */,
|
|
1389
|
+
/**
|
|
1390
|
+
* The color of the small arrow inside the scrollbar buttons.
|
|
1391
|
+
*
|
|
1392
|
+
* @sample stock/scrollbar/style/
|
|
1393
|
+
* Scrollbar styling
|
|
1394
|
+
*
|
|
1395
|
+
* @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
|
|
1396
|
+
*/
|
|
1397
|
+
buttonArrowColor: "#333333" /* Palette.neutralColor80 */,
|
|
1398
|
+
/**
|
|
1399
|
+
* The color of scrollbar buttons.
|
|
1400
|
+
*
|
|
1401
|
+
* @sample stock/scrollbar/style/
|
|
1402
|
+
* Scrollbar styling
|
|
1403
|
+
*
|
|
1404
|
+
* @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
|
|
1405
|
+
*/
|
|
1406
|
+
buttonBackgroundColor: "#e6e6e6" /* Palette.neutralColor10 */,
|
|
1407
|
+
/**
|
|
1408
|
+
* The color of the border of the scrollbar buttons.
|
|
1409
|
+
*
|
|
1410
|
+
* @sample stock/scrollbar/style/
|
|
1411
|
+
* Scrollbar styling
|
|
1412
|
+
*
|
|
1413
|
+
* @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
|
|
1414
|
+
*/
|
|
1415
|
+
buttonBorderColor: "#cccccc" /* Palette.neutralColor20 */,
|
|
1416
|
+
/**
|
|
1417
|
+
* The border width of the scrollbar buttons.
|
|
1418
|
+
*
|
|
1419
|
+
* @sample stock/scrollbar/style/
|
|
1420
|
+
* Scrollbar styling
|
|
1421
|
+
*/
|
|
1422
|
+
buttonBorderWidth: 1,
|
|
1423
|
+
/**
|
|
1424
|
+
* The color of the small rifles in the middle of the scrollbar.
|
|
1425
|
+
*
|
|
1426
|
+
* @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
|
|
1427
|
+
*/
|
|
1428
|
+
rifleColor: 'none',
|
|
1429
|
+
/**
|
|
1430
|
+
* The color of the track background.
|
|
1431
|
+
*
|
|
1432
|
+
* @sample stock/scrollbar/style/
|
|
1433
|
+
* Scrollbar styling
|
|
1434
|
+
*
|
|
1435
|
+
* @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
|
|
1436
|
+
*/
|
|
1437
|
+
trackBackgroundColor: 'rgba(255, 255, 255, 0.001)',
|
|
1438
|
+
/**
|
|
1439
|
+
* The color of the border of the scrollbar track.
|
|
1440
|
+
*
|
|
1441
|
+
* @sample stock/scrollbar/style/
|
|
1442
|
+
* Scrollbar styling
|
|
1443
|
+
*
|
|
1444
|
+
* @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
|
|
1445
|
+
*/
|
|
1446
|
+
trackBorderColor: "#cccccc" /* Palette.neutralColor20 */,
|
|
1447
|
+
/**
|
|
1448
|
+
* The corner radius of the border of the scrollbar track.
|
|
1449
|
+
*
|
|
1450
|
+
* @sample stock/scrollbar/style/
|
|
1451
|
+
* Scrollbar styling
|
|
1452
|
+
*/
|
|
1453
|
+
trackBorderRadius: 5,
|
|
1454
|
+
/**
|
|
1455
|
+
* The width of the border of the scrollbar track.
|
|
1456
|
+
*
|
|
1457
|
+
* @sample stock/scrollbar/style/
|
|
1458
|
+
* Scrollbar styling
|
|
1459
|
+
*/
|
|
1460
|
+
trackBorderWidth: 1
|
|
1461
|
+
};
|
|
1462
|
+
/* *
|
|
1463
|
+
*
|
|
1464
|
+
* Default Export
|
|
1465
|
+
*
|
|
1466
|
+
* */
|
|
1467
|
+
|
|
1468
|
+
return ScrollbarDefaults;
|
|
1469
|
+
});
|
|
1470
|
+
_registerModule(_modules, 'Stock/Scrollbar/Scrollbar.js', [_modules['Core/Defaults.js'], _modules['Core/Globals.js'], _modules['Core/Axis/ScrollbarAxis.js'], _modules['Stock/Scrollbar/ScrollbarDefaults.js'], _modules['Core/Utilities.js']], function (D, H, ScrollbarAxis, ScrollbarDefaults, U) {
|
|
1471
|
+
/* *
|
|
1472
|
+
*
|
|
1473
|
+
* (c) 2010-2024 Torstein Honsi
|
|
1474
|
+
*
|
|
1475
|
+
* License: www.highcharts.com/license
|
|
1476
|
+
*
|
|
1477
|
+
* !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
|
|
1478
|
+
*
|
|
1479
|
+
* */
|
|
1480
|
+
const { defaultOptions } = D;
|
|
1481
|
+
const { addEvent, correctFloat, defined, destroyObjectProperties, fireEvent, merge, pick, removeEvent } = U;
|
|
1482
|
+
/* *
|
|
1483
|
+
*
|
|
1484
|
+
* Constants
|
|
1485
|
+
*
|
|
1486
|
+
* */
|
|
1487
|
+
/* eslint-disable no-invalid-this, valid-jsdoc */
|
|
1488
|
+
/**
|
|
1489
|
+
* A reusable scrollbar, internally used in Highcharts Stock's
|
|
1490
|
+
* navigator and optionally on individual axes.
|
|
1491
|
+
*
|
|
1492
|
+
* @private
|
|
1493
|
+
* @class
|
|
1494
|
+
* @name Highcharts.Scrollbar
|
|
1495
|
+
* @param {Highcharts.SVGRenderer} renderer
|
|
1496
|
+
* @param {Highcharts.ScrollbarOptions} options
|
|
1497
|
+
* @param {Highcharts.Chart} chart
|
|
1498
|
+
*/
|
|
1499
|
+
class Scrollbar {
|
|
1500
|
+
/* *
|
|
1501
|
+
*
|
|
1502
|
+
* Static Functions
|
|
1503
|
+
*
|
|
1504
|
+
* */
|
|
1505
|
+
static compose(AxisClass) {
|
|
1506
|
+
ScrollbarAxis.compose(AxisClass, Scrollbar);
|
|
1507
|
+
}
|
|
1508
|
+
/**
|
|
1509
|
+
* When we have vertical scrollbar, rifles and arrow in buttons should be
|
|
1510
|
+
* rotated. The same method is used in Navigator's handles, to rotate them.
|
|
1511
|
+
*
|
|
1512
|
+
* @function Highcharts.swapXY
|
|
1513
|
+
*
|
|
1514
|
+
* @param {Highcharts.SVGPathArray} path
|
|
1515
|
+
* Path to be rotated.
|
|
1516
|
+
*
|
|
1517
|
+
* @param {boolean} [vertical]
|
|
1518
|
+
* If vertical scrollbar, swap x-y values.
|
|
1519
|
+
*
|
|
1520
|
+
* @return {Highcharts.SVGPathArray}
|
|
1521
|
+
* Rotated path.
|
|
1522
|
+
*
|
|
1523
|
+
* @requires modules/stock
|
|
1524
|
+
*/
|
|
1525
|
+
static swapXY(path, vertical) {
|
|
1526
|
+
if (vertical) {
|
|
1527
|
+
path.forEach((seg) => {
|
|
1528
|
+
const len = seg.length;
|
|
1529
|
+
let temp;
|
|
1530
|
+
for (let i = 0; i < len; i += 2) {
|
|
1531
|
+
temp = seg[i + 1];
|
|
1532
|
+
if (typeof temp === 'number') {
|
|
1533
|
+
seg[i + 1] = seg[i + 2];
|
|
1534
|
+
seg[i + 2] = temp;
|
|
1535
|
+
}
|
|
1536
|
+
}
|
|
1537
|
+
});
|
|
1538
|
+
}
|
|
1539
|
+
return path;
|
|
1540
|
+
}
|
|
1541
|
+
/* *
|
|
1542
|
+
*
|
|
1543
|
+
* Constructors
|
|
1544
|
+
*
|
|
1545
|
+
* */
|
|
1546
|
+
constructor(renderer, options, chart) {
|
|
1547
|
+
/* *
|
|
1548
|
+
*
|
|
1549
|
+
* Properties
|
|
1550
|
+
*
|
|
1551
|
+
* */
|
|
1552
|
+
this._events = [];
|
|
1553
|
+
this.chartX = 0;
|
|
1554
|
+
this.chartY = 0;
|
|
1555
|
+
this.from = 0;
|
|
1556
|
+
this.scrollbarButtons = [];
|
|
1557
|
+
this.scrollbarLeft = 0;
|
|
1558
|
+
this.scrollbarStrokeWidth = 1;
|
|
1559
|
+
this.scrollbarTop = 0;
|
|
1560
|
+
this.size = 0;
|
|
1561
|
+
this.to = 0;
|
|
1562
|
+
this.trackBorderWidth = 1;
|
|
1563
|
+
this.x = 0;
|
|
1564
|
+
this.y = 0;
|
|
1565
|
+
this.init(renderer, options, chart);
|
|
1566
|
+
}
|
|
1567
|
+
/* *
|
|
1568
|
+
*
|
|
1569
|
+
* Functions
|
|
1570
|
+
*
|
|
1571
|
+
* */
|
|
1572
|
+
/**
|
|
1573
|
+
* Set up the mouse and touch events for the Scrollbar
|
|
1574
|
+
*
|
|
1575
|
+
* @private
|
|
1576
|
+
* @function Highcharts.Scrollbar#addEvents
|
|
1577
|
+
*/
|
|
1578
|
+
addEvents() {
|
|
1579
|
+
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);
|
|
1580
|
+
const _events = [
|
|
1581
|
+
// Mouse events
|
|
1582
|
+
[
|
|
1583
|
+
buttons[buttonsOrder[0]].element,
|
|
1584
|
+
'click',
|
|
1585
|
+
this.buttonToMinClick.bind(this)
|
|
1586
|
+
],
|
|
1587
|
+
[
|
|
1588
|
+
buttons[buttonsOrder[1]].element,
|
|
1589
|
+
'click',
|
|
1590
|
+
this.buttonToMaxClick.bind(this)
|
|
1591
|
+
],
|
|
1592
|
+
[track, 'click', this.trackClick.bind(this)],
|
|
1593
|
+
[bar, 'mousedown', mouseDownHandler],
|
|
1594
|
+
[bar.ownerDocument, 'mousemove', mouseMoveHandler],
|
|
1595
|
+
[bar.ownerDocument, 'mouseup', mouseUpHandler],
|
|
1596
|
+
// Touch events
|
|
1597
|
+
[bar, 'touchstart', mouseDownHandler],
|
|
1598
|
+
[bar.ownerDocument, 'touchmove', mouseMoveHandler],
|
|
1599
|
+
[bar.ownerDocument, 'touchend', mouseUpHandler]
|
|
1600
|
+
];
|
|
1601
|
+
// Add them all
|
|
1602
|
+
_events.forEach(function (args) {
|
|
1603
|
+
addEvent.apply(null, args);
|
|
1604
|
+
});
|
|
1605
|
+
this._events = _events;
|
|
1606
|
+
}
|
|
1607
|
+
buttonToMaxClick(e) {
|
|
1608
|
+
const scroller = this;
|
|
1609
|
+
const range = ((scroller.to - scroller.from) *
|
|
1610
|
+
pick(scroller.options.step, 0.2));
|
|
1611
|
+
scroller.updatePosition(scroller.from + range, scroller.to + range);
|
|
1612
|
+
fireEvent(scroller, 'changed', {
|
|
1613
|
+
from: scroller.from,
|
|
1614
|
+
to: scroller.to,
|
|
1615
|
+
trigger: 'scrollbar',
|
|
1616
|
+
DOMEvent: e
|
|
1617
|
+
});
|
|
1618
|
+
}
|
|
1619
|
+
buttonToMinClick(e) {
|
|
1620
|
+
const scroller = this;
|
|
1621
|
+
const range = correctFloat(scroller.to - scroller.from) *
|
|
1622
|
+
pick(scroller.options.step, 0.2);
|
|
1623
|
+
scroller.updatePosition(correctFloat(scroller.from - range), correctFloat(scroller.to - range));
|
|
1624
|
+
fireEvent(scroller, 'changed', {
|
|
1625
|
+
from: scroller.from,
|
|
1626
|
+
to: scroller.to,
|
|
1627
|
+
trigger: 'scrollbar',
|
|
1628
|
+
DOMEvent: e
|
|
1629
|
+
});
|
|
1630
|
+
}
|
|
1631
|
+
/**
|
|
1632
|
+
* Get normalized (0-1) cursor position over the scrollbar
|
|
1633
|
+
*
|
|
1634
|
+
* @private
|
|
1635
|
+
* @function Highcharts.Scrollbar#cursorToScrollbarPosition
|
|
1636
|
+
*
|
|
1637
|
+
* @param {*} normalizedEvent
|
|
1638
|
+
* normalized event, with chartX and chartY values
|
|
1639
|
+
*
|
|
1640
|
+
* @return {Highcharts.Dictionary<number>}
|
|
1641
|
+
* Local position {chartX, chartY}
|
|
1642
|
+
*/
|
|
1643
|
+
cursorToScrollbarPosition(normalizedEvent) {
|
|
1644
|
+
const scroller = this, options = scroller.options, minWidthDifference = options.minWidth > scroller.calculatedWidth ?
|
|
1645
|
+
options.minWidth :
|
|
1646
|
+
0; // minWidth distorts translation
|
|
1647
|
+
return {
|
|
1648
|
+
chartX: (normalizedEvent.chartX - scroller.x -
|
|
1649
|
+
scroller.xOffset) /
|
|
1650
|
+
(scroller.barWidth - minWidthDifference),
|
|
1651
|
+
chartY: (normalizedEvent.chartY - scroller.y -
|
|
1652
|
+
scroller.yOffset) /
|
|
1653
|
+
(scroller.barWidth - minWidthDifference)
|
|
1654
|
+
};
|
|
1655
|
+
}
|
|
1656
|
+
/**
|
|
1657
|
+
* Destroys allocated elements.
|
|
1658
|
+
*
|
|
1659
|
+
* @private
|
|
1660
|
+
* @function Highcharts.Scrollbar#destroy
|
|
1661
|
+
*/
|
|
1662
|
+
destroy() {
|
|
1663
|
+
const scroller = this, navigator = scroller.chart.scroller;
|
|
1664
|
+
// Disconnect events added in addEvents
|
|
1665
|
+
scroller.removeEvents();
|
|
1666
|
+
// Destroy properties
|
|
1667
|
+
[
|
|
1668
|
+
'track',
|
|
1669
|
+
'scrollbarRifles',
|
|
1670
|
+
'scrollbar',
|
|
1671
|
+
'scrollbarGroup',
|
|
1672
|
+
'group'
|
|
1673
|
+
].forEach(function (prop) {
|
|
1674
|
+
if (scroller[prop] && scroller[prop].destroy) {
|
|
1675
|
+
scroller[prop] = scroller[prop].destroy();
|
|
1676
|
+
}
|
|
1677
|
+
});
|
|
1678
|
+
// #6421, chart may have more scrollbars
|
|
1679
|
+
if (navigator && scroller === navigator.scrollbar) {
|
|
1680
|
+
navigator.scrollbar = null;
|
|
1681
|
+
// Destroy elements in collection
|
|
1682
|
+
destroyObjectProperties(navigator.scrollbarButtons);
|
|
1683
|
+
}
|
|
1684
|
+
}
|
|
1685
|
+
/**
|
|
1686
|
+
* Draw the scrollbar buttons with arrows
|
|
1687
|
+
*
|
|
1688
|
+
* @private
|
|
1689
|
+
* @function Highcharts.Scrollbar#drawScrollbarButton
|
|
1690
|
+
* @param {number} index
|
|
1691
|
+
* 0 is left, 1 is right
|
|
1692
|
+
*/
|
|
1693
|
+
drawScrollbarButton(index) {
|
|
1694
|
+
const scroller = this, renderer = scroller.renderer, scrollbarButtons = scroller.scrollbarButtons, options = scroller.options, size = scroller.size, group = renderer.g().add(scroller.group);
|
|
1695
|
+
scrollbarButtons.push(group);
|
|
1696
|
+
if (options.buttonsEnabled) {
|
|
1697
|
+
// Create a rectangle for the scrollbar button
|
|
1698
|
+
const rect = renderer.rect()
|
|
1699
|
+
.addClass('highcharts-scrollbar-button')
|
|
1700
|
+
.add(group);
|
|
1701
|
+
// Presentational attributes
|
|
1702
|
+
if (!scroller.chart.styledMode) {
|
|
1703
|
+
rect.attr({
|
|
1704
|
+
stroke: options.buttonBorderColor,
|
|
1705
|
+
'stroke-width': options.buttonBorderWidth,
|
|
1706
|
+
fill: options.buttonBackgroundColor
|
|
1707
|
+
});
|
|
1708
|
+
}
|
|
1709
|
+
// Place the rectangle based on the rendered stroke width
|
|
1710
|
+
rect.attr(rect.crisp({
|
|
1711
|
+
x: -0.5,
|
|
1712
|
+
y: -0.5,
|
|
1713
|
+
// +1 to compensate for crispifying in rect method
|
|
1714
|
+
width: size + 1,
|
|
1715
|
+
height: size + 1,
|
|
1716
|
+
r: options.buttonBorderRadius
|
|
1717
|
+
}, rect.strokeWidth()));
|
|
1718
|
+
// Button arrow
|
|
1719
|
+
const arrow = renderer
|
|
1720
|
+
.path(Scrollbar.swapXY([[
|
|
1721
|
+
'M',
|
|
1722
|
+
size / 2 + (index ? -1 : 1),
|
|
1723
|
+
size / 2 - 3
|
|
1724
|
+
], [
|
|
1725
|
+
'L',
|
|
1726
|
+
size / 2 + (index ? -1 : 1),
|
|
1727
|
+
size / 2 + 3
|
|
1728
|
+
], [
|
|
1729
|
+
'L',
|
|
1730
|
+
size / 2 + (index ? 2 : -2),
|
|
1731
|
+
size / 2
|
|
1732
|
+
]], options.vertical))
|
|
1733
|
+
.addClass('highcharts-scrollbar-arrow')
|
|
1734
|
+
.add(scrollbarButtons[index]);
|
|
1735
|
+
if (!scroller.chart.styledMode) {
|
|
1736
|
+
arrow.attr({
|
|
1737
|
+
fill: options.buttonArrowColor
|
|
1738
|
+
});
|
|
1739
|
+
}
|
|
1740
|
+
}
|
|
1741
|
+
}
|
|
1742
|
+
/**
|
|
1743
|
+
* @private
|
|
1744
|
+
* @function Highcharts.Scrollbar#init
|
|
1745
|
+
* @param {Highcharts.SVGRenderer} renderer
|
|
1746
|
+
* @param {Highcharts.ScrollbarOptions} options
|
|
1747
|
+
* @param {Highcharts.Chart} chart
|
|
1748
|
+
*/
|
|
1749
|
+
init(renderer, options, chart) {
|
|
1750
|
+
const scroller = this;
|
|
1751
|
+
scroller.scrollbarButtons = [];
|
|
1752
|
+
scroller.renderer = renderer;
|
|
1753
|
+
scroller.userOptions = options;
|
|
1754
|
+
scroller.options = merge(ScrollbarDefaults, defaultOptions.scrollbar, options);
|
|
1755
|
+
scroller.options.margin = pick(scroller.options.margin, 10);
|
|
1756
|
+
scroller.chart = chart;
|
|
1757
|
+
// backward compatibility
|
|
1758
|
+
scroller.size = pick(scroller.options.size, scroller.options.height);
|
|
1759
|
+
// Init
|
|
1760
|
+
if (options.enabled) {
|
|
1761
|
+
scroller.render();
|
|
1762
|
+
scroller.addEvents();
|
|
1763
|
+
}
|
|
1764
|
+
}
|
|
1765
|
+
mouseDownHandler(e) {
|
|
1766
|
+
const scroller = this, normalizedEvent = scroller.chart.pointer?.normalize(e) || e, mousePosition = scroller.cursorToScrollbarPosition(normalizedEvent);
|
|
1767
|
+
scroller.chartX = mousePosition.chartX;
|
|
1768
|
+
scroller.chartY = mousePosition.chartY;
|
|
1769
|
+
scroller.initPositions = [scroller.from, scroller.to];
|
|
1770
|
+
scroller.grabbedCenter = true;
|
|
1771
|
+
}
|
|
1772
|
+
/**
|
|
1773
|
+
* Event handler for the mouse move event.
|
|
1774
|
+
* @private
|
|
1775
|
+
*/
|
|
1776
|
+
mouseMoveHandler(e) {
|
|
1777
|
+
const scroller = this, normalizedEvent = scroller.chart.pointer?.normalize(e) || e, options = scroller.options, direction = options.vertical ?
|
|
1778
|
+
'chartY' : 'chartX', initPositions = scroller.initPositions || [];
|
|
1779
|
+
let scrollPosition, chartPosition, change;
|
|
1780
|
+
// In iOS, a mousemove event with e.pageX === 0 is fired when
|
|
1781
|
+
// holding the finger down in the center of the scrollbar. This
|
|
1782
|
+
// should be ignored.
|
|
1783
|
+
if (scroller.grabbedCenter &&
|
|
1784
|
+
// #4696, scrollbar failed on Android
|
|
1785
|
+
(!e.touches || e.touches[0][direction] !== 0)) {
|
|
1786
|
+
chartPosition = scroller.cursorToScrollbarPosition(normalizedEvent)[direction];
|
|
1787
|
+
scrollPosition = scroller[direction];
|
|
1788
|
+
change = chartPosition - scrollPosition;
|
|
1789
|
+
scroller.hasDragged = true;
|
|
1790
|
+
scroller.updatePosition(initPositions[0] + change, initPositions[1] + change);
|
|
1791
|
+
if (scroller.hasDragged) {
|
|
1792
|
+
fireEvent(scroller, 'changed', {
|
|
1793
|
+
from: scroller.from,
|
|
1794
|
+
to: scroller.to,
|
|
1795
|
+
trigger: 'scrollbar',
|
|
1796
|
+
DOMType: e.type,
|
|
1797
|
+
DOMEvent: e
|
|
1798
|
+
});
|
|
1799
|
+
}
|
|
1800
|
+
}
|
|
1801
|
+
}
|
|
1802
|
+
/**
|
|
1803
|
+
* Event handler for the mouse up event.
|
|
1804
|
+
* @private
|
|
1805
|
+
*/
|
|
1806
|
+
mouseUpHandler(e) {
|
|
1807
|
+
const scroller = this;
|
|
1808
|
+
if (scroller.hasDragged) {
|
|
1809
|
+
fireEvent(scroller, 'changed', {
|
|
1810
|
+
from: scroller.from,
|
|
1811
|
+
to: scroller.to,
|
|
1812
|
+
trigger: 'scrollbar',
|
|
1813
|
+
DOMType: e.type,
|
|
1814
|
+
DOMEvent: e
|
|
1815
|
+
});
|
|
1816
|
+
}
|
|
1817
|
+
scroller.grabbedCenter =
|
|
1818
|
+
scroller.hasDragged =
|
|
1819
|
+
scroller.chartX =
|
|
1820
|
+
scroller.chartY = null;
|
|
1821
|
+
}
|
|
1822
|
+
/**
|
|
1823
|
+
* Position the scrollbar, method called from a parent with defined
|
|
1824
|
+
* dimensions.
|
|
1825
|
+
*
|
|
1826
|
+
* @private
|
|
1827
|
+
* @function Highcharts.Scrollbar#position
|
|
1828
|
+
* @param {number} x
|
|
1829
|
+
* x-position on the chart
|
|
1830
|
+
* @param {number} y
|
|
1831
|
+
* y-position on the chart
|
|
1832
|
+
* @param {number} width
|
|
1833
|
+
* width of the scrollbar
|
|
1834
|
+
* @param {number} height
|
|
1835
|
+
* height of the scrollbar
|
|
1836
|
+
*/
|
|
1837
|
+
position(x, y, width, height) {
|
|
1838
|
+
const scroller = this, options = scroller.options, { buttonsEnabled, margin = 0, vertical } = options, method = scroller.rendered ? 'animate' : 'attr';
|
|
1839
|
+
let xOffset = height, yOffset = 0;
|
|
1840
|
+
// Make the scrollbar visible when it is repositioned, #15763.
|
|
1841
|
+
scroller.group.show();
|
|
1842
|
+
scroller.x = x;
|
|
1843
|
+
scroller.y = y + this.trackBorderWidth;
|
|
1844
|
+
scroller.width = width; // width with buttons
|
|
1845
|
+
scroller.height = height;
|
|
1846
|
+
scroller.xOffset = xOffset;
|
|
1847
|
+
scroller.yOffset = yOffset;
|
|
1848
|
+
// If Scrollbar is a vertical type, swap options:
|
|
1849
|
+
if (vertical) {
|
|
1850
|
+
scroller.width = scroller.yOffset = width = yOffset = scroller.size;
|
|
1851
|
+
scroller.xOffset = xOffset = 0;
|
|
1852
|
+
scroller.yOffset = yOffset = buttonsEnabled ? scroller.size : 0;
|
|
1853
|
+
// width without buttons
|
|
1854
|
+
scroller.barWidth = height - (buttonsEnabled ? width * 2 : 0);
|
|
1855
|
+
scroller.x = x = x + margin;
|
|
1856
|
+
}
|
|
1857
|
+
else {
|
|
1858
|
+
scroller.height = height = scroller.size;
|
|
1859
|
+
scroller.xOffset = xOffset = buttonsEnabled ? scroller.size : 0;
|
|
1860
|
+
// width without buttons
|
|
1861
|
+
scroller.barWidth = width - (buttonsEnabled ? height * 2 : 0);
|
|
1862
|
+
scroller.y = scroller.y + margin;
|
|
1863
|
+
}
|
|
1864
|
+
// Set general position for a group:
|
|
1865
|
+
scroller.group[method]({
|
|
1866
|
+
translateX: x,
|
|
1867
|
+
translateY: scroller.y
|
|
1868
|
+
});
|
|
1869
|
+
// Resize background/track:
|
|
1870
|
+
scroller.track[method]({
|
|
1871
|
+
width: width,
|
|
1872
|
+
height: height
|
|
1873
|
+
});
|
|
1874
|
+
// Move right/bottom button to its place:
|
|
1875
|
+
scroller.scrollbarButtons[1][method]({
|
|
1876
|
+
translateX: vertical ? 0 : width - xOffset,
|
|
1877
|
+
translateY: vertical ? height - yOffset : 0
|
|
1878
|
+
});
|
|
1879
|
+
}
|
|
1880
|
+
/**
|
|
1881
|
+
* Removes the event handlers attached previously with addEvents.
|
|
1882
|
+
*
|
|
1883
|
+
* @private
|
|
1884
|
+
* @function Highcharts.Scrollbar#removeEvents
|
|
1885
|
+
*/
|
|
1886
|
+
removeEvents() {
|
|
1887
|
+
this._events.forEach(function (args) {
|
|
1888
|
+
removeEvent.apply(null, args);
|
|
1889
|
+
});
|
|
1890
|
+
this._events.length = 0;
|
|
1891
|
+
}
|
|
1892
|
+
/**
|
|
1893
|
+
* Render scrollbar with all required items.
|
|
1894
|
+
*
|
|
1895
|
+
* @private
|
|
1896
|
+
* @function Highcharts.Scrollbar#render
|
|
1897
|
+
*/
|
|
1898
|
+
render() {
|
|
1899
|
+
const scroller = this, renderer = scroller.renderer, options = scroller.options, size = scroller.size, styledMode = scroller.chart.styledMode, group = renderer.g('scrollbar')
|
|
1900
|
+
.attr({
|
|
1901
|
+
zIndex: options.zIndex
|
|
1902
|
+
})
|
|
1903
|
+
.hide() // initially hide the scrollbar #15863
|
|
1904
|
+
.add();
|
|
1905
|
+
// Draw the scrollbar group
|
|
1906
|
+
scroller.group = group;
|
|
1907
|
+
// Draw the scrollbar track:
|
|
1908
|
+
scroller.track = renderer.rect()
|
|
1909
|
+
.addClass('highcharts-scrollbar-track')
|
|
1910
|
+
.attr({
|
|
1911
|
+
r: options.trackBorderRadius || 0,
|
|
1912
|
+
height: size,
|
|
1913
|
+
width: size
|
|
1914
|
+
}).add(group);
|
|
1915
|
+
if (!styledMode) {
|
|
1916
|
+
scroller.track.attr({
|
|
1917
|
+
fill: options.trackBackgroundColor,
|
|
1918
|
+
stroke: options.trackBorderColor,
|
|
1919
|
+
'stroke-width': options.trackBorderWidth
|
|
1920
|
+
});
|
|
1921
|
+
}
|
|
1922
|
+
const trackBorderWidth = scroller.trackBorderWidth =
|
|
1923
|
+
scroller.track.strokeWidth();
|
|
1924
|
+
scroller.track.attr({
|
|
1925
|
+
x: -trackBorderWidth % 2 / 2,
|
|
1926
|
+
y: -trackBorderWidth % 2 / 2
|
|
1927
|
+
});
|
|
1928
|
+
// Draw the scrollbar itself
|
|
1929
|
+
scroller.scrollbarGroup = renderer.g().add(group);
|
|
1930
|
+
scroller.scrollbar = renderer.rect()
|
|
1931
|
+
.addClass('highcharts-scrollbar-thumb')
|
|
1932
|
+
.attr({
|
|
1933
|
+
height: size - trackBorderWidth,
|
|
1934
|
+
width: size - trackBorderWidth,
|
|
1935
|
+
r: options.barBorderRadius || 0
|
|
1936
|
+
}).add(scroller.scrollbarGroup);
|
|
1937
|
+
scroller.scrollbarRifles = renderer
|
|
1938
|
+
.path(Scrollbar.swapXY([
|
|
1939
|
+
['M', -3, size / 4],
|
|
1940
|
+
['L', -3, 2 * size / 3],
|
|
1941
|
+
['M', 0, size / 4],
|
|
1942
|
+
['L', 0, 2 * size / 3],
|
|
1943
|
+
['M', 3, size / 4],
|
|
1944
|
+
['L', 3, 2 * size / 3]
|
|
1945
|
+
], options.vertical))
|
|
1946
|
+
.addClass('highcharts-scrollbar-rifles')
|
|
1947
|
+
.add(scroller.scrollbarGroup);
|
|
1948
|
+
if (!styledMode) {
|
|
1949
|
+
scroller.scrollbar.attr({
|
|
1950
|
+
fill: options.barBackgroundColor,
|
|
1951
|
+
stroke: options.barBorderColor,
|
|
1952
|
+
'stroke-width': options.barBorderWidth
|
|
1953
|
+
});
|
|
1954
|
+
scroller.scrollbarRifles.attr({
|
|
1955
|
+
stroke: options.rifleColor,
|
|
1956
|
+
'stroke-width': 1
|
|
1957
|
+
});
|
|
1958
|
+
}
|
|
1959
|
+
scroller.scrollbarStrokeWidth = scroller.scrollbar.strokeWidth();
|
|
1960
|
+
scroller.scrollbarGroup.translate(-scroller.scrollbarStrokeWidth % 2 / 2, -scroller.scrollbarStrokeWidth % 2 / 2);
|
|
1961
|
+
// Draw the buttons:
|
|
1962
|
+
scroller.drawScrollbarButton(0);
|
|
1963
|
+
scroller.drawScrollbarButton(1);
|
|
1964
|
+
}
|
|
1965
|
+
/**
|
|
1966
|
+
* Set scrollbar size, with a given scale.
|
|
1967
|
+
*
|
|
1968
|
+
* @private
|
|
1969
|
+
* @function Highcharts.Scrollbar#setRange
|
|
1970
|
+
* @param {number} from
|
|
1971
|
+
* scale (0-1) where bar should start
|
|
1972
|
+
* @param {number} to
|
|
1973
|
+
* scale (0-1) where bar should end
|
|
1974
|
+
*/
|
|
1975
|
+
setRange(from, to) {
|
|
1976
|
+
const scroller = this, options = scroller.options, vertical = options.vertical, minWidth = options.minWidth, fullWidth = scroller.barWidth, method = (this.rendered &&
|
|
1977
|
+
!this.hasDragged &&
|
|
1978
|
+
!(this.chart.navigator && this.chart.navigator.hasDragged)) ? 'animate' : 'attr';
|
|
1979
|
+
if (!defined(fullWidth)) {
|
|
1980
|
+
return;
|
|
1981
|
+
}
|
|
1982
|
+
const toPX = fullWidth * Math.min(to, 1);
|
|
1983
|
+
let fromPX, newSize;
|
|
1984
|
+
from = Math.max(from, 0);
|
|
1985
|
+
fromPX = Math.ceil(fullWidth * from);
|
|
1986
|
+
scroller.calculatedWidth = newSize = correctFloat(toPX - fromPX);
|
|
1987
|
+
// We need to recalculate position, if minWidth is used
|
|
1988
|
+
if (newSize < minWidth) {
|
|
1989
|
+
fromPX = (fullWidth - minWidth + newSize) * from;
|
|
1990
|
+
newSize = minWidth;
|
|
1991
|
+
}
|
|
1992
|
+
const newPos = Math.floor(fromPX + scroller.xOffset + scroller.yOffset);
|
|
1993
|
+
const newRiflesPos = newSize / 2 - 0.5; // -0.5 -> rifle line width / 2
|
|
1994
|
+
// Store current position:
|
|
1995
|
+
scroller.from = from;
|
|
1996
|
+
scroller.to = to;
|
|
1997
|
+
if (!vertical) {
|
|
1998
|
+
scroller.scrollbarGroup[method]({
|
|
1999
|
+
translateX: newPos
|
|
2000
|
+
});
|
|
2001
|
+
scroller.scrollbar[method]({
|
|
2002
|
+
width: newSize
|
|
2003
|
+
});
|
|
2004
|
+
scroller.scrollbarRifles[method]({
|
|
2005
|
+
translateX: newRiflesPos
|
|
2006
|
+
});
|
|
2007
|
+
scroller.scrollbarLeft = newPos;
|
|
2008
|
+
scroller.scrollbarTop = 0;
|
|
2009
|
+
}
|
|
2010
|
+
else {
|
|
2011
|
+
scroller.scrollbarGroup[method]({
|
|
2012
|
+
translateY: newPos
|
|
2013
|
+
});
|
|
2014
|
+
scroller.scrollbar[method]({
|
|
2015
|
+
height: newSize
|
|
2016
|
+
});
|
|
2017
|
+
scroller.scrollbarRifles[method]({
|
|
2018
|
+
translateY: newRiflesPos
|
|
2019
|
+
});
|
|
2020
|
+
scroller.scrollbarTop = newPos;
|
|
2021
|
+
scroller.scrollbarLeft = 0;
|
|
2022
|
+
}
|
|
2023
|
+
if (newSize <= 12) {
|
|
2024
|
+
scroller.scrollbarRifles.hide();
|
|
2025
|
+
}
|
|
2026
|
+
else {
|
|
2027
|
+
scroller.scrollbarRifles.show();
|
|
2028
|
+
}
|
|
2029
|
+
// Show or hide the scrollbar based on the showFull setting
|
|
2030
|
+
if (options.showFull === false) {
|
|
2031
|
+
if (from <= 0 && to >= 1) {
|
|
2032
|
+
scroller.group.hide();
|
|
2033
|
+
}
|
|
2034
|
+
else {
|
|
2035
|
+
scroller.group.show();
|
|
2036
|
+
}
|
|
2037
|
+
}
|
|
2038
|
+
scroller.rendered = true;
|
|
2039
|
+
}
|
|
2040
|
+
/**
|
|
2041
|
+
* Checks if the extremes should be updated in response to a scrollbar
|
|
2042
|
+
* change event.
|
|
2043
|
+
*
|
|
2044
|
+
* @private
|
|
2045
|
+
* @function Highcharts.Scrollbar#shouldUpdateExtremes
|
|
2046
|
+
*/
|
|
2047
|
+
shouldUpdateExtremes(eventType) {
|
|
2048
|
+
return (pick(this.options.liveRedraw, H.svg &&
|
|
2049
|
+
!H.isTouchDevice &&
|
|
2050
|
+
!this.chart.boosted) ||
|
|
2051
|
+
// Mouseup always should change extremes
|
|
2052
|
+
eventType === 'mouseup' ||
|
|
2053
|
+
eventType === 'touchend' ||
|
|
2054
|
+
// Internal events
|
|
2055
|
+
!defined(eventType));
|
|
2056
|
+
}
|
|
2057
|
+
trackClick(e) {
|
|
2058
|
+
const scroller = this;
|
|
2059
|
+
const normalizedEvent = scroller.chart.pointer?.normalize(e) || e, range = scroller.to - scroller.from, top = scroller.y + scroller.scrollbarTop, left = scroller.x + scroller.scrollbarLeft;
|
|
2060
|
+
if ((scroller.options.vertical && normalizedEvent.chartY > top) ||
|
|
2061
|
+
(!scroller.options.vertical && normalizedEvent.chartX > left)) {
|
|
2062
|
+
// On the top or on the left side of the track:
|
|
2063
|
+
scroller.updatePosition(scroller.from + range, scroller.to + range);
|
|
2064
|
+
}
|
|
2065
|
+
else {
|
|
2066
|
+
// On the bottom or the right side of the track:
|
|
2067
|
+
scroller.updatePosition(scroller.from - range, scroller.to - range);
|
|
2068
|
+
}
|
|
2069
|
+
fireEvent(scroller, 'changed', {
|
|
2070
|
+
from: scroller.from,
|
|
2071
|
+
to: scroller.to,
|
|
2072
|
+
trigger: 'scrollbar',
|
|
2073
|
+
DOMEvent: e
|
|
2074
|
+
});
|
|
2075
|
+
}
|
|
2076
|
+
/**
|
|
2077
|
+
* Update the scrollbar with new options
|
|
2078
|
+
*
|
|
2079
|
+
* @private
|
|
2080
|
+
* @function Highcharts.Scrollbar#update
|
|
2081
|
+
* @param {Highcharts.ScrollbarOptions} options
|
|
2082
|
+
*/
|
|
2083
|
+
update(options) {
|
|
2084
|
+
this.destroy();
|
|
2085
|
+
this.init(this.chart.renderer, merge(true, this.options, options), this.chart);
|
|
2086
|
+
}
|
|
2087
|
+
/**
|
|
2088
|
+
* Update position option in the Scrollbar, with normalized 0-1 scale
|
|
2089
|
+
*
|
|
2090
|
+
* @private
|
|
2091
|
+
* @function Highcharts.Scrollbar#updatePosition
|
|
2092
|
+
* @param {number} from
|
|
2093
|
+
* @param {number} to
|
|
2094
|
+
*/
|
|
2095
|
+
updatePosition(from, to) {
|
|
2096
|
+
if (to > 1) {
|
|
2097
|
+
from = correctFloat(1 - correctFloat(to - from));
|
|
2098
|
+
to = 1;
|
|
2099
|
+
}
|
|
2100
|
+
if (from < 0) {
|
|
2101
|
+
to = correctFloat(to - from);
|
|
2102
|
+
from = 0;
|
|
2103
|
+
}
|
|
2104
|
+
this.from = from;
|
|
2105
|
+
this.to = to;
|
|
2106
|
+
}
|
|
2107
|
+
}
|
|
2108
|
+
/* *
|
|
2109
|
+
*
|
|
2110
|
+
* Static Properties
|
|
2111
|
+
*
|
|
2112
|
+
* */
|
|
2113
|
+
Scrollbar.defaultOptions = ScrollbarDefaults;
|
|
2114
|
+
/* *
|
|
2115
|
+
*
|
|
2116
|
+
* Registry
|
|
2117
|
+
*
|
|
2118
|
+
* */
|
|
2119
|
+
defaultOptions.scrollbar = merge(true, Scrollbar.defaultOptions, defaultOptions.scrollbar);
|
|
2120
|
+
/* *
|
|
2121
|
+
*
|
|
2122
|
+
* Default Export
|
|
2123
|
+
*
|
|
2124
|
+
* */
|
|
2125
|
+
|
|
2126
|
+
return Scrollbar;
|
|
2127
|
+
});
|
|
2128
|
+
_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) {
|
|
2129
|
+
/* *
|
|
2130
|
+
*
|
|
2131
|
+
* (c) 2010-2024 Torstein Honsi
|
|
2132
|
+
*
|
|
2133
|
+
* License: www.highcharts.com/license
|
|
2134
|
+
*
|
|
2135
|
+
* !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
|
|
2136
|
+
*
|
|
2137
|
+
* */
|
|
2138
|
+
const { defaultOptions } = D;
|
|
2139
|
+
const { isTouchDevice } = H;
|
|
2140
|
+
const { addEvent, clamp, correctFloat, defined, destroyObjectProperties, erase, extend, find, fireEvent, isArray, isNumber, merge, pick, removeEvent, splat } = U;
|
|
2141
|
+
/* *
|
|
2142
|
+
*
|
|
2143
|
+
* Functions
|
|
2144
|
+
*
|
|
2145
|
+
* */
|
|
2146
|
+
/**
|
|
2147
|
+
* Finding the min or max of a set of variables where we don't know if they are
|
|
2148
|
+
* defined, is a pattern that is repeated several places in Highcharts. Consider
|
|
2149
|
+
* making this a global utility method.
|
|
2150
|
+
* @private
|
|
2151
|
+
*/
|
|
2152
|
+
function numExt(extreme, ...args) {
|
|
2153
|
+
const numbers = [].filter.call(args, isNumber);
|
|
2154
|
+
if (numbers.length) {
|
|
2155
|
+
return Math[extreme].apply(0, numbers);
|
|
2156
|
+
}
|
|
2157
|
+
}
|
|
2158
|
+
/* *
|
|
2159
|
+
*
|
|
2160
|
+
* Class
|
|
2161
|
+
*
|
|
2162
|
+
* */
|
|
2163
|
+
/**
|
|
2164
|
+
* The Navigator class
|
|
2165
|
+
*
|
|
2166
|
+
* @private
|
|
2167
|
+
* @class
|
|
2168
|
+
* @name Highcharts.Navigator
|
|
2169
|
+
*
|
|
2170
|
+
* @param {Highcharts.Chart} chart
|
|
2171
|
+
* Chart object
|
|
2172
|
+
*/
|
|
2173
|
+
class Navigator {
|
|
2174
|
+
/* *
|
|
2175
|
+
*
|
|
2176
|
+
* Static Properties
|
|
2177
|
+
*
|
|
2178
|
+
* */
|
|
2179
|
+
static compose(ChartClass, AxisClass, SeriesClass) {
|
|
2180
|
+
ChartNavigatorComposition.compose(ChartClass, Navigator);
|
|
2181
|
+
NavigatorComposition.compose(ChartClass, AxisClass, SeriesClass);
|
|
2182
|
+
}
|
|
2183
|
+
/* *
|
|
2184
|
+
*
|
|
2185
|
+
* Constructor
|
|
2186
|
+
*
|
|
2187
|
+
* */
|
|
2188
|
+
constructor(chart) {
|
|
2189
|
+
this.scrollbarHeight = 0;
|
|
2190
|
+
this.init(chart);
|
|
2191
|
+
}
|
|
2192
|
+
/* *
|
|
2193
|
+
*
|
|
2194
|
+
* Functions
|
|
2195
|
+
*
|
|
2196
|
+
* */
|
|
2197
|
+
/**
|
|
2198
|
+
* Draw one of the handles on the side of the zoomed range in the navigator.
|
|
2199
|
+
*
|
|
2200
|
+
* @private
|
|
2201
|
+
* @function Highcharts.Navigator#drawHandle
|
|
2202
|
+
*
|
|
2203
|
+
* @param {number} x
|
|
2204
|
+
* The x center for the handle
|
|
2205
|
+
*
|
|
2206
|
+
* @param {number} index
|
|
2207
|
+
* 0 for left and 1 for right
|
|
2208
|
+
*
|
|
2209
|
+
* @param {boolean|undefined} inverted
|
|
2210
|
+
* Flag for chart.inverted
|
|
2211
|
+
*
|
|
2212
|
+
* @param {string} verb
|
|
2213
|
+
* Use 'animate' or 'attr'
|
|
2214
|
+
*/
|
|
2215
|
+
drawHandle(x, index, inverted, verb) {
|
|
2216
|
+
const navigator = this, height = navigator.navigatorOptions.handles.height;
|
|
2217
|
+
// Place it
|
|
2218
|
+
navigator.handles[index][verb](inverted ? {
|
|
2219
|
+
translateX: Math.round(navigator.left + navigator.height / 2),
|
|
2220
|
+
translateY: Math.round(navigator.top + parseInt(x, 10) + 0.5 - height)
|
|
2221
|
+
} : {
|
|
2222
|
+
translateX: Math.round(navigator.left + parseInt(x, 10)),
|
|
2223
|
+
translateY: Math.round(navigator.top + navigator.height / 2 - height / 2 - 1)
|
|
2224
|
+
});
|
|
2225
|
+
}
|
|
2226
|
+
/**
|
|
2227
|
+
* Render outline around the zoomed range
|
|
2228
|
+
*
|
|
2229
|
+
* @private
|
|
2230
|
+
* @function Highcharts.Navigator#drawOutline
|
|
2231
|
+
*
|
|
2232
|
+
* @param {number} zoomedMin
|
|
2233
|
+
* in pixels position where zoomed range starts
|
|
2234
|
+
*
|
|
2235
|
+
* @param {number} zoomedMax
|
|
2236
|
+
* in pixels position where zoomed range ends
|
|
2237
|
+
*
|
|
2238
|
+
* @param {boolean|undefined} inverted
|
|
2239
|
+
* flag if chart is inverted
|
|
2240
|
+
*
|
|
2241
|
+
* @param {string} verb
|
|
2242
|
+
* use 'animate' or 'attr'
|
|
2243
|
+
*/
|
|
2244
|
+
drawOutline(zoomedMin, zoomedMax, inverted, verb) {
|
|
2245
|
+
const navigator = this, maskInside = navigator.navigatorOptions.maskInside, outlineWidth = navigator.outline.strokeWidth(), halfOutline = outlineWidth / 2, outlineCorrection = (outlineWidth % 2) / 2, // #5800
|
|
2246
|
+
scrollButtonSize = navigator.scrollButtonSize, navigatorSize = navigator.size, navigatorTop = navigator.top, height = navigator.height, lineTop = navigatorTop - halfOutline, lineBtm = navigatorTop + height;
|
|
2247
|
+
let left = navigator.left, verticalMin, path;
|
|
2248
|
+
if (inverted) {
|
|
2249
|
+
verticalMin = navigatorTop + zoomedMax + outlineCorrection;
|
|
2250
|
+
zoomedMax = navigatorTop + zoomedMin + outlineCorrection;
|
|
2251
|
+
path = [
|
|
2252
|
+
[
|
|
2253
|
+
'M',
|
|
2254
|
+
left + height,
|
|
2255
|
+
navigatorTop - scrollButtonSize - outlineCorrection
|
|
2256
|
+
],
|
|
2257
|
+
// top right of zoomed range
|
|
2258
|
+
['L', left + height, verticalMin],
|
|
2259
|
+
['L', left, verticalMin],
|
|
2260
|
+
['M', left, zoomedMax],
|
|
2261
|
+
['L', left + height, zoomedMax],
|
|
2262
|
+
[
|
|
2263
|
+
'L',
|
|
2264
|
+
left + height,
|
|
2265
|
+
navigatorTop + navigatorSize + scrollButtonSize
|
|
2266
|
+
]
|
|
2267
|
+
];
|
|
2268
|
+
if (maskInside) {
|
|
2269
|
+
path.push(
|
|
2270
|
+
// upper left of zoomed range
|
|
2271
|
+
['M', left + height, verticalMin - halfOutline],
|
|
2272
|
+
// upper right of z.r.
|
|
2273
|
+
[
|
|
2274
|
+
'L',
|
|
2275
|
+
left + height,
|
|
2276
|
+
zoomedMax + halfOutline
|
|
2277
|
+
]);
|
|
2278
|
+
}
|
|
2279
|
+
}
|
|
2280
|
+
else {
|
|
2281
|
+
left -= scrollButtonSize;
|
|
2282
|
+
zoomedMin += left + scrollButtonSize - outlineCorrection;
|
|
2283
|
+
zoomedMax += left + scrollButtonSize - outlineCorrection;
|
|
2284
|
+
path = [
|
|
2285
|
+
// left
|
|
2286
|
+
['M', left, lineTop],
|
|
2287
|
+
// upper left of zoomed range
|
|
2288
|
+
['L', zoomedMin, lineTop],
|
|
2289
|
+
// lower left of z.r.
|
|
2290
|
+
['L', zoomedMin, lineBtm],
|
|
2291
|
+
// lower right of z.r.
|
|
2292
|
+
['M', zoomedMax, lineBtm],
|
|
2293
|
+
// upper right of z.r.
|
|
2294
|
+
['L', zoomedMax, lineTop],
|
|
2295
|
+
// right
|
|
2296
|
+
[
|
|
2297
|
+
'L',
|
|
2298
|
+
left + navigatorSize + scrollButtonSize * 2,
|
|
2299
|
+
navigatorTop + halfOutline
|
|
2300
|
+
]
|
|
2301
|
+
];
|
|
2302
|
+
if (maskInside) {
|
|
2303
|
+
path.push(
|
|
2304
|
+
// upper left of zoomed range
|
|
2305
|
+
['M', zoomedMin - halfOutline, lineTop],
|
|
2306
|
+
// upper right of z.r.
|
|
2307
|
+
['L', zoomedMax + halfOutline, lineTop]);
|
|
2308
|
+
}
|
|
2309
|
+
}
|
|
2310
|
+
navigator.outline[verb]({
|
|
2311
|
+
d: path
|
|
2312
|
+
});
|
|
2313
|
+
}
|
|
2314
|
+
/**
|
|
2315
|
+
* Render outline around the zoomed range
|
|
2316
|
+
*
|
|
2317
|
+
* @private
|
|
2318
|
+
* @function Highcharts.Navigator#drawMasks
|
|
2319
|
+
*
|
|
2320
|
+
* @param {number} zoomedMin
|
|
2321
|
+
* in pixels position where zoomed range starts
|
|
2322
|
+
*
|
|
2323
|
+
* @param {number} zoomedMax
|
|
2324
|
+
* in pixels position where zoomed range ends
|
|
2325
|
+
*
|
|
2326
|
+
* @param {boolean|undefined} inverted
|
|
2327
|
+
* flag if chart is inverted
|
|
2328
|
+
*
|
|
2329
|
+
* @param {string} verb
|
|
2330
|
+
* use 'animate' or 'attr'
|
|
2331
|
+
*/
|
|
2332
|
+
drawMasks(zoomedMin, zoomedMax, inverted, verb) {
|
|
2333
|
+
const navigator = this, left = navigator.left, top = navigator.top, navigatorHeight = navigator.height;
|
|
2334
|
+
let height, width, x, y;
|
|
2335
|
+
// Determine rectangle position & size
|
|
2336
|
+
// According to (non)inverted position:
|
|
2337
|
+
if (inverted) {
|
|
2338
|
+
x = [left, left, left];
|
|
2339
|
+
y = [top, top + zoomedMin, top + zoomedMax];
|
|
2340
|
+
width = [navigatorHeight, navigatorHeight, navigatorHeight];
|
|
2341
|
+
height = [
|
|
2342
|
+
zoomedMin,
|
|
2343
|
+
zoomedMax - zoomedMin,
|
|
2344
|
+
navigator.size - zoomedMax
|
|
2345
|
+
];
|
|
2346
|
+
}
|
|
2347
|
+
else {
|
|
2348
|
+
x = [left, left + zoomedMin, left + zoomedMax];
|
|
2349
|
+
y = [top, top, top];
|
|
2350
|
+
width = [
|
|
2351
|
+
zoomedMin,
|
|
2352
|
+
zoomedMax - zoomedMin,
|
|
2353
|
+
navigator.size - zoomedMax
|
|
2354
|
+
];
|
|
2355
|
+
height = [navigatorHeight, navigatorHeight, navigatorHeight];
|
|
2356
|
+
}
|
|
2357
|
+
navigator.shades.forEach((shade, i) => {
|
|
2358
|
+
shade[verb]({
|
|
2359
|
+
x: x[i],
|
|
2360
|
+
y: y[i],
|
|
2361
|
+
width: width[i],
|
|
2362
|
+
height: height[i]
|
|
2363
|
+
});
|
|
2364
|
+
});
|
|
2365
|
+
}
|
|
2366
|
+
/**
|
|
2367
|
+
* Generate DOM elements for a navigator:
|
|
2368
|
+
*
|
|
2369
|
+
* - main navigator group
|
|
2370
|
+
*
|
|
2371
|
+
* - all shades
|
|
2372
|
+
*
|
|
2373
|
+
* - outline
|
|
2374
|
+
*
|
|
2375
|
+
* - handles
|
|
2376
|
+
*
|
|
2377
|
+
* @private
|
|
2378
|
+
* @function Highcharts.Navigator#renderElements
|
|
2379
|
+
*/
|
|
2380
|
+
renderElements() {
|
|
2381
|
+
const navigator = this, navigatorOptions = navigator.navigatorOptions, maskInside = navigatorOptions.maskInside, chart = navigator.chart, inverted = chart.inverted, renderer = chart.renderer, mouseCursor = {
|
|
2382
|
+
cursor: inverted ? 'ns-resize' : 'ew-resize'
|
|
2383
|
+
},
|
|
2384
|
+
// Create the main navigator group
|
|
2385
|
+
navigatorGroup = navigator.navigatorGroup = renderer
|
|
2386
|
+
.g('navigator')
|
|
2387
|
+
.attr({
|
|
2388
|
+
zIndex: 8,
|
|
2389
|
+
visibility: 'hidden'
|
|
2390
|
+
})
|
|
2391
|
+
.add();
|
|
2392
|
+
// Create masks, each mask will get events and fill:
|
|
2393
|
+
[
|
|
2394
|
+
!maskInside,
|
|
2395
|
+
maskInside,
|
|
2396
|
+
!maskInside
|
|
2397
|
+
].forEach((hasMask, index) => {
|
|
2398
|
+
const shade = renderer.rect()
|
|
2399
|
+
.addClass('highcharts-navigator-mask' +
|
|
2400
|
+
(index === 1 ? '-inside' : '-outside'))
|
|
2401
|
+
.add(navigatorGroup);
|
|
2402
|
+
if (!chart.styledMode) {
|
|
2403
|
+
shade.attr({
|
|
2404
|
+
fill: hasMask ?
|
|
2405
|
+
navigatorOptions.maskFill :
|
|
2406
|
+
'rgba(0,0,0,0)'
|
|
2407
|
+
});
|
|
2408
|
+
if (index === 1) {
|
|
2409
|
+
shade.css(mouseCursor);
|
|
2410
|
+
}
|
|
2411
|
+
}
|
|
2412
|
+
navigator.shades[index] = shade;
|
|
2413
|
+
});
|
|
2414
|
+
// Create the outline:
|
|
2415
|
+
navigator.outline = renderer.path()
|
|
2416
|
+
.addClass('highcharts-navigator-outline')
|
|
2417
|
+
.add(navigatorGroup);
|
|
2418
|
+
if (!chart.styledMode) {
|
|
2419
|
+
navigator.outline.attr({
|
|
2420
|
+
'stroke-width': navigatorOptions.outlineWidth,
|
|
2421
|
+
stroke: navigatorOptions.outlineColor
|
|
2422
|
+
});
|
|
2423
|
+
}
|
|
2424
|
+
// Create the handlers:
|
|
2425
|
+
if (navigatorOptions.handles && navigatorOptions.handles.enabled) {
|
|
2426
|
+
const handlesOptions = navigatorOptions.handles, { height, width } = handlesOptions;
|
|
2427
|
+
[0, 1].forEach((index) => {
|
|
2428
|
+
navigator.handles[index] = renderer.symbol(handlesOptions.symbols[index], -width / 2 - 1, 0, width, height, handlesOptions);
|
|
2429
|
+
if (chart.inverted) {
|
|
2430
|
+
navigator.handles[index].attr({
|
|
2431
|
+
rotation: 90,
|
|
2432
|
+
rotationOriginX: Math.floor(-width / 2),
|
|
2433
|
+
rotationOriginY: (height + width) / 2
|
|
2434
|
+
});
|
|
2435
|
+
}
|
|
2436
|
+
// zIndex = 6 for right handle, 7 for left.
|
|
2437
|
+
// Can't be 10, because of the tooltip in inverted chart #2908
|
|
2438
|
+
navigator.handles[index].attr({ zIndex: 7 - index })
|
|
2439
|
+
.addClass('highcharts-navigator-handle ' +
|
|
2440
|
+
'highcharts-navigator-handle-' +
|
|
2441
|
+
['left', 'right'][index]).add(navigatorGroup);
|
|
2442
|
+
if (!chart.styledMode) {
|
|
2443
|
+
navigator.handles[index]
|
|
2444
|
+
.attr({
|
|
2445
|
+
fill: handlesOptions.backgroundColor,
|
|
2446
|
+
stroke: handlesOptions.borderColor,
|
|
2447
|
+
'stroke-width': handlesOptions.lineWidth
|
|
2448
|
+
})
|
|
2449
|
+
.css(mouseCursor);
|
|
2450
|
+
}
|
|
2451
|
+
});
|
|
2452
|
+
}
|
|
2453
|
+
}
|
|
2454
|
+
/**
|
|
2455
|
+
* Update navigator
|
|
2456
|
+
*
|
|
2457
|
+
* @private
|
|
2458
|
+
* @function Highcharts.Navigator#update
|
|
2459
|
+
*
|
|
2460
|
+
* @param {Highcharts.NavigatorOptions} options
|
|
2461
|
+
* Options to merge in when updating navigator
|
|
2462
|
+
*/
|
|
2463
|
+
update(options) {
|
|
2464
|
+
// Remove references to old navigator series in base series
|
|
2465
|
+
(this.series || []).forEach((series) => {
|
|
2466
|
+
if (series.baseSeries) {
|
|
2467
|
+
delete series.baseSeries.navigatorSeries;
|
|
2468
|
+
}
|
|
2469
|
+
});
|
|
2470
|
+
// Destroy and rebuild navigator
|
|
2471
|
+
this.destroy();
|
|
2472
|
+
const chartOptions = this.chart.options;
|
|
2473
|
+
merge(true, chartOptions.navigator, options);
|
|
2474
|
+
this.init(this.chart);
|
|
2475
|
+
}
|
|
2476
|
+
/**
|
|
2477
|
+
* Render the navigator
|
|
2478
|
+
*
|
|
2479
|
+
* @private
|
|
2480
|
+
* @function Highcharts.Navigator#render
|
|
2481
|
+
* @param {number} min
|
|
2482
|
+
* X axis value minimum
|
|
2483
|
+
* @param {number} max
|
|
2484
|
+
* X axis value maximum
|
|
2485
|
+
* @param {number} [pxMin]
|
|
2486
|
+
* Pixel value minimum
|
|
2487
|
+
* @param {number} [pxMax]
|
|
2488
|
+
* Pixel value maximum
|
|
2489
|
+
*/
|
|
2490
|
+
render(min, max, pxMin, pxMax) {
|
|
2491
|
+
const navigator = this, chart = navigator.chart, xAxis = navigator.xAxis, pointRange = xAxis.pointRange || 0, scrollbarXAxis = xAxis.navigatorAxis.fake ? chart.xAxis[0] : xAxis, navigatorEnabled = navigator.navigatorEnabled, rendered = navigator.rendered, inverted = chart.inverted, minRange = chart.xAxis[0].minRange, maxRange = chart.xAxis[0].options.maxRange, scrollButtonSize = navigator.scrollButtonSize;
|
|
2492
|
+
let navigatorWidth, scrollbarLeft, scrollbarTop, scrollbarHeight = navigator.scrollbarHeight, navigatorSize, verb;
|
|
2493
|
+
// Don't redraw while moving the handles (#4703).
|
|
2494
|
+
if (this.hasDragged && !defined(pxMin)) {
|
|
2495
|
+
return;
|
|
2496
|
+
}
|
|
2497
|
+
min = correctFloat(min - pointRange / 2);
|
|
2498
|
+
max = correctFloat(max + pointRange / 2);
|
|
2499
|
+
// Don't render the navigator until we have data (#486, #4202, #5172).
|
|
2500
|
+
if (!isNumber(min) || !isNumber(max)) {
|
|
2501
|
+
// However, if navigator was already rendered, we may need to resize
|
|
2502
|
+
// it. For example hidden series, but visible navigator (#6022).
|
|
2503
|
+
if (rendered) {
|
|
2504
|
+
pxMin = 0;
|
|
2505
|
+
pxMax = pick(xAxis.width, scrollbarXAxis.width);
|
|
2506
|
+
}
|
|
2507
|
+
else {
|
|
2508
|
+
return;
|
|
2509
|
+
}
|
|
2510
|
+
}
|
|
2511
|
+
navigator.left = pick(xAxis.left,
|
|
2512
|
+
// in case of scrollbar only, without navigator
|
|
2513
|
+
chart.plotLeft + scrollButtonSize +
|
|
2514
|
+
(inverted ? chart.plotWidth : 0));
|
|
2515
|
+
let zoomedMax = navigator.size = navigatorSize = pick(xAxis.len, (inverted ? chart.plotHeight : chart.plotWidth) -
|
|
2516
|
+
2 * scrollButtonSize);
|
|
2517
|
+
if (inverted) {
|
|
2518
|
+
navigatorWidth = scrollbarHeight;
|
|
2519
|
+
}
|
|
2520
|
+
else {
|
|
2521
|
+
navigatorWidth = navigatorSize + 2 * scrollButtonSize;
|
|
2522
|
+
}
|
|
2523
|
+
// Get the pixel position of the handles
|
|
2524
|
+
pxMin = pick(pxMin, xAxis.toPixels(min, true));
|
|
2525
|
+
pxMax = pick(pxMax, xAxis.toPixels(max, true));
|
|
2526
|
+
// Verify (#1851, #2238)
|
|
2527
|
+
if (!isNumber(pxMin) || Math.abs(pxMin) === Infinity) {
|
|
2528
|
+
pxMin = 0;
|
|
2529
|
+
pxMax = navigatorWidth;
|
|
2530
|
+
}
|
|
2531
|
+
// Are we below the minRange? (#2618, #6191)
|
|
2532
|
+
const newMin = xAxis.toValue(pxMin, true), newMax = xAxis.toValue(pxMax, true), currentRange = Math.abs(correctFloat(newMax - newMin));
|
|
2533
|
+
if (currentRange < minRange) {
|
|
2534
|
+
if (this.grabbedLeft) {
|
|
2535
|
+
pxMin = xAxis.toPixels(newMax - minRange - pointRange, true);
|
|
2536
|
+
}
|
|
2537
|
+
else if (this.grabbedRight) {
|
|
2538
|
+
pxMax = xAxis.toPixels(newMin + minRange + pointRange, true);
|
|
2539
|
+
}
|
|
2540
|
+
}
|
|
2541
|
+
else if (defined(maxRange) &&
|
|
2542
|
+
correctFloat(currentRange - pointRange) > maxRange) {
|
|
2543
|
+
if (this.grabbedLeft) {
|
|
2544
|
+
pxMin = xAxis.toPixels(newMax - maxRange - pointRange, true);
|
|
2545
|
+
}
|
|
2546
|
+
else if (this.grabbedRight) {
|
|
2547
|
+
pxMax = xAxis.toPixels(newMin + maxRange + pointRange, true);
|
|
2548
|
+
}
|
|
2549
|
+
}
|
|
2550
|
+
// Handles are allowed to cross, but never exceed the plot area
|
|
2551
|
+
navigator.zoomedMax = clamp(Math.max(pxMin, pxMax), 0, zoomedMax);
|
|
2552
|
+
navigator.zoomedMin = clamp(navigator.fixedWidth ?
|
|
2553
|
+
navigator.zoomedMax - navigator.fixedWidth :
|
|
2554
|
+
Math.min(pxMin, pxMax), 0, zoomedMax);
|
|
2555
|
+
navigator.range = navigator.zoomedMax - navigator.zoomedMin;
|
|
2556
|
+
zoomedMax = Math.round(navigator.zoomedMax);
|
|
2557
|
+
const zoomedMin = Math.round(navigator.zoomedMin);
|
|
2558
|
+
if (navigatorEnabled) {
|
|
2559
|
+
navigator.navigatorGroup.attr({
|
|
2560
|
+
visibility: 'inherit'
|
|
2561
|
+
});
|
|
2562
|
+
// Place elements
|
|
2563
|
+
verb = rendered && !navigator.hasDragged ? 'animate' : 'attr';
|
|
2564
|
+
navigator.drawMasks(zoomedMin, zoomedMax, inverted, verb);
|
|
2565
|
+
navigator.drawOutline(zoomedMin, zoomedMax, inverted, verb);
|
|
2566
|
+
if (navigator.navigatorOptions.handles.enabled) {
|
|
2567
|
+
navigator.drawHandle(zoomedMin, 0, inverted, verb);
|
|
2568
|
+
navigator.drawHandle(zoomedMax, 1, inverted, verb);
|
|
2569
|
+
}
|
|
2570
|
+
}
|
|
2571
|
+
if (navigator.scrollbar) {
|
|
2572
|
+
if (inverted) {
|
|
2573
|
+
scrollbarTop = navigator.top - scrollButtonSize;
|
|
2574
|
+
scrollbarLeft = navigator.left - scrollbarHeight +
|
|
2575
|
+
(navigatorEnabled || !scrollbarXAxis.opposite ? 0 :
|
|
2576
|
+
// Multiple axes has offsets:
|
|
2577
|
+
(scrollbarXAxis.titleOffset || 0) +
|
|
2578
|
+
// Self margin from the axis.title
|
|
2579
|
+
scrollbarXAxis.axisTitleMargin);
|
|
2580
|
+
scrollbarHeight = navigatorSize + 2 * scrollButtonSize;
|
|
2581
|
+
}
|
|
2582
|
+
else {
|
|
2583
|
+
scrollbarTop = navigator.top + (navigatorEnabled ?
|
|
2584
|
+
navigator.height :
|
|
2585
|
+
-scrollbarHeight);
|
|
2586
|
+
scrollbarLeft = navigator.left - scrollButtonSize;
|
|
2587
|
+
}
|
|
2588
|
+
// Reposition scrollbar
|
|
2589
|
+
navigator.scrollbar.position(scrollbarLeft, scrollbarTop, navigatorWidth, scrollbarHeight);
|
|
2590
|
+
// Keep scale 0-1
|
|
2591
|
+
navigator.scrollbar.setRange(
|
|
2592
|
+
// Use real value, not rounded because range can be very small
|
|
2593
|
+
// (#1716)
|
|
2594
|
+
navigator.zoomedMin / (navigatorSize || 1), navigator.zoomedMax / (navigatorSize || 1));
|
|
2595
|
+
}
|
|
2596
|
+
navigator.rendered = true;
|
|
2597
|
+
fireEvent(this, 'afterRender');
|
|
2598
|
+
}
|
|
2599
|
+
/**
|
|
2600
|
+
* Set up the mouse and touch events for the navigator
|
|
2601
|
+
*
|
|
2602
|
+
* @private
|
|
2603
|
+
* @function Highcharts.Navigator#addMouseEvents
|
|
2604
|
+
*/
|
|
2605
|
+
addMouseEvents() {
|
|
2606
|
+
const navigator = this, chart = navigator.chart, container = chart.container;
|
|
2607
|
+
let eventsToUnbind = [], mouseMoveHandler, mouseUpHandler;
|
|
2608
|
+
/**
|
|
2609
|
+
* Create mouse events' handlers.
|
|
2610
|
+
* Make them as separate functions to enable wrapping them:
|
|
2611
|
+
*/
|
|
2612
|
+
navigator.mouseMoveHandler = mouseMoveHandler = function (e) {
|
|
2613
|
+
navigator.onMouseMove(e);
|
|
2614
|
+
};
|
|
2615
|
+
navigator.mouseUpHandler = mouseUpHandler = function (e) {
|
|
2616
|
+
navigator.onMouseUp(e);
|
|
2617
|
+
};
|
|
2618
|
+
// Add shades and handles mousedown events
|
|
2619
|
+
eventsToUnbind = navigator.getPartsEvents('mousedown');
|
|
2620
|
+
eventsToUnbind.push(
|
|
2621
|
+
// Add mouse move and mouseup events. These are bind to doc/div,
|
|
2622
|
+
// because Navigator.grabbedSomething flags are stored in mousedown
|
|
2623
|
+
// events
|
|
2624
|
+
addEvent(chart.renderTo, 'mousemove', mouseMoveHandler), addEvent(container.ownerDocument, 'mouseup', mouseUpHandler),
|
|
2625
|
+
// Touch events
|
|
2626
|
+
addEvent(chart.renderTo, 'touchmove', mouseMoveHandler), addEvent(container.ownerDocument, 'touchend', mouseUpHandler));
|
|
2627
|
+
eventsToUnbind.concat(navigator.getPartsEvents('touchstart'));
|
|
2628
|
+
navigator.eventsToUnbind = eventsToUnbind;
|
|
2629
|
+
// Data events
|
|
2630
|
+
if (navigator.series && navigator.series[0]) {
|
|
2631
|
+
eventsToUnbind.push(addEvent(navigator.series[0].xAxis, 'foundExtremes', function () {
|
|
2632
|
+
chart.navigator.modifyNavigatorAxisExtremes();
|
|
2633
|
+
}));
|
|
2634
|
+
}
|
|
2635
|
+
}
|
|
2636
|
+
/**
|
|
2637
|
+
* Generate events for handles and masks
|
|
2638
|
+
*
|
|
2639
|
+
* @private
|
|
2640
|
+
* @function Highcharts.Navigator#getPartsEvents
|
|
2641
|
+
*
|
|
2642
|
+
* @param {string} eventName
|
|
2643
|
+
* Event name handler, 'mousedown' or 'touchstart'
|
|
2644
|
+
*
|
|
2645
|
+
* @return {Array<Function>}
|
|
2646
|
+
* An array of functions to remove navigator functions from the
|
|
2647
|
+
* events again.
|
|
2648
|
+
*/
|
|
2649
|
+
getPartsEvents(eventName) {
|
|
2650
|
+
const navigator = this, events = [];
|
|
2651
|
+
['shades', 'handles'].forEach(function (name) {
|
|
2652
|
+
navigator[name].forEach(function (navigatorItem, index) {
|
|
2653
|
+
events.push(addEvent(navigatorItem.element, eventName, function (e) {
|
|
2654
|
+
navigator[name + 'Mousedown'](e, index);
|
|
2655
|
+
}));
|
|
2656
|
+
});
|
|
2657
|
+
});
|
|
2658
|
+
return events;
|
|
2659
|
+
}
|
|
2660
|
+
/**
|
|
2661
|
+
* Mousedown on a shaded mask, either:
|
|
2662
|
+
*
|
|
2663
|
+
* - will be stored for future drag&drop
|
|
2664
|
+
*
|
|
2665
|
+
* - will directly shift to a new range
|
|
2666
|
+
*
|
|
2667
|
+
* @private
|
|
2668
|
+
* @function Highcharts.Navigator#shadesMousedown
|
|
2669
|
+
*
|
|
2670
|
+
* @param {Highcharts.PointerEventObject} e
|
|
2671
|
+
* Mouse event
|
|
2672
|
+
*
|
|
2673
|
+
* @param {number} index
|
|
2674
|
+
* Index of a mask in Navigator.shades array
|
|
2675
|
+
*/
|
|
2676
|
+
shadesMousedown(e, index) {
|
|
2677
|
+
e = this.chart.pointer?.normalize(e) || e;
|
|
2678
|
+
const navigator = this, chart = navigator.chart, xAxis = navigator.xAxis, zoomedMin = navigator.zoomedMin, navigatorSize = navigator.size, range = navigator.range;
|
|
2679
|
+
let navigatorPosition = navigator.left, chartX = e.chartX, fixedMax, fixedMin, ext, left;
|
|
2680
|
+
// For inverted chart, swap some options:
|
|
2681
|
+
if (chart.inverted) {
|
|
2682
|
+
chartX = e.chartY;
|
|
2683
|
+
navigatorPosition = navigator.top;
|
|
2684
|
+
}
|
|
2685
|
+
if (index === 1) {
|
|
2686
|
+
// Store information for drag&drop
|
|
2687
|
+
navigator.grabbedCenter = chartX;
|
|
2688
|
+
navigator.fixedWidth = range;
|
|
2689
|
+
navigator.dragOffset = chartX - zoomedMin;
|
|
2690
|
+
}
|
|
2691
|
+
else {
|
|
2692
|
+
// Shift the range by clicking on shaded areas
|
|
2693
|
+
left = chartX - navigatorPosition - range / 2;
|
|
2694
|
+
if (index === 0) {
|
|
2695
|
+
left = Math.max(0, left);
|
|
2696
|
+
}
|
|
2697
|
+
else if (index === 2 && left + range >= navigatorSize) {
|
|
2698
|
+
left = navigatorSize - range;
|
|
2699
|
+
if (navigator.reversedExtremes) {
|
|
2700
|
+
// #7713
|
|
2701
|
+
left -= range;
|
|
2702
|
+
fixedMin = navigator.getUnionExtremes().dataMin;
|
|
2703
|
+
}
|
|
2704
|
+
else {
|
|
2705
|
+
// #2293, #3543
|
|
2706
|
+
fixedMax = navigator.getUnionExtremes().dataMax;
|
|
2707
|
+
}
|
|
2708
|
+
}
|
|
2709
|
+
if (left !== zoomedMin) { // it has actually moved
|
|
2710
|
+
navigator.fixedWidth = range; // #1370
|
|
2711
|
+
ext = xAxis.navigatorAxis.toFixedRange(left, left + range, fixedMin, fixedMax);
|
|
2712
|
+
if (defined(ext.min)) { // #7411
|
|
2713
|
+
fireEvent(this, 'setRange', {
|
|
2714
|
+
min: Math.min(ext.min, ext.max),
|
|
2715
|
+
max: Math.max(ext.min, ext.max),
|
|
2716
|
+
redraw: true,
|
|
2717
|
+
eventArguments: {
|
|
2718
|
+
trigger: 'navigator'
|
|
2719
|
+
}
|
|
2720
|
+
});
|
|
2721
|
+
}
|
|
2722
|
+
}
|
|
2723
|
+
}
|
|
2724
|
+
}
|
|
2725
|
+
/**
|
|
2726
|
+
* Mousedown on a handle mask.
|
|
2727
|
+
* Will store necessary information for drag&drop.
|
|
2728
|
+
*
|
|
2729
|
+
* @private
|
|
2730
|
+
* @function Highcharts.Navigator#handlesMousedown
|
|
2731
|
+
* @param {Highcharts.PointerEventObject} e
|
|
2732
|
+
* Mouse event
|
|
2733
|
+
* @param {number} index
|
|
2734
|
+
* Index of a handle in Navigator.handles array
|
|
2735
|
+
*/
|
|
2736
|
+
handlesMousedown(e, index) {
|
|
2737
|
+
e = this.chart.pointer?.normalize(e) || e;
|
|
2738
|
+
const navigator = this, chart = navigator.chart, baseXAxis = chart.xAxis[0],
|
|
2739
|
+
// For reversed axes, min and max are changed,
|
|
2740
|
+
// so the other extreme should be stored
|
|
2741
|
+
reverse = navigator.reversedExtremes;
|
|
2742
|
+
if (index === 0) {
|
|
2743
|
+
// Grab the left handle
|
|
2744
|
+
navigator.grabbedLeft = true;
|
|
2745
|
+
navigator.otherHandlePos = navigator.zoomedMax;
|
|
2746
|
+
navigator.fixedExtreme = reverse ? baseXAxis.min : baseXAxis.max;
|
|
2747
|
+
}
|
|
2748
|
+
else {
|
|
2749
|
+
// Grab the right handle
|
|
2750
|
+
navigator.grabbedRight = true;
|
|
2751
|
+
navigator.otherHandlePos = navigator.zoomedMin;
|
|
2752
|
+
navigator.fixedExtreme = reverse ? baseXAxis.max : baseXAxis.min;
|
|
2753
|
+
}
|
|
2754
|
+
chart.setFixedRange(void 0);
|
|
2755
|
+
}
|
|
2756
|
+
/**
|
|
2757
|
+
* Mouse move event based on x/y mouse position.
|
|
2758
|
+
*
|
|
2759
|
+
* @private
|
|
2760
|
+
* @function Highcharts.Navigator#onMouseMove
|
|
2761
|
+
*
|
|
2762
|
+
* @param {Highcharts.PointerEventObject} e
|
|
2763
|
+
* Mouse event
|
|
2764
|
+
*/
|
|
2765
|
+
onMouseMove(e) {
|
|
2766
|
+
const navigator = this, chart = navigator.chart, navigatorSize = navigator.navigatorSize, range = navigator.range, dragOffset = navigator.dragOffset, inverted = chart.inverted;
|
|
2767
|
+
let left = navigator.left, chartX;
|
|
2768
|
+
// In iOS, a mousemove event with e.pageX === 0 is fired when holding
|
|
2769
|
+
// the finger down in the center of the scrollbar. This should be
|
|
2770
|
+
// ignored.
|
|
2771
|
+
if (!e.touches || e.touches[0].pageX !== 0) { // #4696
|
|
2772
|
+
e = chart.pointer?.normalize(e) || e;
|
|
2773
|
+
chartX = e.chartX;
|
|
2774
|
+
// Swap some options for inverted chart
|
|
2775
|
+
if (inverted) {
|
|
2776
|
+
left = navigator.top;
|
|
2777
|
+
chartX = e.chartY;
|
|
2778
|
+
}
|
|
2779
|
+
// Drag left handle or top handle
|
|
2780
|
+
if (navigator.grabbedLeft) {
|
|
2781
|
+
navigator.hasDragged = true;
|
|
2782
|
+
navigator.render(0, 0, chartX - left, navigator.otherHandlePos);
|
|
2783
|
+
// Drag right handle or bottom handle
|
|
2784
|
+
}
|
|
2785
|
+
else if (navigator.grabbedRight) {
|
|
2786
|
+
navigator.hasDragged = true;
|
|
2787
|
+
navigator.render(0, 0, navigator.otherHandlePos, chartX - left);
|
|
2788
|
+
// Drag scrollbar or open area in navigator
|
|
2789
|
+
}
|
|
2790
|
+
else if (navigator.grabbedCenter) {
|
|
2791
|
+
navigator.hasDragged = true;
|
|
2792
|
+
if (chartX < dragOffset) { // outside left
|
|
2793
|
+
chartX = dragOffset;
|
|
2794
|
+
// outside right
|
|
2795
|
+
}
|
|
2796
|
+
else if (chartX >
|
|
2797
|
+
navigatorSize + dragOffset - range) {
|
|
2798
|
+
chartX = navigatorSize + dragOffset - range;
|
|
2799
|
+
}
|
|
2800
|
+
navigator.render(0, 0, chartX - dragOffset, chartX - dragOffset + range);
|
|
2801
|
+
}
|
|
2802
|
+
if (navigator.hasDragged &&
|
|
2803
|
+
navigator.scrollbar &&
|
|
2804
|
+
pick(navigator.scrollbar.options.liveRedraw,
|
|
2805
|
+
// By default, don't run live redraw on touch
|
|
2806
|
+
// devices or if the chart is in boost.
|
|
2807
|
+
!isTouchDevice &&
|
|
2808
|
+
!this.chart.boosted)) {
|
|
2809
|
+
e.DOMType = e.type;
|
|
2810
|
+
setTimeout(function () {
|
|
2811
|
+
navigator.onMouseUp(e);
|
|
2812
|
+
}, 0);
|
|
2813
|
+
}
|
|
2814
|
+
}
|
|
2815
|
+
}
|
|
2816
|
+
/**
|
|
2817
|
+
* Mouse up event based on x/y mouse position.
|
|
2818
|
+
*
|
|
2819
|
+
* @private
|
|
2820
|
+
* @function Highcharts.Navigator#onMouseUp
|
|
2821
|
+
* @param {Highcharts.PointerEventObject} e
|
|
2822
|
+
* Mouse event
|
|
2823
|
+
*/
|
|
2824
|
+
onMouseUp(e) {
|
|
2825
|
+
const navigator = this, chart = navigator.chart, xAxis = navigator.xAxis, scrollbar = navigator.scrollbar, DOMEvent = e.DOMEvent || e, inverted = chart.inverted, verb = navigator.rendered && !navigator.hasDragged ?
|
|
2826
|
+
'animate' : 'attr';
|
|
2827
|
+
let zoomedMax, zoomedMin, unionExtremes, fixedMin, fixedMax, ext;
|
|
2828
|
+
if (
|
|
2829
|
+
// MouseUp is called for both, navigator and scrollbar (that order),
|
|
2830
|
+
// which causes calling afterSetExtremes twice. Prevent first call
|
|
2831
|
+
// by checking if scrollbar is going to set new extremes (#6334)
|
|
2832
|
+
(navigator.hasDragged && (!scrollbar || !scrollbar.hasDragged)) ||
|
|
2833
|
+
e.trigger === 'scrollbar') {
|
|
2834
|
+
unionExtremes = navigator.getUnionExtremes();
|
|
2835
|
+
// When dragging one handle, make sure the other one doesn't change
|
|
2836
|
+
if (navigator.zoomedMin === navigator.otherHandlePos) {
|
|
2837
|
+
fixedMin = navigator.fixedExtreme;
|
|
2838
|
+
}
|
|
2839
|
+
else if (navigator.zoomedMax === navigator.otherHandlePos) {
|
|
2840
|
+
fixedMax = navigator.fixedExtreme;
|
|
2841
|
+
}
|
|
2842
|
+
// Snap to right edge (#4076)
|
|
2843
|
+
if (navigator.zoomedMax === navigator.size) {
|
|
2844
|
+
fixedMax = navigator.reversedExtremes ?
|
|
2845
|
+
unionExtremes.dataMin :
|
|
2846
|
+
unionExtremes.dataMax;
|
|
2847
|
+
}
|
|
2848
|
+
// Snap to left edge (#7576)
|
|
2849
|
+
if (navigator.zoomedMin === 0) {
|
|
2850
|
+
fixedMin = navigator.reversedExtremes ?
|
|
2851
|
+
unionExtremes.dataMax :
|
|
2852
|
+
unionExtremes.dataMin;
|
|
2853
|
+
}
|
|
2854
|
+
ext = xAxis.navigatorAxis.toFixedRange(navigator.zoomedMin, navigator.zoomedMax, fixedMin, fixedMax);
|
|
2855
|
+
if (defined(ext.min)) {
|
|
2856
|
+
fireEvent(this, 'setRange', {
|
|
2857
|
+
min: Math.min(ext.min, ext.max),
|
|
2858
|
+
max: Math.max(ext.min, ext.max),
|
|
2859
|
+
redraw: true,
|
|
2860
|
+
animation: navigator.hasDragged ? false : null,
|
|
2861
|
+
eventArguments: {
|
|
2862
|
+
trigger: 'navigator',
|
|
2863
|
+
triggerOp: 'navigator-drag',
|
|
2864
|
+
DOMEvent: DOMEvent // #1838
|
|
2865
|
+
}
|
|
2866
|
+
});
|
|
2867
|
+
}
|
|
2868
|
+
}
|
|
2869
|
+
if (e.DOMType !== 'mousemove' &&
|
|
2870
|
+
e.DOMType !== 'touchmove') {
|
|
2871
|
+
navigator.grabbedLeft = navigator.grabbedRight =
|
|
2872
|
+
navigator.grabbedCenter = navigator.fixedWidth =
|
|
2873
|
+
navigator.fixedExtreme = navigator.otherHandlePos =
|
|
2874
|
+
navigator.hasDragged = navigator.dragOffset = null;
|
|
2875
|
+
}
|
|
2876
|
+
// Update position of navigator shades, outline and handles (#12573)
|
|
2877
|
+
if (navigator.navigatorEnabled &&
|
|
2878
|
+
isNumber(navigator.zoomedMin) &&
|
|
2879
|
+
isNumber(navigator.zoomedMax)) {
|
|
2880
|
+
zoomedMin = Math.round(navigator.zoomedMin);
|
|
2881
|
+
zoomedMax = Math.round(navigator.zoomedMax);
|
|
2882
|
+
if (navigator.shades) {
|
|
2883
|
+
navigator.drawMasks(zoomedMin, zoomedMax, inverted, verb);
|
|
2884
|
+
}
|
|
2885
|
+
if (navigator.outline) {
|
|
2886
|
+
navigator.drawOutline(zoomedMin, zoomedMax, inverted, verb);
|
|
2887
|
+
}
|
|
2888
|
+
if (navigator.navigatorOptions.handles.enabled &&
|
|
2889
|
+
Object.keys(navigator.handles).length ===
|
|
2890
|
+
navigator.handles.length) {
|
|
2891
|
+
navigator.drawHandle(zoomedMin, 0, inverted, verb);
|
|
2892
|
+
navigator.drawHandle(zoomedMax, 1, inverted, verb);
|
|
2893
|
+
}
|
|
2894
|
+
}
|
|
2895
|
+
}
|
|
2896
|
+
/**
|
|
2897
|
+
* Removes the event handlers attached previously with addEvents.
|
|
2898
|
+
*
|
|
2899
|
+
* @private
|
|
2900
|
+
* @function Highcharts.Navigator#removeEvents
|
|
2901
|
+
*/
|
|
2902
|
+
removeEvents() {
|
|
2903
|
+
if (this.eventsToUnbind) {
|
|
2904
|
+
this.eventsToUnbind.forEach(function (unbind) {
|
|
2905
|
+
unbind();
|
|
2906
|
+
});
|
|
2907
|
+
this.eventsToUnbind = void 0;
|
|
2908
|
+
}
|
|
2909
|
+
this.removeBaseSeriesEvents();
|
|
2910
|
+
}
|
|
2911
|
+
/**
|
|
2912
|
+
* Remove data events.
|
|
2913
|
+
*
|
|
2914
|
+
* @private
|
|
2915
|
+
* @function Highcharts.Navigator#removeBaseSeriesEvents
|
|
2916
|
+
*/
|
|
2917
|
+
removeBaseSeriesEvents() {
|
|
2918
|
+
const baseSeries = this.baseSeries || [];
|
|
2919
|
+
if (this.navigatorEnabled && baseSeries[0]) {
|
|
2920
|
+
if (this.navigatorOptions.adaptToUpdatedData !== false) {
|
|
2921
|
+
baseSeries.forEach(function (series) {
|
|
2922
|
+
removeEvent(series, 'updatedData', this.updatedDataHandler);
|
|
2923
|
+
}, this);
|
|
2924
|
+
}
|
|
2925
|
+
// We only listen for extremes-events on the first baseSeries
|
|
2926
|
+
if (baseSeries[0].xAxis) {
|
|
2927
|
+
removeEvent(baseSeries[0].xAxis, 'foundExtremes', this.modifyBaseAxisExtremes);
|
|
2928
|
+
}
|
|
2929
|
+
}
|
|
2930
|
+
}
|
|
2931
|
+
/**
|
|
2932
|
+
* Initialize the Navigator object
|
|
2933
|
+
*
|
|
2934
|
+
* @private
|
|
2935
|
+
* @function Highcharts.Navigator#init
|
|
2936
|
+
*/
|
|
2937
|
+
init(chart) {
|
|
2938
|
+
const chartOptions = chart.options, navigatorOptions = chartOptions.navigator || {}, navigatorEnabled = navigatorOptions.enabled, scrollbarOptions = chartOptions.scrollbar || {}, scrollbarEnabled = scrollbarOptions.enabled, height = navigatorEnabled && navigatorOptions.height || 0, scrollbarHeight = scrollbarEnabled && scrollbarOptions.height || 0, scrollButtonSize = scrollbarOptions.buttonsEnabled && scrollbarHeight || 0;
|
|
2939
|
+
this.handles = [];
|
|
2940
|
+
this.shades = [];
|
|
2941
|
+
this.chart = chart;
|
|
2942
|
+
this.setBaseSeries();
|
|
2943
|
+
this.height = height;
|
|
2944
|
+
this.scrollbarHeight = scrollbarHeight;
|
|
2945
|
+
this.scrollButtonSize = scrollButtonSize;
|
|
2946
|
+
this.scrollbarEnabled = scrollbarEnabled;
|
|
2947
|
+
this.navigatorEnabled = navigatorEnabled;
|
|
2948
|
+
this.navigatorOptions = navigatorOptions;
|
|
2949
|
+
this.scrollbarOptions = scrollbarOptions;
|
|
2950
|
+
this.opposite = pick(navigatorOptions.opposite, Boolean(!navigatorEnabled && chart.inverted)); // #6262
|
|
2951
|
+
const navigator = this, baseSeries = navigator.baseSeries, xAxisIndex = chart.xAxis.length, yAxisIndex = chart.yAxis.length, baseXaxis = baseSeries && baseSeries[0] && baseSeries[0].xAxis ||
|
|
2952
|
+
chart.xAxis[0] || { options: {} };
|
|
2953
|
+
chart.isDirtyBox = true;
|
|
2954
|
+
if (navigator.navigatorEnabled) {
|
|
2955
|
+
// an x axis is required for scrollbar also
|
|
2956
|
+
navigator.xAxis = new Axis(chart, merge({
|
|
2957
|
+
// inherit base xAxis' break, ordinal options and overscroll
|
|
2958
|
+
breaks: baseXaxis.options.breaks,
|
|
2959
|
+
ordinal: baseXaxis.options.ordinal,
|
|
2960
|
+
overscroll: baseXaxis.options.overscroll
|
|
2961
|
+
}, navigatorOptions.xAxis, {
|
|
2962
|
+
id: 'navigator-x-axis',
|
|
2963
|
+
yAxis: 'navigator-y-axis',
|
|
2964
|
+
type: 'datetime',
|
|
2965
|
+
index: xAxisIndex,
|
|
2966
|
+
isInternal: true,
|
|
2967
|
+
offset: 0,
|
|
2968
|
+
keepOrdinalPadding: true,
|
|
2969
|
+
startOnTick: false,
|
|
2970
|
+
endOnTick: false,
|
|
2971
|
+
minPadding: 0,
|
|
2972
|
+
maxPadding: 0,
|
|
2973
|
+
zoomEnabled: false
|
|
2974
|
+
}, chart.inverted ? {
|
|
2975
|
+
offsets: [scrollButtonSize, 0, -scrollButtonSize, 0],
|
|
2976
|
+
width: height
|
|
2977
|
+
} : {
|
|
2978
|
+
offsets: [0, -scrollButtonSize, 0, scrollButtonSize],
|
|
2979
|
+
height: height
|
|
2980
|
+
}), 'xAxis');
|
|
2981
|
+
navigator.yAxis = new Axis(chart, merge(navigatorOptions.yAxis, {
|
|
2982
|
+
id: 'navigator-y-axis',
|
|
2983
|
+
alignTicks: false,
|
|
2984
|
+
offset: 0,
|
|
2985
|
+
index: yAxisIndex,
|
|
2986
|
+
isInternal: true,
|
|
2987
|
+
reversed: pick((navigatorOptions.yAxis &&
|
|
2988
|
+
navigatorOptions.yAxis.reversed), (chart.yAxis[0] && chart.yAxis[0].reversed), false),
|
|
2989
|
+
zoomEnabled: false
|
|
2990
|
+
}, chart.inverted ? {
|
|
2991
|
+
width: height
|
|
2992
|
+
} : {
|
|
2993
|
+
height: height
|
|
2994
|
+
}), 'yAxis');
|
|
2995
|
+
// If we have a base series, initialize the navigator series
|
|
2996
|
+
if (baseSeries || navigatorOptions.series.data) {
|
|
2997
|
+
navigator.updateNavigatorSeries(false);
|
|
2998
|
+
// If not, set up an event to listen for added series
|
|
2999
|
+
}
|
|
3000
|
+
else if (chart.series.length === 0) {
|
|
3001
|
+
navigator.unbindRedraw = addEvent(chart, 'beforeRedraw', function () {
|
|
3002
|
+
// We've got one, now add it as base
|
|
3003
|
+
if (chart.series.length > 0 && !navigator.series) {
|
|
3004
|
+
navigator.setBaseSeries();
|
|
3005
|
+
navigator.unbindRedraw(); // reset
|
|
3006
|
+
}
|
|
3007
|
+
});
|
|
3008
|
+
}
|
|
3009
|
+
navigator.reversedExtremes = (chart.inverted && !navigator.xAxis.reversed) || (!chart.inverted && navigator.xAxis.reversed);
|
|
3010
|
+
// Render items, so we can bind events to them:
|
|
3011
|
+
navigator.renderElements();
|
|
3012
|
+
// Add mouse events
|
|
3013
|
+
navigator.addMouseEvents();
|
|
3014
|
+
// in case of scrollbar only, fake an x axis to get translation
|
|
3015
|
+
}
|
|
3016
|
+
else {
|
|
3017
|
+
navigator.xAxis = {
|
|
3018
|
+
chart,
|
|
3019
|
+
navigatorAxis: {
|
|
3020
|
+
fake: true
|
|
3021
|
+
},
|
|
3022
|
+
translate: function (value, reverse) {
|
|
3023
|
+
const axis = chart.xAxis[0], ext = axis.getExtremes(), scrollTrackWidth = axis.len - 2 * scrollButtonSize, min = numExt('min', axis.options.min, ext.dataMin), valueRange = numExt('max', axis.options.max, ext.dataMax) - min;
|
|
3024
|
+
return reverse ?
|
|
3025
|
+
// from pixel to value
|
|
3026
|
+
(value * valueRange / scrollTrackWidth) + min :
|
|
3027
|
+
// from value to pixel
|
|
3028
|
+
scrollTrackWidth * (value - min) / valueRange;
|
|
3029
|
+
},
|
|
3030
|
+
toPixels: function (value) {
|
|
3031
|
+
return this.translate(value);
|
|
3032
|
+
},
|
|
3033
|
+
toValue: function (value) {
|
|
3034
|
+
return this.translate(value, true);
|
|
3035
|
+
}
|
|
3036
|
+
};
|
|
3037
|
+
navigator.xAxis.navigatorAxis.axis = navigator.xAxis;
|
|
3038
|
+
navigator.xAxis.navigatorAxis.toFixedRange = (NavigatorAxisAdditions.prototype.toFixedRange.bind(navigator.xAxis.navigatorAxis));
|
|
3039
|
+
}
|
|
3040
|
+
// Initialize the scrollbar
|
|
3041
|
+
if (chart.options.scrollbar.enabled) {
|
|
3042
|
+
const options = merge(chart.options.scrollbar, { vertical: chart.inverted });
|
|
3043
|
+
if (!isNumber(options.margin) && navigator.navigatorEnabled) {
|
|
3044
|
+
options.margin = chart.inverted ? -3 : 3;
|
|
3045
|
+
}
|
|
3046
|
+
chart.scrollbar = navigator.scrollbar = new Scrollbar(chart.renderer, options, chart);
|
|
3047
|
+
addEvent(navigator.scrollbar, 'changed', function (e) {
|
|
3048
|
+
const range = navigator.size, to = range * this.to, from = range * this.from;
|
|
3049
|
+
navigator.hasDragged = navigator.scrollbar.hasDragged;
|
|
3050
|
+
navigator.render(0, 0, from, to);
|
|
3051
|
+
if (this.shouldUpdateExtremes(e.DOMType)) {
|
|
3052
|
+
setTimeout(function () {
|
|
3053
|
+
navigator.onMouseUp(e);
|
|
3054
|
+
});
|
|
3055
|
+
}
|
|
3056
|
+
});
|
|
3057
|
+
}
|
|
3058
|
+
// Add data events
|
|
3059
|
+
navigator.addBaseSeriesEvents();
|
|
3060
|
+
// Add redraw events
|
|
3061
|
+
navigator.addChartEvents();
|
|
3062
|
+
}
|
|
3063
|
+
/**
|
|
3064
|
+
* Get the union data extremes of the chart - the outer data extremes of the
|
|
3065
|
+
* base X axis and the navigator axis.
|
|
3066
|
+
*
|
|
3067
|
+
* @private
|
|
3068
|
+
* @function Highcharts.Navigator#getUnionExtremes
|
|
3069
|
+
*/
|
|
3070
|
+
getUnionExtremes(returnFalseOnNoBaseSeries) {
|
|
3071
|
+
const baseAxis = this.chart.xAxis[0], navAxis = this.xAxis, navAxisOptions = navAxis.options, baseAxisOptions = baseAxis.options;
|
|
3072
|
+
let ret;
|
|
3073
|
+
if (!returnFalseOnNoBaseSeries || baseAxis.dataMin !== null) {
|
|
3074
|
+
ret = {
|
|
3075
|
+
dataMin: pick(// #4053
|
|
3076
|
+
navAxisOptions && navAxisOptions.min, numExt('min', baseAxisOptions.min, baseAxis.dataMin, navAxis.dataMin, navAxis.min)),
|
|
3077
|
+
dataMax: pick(navAxisOptions && navAxisOptions.max, numExt('max', baseAxisOptions.max, baseAxis.dataMax, navAxis.dataMax, navAxis.max))
|
|
3078
|
+
};
|
|
3079
|
+
}
|
|
3080
|
+
return ret;
|
|
3081
|
+
}
|
|
3082
|
+
/**
|
|
3083
|
+
* Set the base series and update the navigator series from this. With a bit
|
|
3084
|
+
* of modification we should be able to make this an API method to be called
|
|
3085
|
+
* from the outside
|
|
3086
|
+
*
|
|
3087
|
+
* @private
|
|
3088
|
+
* @function Highcharts.Navigator#setBaseSeries
|
|
3089
|
+
* @param {Highcharts.SeriesOptionsType} [baseSeriesOptions]
|
|
3090
|
+
* Additional series options for a navigator
|
|
3091
|
+
* @param {boolean} [redraw]
|
|
3092
|
+
* Whether to redraw after update.
|
|
3093
|
+
*/
|
|
3094
|
+
setBaseSeries(baseSeriesOptions, redraw) {
|
|
3095
|
+
const chart = this.chart, baseSeries = this.baseSeries = [];
|
|
3096
|
+
baseSeriesOptions = (baseSeriesOptions ||
|
|
3097
|
+
chart.options && chart.options.navigator.baseSeries ||
|
|
3098
|
+
(chart.series.length ?
|
|
3099
|
+
// Find the first non-navigator series (#8430)
|
|
3100
|
+
find(chart.series, (s) => (!s.options.isInternal)).index :
|
|
3101
|
+
0));
|
|
3102
|
+
// Iterate through series and add the ones that should be shown in
|
|
3103
|
+
// navigator.
|
|
3104
|
+
(chart.series || []).forEach((series, i) => {
|
|
3105
|
+
if (
|
|
3106
|
+
// Don't include existing nav series
|
|
3107
|
+
!series.options.isInternal &&
|
|
3108
|
+
(series.options.showInNavigator ||
|
|
3109
|
+
(i === baseSeriesOptions ||
|
|
3110
|
+
series.options.id === baseSeriesOptions) &&
|
|
3111
|
+
series.options.showInNavigator !== false)) {
|
|
3112
|
+
baseSeries.push(series);
|
|
3113
|
+
}
|
|
3114
|
+
});
|
|
3115
|
+
// When run after render, this.xAxis already exists
|
|
3116
|
+
if (this.xAxis && !this.xAxis.navigatorAxis.fake) {
|
|
3117
|
+
this.updateNavigatorSeries(true, redraw);
|
|
3118
|
+
}
|
|
3119
|
+
}
|
|
3120
|
+
/**
|
|
3121
|
+
* Update series in the navigator from baseSeries, adding new if does not
|
|
3122
|
+
* exist.
|
|
3123
|
+
*
|
|
3124
|
+
* @private
|
|
3125
|
+
* @function Highcharts.Navigator.updateNavigatorSeries
|
|
3126
|
+
*/
|
|
3127
|
+
updateNavigatorSeries(addEvents, redraw) {
|
|
3128
|
+
const navigator = this, chart = navigator.chart, baseSeries = navigator.baseSeries, navSeriesMixin = {
|
|
3129
|
+
enableMouseTracking: false,
|
|
3130
|
+
index: null,
|
|
3131
|
+
linkedTo: null,
|
|
3132
|
+
group: 'nav',
|
|
3133
|
+
padXAxis: false,
|
|
3134
|
+
xAxis: 'navigator-x-axis',
|
|
3135
|
+
yAxis: 'navigator-y-axis',
|
|
3136
|
+
showInLegend: false,
|
|
3137
|
+
stacking: void 0,
|
|
3138
|
+
isInternal: true,
|
|
3139
|
+
states: {
|
|
3140
|
+
inactive: {
|
|
3141
|
+
opacity: 1
|
|
3142
|
+
}
|
|
3143
|
+
}
|
|
3144
|
+
},
|
|
3145
|
+
// Remove navigator series that are no longer in the baseSeries
|
|
3146
|
+
navigatorSeries = navigator.series =
|
|
3147
|
+
(navigator.series || []).filter((navSeries) => {
|
|
3148
|
+
const base = navSeries.baseSeries;
|
|
3149
|
+
if (baseSeries.indexOf(base) < 0) { // Not in array
|
|
3150
|
+
// If there is still a base series connected to this
|
|
3151
|
+
// series, remove event handler and reference.
|
|
3152
|
+
if (base) {
|
|
3153
|
+
removeEvent(base, 'updatedData', navigator.updatedDataHandler);
|
|
3154
|
+
delete base.navigatorSeries;
|
|
3155
|
+
}
|
|
3156
|
+
// Kill the nav series. It may already have been
|
|
3157
|
+
// destroyed (#8715).
|
|
3158
|
+
if (navSeries.chart) {
|
|
3159
|
+
navSeries.destroy();
|
|
3160
|
+
}
|
|
3161
|
+
return false;
|
|
3162
|
+
}
|
|
3163
|
+
return true;
|
|
3164
|
+
});
|
|
3165
|
+
let baseOptions, mergedNavSeriesOptions, chartNavigatorSeriesOptions = navigator.navigatorOptions.series, baseNavigatorOptions;
|
|
3166
|
+
// Go through each base series and merge the options to create new
|
|
3167
|
+
// series
|
|
3168
|
+
if (baseSeries && baseSeries.length) {
|
|
3169
|
+
baseSeries.forEach((base) => {
|
|
3170
|
+
const linkedNavSeries = base.navigatorSeries, userNavOptions = extend(
|
|
3171
|
+
// Grab color and visibility from base as default
|
|
3172
|
+
{
|
|
3173
|
+
color: base.color,
|
|
3174
|
+
visible: base.visible
|
|
3175
|
+
}, !isArray(chartNavigatorSeriesOptions) ?
|
|
3176
|
+
chartNavigatorSeriesOptions :
|
|
3177
|
+
defaultOptions.navigator.series);
|
|
3178
|
+
// Don't update if the series exists in nav and we have disabled
|
|
3179
|
+
// adaptToUpdatedData.
|
|
3180
|
+
if (linkedNavSeries &&
|
|
3181
|
+
navigator.navigatorOptions.adaptToUpdatedData === false) {
|
|
3182
|
+
return;
|
|
3183
|
+
}
|
|
3184
|
+
navSeriesMixin.name = 'Navigator ' + baseSeries.length;
|
|
3185
|
+
baseOptions = base.options || {};
|
|
3186
|
+
baseNavigatorOptions = baseOptions.navigatorOptions || {};
|
|
3187
|
+
// The dataLabels options are not merged correctly
|
|
3188
|
+
// if the settings are an array, #13847.
|
|
3189
|
+
userNavOptions.dataLabels = splat(userNavOptions.dataLabels);
|
|
3190
|
+
mergedNavSeriesOptions = merge(baseOptions, navSeriesMixin, userNavOptions, baseNavigatorOptions);
|
|
3191
|
+
// Once nav series type is resolved, pick correct pointRange
|
|
3192
|
+
mergedNavSeriesOptions.pointRange = pick(
|
|
3193
|
+
// Stricte set pointRange in options
|
|
3194
|
+
userNavOptions.pointRange, baseNavigatorOptions.pointRange,
|
|
3195
|
+
// Fallback to default values, e.g. `null` for column
|
|
3196
|
+
defaultOptions.plotOptions[mergedNavSeriesOptions.type || 'line'].pointRange);
|
|
3197
|
+
// Merge data separately. Do a slice to avoid mutating the
|
|
3198
|
+
// navigator options from base series (#4923).
|
|
3199
|
+
const navigatorSeriesData = baseNavigatorOptions.data || userNavOptions.data;
|
|
3200
|
+
navigator.hasNavigatorData =
|
|
3201
|
+
navigator.hasNavigatorData || !!navigatorSeriesData;
|
|
3202
|
+
mergedNavSeriesOptions.data =
|
|
3203
|
+
navigatorSeriesData ||
|
|
3204
|
+
baseOptions.data && baseOptions.data.slice(0);
|
|
3205
|
+
// Update or add the series
|
|
3206
|
+
if (linkedNavSeries && linkedNavSeries.options) {
|
|
3207
|
+
linkedNavSeries.update(mergedNavSeriesOptions, redraw);
|
|
3208
|
+
}
|
|
3209
|
+
else {
|
|
3210
|
+
base.navigatorSeries = chart.initSeries(mergedNavSeriesOptions);
|
|
3211
|
+
// Set data on initial run with dataSorting enabled (#20318)
|
|
3212
|
+
chart.setSortedData();
|
|
3213
|
+
base.navigatorSeries.baseSeries = base; // Store ref
|
|
3214
|
+
navigatorSeries.push(base.navigatorSeries);
|
|
3215
|
+
}
|
|
3216
|
+
});
|
|
3217
|
+
}
|
|
3218
|
+
// If user has defined data (and no base series) or explicitly defined
|
|
3219
|
+
// navigator.series as an array, we create these series on top of any
|
|
3220
|
+
// base series.
|
|
3221
|
+
if (chartNavigatorSeriesOptions.data &&
|
|
3222
|
+
!(baseSeries && baseSeries.length) ||
|
|
3223
|
+
isArray(chartNavigatorSeriesOptions)) {
|
|
3224
|
+
navigator.hasNavigatorData = false;
|
|
3225
|
+
// Allow navigator.series to be an array
|
|
3226
|
+
chartNavigatorSeriesOptions =
|
|
3227
|
+
splat(chartNavigatorSeriesOptions);
|
|
3228
|
+
chartNavigatorSeriesOptions.forEach((userSeriesOptions, i) => {
|
|
3229
|
+
navSeriesMixin.name =
|
|
3230
|
+
'Navigator ' + (navigatorSeries.length + 1);
|
|
3231
|
+
mergedNavSeriesOptions = merge(defaultOptions.navigator.series, {
|
|
3232
|
+
// Since we don't have a base series to pull color from,
|
|
3233
|
+
// try to fake it by using color from series with same
|
|
3234
|
+
// index. Otherwise pull from the colors array. We need
|
|
3235
|
+
// an explicit color as otherwise updates will increment
|
|
3236
|
+
// color counter and we'll get a new color for each
|
|
3237
|
+
// update of the nav series.
|
|
3238
|
+
color: chart.series[i] &&
|
|
3239
|
+
!chart.series[i].options.isInternal &&
|
|
3240
|
+
chart.series[i].color ||
|
|
3241
|
+
chart.options.colors[i] ||
|
|
3242
|
+
chart.options.colors[0]
|
|
3243
|
+
}, navSeriesMixin, userSeriesOptions);
|
|
3244
|
+
mergedNavSeriesOptions.data = userSeriesOptions.data;
|
|
3245
|
+
if (mergedNavSeriesOptions.data) {
|
|
3246
|
+
navigator.hasNavigatorData = true;
|
|
3247
|
+
navigatorSeries.push(chart.initSeries(mergedNavSeriesOptions));
|
|
3248
|
+
}
|
|
3249
|
+
});
|
|
3250
|
+
}
|
|
3251
|
+
if (addEvents) {
|
|
3252
|
+
this.addBaseSeriesEvents();
|
|
3253
|
+
}
|
|
3254
|
+
}
|
|
3255
|
+
/**
|
|
3256
|
+
* Add data events.
|
|
3257
|
+
* For example when main series is updated we need to recalculate extremes
|
|
3258
|
+
*
|
|
3259
|
+
* @private
|
|
3260
|
+
* @function Highcharts.Navigator#addBaseSeriesEvent
|
|
3261
|
+
*/
|
|
3262
|
+
addBaseSeriesEvents() {
|
|
3263
|
+
const navigator = this, baseSeries = navigator.baseSeries || [];
|
|
3264
|
+
// Bind modified extremes event to first base's xAxis only.
|
|
3265
|
+
// In event of > 1 base-xAxes, the navigator will ignore those.
|
|
3266
|
+
// Adding this multiple times to the same axis is no problem, as
|
|
3267
|
+
// duplicates should be discarded by the browser.
|
|
3268
|
+
if (baseSeries[0] && baseSeries[0].xAxis) {
|
|
3269
|
+
baseSeries[0].eventsToUnbind.push(addEvent(baseSeries[0].xAxis, 'foundExtremes', this.modifyBaseAxisExtremes));
|
|
3270
|
+
}
|
|
3271
|
+
baseSeries.forEach((base) => {
|
|
3272
|
+
// Link base series show/hide to navigator series visibility
|
|
3273
|
+
base.eventsToUnbind.push(addEvent(base, 'show', function () {
|
|
3274
|
+
if (this.navigatorSeries) {
|
|
3275
|
+
this.navigatorSeries.setVisible(true, false);
|
|
3276
|
+
}
|
|
3277
|
+
}));
|
|
3278
|
+
base.eventsToUnbind.push(addEvent(base, 'hide', function () {
|
|
3279
|
+
if (this.navigatorSeries) {
|
|
3280
|
+
this.navigatorSeries.setVisible(false, false);
|
|
3281
|
+
}
|
|
3282
|
+
}));
|
|
3283
|
+
// Respond to updated data in the base series, unless explicitly
|
|
3284
|
+
// not adapting to data changes.
|
|
3285
|
+
if (this.navigatorOptions.adaptToUpdatedData !== false) {
|
|
3286
|
+
if (base.xAxis) {
|
|
3287
|
+
base.eventsToUnbind.push(addEvent(base, 'updatedData', this.updatedDataHandler));
|
|
3288
|
+
}
|
|
3289
|
+
}
|
|
3290
|
+
// Handle series removal
|
|
3291
|
+
base.eventsToUnbind.push(addEvent(base, 'remove', function () {
|
|
3292
|
+
if (this.navigatorSeries) {
|
|
3293
|
+
erase(navigator.series, this.navigatorSeries);
|
|
3294
|
+
if (defined(this.navigatorSeries.options)) {
|
|
3295
|
+
this.navigatorSeries.remove(false);
|
|
3296
|
+
}
|
|
3297
|
+
delete this.navigatorSeries;
|
|
3298
|
+
}
|
|
3299
|
+
}));
|
|
3300
|
+
});
|
|
3301
|
+
}
|
|
3302
|
+
/**
|
|
3303
|
+
* Get minimum from all base series connected to the navigator
|
|
3304
|
+
* @private
|
|
3305
|
+
* @param {number} currentSeriesMin
|
|
3306
|
+
* Minium from the current series
|
|
3307
|
+
* @return {number}
|
|
3308
|
+
* Minimum from all series
|
|
3309
|
+
*/
|
|
3310
|
+
getBaseSeriesMin(currentSeriesMin) {
|
|
3311
|
+
return this.baseSeries.reduce(function (min, series) {
|
|
3312
|
+
// (#10193)
|
|
3313
|
+
return Math.min(min, series.xData && series.xData.length ?
|
|
3314
|
+
series.xData[0] : min);
|
|
3315
|
+
}, currentSeriesMin);
|
|
3316
|
+
}
|
|
3317
|
+
/**
|
|
3318
|
+
* Set the navigator x axis extremes to reflect the total. The navigator
|
|
3319
|
+
* extremes should always be the extremes of the union of all series in the
|
|
3320
|
+
* chart as well as the navigator series.
|
|
3321
|
+
*
|
|
3322
|
+
* @private
|
|
3323
|
+
* @function Highcharts.Navigator#modifyNavigatorAxisExtremes
|
|
3324
|
+
*/
|
|
3325
|
+
modifyNavigatorAxisExtremes() {
|
|
3326
|
+
const xAxis = this.xAxis;
|
|
3327
|
+
if (typeof xAxis.getExtremes !== 'undefined') {
|
|
3328
|
+
const unionExtremes = this.getUnionExtremes(true);
|
|
3329
|
+
if (unionExtremes &&
|
|
3330
|
+
(unionExtremes.dataMin !== xAxis.min ||
|
|
3331
|
+
unionExtremes.dataMax !== xAxis.max)) {
|
|
3332
|
+
xAxis.min = unionExtremes.dataMin;
|
|
3333
|
+
xAxis.max = unionExtremes.dataMax;
|
|
3334
|
+
}
|
|
3335
|
+
}
|
|
3336
|
+
}
|
|
3337
|
+
/**
|
|
3338
|
+
* Hook to modify the base axis extremes with information from the Navigator
|
|
3339
|
+
*
|
|
3340
|
+
* @private
|
|
3341
|
+
* @function Highcharts.Navigator#modifyBaseAxisExtremes
|
|
3342
|
+
*/
|
|
3343
|
+
modifyBaseAxisExtremes() {
|
|
3344
|
+
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,
|
|
3345
|
+
// When the extremes have been set by range selector button, don't
|
|
3346
|
+
// stick to min or max. The range selector buttons will handle the
|
|
3347
|
+
// extremes. (#5489)
|
|
3348
|
+
unmutable = baseXAxis.eventArgs &&
|
|
3349
|
+
baseXAxis.eventArgs.trigger === 'rangeSelectorButton';
|
|
3350
|
+
let newMax, newMin;
|
|
3351
|
+
if (!unmutable) {
|
|
3352
|
+
// If the zoomed range is already at the min, move it to the right
|
|
3353
|
+
// as new data comes in
|
|
3354
|
+
if (stickToMin) {
|
|
3355
|
+
newMin = baseDataMin;
|
|
3356
|
+
newMax = newMin + range;
|
|
3357
|
+
}
|
|
3358
|
+
// If the zoomed range is already at the max, move it to the right
|
|
3359
|
+
// as new data comes in
|
|
3360
|
+
if (stickToMax) {
|
|
3361
|
+
newMax = baseDataMax + overscroll;
|
|
3362
|
+
// If stickToMin is true, the new min value is set above
|
|
3363
|
+
if (!stickToMin) {
|
|
3364
|
+
newMin = Math.max(baseDataMin, // don't go below data extremes (#13184)
|
|
3365
|
+
newMax - range, navigator.getBaseSeriesMin(navigatorSeries && navigatorSeries.xData ?
|
|
3366
|
+
navigatorSeries.xData[0] :
|
|
3367
|
+
-Number.MAX_VALUE));
|
|
3368
|
+
}
|
|
3369
|
+
}
|
|
3370
|
+
// Update the extremes
|
|
3371
|
+
if (hasSetExtremes && (stickToMin || stickToMax)) {
|
|
3372
|
+
if (isNumber(newMin)) {
|
|
3373
|
+
baseXAxis.min = baseXAxis.userMin = newMin;
|
|
3374
|
+
baseXAxis.max = baseXAxis.userMax = newMax;
|
|
3375
|
+
}
|
|
3376
|
+
}
|
|
3377
|
+
}
|
|
3378
|
+
// Reset
|
|
3379
|
+
navigator.stickToMin =
|
|
3380
|
+
navigator.stickToMax = null;
|
|
3381
|
+
}
|
|
3382
|
+
/**
|
|
3383
|
+
* Handler for updated data on the base series. When data is modified, the
|
|
3384
|
+
* navigator series must reflect it. This is called from the Chart.redraw
|
|
3385
|
+
* function before axis and series extremes are computed.
|
|
3386
|
+
*
|
|
3387
|
+
* @private
|
|
3388
|
+
* @function Highcharts.Navigator#updateDataHandler
|
|
3389
|
+
*/
|
|
3390
|
+
updatedDataHandler() {
|
|
3391
|
+
const navigator = this.chart.navigator, baseSeries = this, navigatorSeries = this.navigatorSeries, shouldStickToMax = navigator.reversedExtremes ?
|
|
3392
|
+
Math.round(navigator.zoomedMin) === 0 :
|
|
3393
|
+
Math.round(navigator.zoomedMax) >= Math.round(navigator.size);
|
|
3394
|
+
// If the scrollbar is scrolled all the way to the right, keep right as
|
|
3395
|
+
// new data comes in, unless user set navigator.stickToMax to false.
|
|
3396
|
+
navigator.stickToMax = pick(this.chart.options.navigator &&
|
|
3397
|
+
this.chart.options.navigator.stickToMax, shouldStickToMax);
|
|
3398
|
+
navigator.stickToMin = navigator.shouldStickToMin(baseSeries, navigator);
|
|
3399
|
+
// Set the navigator series data to the new data of the base series
|
|
3400
|
+
if (navigatorSeries && !navigator.hasNavigatorData) {
|
|
3401
|
+
navigatorSeries.options.pointStart = baseSeries.xData[0];
|
|
3402
|
+
navigatorSeries.setData(baseSeries.options.data, false, null, false); // #5414
|
|
3403
|
+
}
|
|
3404
|
+
}
|
|
3405
|
+
/**
|
|
3406
|
+
* Detect if the zoomed area should stick to the minimum, #14742.
|
|
3407
|
+
*
|
|
3408
|
+
* @private
|
|
3409
|
+
* @function Highcharts.Navigator#shouldStickToMin
|
|
3410
|
+
*/
|
|
3411
|
+
shouldStickToMin(baseSeries, navigator) {
|
|
3412
|
+
const xDataMin = navigator.getBaseSeriesMin(baseSeries.xData[0]), xAxis = baseSeries.xAxis, max = xAxis.max, min = xAxis.min, range = xAxis.options.range;
|
|
3413
|
+
let stickToMin = true;
|
|
3414
|
+
if (isNumber(max) && isNumber(min)) {
|
|
3415
|
+
// If range declared, stick to the minimum only if the range
|
|
3416
|
+
// is smaller than the data set range.
|
|
3417
|
+
if (range && max - xDataMin > 0) {
|
|
3418
|
+
stickToMin = max - xDataMin < range;
|
|
3419
|
+
}
|
|
3420
|
+
else {
|
|
3421
|
+
// If the current axis minimum falls outside the new
|
|
3422
|
+
// updated dataset, we must adjust.
|
|
3423
|
+
stickToMin = min <= xDataMin;
|
|
3424
|
+
}
|
|
3425
|
+
}
|
|
3426
|
+
else {
|
|
3427
|
+
stickToMin = false; // #15864
|
|
3428
|
+
}
|
|
3429
|
+
return stickToMin;
|
|
3430
|
+
}
|
|
3431
|
+
/**
|
|
3432
|
+
* Add chart events, like redrawing navigator, when chart requires that.
|
|
3433
|
+
*
|
|
3434
|
+
* @private
|
|
3435
|
+
* @function Highcharts.Navigator#addChartEvents
|
|
3436
|
+
*/
|
|
3437
|
+
addChartEvents() {
|
|
3438
|
+
if (!this.eventsToUnbind) {
|
|
3439
|
+
this.eventsToUnbind = [];
|
|
3440
|
+
}
|
|
3441
|
+
this.eventsToUnbind.push(
|
|
3442
|
+
// Move the scrollbar after redraw, like after data updata even if
|
|
3443
|
+
// axes don't redraw
|
|
3444
|
+
addEvent(this.chart, 'redraw', function () {
|
|
3445
|
+
const navigator = this.navigator, xAxis = navigator && (navigator.baseSeries &&
|
|
3446
|
+
navigator.baseSeries[0] &&
|
|
3447
|
+
navigator.baseSeries[0].xAxis ||
|
|
3448
|
+
this.xAxis[0]); // #5709, #13114
|
|
3449
|
+
if (xAxis) {
|
|
3450
|
+
navigator.render(xAxis.min, xAxis.max);
|
|
3451
|
+
}
|
|
3452
|
+
}),
|
|
3453
|
+
// Make room for the navigator, can be placed around the chart:
|
|
3454
|
+
addEvent(this.chart, 'getMargins', function () {
|
|
3455
|
+
let chart = this, navigator = chart.navigator, marginName = navigator.opposite ?
|
|
3456
|
+
'plotTop' : 'marginBottom';
|
|
3457
|
+
if (chart.inverted) {
|
|
3458
|
+
marginName = navigator.opposite ?
|
|
3459
|
+
'marginRight' : 'plotLeft';
|
|
3460
|
+
}
|
|
3461
|
+
chart[marginName] =
|
|
3462
|
+
(chart[marginName] || 0) + (navigator.navigatorEnabled || !chart.inverted ?
|
|
3463
|
+
navigator.height + navigator.scrollbarHeight :
|
|
3464
|
+
0) + navigator.navigatorOptions.margin;
|
|
3465
|
+
}), addEvent(Navigator, 'setRange', function (e) {
|
|
3466
|
+
this.chart.xAxis[0].setExtremes(e.min, e.max, e.redraw, e.animation, e.eventArguments);
|
|
3467
|
+
}));
|
|
3468
|
+
}
|
|
3469
|
+
/**
|
|
3470
|
+
* Destroys allocated elements.
|
|
3471
|
+
*
|
|
3472
|
+
* @private
|
|
3473
|
+
* @function Highcharts.Navigator#destroy
|
|
3474
|
+
*/
|
|
3475
|
+
destroy() {
|
|
3476
|
+
// Disconnect events added in addEvents
|
|
3477
|
+
this.removeEvents();
|
|
3478
|
+
if (this.xAxis) {
|
|
3479
|
+
erase(this.chart.xAxis, this.xAxis);
|
|
3480
|
+
erase(this.chart.axes, this.xAxis);
|
|
3481
|
+
}
|
|
3482
|
+
if (this.yAxis) {
|
|
3483
|
+
erase(this.chart.yAxis, this.yAxis);
|
|
3484
|
+
erase(this.chart.axes, this.yAxis);
|
|
3485
|
+
}
|
|
3486
|
+
// Destroy series
|
|
3487
|
+
(this.series || []).forEach((s) => {
|
|
3488
|
+
if (s.destroy) {
|
|
3489
|
+
s.destroy();
|
|
3490
|
+
}
|
|
3491
|
+
});
|
|
3492
|
+
// Destroy properties
|
|
3493
|
+
[
|
|
3494
|
+
'series', 'xAxis', 'yAxis', 'shades', 'outline', 'scrollbarTrack',
|
|
3495
|
+
'scrollbarRifles', 'scrollbarGroup', 'scrollbar', 'navigatorGroup',
|
|
3496
|
+
'rendered'
|
|
3497
|
+
].forEach((prop) => {
|
|
3498
|
+
if (this[prop] && this[prop].destroy) {
|
|
3499
|
+
this[prop].destroy();
|
|
3500
|
+
}
|
|
3501
|
+
this[prop] = null;
|
|
3502
|
+
});
|
|
3503
|
+
// Destroy elements in collection
|
|
3504
|
+
[this.handles].forEach((coll) => {
|
|
3505
|
+
destroyObjectProperties(coll);
|
|
3506
|
+
});
|
|
3507
|
+
}
|
|
3508
|
+
}
|
|
3509
|
+
/* *
|
|
3510
|
+
*
|
|
3511
|
+
* Default Export
|
|
3512
|
+
*
|
|
3513
|
+
* */
|
|
3514
|
+
|
|
3515
|
+
return Navigator;
|
|
3516
|
+
});
|
|
3517
|
+
_registerModule(_modules, 'Stock/Navigator/StandaloneNavigatorDefaults.js', [], function () {
|
|
3518
|
+
/* *
|
|
3519
|
+
*
|
|
3520
|
+
* (c) 2010-2024 Mateusz Bernacik
|
|
3521
|
+
*
|
|
3522
|
+
* License: www.highcharts.com/license
|
|
3523
|
+
*
|
|
3524
|
+
* !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
|
|
3525
|
+
*
|
|
3526
|
+
* */
|
|
3527
|
+
/* *
|
|
3528
|
+
*
|
|
3529
|
+
* Constants
|
|
3530
|
+
*
|
|
3531
|
+
* */
|
|
3532
|
+
const standaloneNavigatorDefaults = {
|
|
3533
|
+
chart: {
|
|
3534
|
+
height: 70,
|
|
3535
|
+
margin: [0, 5, 0, 5]
|
|
3536
|
+
},
|
|
3537
|
+
exporting: {
|
|
3538
|
+
enabled: false
|
|
3539
|
+
},
|
|
3540
|
+
legend: {
|
|
3541
|
+
enabled: false
|
|
3542
|
+
},
|
|
3543
|
+
navigator: {
|
|
3544
|
+
enabled: false
|
|
3545
|
+
},
|
|
3546
|
+
plotOptions: {
|
|
3547
|
+
series: {
|
|
3548
|
+
states: {
|
|
3549
|
+
hover: {
|
|
3550
|
+
enabled: false
|
|
3551
|
+
}
|
|
3552
|
+
},
|
|
3553
|
+
marker: {
|
|
3554
|
+
enabled: false
|
|
3555
|
+
}
|
|
3556
|
+
}
|
|
3557
|
+
},
|
|
3558
|
+
scrollbar: {
|
|
3559
|
+
enabled: false
|
|
3560
|
+
},
|
|
3561
|
+
title: {
|
|
3562
|
+
text: ''
|
|
3563
|
+
},
|
|
3564
|
+
tooltip: {
|
|
3565
|
+
enabled: false
|
|
3566
|
+
},
|
|
3567
|
+
xAxis: {
|
|
3568
|
+
visible: false
|
|
3569
|
+
},
|
|
3570
|
+
yAxis: {
|
|
3571
|
+
height: 0,
|
|
3572
|
+
visible: false
|
|
3573
|
+
}
|
|
3574
|
+
};
|
|
3575
|
+
/* *
|
|
3576
|
+
*
|
|
3577
|
+
* Default Export
|
|
3578
|
+
*
|
|
3579
|
+
* */
|
|
3580
|
+
|
|
3581
|
+
return standaloneNavigatorDefaults;
|
|
3582
|
+
});
|
|
3583
|
+
_registerModule(_modules, 'Stock/Navigator/StandaloneNavigator.js', [_modules['Core/Chart/Chart.js'], _modules['Stock/Navigator/Navigator.js'], _modules['Core/Globals.js'], _modules['Core/Utilities.js'], _modules['Core/Axis/Axis.js'], _modules['Stock/Navigator/StandaloneNavigatorDefaults.js']], function (Chart, Navigator, G, U, Axis, standaloneNavigatorDefaults) {
|
|
3584
|
+
/* *
|
|
3585
|
+
*
|
|
3586
|
+
* (c) 2010-2024 Mateusz Bernacik
|
|
3587
|
+
*
|
|
3588
|
+
* License: www.highcharts.com/license
|
|
3589
|
+
*
|
|
3590
|
+
* !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
|
|
3591
|
+
*
|
|
3592
|
+
* */
|
|
3593
|
+
const { merge, addEvent, fireEvent, pick } = U;
|
|
3594
|
+
/* *
|
|
3595
|
+
*
|
|
3596
|
+
* Class
|
|
3597
|
+
*
|
|
3598
|
+
* */
|
|
3599
|
+
/**
|
|
3600
|
+
* The StandaloneNavigator class. The StandaloneNavigator class allows for
|
|
3601
|
+
* creating a standalone navigator component that synchronizes the extremes
|
|
3602
|
+
* across multiple bound charts.
|
|
3603
|
+
*
|
|
3604
|
+
* @class
|
|
3605
|
+
* @name Highcharts.StandaloneNavigator
|
|
3606
|
+
*
|
|
3607
|
+
* @param {string|Highcharts.HTMLDOMElement} [renderTo]
|
|
3608
|
+
* The DOM element to render to, or its id.
|
|
3609
|
+
*
|
|
3610
|
+
* @param {StandaloneNavigatorOptions} userOptions
|
|
3611
|
+
* The standalone navigator options.
|
|
3612
|
+
*/
|
|
3613
|
+
class StandaloneNavigator {
|
|
3614
|
+
/* *
|
|
3615
|
+
*
|
|
3616
|
+
* Static Functions
|
|
3617
|
+
*
|
|
3618
|
+
* */
|
|
3619
|
+
/**
|
|
3620
|
+
* Factory function for standalone navigator.
|
|
3621
|
+
*
|
|
3622
|
+
* @function Highcharts.navigator
|
|
3623
|
+
*
|
|
3624
|
+
* @param {string|Highcharts.HTMLDOMElement} [renderTo]
|
|
3625
|
+
* The DOM element to render to, or its id.
|
|
3626
|
+
*
|
|
3627
|
+
* @param {StandaloneNavigatorOptions} options
|
|
3628
|
+
* The standalone navigator options with chart-like structure.
|
|
3629
|
+
*
|
|
3630
|
+
* Returns the navigator object.
|
|
3631
|
+
*/
|
|
3632
|
+
static navigator(renderTo, options) {
|
|
3633
|
+
const nav = new StandaloneNavigator(renderTo, options);
|
|
3634
|
+
if (!G.navigators) {
|
|
3635
|
+
G.navigators = [nav];
|
|
3636
|
+
}
|
|
3637
|
+
else {
|
|
3638
|
+
G.navigators.push(nav);
|
|
3639
|
+
}
|
|
3640
|
+
return nav;
|
|
3641
|
+
}
|
|
3642
|
+
/* *
|
|
3643
|
+
*
|
|
3644
|
+
* Constructor
|
|
3645
|
+
*
|
|
3646
|
+
* */
|
|
3647
|
+
constructor(element, userOptions) {
|
|
3648
|
+
this.boundAxes = [];
|
|
3649
|
+
this.userOptions = userOptions;
|
|
3650
|
+
this.chartOptions = merge(G.getOptions(), standaloneNavigatorDefaults, { navigator: userOptions });
|
|
3651
|
+
const chart = new Chart(element, this.chartOptions);
|
|
3652
|
+
chart.options = merge(chart.options, { navigator: { enabled: true }, scrollbar: { enabled: true } });
|
|
3653
|
+
if (this.chartOptions.navigator && this.chartOptions.scrollbar) {
|
|
3654
|
+
this.chartOptions.navigator.enabled = true;
|
|
3655
|
+
this.chartOptions.scrollbar.enabled = true;
|
|
3656
|
+
}
|
|
3657
|
+
this.navigator = new Navigator(chart);
|
|
3658
|
+
chart.navigator = this.navigator;
|
|
3659
|
+
this.initNavigator();
|
|
3660
|
+
}
|
|
3661
|
+
/**
|
|
3662
|
+
* Binds an axis to the standalone navigator,
|
|
3663
|
+
* allowing the navigator to control the axis' range.
|
|
3664
|
+
*
|
|
3665
|
+
* @sample stock/standalone-navigator/bind/
|
|
3666
|
+
* Bind chart with a button
|
|
3667
|
+
*
|
|
3668
|
+
* @function Highcharts.StandaloneNavigator#bind
|
|
3669
|
+
*
|
|
3670
|
+
* @param {Axis | Chart} axisOrChart
|
|
3671
|
+
* The Axis or Chart to bind to the navigator.
|
|
3672
|
+
*
|
|
3673
|
+
* @param {boolean} [twoWay=true]
|
|
3674
|
+
* Enables two-way binding between the navigator and the axis/chart.
|
|
3675
|
+
* When true, changes in the navigator's range will update the axis
|
|
3676
|
+
* and vice versa. When false, changes in the navigator's range will
|
|
3677
|
+
* be reflected in the axis, but changes in the axis ranges won't be
|
|
3678
|
+
* reflected on the navigator.
|
|
3679
|
+
*/
|
|
3680
|
+
bind(axisOrChart, twoWay = true) {
|
|
3681
|
+
const nav = this;
|
|
3682
|
+
// If the chart is passed, bind the first xAxis
|
|
3683
|
+
const axis = (axisOrChart instanceof Chart) ?
|
|
3684
|
+
axisOrChart.xAxis[0] :
|
|
3685
|
+
axisOrChart;
|
|
3686
|
+
if (!(axis instanceof Axis)) {
|
|
3687
|
+
return;
|
|
3688
|
+
}
|
|
3689
|
+
const { min, max } = this.navigator.xAxis, removeEventCallbacks = [];
|
|
3690
|
+
if (twoWay) {
|
|
3691
|
+
const removeSetExtremesEvent = addEvent(axis, 'setExtremes', (e) => {
|
|
3692
|
+
if (e.trigger === 'pan' ||
|
|
3693
|
+
e.trigger === 'zoom' ||
|
|
3694
|
+
e.trigger === 'mouseWheelZoom') {
|
|
3695
|
+
nav.setRange(e.min, e.max, true, e.trigger !== 'pan', { trigger: axis });
|
|
3696
|
+
}
|
|
3697
|
+
});
|
|
3698
|
+
removeEventCallbacks.push(removeSetExtremesEvent);
|
|
3699
|
+
}
|
|
3700
|
+
const removeSetRangeEvent = addEvent(this.navigator, 'setRange', (e) => {
|
|
3701
|
+
axis.setExtremes(e.min, e.max, e.redraw, e.animation);
|
|
3702
|
+
});
|
|
3703
|
+
removeEventCallbacks.push(removeSetRangeEvent);
|
|
3704
|
+
let boundAxis = this.boundAxes.filter(function (boundAxis) {
|
|
3705
|
+
return boundAxis.axis === axis;
|
|
3706
|
+
})[0];
|
|
3707
|
+
if (!boundAxis) {
|
|
3708
|
+
boundAxis = { axis, callbacks: [] };
|
|
3709
|
+
this.boundAxes.push(boundAxis);
|
|
3710
|
+
}
|
|
3711
|
+
boundAxis.callbacks = removeEventCallbacks;
|
|
3712
|
+
// Show axis' series in navigator based on showInNavigator property
|
|
3713
|
+
axis.series.forEach((series) => {
|
|
3714
|
+
if (series.options.showInNavigator) {
|
|
3715
|
+
nav.addSeries(series.options);
|
|
3716
|
+
}
|
|
3717
|
+
});
|
|
3718
|
+
// Set extremes to match the navigator's extremes
|
|
3719
|
+
axis.setExtremes(min, max);
|
|
3720
|
+
// Unbind the axis before it's destroyed
|
|
3721
|
+
addEvent(axis, 'destroy', (e) => {
|
|
3722
|
+
if (!e.keepEvents) {
|
|
3723
|
+
this.unbind(axis);
|
|
3724
|
+
}
|
|
3725
|
+
});
|
|
3726
|
+
}
|
|
3727
|
+
/**
|
|
3728
|
+
* Unbinds a single axis or all bound axes from the standalone navigator.
|
|
3729
|
+
*
|
|
3730
|
+
* @sample stock/standalone-navigator/unbind/
|
|
3731
|
+
* Unbind chart with a button
|
|
3732
|
+
*
|
|
3733
|
+
* @function Highcharts.StandaloneNavigator#unbind
|
|
3734
|
+
*
|
|
3735
|
+
* @param {Chart | Axis | undefined} axisOrChart
|
|
3736
|
+
* Passing a Chart object unbinds the first X axis of the chart,
|
|
3737
|
+
* an Axis object unbinds that specific axis,
|
|
3738
|
+
* and undefined unbinds all axes bound to the navigator.
|
|
3739
|
+
*/
|
|
3740
|
+
unbind(axisOrChart) {
|
|
3741
|
+
// If no axis or chart is provided, unbind all bound axes
|
|
3742
|
+
if (!axisOrChart) {
|
|
3743
|
+
this.boundAxes.forEach(({ callbacks }) => {
|
|
3744
|
+
callbacks.forEach((removeCallback) => removeCallback());
|
|
3745
|
+
});
|
|
3746
|
+
this.boundAxes.length = 0;
|
|
3747
|
+
return;
|
|
3748
|
+
}
|
|
3749
|
+
const axis = (axisOrChart instanceof Axis) ?
|
|
3750
|
+
axisOrChart :
|
|
3751
|
+
axisOrChart.xAxis[0];
|
|
3752
|
+
for (let i = this.boundAxes.length - 1; i >= 0; i--) {
|
|
3753
|
+
if (this.boundAxes[i].axis === axis) {
|
|
3754
|
+
this.boundAxes[i].callbacks.forEach((callback) => callback());
|
|
3755
|
+
this.boundAxes.splice(i, 1);
|
|
3756
|
+
}
|
|
3757
|
+
}
|
|
3758
|
+
}
|
|
3759
|
+
/**
|
|
3760
|
+
* Destroys allocated standalone navigator elements.
|
|
3761
|
+
*
|
|
3762
|
+
* @function Highcharts.StandaloneNavigator#destroy
|
|
3763
|
+
*/
|
|
3764
|
+
destroy() {
|
|
3765
|
+
// Disconnect events
|
|
3766
|
+
this.boundAxes.forEach(({ callbacks }) => {
|
|
3767
|
+
callbacks.forEach((removeCallback) => removeCallback());
|
|
3768
|
+
});
|
|
3769
|
+
this.boundAxes.length = 0;
|
|
3770
|
+
this.navigator.destroy();
|
|
3771
|
+
this.navigator.chart.destroy();
|
|
3772
|
+
}
|
|
3773
|
+
/**
|
|
3774
|
+
* Updates the standalone navigator's options with a new set of user
|
|
3775
|
+
* options.
|
|
3776
|
+
*
|
|
3777
|
+
* @sample stock/standalone-navigator/update/
|
|
3778
|
+
* Bind chart with a button
|
|
3779
|
+
*
|
|
3780
|
+
* @function Highcharts.StandaloneNavigator#update
|
|
3781
|
+
*
|
|
3782
|
+
* @param {StandaloneNavigatorOptions} newOptions
|
|
3783
|
+
* Updates the standalone navigator's options with new user options.
|
|
3784
|
+
*
|
|
3785
|
+
* @param {boolean | undefined} redraw
|
|
3786
|
+
* Whether to redraw the standalone navigator. By default, if not
|
|
3787
|
+
* specified, the standalone navigator will be redrawn.
|
|
3788
|
+
*/
|
|
3789
|
+
update(newOptions, redraw) {
|
|
3790
|
+
this.chartOptions = merge(this.chartOptions, { navigator: newOptions });
|
|
3791
|
+
this.navigator.chart.update(this.chartOptions, redraw);
|
|
3792
|
+
}
|
|
3793
|
+
/**
|
|
3794
|
+
* Redraws the standalone navigator.
|
|
3795
|
+
*
|
|
3796
|
+
* @function Highcharts.StandaloneNavigator#redraw
|
|
3797
|
+
*/
|
|
3798
|
+
redraw() {
|
|
3799
|
+
this.navigator.chart.redraw();
|
|
3800
|
+
}
|
|
3801
|
+
/**
|
|
3802
|
+
* Adds a series to the standalone navigator.
|
|
3803
|
+
*
|
|
3804
|
+
* @private
|
|
3805
|
+
*
|
|
3806
|
+
* @param {SeriesOptions} seriesOptions
|
|
3807
|
+
* Options for the series to be added to the navigator.
|
|
3808
|
+
*/
|
|
3809
|
+
addSeries(seriesOptions) {
|
|
3810
|
+
this.navigator.chart.addSeries(merge(seriesOptions, { showInNavigator: pick(seriesOptions.showInNavigator, true) }));
|
|
3811
|
+
this.navigator.setBaseSeries();
|
|
3812
|
+
}
|
|
3813
|
+
/**
|
|
3814
|
+
* Initialize the standalone navigator.
|
|
3815
|
+
*
|
|
3816
|
+
* @private
|
|
3817
|
+
*/
|
|
3818
|
+
initNavigator() {
|
|
3819
|
+
const nav = this.navigator;
|
|
3820
|
+
nav.top = 1;
|
|
3821
|
+
nav.xAxis.setScale();
|
|
3822
|
+
nav.yAxis.setScale();
|
|
3823
|
+
nav.xAxis.render();
|
|
3824
|
+
nav.yAxis.render();
|
|
3825
|
+
nav.series?.forEach((s) => {
|
|
3826
|
+
s.translate();
|
|
3827
|
+
s.render();
|
|
3828
|
+
s.redraw();
|
|
3829
|
+
});
|
|
3830
|
+
const { min, max } = this.getInitialExtremes();
|
|
3831
|
+
nav.chart.xAxis[0].userMin = min;
|
|
3832
|
+
nav.chart.xAxis[0].userMax = max;
|
|
3833
|
+
nav.render(min, max);
|
|
3834
|
+
}
|
|
3835
|
+
/**
|
|
3836
|
+
* Get the current range of the standalone navigator.
|
|
3837
|
+
*
|
|
3838
|
+
* @sample stock/standalone-navigator/getrange/
|
|
3839
|
+
* Report the standalone navigator's range by clicking on a button
|
|
3840
|
+
*
|
|
3841
|
+
* @function Highcharts.StandaloneNavigator#getRange
|
|
3842
|
+
*
|
|
3843
|
+
* @return {Highcharts.ExtremesObject}
|
|
3844
|
+
* The current range of the standalone navigator.
|
|
3845
|
+
*/
|
|
3846
|
+
getRange() {
|
|
3847
|
+
const { min, max } = this.navigator.chart.xAxis[0].getExtremes(), { userMin, userMax, min: dataMin, max: dataMax } = this.navigator.xAxis.getExtremes();
|
|
3848
|
+
return {
|
|
3849
|
+
min: pick(min, dataMin),
|
|
3850
|
+
max: pick(max, dataMax),
|
|
3851
|
+
dataMin,
|
|
3852
|
+
dataMax,
|
|
3853
|
+
userMin,
|
|
3854
|
+
userMax
|
|
3855
|
+
};
|
|
3856
|
+
}
|
|
3857
|
+
/**
|
|
3858
|
+
* Set the range of the standalone navigator.
|
|
3859
|
+
*
|
|
3860
|
+
* @sample stock/standalone-navigator/setrange/
|
|
3861
|
+
* Set range from a button
|
|
3862
|
+
*
|
|
3863
|
+
* @function Highcharts.StandaloneNavigator#setRange
|
|
3864
|
+
*
|
|
3865
|
+
* @param {number | undefined} min
|
|
3866
|
+
* The new minimum value.
|
|
3867
|
+
*
|
|
3868
|
+
* @param {number | undefined} max
|
|
3869
|
+
* The new maximum value.
|
|
3870
|
+
*
|
|
3871
|
+
* @emits Highcharts.StandaloneNavigator#event:setRange
|
|
3872
|
+
*/
|
|
3873
|
+
setRange(min, max, redraw, animation, eventArguments) {
|
|
3874
|
+
fireEvent(this.navigator, 'setRange', {
|
|
3875
|
+
min,
|
|
3876
|
+
max,
|
|
3877
|
+
redraw,
|
|
3878
|
+
animation,
|
|
3879
|
+
eventArguments: merge(eventArguments, { trigger: 'navigator' })
|
|
3880
|
+
});
|
|
3881
|
+
}
|
|
3882
|
+
/**
|
|
3883
|
+
* Get the initial, options based extremes for the standalone navigator.
|
|
3884
|
+
*
|
|
3885
|
+
* @private
|
|
3886
|
+
*
|
|
3887
|
+
* @return {{ min: number, max: number }}
|
|
3888
|
+
* The initial minimum and maximum extremes values.
|
|
3889
|
+
*/
|
|
3890
|
+
getInitialExtremes() {
|
|
3891
|
+
const { min, max } = this.navigator.xAxis.getExtremes();
|
|
3892
|
+
return {
|
|
3893
|
+
min: min,
|
|
3894
|
+
max: max
|
|
3895
|
+
};
|
|
3896
|
+
}
|
|
3897
|
+
}
|
|
3898
|
+
/* *
|
|
3899
|
+
*
|
|
3900
|
+
* API Declarations
|
|
3901
|
+
*
|
|
3902
|
+
* */
|
|
3903
|
+
/**
|
|
3904
|
+
* Standalone Navigator options.
|
|
3905
|
+
*
|
|
3906
|
+
* @interface Highcharts.StandaloneNavigatorOptions
|
|
3907
|
+
*/ /**
|
|
3908
|
+
*/
|
|
3909
|
+
''; // detach doclets above
|
|
3910
|
+
|
|
3911
|
+
return StandaloneNavigator;
|
|
3912
|
+
});
|
|
3913
|
+
_registerModule(_modules, 'masters/modules/navigator.src.js', [_modules['Core/Globals.js'], _modules['Stock/Navigator/StandaloneNavigator.js'], _modules['Stock/Navigator/NavigatorComposition.js']], function (Highcharts, StandaloneNavigator, NavigatorComposition) {
|
|
3914
|
+
|
|
3915
|
+
const G = Highcharts;
|
|
3916
|
+
G.StandaloneNavigator = G.StandaloneNavigator || StandaloneNavigator;
|
|
3917
|
+
NavigatorComposition.compose(G.Chart, G.Axis, G.Series);
|
|
3918
|
+
G.navigator = StandaloneNavigator.navigator;
|
|
3919
|
+
|
|
3920
|
+
});
|
|
3921
|
+
}));
|