@highcharts/grid-pro 2.0.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 +35 -0
- package/css/grid-pro.css +1756 -0
- package/es-modules/Accessibility/A11yI18n.d.ts +95 -0
- package/es-modules/Accessibility/A11yI18n.js +290 -0
- package/es-modules/Accessibility/Accessibility.d.ts +116 -0
- package/es-modules/Accessibility/Accessibility.js +402 -0
- package/es-modules/Accessibility/AccessibilityComponent.d.ts +97 -0
- package/es-modules/Accessibility/AccessibilityComponent.js +147 -0
- package/es-modules/Accessibility/Components/AnnotationsA11y.d.ts +43 -0
- package/es-modules/Accessibility/Components/AnnotationsA11y.js +160 -0
- package/es-modules/Accessibility/Components/ContainerComponent.d.ts +48 -0
- package/es-modules/Accessibility/Components/ContainerComponent.js +142 -0
- package/es-modules/Accessibility/Components/InfoRegionsComponent.d.ts +144 -0
- package/es-modules/Accessibility/Components/InfoRegionsComponent.js +555 -0
- package/es-modules/Accessibility/Components/LegendComponent.d.ts +124 -0
- package/es-modules/Accessibility/Components/LegendComponent.js +474 -0
- package/es-modules/Accessibility/Components/MenuComponent.d.ts +93 -0
- package/es-modules/Accessibility/Components/MenuComponent.js +430 -0
- package/es-modules/Accessibility/Components/NavigatorComponent.d.ts +57 -0
- package/es-modules/Accessibility/Components/NavigatorComponent.js +235 -0
- package/es-modules/Accessibility/Components/RangeSelectorComponent.d.ts +126 -0
- package/es-modules/Accessibility/Components/RangeSelectorComponent.js +473 -0
- package/es-modules/Accessibility/Components/SeriesComponent/ForcedMarkers.d.ts +18 -0
- package/es-modules/Accessibility/Components/SeriesComponent/ForcedMarkers.js +234 -0
- package/es-modules/Accessibility/Components/SeriesComponent/NewDataAnnouncer.d.ts +87 -0
- package/es-modules/Accessibility/Components/SeriesComponent/NewDataAnnouncer.js +309 -0
- package/es-modules/Accessibility/Components/SeriesComponent/SeriesComponent.d.ts +53 -0
- package/es-modules/Accessibility/Components/SeriesComponent/SeriesComponent.js +130 -0
- package/es-modules/Accessibility/Components/SeriesComponent/SeriesDescriber.d.ts +28 -0
- package/es-modules/Accessibility/Components/SeriesComponent/SeriesDescriber.js +415 -0
- package/es-modules/Accessibility/Components/SeriesComponent/SeriesKeyboardNavigation.d.ts +114 -0
- package/es-modules/Accessibility/Components/SeriesComponent/SeriesKeyboardNavigation.js +721 -0
- package/es-modules/Accessibility/Components/ZoomComponent.d.ts +96 -0
- package/es-modules/Accessibility/Components/ZoomComponent.js +314 -0
- package/es-modules/Accessibility/FocusBorder.d.ts +40 -0
- package/es-modules/Accessibility/FocusBorder.js +301 -0
- package/es-modules/Accessibility/HighContrastMode.d.ts +35 -0
- package/es-modules/Accessibility/HighContrastMode.js +100 -0
- package/es-modules/Accessibility/HighContrastTheme.d.ts +11 -0
- package/es-modules/Accessibility/HighContrastTheme.js +212 -0
- package/es-modules/Accessibility/KeyboardNavigation.d.ts +133 -0
- package/es-modules/Accessibility/KeyboardNavigation.js +450 -0
- package/es-modules/Accessibility/KeyboardNavigationHandler.d.ts +48 -0
- package/es-modules/Accessibility/KeyboardNavigationHandler.js +126 -0
- package/es-modules/Accessibility/Options/A11yDefaults.d.ts +68 -0
- package/es-modules/Accessibility/Options/A11yDefaults.js +971 -0
- package/es-modules/Accessibility/Options/DeprecatedOptions.d.ts +22 -0
- package/es-modules/Accessibility/Options/DeprecatedOptions.js +265 -0
- package/es-modules/Accessibility/Options/LangDefaults.d.ts +4 -0
- package/es-modules/Accessibility/Options/LangDefaults.js +440 -0
- package/es-modules/Accessibility/ProxyElement.d.ts +78 -0
- package/es-modules/Accessibility/ProxyElement.js +223 -0
- package/es-modules/Accessibility/ProxyProvider.d.ts +90 -0
- package/es-modules/Accessibility/ProxyProvider.js +315 -0
- package/es-modules/Accessibility/Utils/Announcer.d.ts +26 -0
- package/es-modules/Accessibility/Utils/Announcer.js +90 -0
- package/es-modules/Accessibility/Utils/ChartUtilities.d.ts +90 -0
- package/es-modules/Accessibility/Utils/ChartUtilities.js +298 -0
- package/es-modules/Accessibility/Utils/DOMElementProvider.d.ts +20 -0
- package/es-modules/Accessibility/Utils/DOMElementProvider.js +69 -0
- package/es-modules/Accessibility/Utils/EventProvider.d.ts +26 -0
- package/es-modules/Accessibility/Utils/EventProvider.js +65 -0
- package/es-modules/Accessibility/Utils/HTMLUtilities.d.ts +108 -0
- package/es-modules/Accessibility/Utils/HTMLUtilities.js +319 -0
- package/es-modules/Core/Animation/AnimationUtilities.d.ts +107 -0
- package/es-modules/Core/Animation/AnimationUtilities.js +200 -0
- package/es-modules/Core/Animation/Fx.d.ts +130 -0
- package/es-modules/Core/Animation/Fx.js +388 -0
- package/es-modules/Core/Chart/Chart.d.ts +1009 -0
- package/es-modules/Core/Chart/Chart.js +3008 -0
- package/es-modules/Core/Chart/Chart3D.d.ts +276 -0
- package/es-modules/Core/Chart/Chart3D.js +1686 -0
- package/es-modules/Core/Chart/ChartDefaults.d.ts +8 -0
- package/es-modules/Core/Chart/ChartDefaults.js +1304 -0
- package/es-modules/Core/Chart/ChartNavigationComposition.d.ts +55 -0
- package/es-modules/Core/Chart/ChartNavigationComposition.js +90 -0
- package/es-modules/Core/Chart/GanttChart.d.ts +74 -0
- package/es-modules/Core/Chart/GanttChart.js +189 -0
- package/es-modules/Core/Chart/MapChart.d.ts +132 -0
- package/es-modules/Core/Chart/MapChart.js +232 -0
- package/es-modules/Core/Chart/StockChart.d.ts +117 -0
- package/es-modules/Core/Chart/StockChart.js +641 -0
- package/es-modules/Core/Color/Color.d.ts +112 -0
- package/es-modules/Core/Color/Color.js +418 -0
- package/es-modules/Core/Color/Palettes.d.ts +84 -0
- package/es-modules/Core/Color/Palettes.js +23 -0
- package/es-modules/Core/Defaults.d.ts +42 -0
- package/es-modules/Core/Defaults.js +2977 -0
- package/es-modules/Core/Foundation.d.ts +19 -0
- package/es-modules/Core/Foundation.js +63 -0
- package/es-modules/Core/Geometry/CircleUtilities.d.ts +189 -0
- package/es-modules/Core/Geometry/CircleUtilities.js +388 -0
- package/es-modules/Core/Geometry/GeometryUtilities.d.ts +48 -0
- package/es-modules/Core/Geometry/GeometryUtilities.js +105 -0
- package/es-modules/Core/Geometry/PolygonClip.d.ts +19 -0
- package/es-modules/Core/Geometry/PolygonClip.js +96 -0
- package/es-modules/Core/Globals.d.ts +110 -0
- package/es-modules/Core/Globals.js +127 -0
- package/es-modules/Core/HttpUtilities.d.ts +61 -0
- package/es-modules/Core/HttpUtilities.js +214 -0
- package/es-modules/Core/MSPointer.d.ts +74 -0
- package/es-modules/Core/MSPointer.js +218 -0
- package/es-modules/Core/Math3D.d.ts +117 -0
- package/es-modules/Core/Math3D.js +250 -0
- package/es-modules/Core/Pointer.d.ts +590 -0
- package/es-modules/Core/Pointer.js +1631 -0
- package/es-modules/Core/Renderer/HTML/AST.d.ts +163 -0
- package/es-modules/Core/Renderer/HTML/AST.js +562 -0
- package/es-modules/Core/Renderer/HTML/HTMLElement.d.ts +76 -0
- package/es-modules/Core/Renderer/HTML/HTMLElement.js +471 -0
- package/es-modules/Core/Renderer/RendererRegistry.d.ts +29 -0
- package/es-modules/Core/Renderer/RendererRegistry.js +76 -0
- package/es-modules/Core/Renderer/RendererUtilities.d.ts +26 -0
- package/es-modules/Core/Renderer/RendererUtilities.js +172 -0
- package/es-modules/Core/Responsive.d.ts +55 -0
- package/es-modules/Core/Responsive.js +260 -0
- package/es-modules/Core/Templating.d.ts +125 -0
- package/es-modules/Core/Templating.js +428 -0
- package/es-modules/Core/Time.d.ts +69 -0
- package/es-modules/Core/Time.js +172 -0
- package/es-modules/Core/Tooltip.d.ts +297 -0
- package/es-modules/Core/Tooltip.js +1377 -0
- package/es-modules/Core/Utilities.d.ts +770 -0
- package/es-modules/Core/Utilities.js +1989 -0
- package/es-modules/Data/ColumnUtils.d.ts +87 -0
- package/es-modules/Data/ColumnUtils.js +140 -0
- package/es-modules/Data/Connectors/CSVConnector.d.ts +63 -0
- package/es-modules/Data/Connectors/CSVConnector.js +149 -0
- package/es-modules/Data/Connectors/CSVConnectorOptions.d.ts +149 -0
- package/es-modules/Data/Connectors/DataConnector.d.ts +204 -0
- package/es-modules/Data/Connectors/DataConnector.js +345 -0
- package/es-modules/Data/Connectors/DataConnectorOptions.d.ts +87 -0
- package/es-modules/Data/Connectors/DataConnectorType.d.ts +45 -0
- package/es-modules/Data/Connectors/GoogleSheetsConnector.d.ts +65 -0
- package/es-modules/Data/Connectors/GoogleSheetsConnector.js +226 -0
- package/es-modules/Data/Connectors/GoogleSheetsConnectorOptions.d.ts +167 -0
- package/es-modules/Data/Connectors/HTMLTableConnector.d.ts +77 -0
- package/es-modules/Data/Connectors/HTMLTableConnector.js +119 -0
- package/es-modules/Data/Connectors/HTMLTableConnectorOptions.d.ts +49 -0
- package/es-modules/Data/Connectors/JSONConnector.d.ts +64 -0
- package/es-modules/Data/Connectors/JSONConnector.js +156 -0
- package/es-modules/Data/Connectors/JSONConnectorOptions.d.ts +185 -0
- package/es-modules/Data/Converters/CSVConverter.d.ts +64 -0
- package/es-modules/Data/Converters/CSVConverter.js +374 -0
- package/es-modules/Data/Converters/CSVConverterOptions.d.ts +53 -0
- package/es-modules/Data/Converters/DataConverter.d.ts +168 -0
- package/es-modules/Data/Converters/DataConverter.js +387 -0
- package/es-modules/Data/Converters/DataConverterType.d.ts +40 -0
- package/es-modules/Data/Converters/DataConverterUtils.d.ts +82 -0
- package/es-modules/Data/Converters/DataConverterUtils.js +216 -0
- package/es-modules/Data/Converters/GoogleSheetsConverter.d.ts +46 -0
- package/es-modules/Data/Converters/GoogleSheetsConverter.js +135 -0
- package/es-modules/Data/Converters/GoogleSheetsConverterOptions.d.ts +52 -0
- package/es-modules/Data/Converters/HTMLTableConverter.d.ts +72 -0
- package/es-modules/Data/Converters/HTMLTableConverter.js +362 -0
- package/es-modules/Data/Converters/HTMLTableConverterOptions.d.ts +51 -0
- package/es-modules/Data/Converters/JSONConverter.d.ts +99 -0
- package/es-modules/Data/Converters/JSONConverter.js +239 -0
- package/es-modules/Data/Converters/JSONConverterOptions.d.ts +52 -0
- package/es-modules/Data/DataCursor.d.ts +176 -0
- package/es-modules/Data/DataCursor.js +379 -0
- package/es-modules/Data/DataEvent.d.ts +81 -0
- package/es-modules/Data/DataEvent.js +14 -0
- package/es-modules/Data/DataPool.d.ts +130 -0
- package/es-modules/Data/DataPool.js +257 -0
- package/es-modules/Data/DataPoolOptions.d.ts +66 -0
- package/es-modules/Data/DataTable.d.ts +563 -0
- package/es-modules/Data/DataTable.js +930 -0
- package/es-modules/Data/DataTableCore.d.ts +165 -0
- package/es-modules/Data/DataTableCore.js +316 -0
- package/es-modules/Data/DataTableOptions.d.ts +25 -0
- package/es-modules/Data/DataTableOptions.js +15 -0
- package/es-modules/Data/Formula/Formula.d.ts +21 -0
- package/es-modules/Data/Formula/Formula.js +54 -0
- package/es-modules/Data/Formula/FormulaParser.d.ts +31 -0
- package/es-modules/Data/Formula/FormulaParser.js +488 -0
- package/es-modules/Data/Formula/FormulaProcessor.d.ts +155 -0
- package/es-modules/Data/Formula/FormulaProcessor.js +529 -0
- package/es-modules/Data/Formula/FormulaTypes.d.ts +138 -0
- package/es-modules/Data/Formula/FormulaTypes.js +135 -0
- package/es-modules/Data/Formula/Functions/ABS.d.ts +19 -0
- package/es-modules/Data/Formula/Functions/ABS.js +67 -0
- package/es-modules/Data/Formula/Functions/AND.d.ts +20 -0
- package/es-modules/Data/Formula/Functions/AND.js +59 -0
- package/es-modules/Data/Formula/Functions/AVERAGE.d.ts +20 -0
- package/es-modules/Data/Formula/Functions/AVERAGE.js +74 -0
- package/es-modules/Data/Formula/Functions/AVERAGEA.d.ts +20 -0
- package/es-modules/Data/Formula/Functions/AVERAGEA.js +90 -0
- package/es-modules/Data/Formula/Functions/COUNT.d.ts +20 -0
- package/es-modules/Data/Formula/Functions/COUNT.js +65 -0
- package/es-modules/Data/Formula/Functions/COUNTA.d.ts +20 -0
- package/es-modules/Data/Formula/Functions/COUNTA.js +71 -0
- package/es-modules/Data/Formula/Functions/IF.d.ts +21 -0
- package/es-modules/Data/Formula/Functions/IF.js +54 -0
- package/es-modules/Data/Formula/Functions/ISNA.d.ts +20 -0
- package/es-modules/Data/Formula/Functions/ISNA.js +52 -0
- package/es-modules/Data/Formula/Functions/MAX.d.ts +20 -0
- package/es-modules/Data/Formula/Functions/MAX.js +69 -0
- package/es-modules/Data/Formula/Functions/MEDIAN.d.ts +20 -0
- package/es-modules/Data/Formula/Functions/MEDIAN.js +78 -0
- package/es-modules/Data/Formula/Functions/MIN.d.ts +20 -0
- package/es-modules/Data/Formula/Functions/MIN.js +69 -0
- package/es-modules/Data/Formula/Functions/MOD.d.ts +20 -0
- package/es-modules/Data/Formula/Functions/MOD.js +63 -0
- package/es-modules/Data/Formula/Functions/MODE.d.ts +41 -0
- package/es-modules/Data/Formula/Functions/MODE.js +149 -0
- package/es-modules/Data/Formula/Functions/NOT.d.ts +20 -0
- package/es-modules/Data/Formula/Functions/NOT.js +60 -0
- package/es-modules/Data/Formula/Functions/OR.d.ts +20 -0
- package/es-modules/Data/Formula/Functions/OR.js +62 -0
- package/es-modules/Data/Formula/Functions/PRODUCT.d.ts +20 -0
- package/es-modules/Data/Formula/Functions/PRODUCT.js +68 -0
- package/es-modules/Data/Formula/Functions/SUM.d.ts +20 -0
- package/es-modules/Data/Formula/Functions/SUM.js +65 -0
- package/es-modules/Data/Formula/Functions/XOR.d.ts +20 -0
- package/es-modules/Data/Formula/Functions/XOR.js +81 -0
- package/es-modules/Data/Modifiers/ChainModifier.d.ts +128 -0
- package/es-modules/Data/Modifiers/ChainModifier.js +231 -0
- package/es-modules/Data/Modifiers/ChainModifierOptions.d.ts +20 -0
- package/es-modules/Data/Modifiers/ChainModifierOptions.js +14 -0
- package/es-modules/Data/Modifiers/DataModifier.d.ts +117 -0
- package/es-modules/Data/Modifiers/DataModifier.js +202 -0
- package/es-modules/Data/Modifiers/DataModifierEvent.d.ts +28 -0
- package/es-modules/Data/Modifiers/DataModifierEvent.js +15 -0
- package/es-modules/Data/Modifiers/DataModifierOptions.d.ts +11 -0
- package/es-modules/Data/Modifiers/DataModifierOptions.js +15 -0
- package/es-modules/Data/Modifiers/DataModifierType.d.ts +44 -0
- package/es-modules/Data/Modifiers/FilterModifier.d.ts +53 -0
- package/es-modules/Data/Modifiers/FilterModifier.js +172 -0
- package/es-modules/Data/Modifiers/FilterModifierOptions.d.ts +110 -0
- package/es-modules/Data/Modifiers/FilterModifierOptions.js +14 -0
- package/es-modules/Data/Modifiers/InvertModifier.d.ts +48 -0
- package/es-modules/Data/Modifiers/InvertModifier.js +116 -0
- package/es-modules/Data/Modifiers/InvertModifierOptions.d.ts +11 -0
- package/es-modules/Data/Modifiers/InvertModifierOptions.js +15 -0
- package/es-modules/Data/Modifiers/MathModifier.d.ts +68 -0
- package/es-modules/Data/Modifiers/MathModifier.js +165 -0
- package/es-modules/Data/Modifiers/MathModifierOptions.d.ts +50 -0
- package/es-modules/Data/Modifiers/MathModifierOptions.js +14 -0
- package/es-modules/Data/Modifiers/RangeModifier.d.ts +46 -0
- package/es-modules/Data/Modifiers/RangeModifier.js +96 -0
- package/es-modules/Data/Modifiers/RangeModifierOptions.d.ts +22 -0
- package/es-modules/Data/Modifiers/RangeModifierOptions.js +15 -0
- package/es-modules/Data/Modifiers/SortModifier.d.ts +54 -0
- package/es-modules/Data/Modifiers/SortModifier.js +144 -0
- package/es-modules/Data/Modifiers/SortModifierOptions.d.ts +44 -0
- package/es-modules/Data/Modifiers/SortModifierOptions.js +14 -0
- package/es-modules/Grid/Core/Accessibility/A11yOptions.d.ts +148 -0
- package/es-modules/Grid/Core/Accessibility/A11yOptions.js +17 -0
- package/es-modules/Grid/Core/Accessibility/Accessibility.d.ts +115 -0
- package/es-modules/Grid/Core/Accessibility/Accessibility.js +231 -0
- package/es-modules/Grid/Core/Credits.d.ts +57 -0
- package/es-modules/Grid/Core/Credits.js +125 -0
- package/es-modules/Grid/Core/Defaults.d.ts +20 -0
- package/es-modules/Grid/Core/Defaults.js +148 -0
- package/es-modules/Grid/Core/Globals.d.ts +103 -0
- package/es-modules/Grid/Core/Globals.js +134 -0
- package/es-modules/Grid/Core/Grid.d.ts +295 -0
- package/es-modules/Grid/Core/Grid.js +730 -0
- package/es-modules/Grid/Core/GridUtils.d.ts +110 -0
- package/es-modules/Grid/Core/GridUtils.js +191 -0
- package/es-modules/Grid/Core/Options.d.ts +599 -0
- package/es-modules/Grid/Core/Options.js +16 -0
- package/es-modules/Grid/Core/Pagination/Icons.d.ts +7 -0
- package/es-modules/Grid/Core/Pagination/Icons.js +7 -0
- package/es-modules/Grid/Core/Pagination/Pagination.d.ts +278 -0
- package/es-modules/Grid/Core/Pagination/Pagination.js +842 -0
- package/es-modules/Grid/Core/Pagination/PaginationOptions.d.ts +228 -0
- package/es-modules/Grid/Core/Querying/FilteringController.d.ts +66 -0
- package/es-modules/Grid/Core/Querying/FilteringController.js +256 -0
- package/es-modules/Grid/Core/Querying/PaginationController.d.ts +50 -0
- package/es-modules/Grid/Core/Querying/PaginationController.js +101 -0
- package/es-modules/Grid/Core/Querying/QueryingController.d.ts +58 -0
- package/es-modules/Grid/Core/Querying/QueryingController.js +127 -0
- package/es-modules/Grid/Core/Querying/SortingController.d.ts +67 -0
- package/es-modules/Grid/Core/Querying/SortingController.js +136 -0
- package/es-modules/Grid/Core/Table/Actions/ColumnFiltering/ColumnFiltering.d.ts +114 -0
- package/es-modules/Grid/Core/Table/Actions/ColumnFiltering/ColumnFiltering.js +351 -0
- package/es-modules/Grid/Core/Table/Actions/ColumnFiltering/FilterCell.d.ts +14 -0
- package/es-modules/Grid/Core/Table/Actions/ColumnFiltering/FilterCell.js +86 -0
- package/es-modules/Grid/Core/Table/Actions/ColumnFiltering/FilterRow.d.ts +19 -0
- package/es-modules/Grid/Core/Table/Actions/ColumnFiltering/FilterRow.js +80 -0
- package/es-modules/Grid/Core/Table/Actions/ColumnFiltering/FilteringTypes.d.ts +52 -0
- package/es-modules/Grid/Core/Table/Actions/ColumnFiltering/FilteringTypes.js +81 -0
- package/es-modules/Grid/Core/Table/Actions/ColumnSorting.d.ts +56 -0
- package/es-modules/Grid/Core/Table/Actions/ColumnSorting.js +170 -0
- package/es-modules/Grid/Core/Table/Actions/ColumnsResizer.d.ts +55 -0
- package/es-modules/Grid/Core/Table/Actions/ColumnsResizer.js +182 -0
- package/es-modules/Grid/Core/Table/Actions/RowsVirtualizer.d.ts +87 -0
- package/es-modules/Grid/Core/Table/Actions/RowsVirtualizer.js +346 -0
- package/es-modules/Grid/Core/Table/Body/TableCell.d.ts +88 -0
- package/es-modules/Grid/Core/Table/Body/TableCell.js +231 -0
- package/es-modules/Grid/Core/Table/Body/TableRow.d.ts +79 -0
- package/es-modules/Grid/Core/Table/Body/TableRow.js +177 -0
- package/es-modules/Grid/Core/Table/Cell.d.ts +92 -0
- package/es-modules/Grid/Core/Table/Cell.js +223 -0
- package/es-modules/Grid/Core/Table/CellContent/CellContent.d.ts +30 -0
- package/es-modules/Grid/Core/Table/CellContent/CellContent.js +40 -0
- package/es-modules/Grid/Core/Table/CellContent/TextContent.d.ts +19 -0
- package/es-modules/Grid/Core/Table/CellContent/TextContent.js +98 -0
- package/es-modules/Grid/Core/Table/Column.d.ts +136 -0
- package/es-modules/Grid/Core/Table/Column.js +230 -0
- package/es-modules/Grid/Core/Table/ColumnResizing/AdjacentResizingMode.d.ts +7 -0
- package/es-modules/Grid/Core/Table/ColumnResizing/AdjacentResizingMode.js +62 -0
- package/es-modules/Grid/Core/Table/ColumnResizing/ColumnResizing.d.ts +32 -0
- package/es-modules/Grid/Core/Table/ColumnResizing/ColumnResizing.js +68 -0
- package/es-modules/Grid/Core/Table/ColumnResizing/DistributedResizingMode.d.ts +7 -0
- package/es-modules/Grid/Core/Table/ColumnResizing/DistributedResizingMode.js +53 -0
- package/es-modules/Grid/Core/Table/ColumnResizing/IndependentResizingMode.d.ts +7 -0
- package/es-modules/Grid/Core/Table/ColumnResizing/IndependentResizingMode.js +63 -0
- package/es-modules/Grid/Core/Table/ColumnResizing/ResizingMode.d.ts +92 -0
- package/es-modules/Grid/Core/Table/ColumnResizing/ResizingMode.js +194 -0
- package/es-modules/Grid/Core/Table/Header/ColumnToolbar/ColumnToolbar.d.ts +68 -0
- package/es-modules/Grid/Core/Table/Header/ColumnToolbar/ColumnToolbar.js +187 -0
- package/es-modules/Grid/Core/Table/Header/ColumnToolbar/FilterPopup.d.ts +29 -0
- package/es-modules/Grid/Core/Table/Header/ColumnToolbar/FilterPopup.js +77 -0
- package/es-modules/Grid/Core/Table/Header/ColumnToolbar/MenuButtons/FilterMenuButton.d.ts +13 -0
- package/es-modules/Grid/Core/Table/Header/ColumnToolbar/MenuButtons/FilterMenuButton.js +79 -0
- package/es-modules/Grid/Core/Table/Header/ColumnToolbar/MenuButtons/SortMenuButton.d.ts +12 -0
- package/es-modules/Grid/Core/Table/Header/ColumnToolbar/MenuButtons/SortMenuButton.js +71 -0
- package/es-modules/Grid/Core/Table/Header/ColumnToolbar/MenuPopup.d.ts +12 -0
- package/es-modules/Grid/Core/Table/Header/ColumnToolbar/MenuPopup.js +66 -0
- package/es-modules/Grid/Core/Table/Header/ColumnToolbar/StateHelpers.d.ts +25 -0
- package/es-modules/Grid/Core/Table/Header/ColumnToolbar/StateHelpers.js +65 -0
- package/es-modules/Grid/Core/Table/Header/ColumnToolbar/ToolbarButtons/FilterToolbarButton.d.ts +12 -0
- package/es-modules/Grid/Core/Table/Header/ColumnToolbar/ToolbarButtons/FilterToolbarButton.js +81 -0
- package/es-modules/Grid/Core/Table/Header/ColumnToolbar/ToolbarButtons/MenuToolbarButton.d.ts +12 -0
- package/es-modules/Grid/Core/Table/Header/ColumnToolbar/ToolbarButtons/MenuToolbarButton.js +80 -0
- package/es-modules/Grid/Core/Table/Header/ColumnToolbar/ToolbarButtons/SortToolbarButton.d.ts +11 -0
- package/es-modules/Grid/Core/Table/Header/ColumnToolbar/ToolbarButtons/SortToolbarButton.js +81 -0
- package/es-modules/Grid/Core/Table/Header/HeaderCell.d.ts +70 -0
- package/es-modules/Grid/Core/Table/Header/HeaderCell.js +225 -0
- package/es-modules/Grid/Core/Table/Header/HeaderRow.d.ts +53 -0
- package/es-modules/Grid/Core/Table/Header/HeaderRow.js +182 -0
- package/es-modules/Grid/Core/Table/Header/TableHeader.d.ts +65 -0
- package/es-modules/Grid/Core/Table/Header/TableHeader.js +159 -0
- package/es-modules/Grid/Core/Table/Row.d.ts +76 -0
- package/es-modules/Grid/Core/Table/Row.js +131 -0
- package/es-modules/Grid/Core/Table/Table.d.ts +181 -0
- package/es-modules/Grid/Core/Table/Table.js +399 -0
- package/es-modules/Grid/Core/UI/Button.d.ts +31 -0
- package/es-modules/Grid/Core/UI/Button.js +16 -0
- package/es-modules/Grid/Core/UI/ContextMenu.d.ts +38 -0
- package/es-modules/Grid/Core/UI/ContextMenu.js +132 -0
- package/es-modules/Grid/Core/UI/ContextMenuButton.d.ts +126 -0
- package/es-modules/Grid/Core/UI/ContextMenuButton.js +183 -0
- package/es-modules/Grid/Core/UI/Popup.d.ts +149 -0
- package/es-modules/Grid/Core/UI/Popup.js +271 -0
- package/es-modules/Grid/Core/UI/SvgIcons.d.ts +53 -0
- package/es-modules/Grid/Core/UI/SvgIcons.js +158 -0
- package/es-modules/Grid/Core/UI/Toolbar.d.ts +16 -0
- package/es-modules/Grid/Core/UI/Toolbar.js +16 -0
- package/es-modules/Grid/Core/UI/ToolbarButton.d.ts +135 -0
- package/es-modules/Grid/Core/UI/ToolbarButton.js +191 -0
- package/es-modules/Grid/Pro/CellEditing/CellEditMode.d.ts +112 -0
- package/es-modules/Grid/Pro/CellEditing/CellEditing.d.ts +80 -0
- package/es-modules/Grid/Pro/CellEditing/CellEditing.js +211 -0
- package/es-modules/Grid/Pro/CellEditing/CellEditingComposition.d.ts +123 -0
- package/es-modules/Grid/Pro/CellEditing/CellEditingComposition.js +198 -0
- package/es-modules/Grid/Pro/CellRendering/CellContentPro.d.ts +23 -0
- package/es-modules/Grid/Pro/CellRendering/CellContentPro.js +45 -0
- package/es-modules/Grid/Pro/CellRendering/CellRenderer.d.ts +50 -0
- package/es-modules/Grid/Pro/CellRendering/CellRenderer.js +41 -0
- package/es-modules/Grid/Pro/CellRendering/CellRendererRegistry.d.ts +18 -0
- package/es-modules/Grid/Pro/CellRendering/CellRendererRegistry.js +58 -0
- package/es-modules/Grid/Pro/CellRendering/CellRendererType.d.ts +48 -0
- package/es-modules/Grid/Pro/CellRendering/CellRenderersComposition.d.ts +18 -0
- package/es-modules/Grid/Pro/CellRendering/CellRenderersComposition.js +79 -0
- package/es-modules/Grid/Pro/CellRendering/ContentTypes/CheckboxContent.d.ts +30 -0
- package/es-modules/Grid/Pro/CellRendering/ContentTypes/CheckboxContent.js +122 -0
- package/es-modules/Grid/Pro/CellRendering/ContentTypes/DateInputContent.d.ts +12 -0
- package/es-modules/Grid/Pro/CellRendering/ContentTypes/DateInputContent.js +39 -0
- package/es-modules/Grid/Pro/CellRendering/ContentTypes/DateInputContentBase.d.ts +66 -0
- package/es-modules/Grid/Pro/CellRendering/ContentTypes/DateInputContentBase.js +145 -0
- package/es-modules/Grid/Pro/CellRendering/ContentTypes/DateTimeInputContent.d.ts +12 -0
- package/es-modules/Grid/Pro/CellRendering/ContentTypes/DateTimeInputContent.js +38 -0
- package/es-modules/Grid/Pro/CellRendering/ContentTypes/NumberInputContent.d.ts +58 -0
- package/es-modules/Grid/Pro/CellRendering/ContentTypes/NumberInputContent.js +158 -0
- package/es-modules/Grid/Pro/CellRendering/ContentTypes/SelectContent.d.ts +58 -0
- package/es-modules/Grid/Pro/CellRendering/ContentTypes/SelectContent.js +173 -0
- package/es-modules/Grid/Pro/CellRendering/ContentTypes/SparklineContent.d.ts +28 -0
- package/es-modules/Grid/Pro/CellRendering/ContentTypes/SparklineContent.js +157 -0
- package/es-modules/Grid/Pro/CellRendering/ContentTypes/TextInputContent.d.ts +58 -0
- package/es-modules/Grid/Pro/CellRendering/ContentTypes/TextInputContent.js +168 -0
- package/es-modules/Grid/Pro/CellRendering/ContentTypes/TimeInputContent.d.ts +13 -0
- package/es-modules/Grid/Pro/CellRendering/ContentTypes/TimeInputContent.js +41 -0
- package/es-modules/Grid/Pro/CellRendering/Renderers/CheckboxRenderer.d.ts +50 -0
- package/es-modules/Grid/Pro/CellRendering/Renderers/CheckboxRenderer.js +65 -0
- package/es-modules/Grid/Pro/CellRendering/Renderers/DateInputRenderer.d.ts +37 -0
- package/es-modules/Grid/Pro/CellRendering/Renderers/DateInputRenderer.js +65 -0
- package/es-modules/Grid/Pro/CellRendering/Renderers/DateInputRendererBase.d.ts +26 -0
- package/es-modules/Grid/Pro/CellRendering/Renderers/DateInputRendererBase.js +16 -0
- package/es-modules/Grid/Pro/CellRendering/Renderers/DateTimeInputRenderer.d.ts +37 -0
- package/es-modules/Grid/Pro/CellRendering/Renderers/DateTimeInputRenderer.js +64 -0
- package/es-modules/Grid/Pro/CellRendering/Renderers/NumberInputRenderer.d.ts +52 -0
- package/es-modules/Grid/Pro/CellRendering/Renderers/NumberInputRenderer.js +64 -0
- package/es-modules/Grid/Pro/CellRendering/Renderers/SelectRenderer.d.ts +74 -0
- package/es-modules/Grid/Pro/CellRendering/Renderers/SelectRenderer.js +66 -0
- package/es-modules/Grid/Pro/CellRendering/Renderers/SparklineRenderer.d.ts +45 -0
- package/es-modules/Grid/Pro/CellRendering/Renderers/SparklineRenderer.js +89 -0
- package/es-modules/Grid/Pro/CellRendering/Renderers/TextInputRenderer.d.ts +54 -0
- package/es-modules/Grid/Pro/CellRendering/Renderers/TextInputRenderer.js +65 -0
- package/es-modules/Grid/Pro/CellRendering/Renderers/TextRenderer.d.ts +43 -0
- package/es-modules/Grid/Pro/CellRendering/Renderers/TextRenderer.js +74 -0
- package/es-modules/Grid/Pro/CellRendering/Renderers/TimeInputRenderer.d.ts +37 -0
- package/es-modules/Grid/Pro/CellRendering/Renderers/TimeInputRenderer.js +64 -0
- package/es-modules/Grid/Pro/ColumnTypes/ColumnDataType.d.ts +29 -0
- package/es-modules/Grid/Pro/ColumnTypes/Validator.d.ts +118 -0
- package/es-modules/Grid/Pro/ColumnTypes/Validator.js +270 -0
- package/es-modules/Grid/Pro/ColumnTypes/ValidatorComposition.d.ts +32 -0
- package/es-modules/Grid/Pro/ColumnTypes/ValidatorComposition.js +63 -0
- package/es-modules/Grid/Pro/Credits/CreditsPro.d.ts +35 -0
- package/es-modules/Grid/Pro/Credits/CreditsPro.js +112 -0
- package/es-modules/Grid/Pro/Credits/CreditsProComposition.d.ts +28 -0
- package/es-modules/Grid/Pro/Credits/CreditsProComposition.js +61 -0
- package/es-modules/Grid/Pro/Export/Exporting.d.ts +68 -0
- package/es-modules/Grid/Pro/Export/Exporting.js +202 -0
- package/es-modules/Grid/Pro/Export/ExportingComposition.d.ts +68 -0
- package/es-modules/Grid/Pro/Export/ExportingComposition.js +55 -0
- package/es-modules/Grid/Pro/GridEvents.d.ts +119 -0
- package/es-modules/Grid/Pro/GridEvents.js +107 -0
- package/es-modules/Grid/Pro/Pagination/PaginationComposition.d.ts +75 -0
- package/es-modules/Grid/Pro/Pagination/PaginationComposition.js +76 -0
- package/es-modules/Grid/Pro/highcharts.d.ts +7 -0
- package/es-modules/Grid/index.d.ts +5 -0
- package/es-modules/Grid/index.js +19 -0
- package/es-modules/Shared/BaseForm.d.ts +49 -0
- package/es-modules/Shared/BaseForm.js +126 -0
- package/es-modules/Shared/DownloadURL.d.ts +85 -0
- package/es-modules/Shared/DownloadURL.js +198 -0
- package/es-modules/Shared/LangOptionsCore.d.ts +27 -0
- package/es-modules/Shared/TimeBase.d.ts +353 -0
- package/es-modules/Shared/TimeBase.js +830 -0
- package/es-modules/Shared/Types.d.ts +48 -0
- package/es-modules/masters/grid-pro.src.d.ts +99 -0
- package/es-modules/masters/grid-pro.src.js +129 -0
- package/grid-pro.d.ts +50 -0
- package/grid-pro.js +12 -0
- package/grid-pro.js.map +1 -0
- package/grid-pro.src.d.ts +50 -0
- package/grid-pro.src.js +26623 -0
- package/package.json +21 -0
|
@@ -0,0 +1,3008 @@
|
|
|
1
|
+
/* *
|
|
2
|
+
*
|
|
3
|
+
* (c) 2010-2025 Torstein Honsi
|
|
4
|
+
*
|
|
5
|
+
* License: www.highcharts.com/license
|
|
6
|
+
*
|
|
7
|
+
* !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
|
|
8
|
+
*
|
|
9
|
+
* */
|
|
10
|
+
'use strict';
|
|
11
|
+
import A from '../Animation/AnimationUtilities.js';
|
|
12
|
+
const { animate, animObject, setAnimation } = A;
|
|
13
|
+
import Axis from '../Axis/Axis.js';
|
|
14
|
+
import D from '../Defaults.js';
|
|
15
|
+
const { defaultOptions } = D;
|
|
16
|
+
import Templating from '../Templating.js';
|
|
17
|
+
const { numberFormat } = Templating;
|
|
18
|
+
import Foundation from '../Foundation.js';
|
|
19
|
+
const { registerEventOptions } = Foundation;
|
|
20
|
+
import H from '../Globals.js';
|
|
21
|
+
const { charts, doc, marginNames, svg, win } = H;
|
|
22
|
+
import RendererRegistry from '../Renderer/RendererRegistry.js';
|
|
23
|
+
import Series from '../Series/Series.js';
|
|
24
|
+
import SeriesRegistry from '../Series/SeriesRegistry.js';
|
|
25
|
+
const { seriesTypes } = SeriesRegistry;
|
|
26
|
+
import SVGRenderer from '../Renderer/SVG/SVGRenderer.js';
|
|
27
|
+
import Time from '../Time.js';
|
|
28
|
+
import U from '../Utilities.js';
|
|
29
|
+
import AST from '../Renderer/HTML/AST.js';
|
|
30
|
+
import Tick from '../Axis/Tick.js';
|
|
31
|
+
const { addEvent, attr, createElement, css, defined, diffObjects, discardElement, erase, error, extend, find, fireEvent, getAlignFactor, getStyle, isArray, isNumber, isObject, isString, merge, objectEach, pick, pInt, relativeLength, removeEvent, splat, syncTimeout, uniqueKey } = U;
|
|
32
|
+
/* *
|
|
33
|
+
*
|
|
34
|
+
* Class
|
|
35
|
+
*
|
|
36
|
+
* */
|
|
37
|
+
/* eslint-disable no-invalid-this, valid-jsdoc */
|
|
38
|
+
/**
|
|
39
|
+
* The Chart class. The recommended constructor is {@link Highcharts#chart}.
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* let chart = Highcharts.chart('container', {
|
|
43
|
+
* title: {
|
|
44
|
+
* text: 'My chart'
|
|
45
|
+
* },
|
|
46
|
+
* series: [{
|
|
47
|
+
* data: [1, 3, 2, 4]
|
|
48
|
+
* }]
|
|
49
|
+
* })
|
|
50
|
+
*
|
|
51
|
+
* @class
|
|
52
|
+
* @name Highcharts.Chart
|
|
53
|
+
*
|
|
54
|
+
* @param {string|Highcharts.HTMLDOMElement} [renderTo]
|
|
55
|
+
* The DOM element to render to, or its id.
|
|
56
|
+
*
|
|
57
|
+
* @param {Highcharts.Options} options
|
|
58
|
+
* The chart options structure.
|
|
59
|
+
*
|
|
60
|
+
* @param {Highcharts.ChartCallbackFunction} [callback]
|
|
61
|
+
* Function to run when the chart has loaded and all external images
|
|
62
|
+
* are loaded. Defining a
|
|
63
|
+
* [chart.events.load](https://api.highcharts.com/highcharts/chart.events.load)
|
|
64
|
+
* handler is equivalent.
|
|
65
|
+
*/
|
|
66
|
+
class Chart {
|
|
67
|
+
/**
|
|
68
|
+
* Factory function for basic charts.
|
|
69
|
+
*
|
|
70
|
+
* @example
|
|
71
|
+
* // Render a chart in to div#container
|
|
72
|
+
* let chart = Highcharts.chart('container', {
|
|
73
|
+
* title: {
|
|
74
|
+
* text: 'My chart'
|
|
75
|
+
* },
|
|
76
|
+
* series: [{
|
|
77
|
+
* data: [1, 3, 2, 4]
|
|
78
|
+
* }]
|
|
79
|
+
* });
|
|
80
|
+
*
|
|
81
|
+
* @function Highcharts.chart
|
|
82
|
+
*
|
|
83
|
+
* @param {string|Highcharts.HTMLDOMElement} [renderTo]
|
|
84
|
+
* The DOM element to render to, or its id.
|
|
85
|
+
*
|
|
86
|
+
* @param {Highcharts.Options} options
|
|
87
|
+
* The chart options structure.
|
|
88
|
+
*
|
|
89
|
+
* @param {Highcharts.ChartCallbackFunction} [callback]
|
|
90
|
+
* Function to run when the chart has loaded and all external images are
|
|
91
|
+
* loaded. Defining a
|
|
92
|
+
* [chart.events.load](https://api.highcharts.com/highcharts/chart.events.load)
|
|
93
|
+
* handler is equivalent.
|
|
94
|
+
*
|
|
95
|
+
* @return {Highcharts.Chart}
|
|
96
|
+
* Returns the Chart object.
|
|
97
|
+
*/
|
|
98
|
+
static chart(a, b, c) {
|
|
99
|
+
return new Chart(a, b, c);
|
|
100
|
+
}
|
|
101
|
+
// Implementation
|
|
102
|
+
constructor(a,
|
|
103
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
104
|
+
b, c
|
|
105
|
+
/* eslint-enable @typescript-eslint/no-unused-vars */
|
|
106
|
+
) {
|
|
107
|
+
this.sharedClips = {};
|
|
108
|
+
const args = [
|
|
109
|
+
// ES5 builds fail unless we cast it to an Array
|
|
110
|
+
...arguments
|
|
111
|
+
];
|
|
112
|
+
// Remove the optional first argument, renderTo, and set it on this.
|
|
113
|
+
if (isString(a) || a.nodeName) {
|
|
114
|
+
this.renderTo = args.shift();
|
|
115
|
+
}
|
|
116
|
+
this.init(args[0], args[1]);
|
|
117
|
+
}
|
|
118
|
+
/* *
|
|
119
|
+
*
|
|
120
|
+
* Functions
|
|
121
|
+
*
|
|
122
|
+
* */
|
|
123
|
+
/**
|
|
124
|
+
* Function setting zoom options after chart init and after chart update.
|
|
125
|
+
* Offers support for deprecated options.
|
|
126
|
+
*
|
|
127
|
+
* @private
|
|
128
|
+
* @function Highcharts.Chart#setZoomOptions
|
|
129
|
+
*/
|
|
130
|
+
setZoomOptions() {
|
|
131
|
+
const chart = this, options = chart.options.chart, zooming = options.zooming;
|
|
132
|
+
chart.zooming = {
|
|
133
|
+
...zooming,
|
|
134
|
+
type: pick(options.zoomType, zooming.type),
|
|
135
|
+
key: pick(options.zoomKey, zooming.key),
|
|
136
|
+
pinchType: pick(options.pinchType, zooming.pinchType),
|
|
137
|
+
singleTouch: pick(options.zoomBySingleTouch, zooming.singleTouch, false),
|
|
138
|
+
resetButton: merge(zooming.resetButton, options.resetZoomButton)
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Overridable function that initializes the chart. The constructor's
|
|
143
|
+
* arguments are passed on directly.
|
|
144
|
+
*
|
|
145
|
+
* @function Highcharts.Chart#init
|
|
146
|
+
*
|
|
147
|
+
* @param {Highcharts.Options} userOptions
|
|
148
|
+
* Custom options.
|
|
149
|
+
*
|
|
150
|
+
* @param {Function} [callback]
|
|
151
|
+
* Function to run when the chart has loaded and all external
|
|
152
|
+
* images are loaded.
|
|
153
|
+
*
|
|
154
|
+
*
|
|
155
|
+
* @emits Highcharts.Chart#event:init
|
|
156
|
+
* @emits Highcharts.Chart#event:afterInit
|
|
157
|
+
*/
|
|
158
|
+
init(userOptions, callback) {
|
|
159
|
+
// Fire the event with a default function
|
|
160
|
+
fireEvent(this, 'init', { args: arguments }, function () {
|
|
161
|
+
const options = merge(defaultOptions, userOptions), // Do the merge
|
|
162
|
+
optionsChart = options.chart, renderTo = this.renderTo || optionsChart.renderTo;
|
|
163
|
+
/**
|
|
164
|
+
* The original options given to the constructor or a chart factory
|
|
165
|
+
* like {@link Highcharts.chart} and {@link Highcharts.stockChart}.
|
|
166
|
+
* The original options are shallow copied to avoid mutation. The
|
|
167
|
+
* copy, `chart.userOptions`, may later be mutated to reflect
|
|
168
|
+
* updated options throughout the lifetime of the chart.
|
|
169
|
+
*
|
|
170
|
+
* For collections, like `series`, `xAxis` and `yAxis`, the chart
|
|
171
|
+
* user options should always be reflected by the item user option,
|
|
172
|
+
* so for example the following should always be true:
|
|
173
|
+
*
|
|
174
|
+
* `chart.xAxis[0].userOptions === chart.userOptions.xAxis[0]`
|
|
175
|
+
*
|
|
176
|
+
* @name Highcharts.Chart#userOptions
|
|
177
|
+
* @type {Highcharts.Options}
|
|
178
|
+
*/
|
|
179
|
+
this.userOptions = extend({}, userOptions);
|
|
180
|
+
if (!(this.renderTo = (isString(renderTo) ?
|
|
181
|
+
doc.getElementById(renderTo) :
|
|
182
|
+
renderTo))) {
|
|
183
|
+
// Display an error if the renderTo is wrong
|
|
184
|
+
error(13, true, this);
|
|
185
|
+
}
|
|
186
|
+
this.margin = [];
|
|
187
|
+
this.spacing = [];
|
|
188
|
+
// An array of functions that returns labels that should be
|
|
189
|
+
// considered for anti-collision
|
|
190
|
+
this.labelCollectors = [];
|
|
191
|
+
this.callback = callback;
|
|
192
|
+
this.isResizing = 0;
|
|
193
|
+
/**
|
|
194
|
+
* The options structure for the chart after merging
|
|
195
|
+
* {@link #defaultOptions} and {@link #userOptions}. It contains
|
|
196
|
+
* members for the sub elements like series, legend, tooltip etc.
|
|
197
|
+
*
|
|
198
|
+
* @name Highcharts.Chart#options
|
|
199
|
+
* @type {Highcharts.Options}
|
|
200
|
+
*/
|
|
201
|
+
this.options = options;
|
|
202
|
+
/**
|
|
203
|
+
* All the axes in the chart.
|
|
204
|
+
*
|
|
205
|
+
* @see Highcharts.Chart.xAxis
|
|
206
|
+
* @see Highcharts.Chart.yAxis
|
|
207
|
+
*
|
|
208
|
+
* @name Highcharts.Chart#axes
|
|
209
|
+
* @type {Array<Highcharts.Axis>}
|
|
210
|
+
*/
|
|
211
|
+
this.axes = [];
|
|
212
|
+
/**
|
|
213
|
+
* All the current series in the chart.
|
|
214
|
+
*
|
|
215
|
+
* @name Highcharts.Chart#series
|
|
216
|
+
* @type {Array<Highcharts.Series>}
|
|
217
|
+
*/
|
|
218
|
+
this.series = [];
|
|
219
|
+
this.locale = options.lang.locale ??
|
|
220
|
+
this.renderTo.closest('[lang]')?.lang;
|
|
221
|
+
/**
|
|
222
|
+
* The `Time` object associated with the chart. Since v6.0.5,
|
|
223
|
+
* time settings can be applied individually for each chart. If
|
|
224
|
+
* no individual settings apply, the `Time` object is shared by
|
|
225
|
+
* all instances.
|
|
226
|
+
*
|
|
227
|
+
* @name Highcharts.Chart#time
|
|
228
|
+
* @type {Highcharts.Time}
|
|
229
|
+
*/
|
|
230
|
+
this.time = new Time(extend(options.time || {}, {
|
|
231
|
+
locale: this.locale
|
|
232
|
+
}), options.lang);
|
|
233
|
+
options.time = this.time.options;
|
|
234
|
+
/**
|
|
235
|
+
* Callback function to override the default function that formats
|
|
236
|
+
* all the numbers in the chart. Returns a string with the formatted
|
|
237
|
+
* number.
|
|
238
|
+
*
|
|
239
|
+
* @name Highcharts.Chart#numberFormatter
|
|
240
|
+
* @type {Highcharts.NumberFormatterCallbackFunction}
|
|
241
|
+
*/
|
|
242
|
+
this.numberFormatter = (optionsChart.numberFormatter || numberFormat).bind(this);
|
|
243
|
+
/**
|
|
244
|
+
* Whether the chart is in styled mode, meaning all presentational
|
|
245
|
+
* attributes are avoided.
|
|
246
|
+
*
|
|
247
|
+
* @name Highcharts.Chart#styledMode
|
|
248
|
+
* @type {boolean}
|
|
249
|
+
*/
|
|
250
|
+
this.styledMode = optionsChart.styledMode;
|
|
251
|
+
this.hasCartesianSeries = optionsChart.showAxes;
|
|
252
|
+
const chart = this;
|
|
253
|
+
/**
|
|
254
|
+
* Index position of the chart in the {@link Highcharts#charts}
|
|
255
|
+
* property.
|
|
256
|
+
*
|
|
257
|
+
* @name Highcharts.Chart#index
|
|
258
|
+
* @type {number}
|
|
259
|
+
* @readonly
|
|
260
|
+
*/
|
|
261
|
+
chart.index = charts.length; // Add the chart to the global lookup
|
|
262
|
+
charts.push(chart);
|
|
263
|
+
H.chartCount++;
|
|
264
|
+
// Chart event handlers
|
|
265
|
+
registerEventOptions(this, optionsChart);
|
|
266
|
+
/**
|
|
267
|
+
* A collection of the X axes in the chart.
|
|
268
|
+
*
|
|
269
|
+
* @name Highcharts.Chart#xAxis
|
|
270
|
+
* @type {Array<Highcharts.Axis>}
|
|
271
|
+
*/
|
|
272
|
+
chart.xAxis = [];
|
|
273
|
+
/**
|
|
274
|
+
* A collection of the Y axes in the chart.
|
|
275
|
+
*
|
|
276
|
+
* @name Highcharts.Chart#yAxis
|
|
277
|
+
* @type {Array<Highcharts.Axis>}
|
|
278
|
+
*
|
|
279
|
+
* @todo
|
|
280
|
+
* Make events official: Fire the event `afterInit`.
|
|
281
|
+
*/
|
|
282
|
+
chart.yAxis = [];
|
|
283
|
+
chart.pointCount = chart.colorCounter = chart.symbolCounter = 0;
|
|
284
|
+
this.setZoomOptions();
|
|
285
|
+
// Fire after init but before first render, before axes and series
|
|
286
|
+
// have been initialized.
|
|
287
|
+
fireEvent(chart, 'afterInit');
|
|
288
|
+
chart.firstRender();
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Internal function to initialize an individual series.
|
|
293
|
+
*
|
|
294
|
+
* @private
|
|
295
|
+
* @function Highcharts.Chart#initSeries
|
|
296
|
+
*/
|
|
297
|
+
initSeries(options) {
|
|
298
|
+
const chart = this, optionsChart = chart.options.chart, type = (options.type ||
|
|
299
|
+
optionsChart.type), SeriesClass = seriesTypes[type];
|
|
300
|
+
// No such series type
|
|
301
|
+
if (!SeriesClass) {
|
|
302
|
+
error(17, true, chart, { missingModuleFor: type });
|
|
303
|
+
}
|
|
304
|
+
const series = new SeriesClass();
|
|
305
|
+
if (typeof series.init === 'function') {
|
|
306
|
+
series.init(chart, options);
|
|
307
|
+
}
|
|
308
|
+
return series;
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Internal function to set data for all series with enabled sorting.
|
|
312
|
+
*
|
|
313
|
+
* @private
|
|
314
|
+
* @function Highcharts.Chart#setSortedData
|
|
315
|
+
*/
|
|
316
|
+
setSortedData() {
|
|
317
|
+
this.getSeriesOrderByLinks().forEach(function (series) {
|
|
318
|
+
// We need to set data for series with sorting after series init
|
|
319
|
+
if (!series.points && !series.data && series.enabledDataSorting) {
|
|
320
|
+
series.setData(series.options.data, false);
|
|
321
|
+
}
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Sort and return chart series in order depending on the number of linked
|
|
326
|
+
* series.
|
|
327
|
+
*
|
|
328
|
+
* @private
|
|
329
|
+
* @function Highcharts.Series#getSeriesOrderByLinks
|
|
330
|
+
*/
|
|
331
|
+
getSeriesOrderByLinks() {
|
|
332
|
+
return this.series.concat().sort(function (a, b) {
|
|
333
|
+
if (a.linkedSeries.length || b.linkedSeries.length) {
|
|
334
|
+
return b.linkedSeries.length - a.linkedSeries.length;
|
|
335
|
+
}
|
|
336
|
+
return 0;
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* Order all series or axes above a given index. When series or axes are
|
|
341
|
+
* added and ordered by configuration, only the last series is handled
|
|
342
|
+
* (#248, #1123, #2456, #6112). This function is called on series and axis
|
|
343
|
+
* initialization and destroy.
|
|
344
|
+
*
|
|
345
|
+
* @private
|
|
346
|
+
* @function Highcharts.Chart#orderItems
|
|
347
|
+
* @param {string} coll The collection name
|
|
348
|
+
* @param {number} [fromIndex=0]
|
|
349
|
+
* If this is given, only the series above this index are handled.
|
|
350
|
+
*/
|
|
351
|
+
orderItems(coll, fromIndex = 0) {
|
|
352
|
+
const collection = this[coll],
|
|
353
|
+
// Item options should be reflected in chart.options.series,
|
|
354
|
+
// chart.options.yAxis etc
|
|
355
|
+
optionsArray = this.options[coll] = splat(this.options[coll])
|
|
356
|
+
.slice(), userOptionsArray = this.userOptions[coll] = this.userOptions[coll] ?
|
|
357
|
+
splat(this.userOptions[coll]).slice() :
|
|
358
|
+
[];
|
|
359
|
+
if (this.hasRendered) {
|
|
360
|
+
// Remove all above index
|
|
361
|
+
optionsArray.splice(fromIndex);
|
|
362
|
+
userOptionsArray.splice(fromIndex);
|
|
363
|
+
}
|
|
364
|
+
if (collection) {
|
|
365
|
+
for (let i = fromIndex, iEnd = collection.length; i < iEnd; ++i) {
|
|
366
|
+
const item = collection[i];
|
|
367
|
+
if (item) {
|
|
368
|
+
/**
|
|
369
|
+
* Contains the series' index in the `Chart.series` array.
|
|
370
|
+
*
|
|
371
|
+
* @name Highcharts.Series#index
|
|
372
|
+
* @type {number}
|
|
373
|
+
* @readonly
|
|
374
|
+
*/
|
|
375
|
+
item.index = i;
|
|
376
|
+
if (item instanceof Series) {
|
|
377
|
+
item.name = item.getName();
|
|
378
|
+
}
|
|
379
|
+
if (!item.options.isInternal) {
|
|
380
|
+
optionsArray[i] = item.options;
|
|
381
|
+
userOptionsArray[i] = item.userOptions;
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
/**
|
|
388
|
+
* Get the clipping for a series. Could be called for a series to initialate
|
|
389
|
+
* animating the clip or to set the final clip (only width and x).
|
|
390
|
+
*
|
|
391
|
+
* @private
|
|
392
|
+
* @function Highcharts.Chart#getClipBox
|
|
393
|
+
*/
|
|
394
|
+
getClipBox(series, chartCoords) {
|
|
395
|
+
const inverted = this.inverted, { xAxis, yAxis } = series || {};
|
|
396
|
+
// If no axes on the series, or series undefined, use global clipBox
|
|
397
|
+
let { x, y, width, height } = merge(this.clipBox);
|
|
398
|
+
if (series) {
|
|
399
|
+
// Otherwise, use clipBox.width which is corrected for
|
|
400
|
+
// plotBorderWidth and clipOffset
|
|
401
|
+
if (xAxis && xAxis.len !== this.plotSizeX) {
|
|
402
|
+
width = xAxis.len;
|
|
403
|
+
}
|
|
404
|
+
if (yAxis && yAxis.len !== this.plotSizeY) {
|
|
405
|
+
height = yAxis.len;
|
|
406
|
+
}
|
|
407
|
+
// If the chart is inverted and the series is not invertible, the
|
|
408
|
+
// chart clip box should be inverted, but not the series clip box
|
|
409
|
+
// (#20264)
|
|
410
|
+
if (inverted && !series.invertible) {
|
|
411
|
+
[width, height] = [height, width];
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
if (chartCoords) {
|
|
415
|
+
x += (inverted ? yAxis : xAxis)?.pos ?? this.plotLeft;
|
|
416
|
+
y += (inverted ? xAxis : yAxis)?.pos ?? this.plotTop;
|
|
417
|
+
}
|
|
418
|
+
return { x, y, width, height };
|
|
419
|
+
}
|
|
420
|
+
/**
|
|
421
|
+
* Check whether a given point is within the plot area.
|
|
422
|
+
*
|
|
423
|
+
* @function Highcharts.Chart#isInsidePlot
|
|
424
|
+
*
|
|
425
|
+
* @param {number} plotX
|
|
426
|
+
* Pixel x relative to the plot area.
|
|
427
|
+
*
|
|
428
|
+
* @param {number} plotY
|
|
429
|
+
* Pixel y relative to the plot area.
|
|
430
|
+
*
|
|
431
|
+
* @param {Highcharts.ChartIsInsideOptionsObject} [options]
|
|
432
|
+
* Options object.
|
|
433
|
+
*
|
|
434
|
+
* @return {boolean}
|
|
435
|
+
* Returns true if the given point is inside the plot area.
|
|
436
|
+
*/
|
|
437
|
+
isInsidePlot(plotX, plotY, options = {}) {
|
|
438
|
+
const { inverted, plotBox, plotLeft, plotTop, scrollablePlotBox } = this, { scrollLeft = 0, scrollTop = 0 } = (options.visiblePlotOnly &&
|
|
439
|
+
this.scrollablePlotArea?.scrollingContainer) || {}, series = options.series, box = (options.visiblePlotOnly && scrollablePlotBox) || plotBox, x = options.inverted ? plotY : plotX, y = options.inverted ? plotX : plotY, e = {
|
|
440
|
+
x,
|
|
441
|
+
y,
|
|
442
|
+
isInsidePlot: true,
|
|
443
|
+
options
|
|
444
|
+
};
|
|
445
|
+
if (!options.ignoreX) {
|
|
446
|
+
const xAxis = (series &&
|
|
447
|
+
(inverted && !this.polar ? series.yAxis : series.xAxis)) || {
|
|
448
|
+
pos: plotLeft,
|
|
449
|
+
len: Infinity
|
|
450
|
+
};
|
|
451
|
+
const chartX = options.paneCoordinates ?
|
|
452
|
+
xAxis.pos + x : plotLeft + x;
|
|
453
|
+
if (!(chartX >= Math.max(scrollLeft + plotLeft, xAxis.pos) &&
|
|
454
|
+
chartX <= Math.min(scrollLeft + plotLeft + box.width, xAxis.pos + xAxis.len))) {
|
|
455
|
+
e.isInsidePlot = false;
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
if (!options.ignoreY && e.isInsidePlot) {
|
|
459
|
+
const yAxis = (!inverted && options.axis &&
|
|
460
|
+
!options.axis.isXAxis && options.axis) || (series && (inverted ? series.xAxis : series.yAxis)) || {
|
|
461
|
+
pos: plotTop,
|
|
462
|
+
len: Infinity
|
|
463
|
+
};
|
|
464
|
+
const chartY = options.paneCoordinates ?
|
|
465
|
+
yAxis.pos + y : plotTop + y;
|
|
466
|
+
if (!(chartY >= Math.max(scrollTop + plotTop, yAxis.pos) &&
|
|
467
|
+
chartY <= Math.min(scrollTop + plotTop + box.height, yAxis.pos + yAxis.len))) {
|
|
468
|
+
e.isInsidePlot = false;
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
fireEvent(this, 'afterIsInsidePlot', e);
|
|
472
|
+
return e.isInsidePlot;
|
|
473
|
+
}
|
|
474
|
+
/**
|
|
475
|
+
* Redraw the chart after changes have been done to the data, axis extremes
|
|
476
|
+
* chart size or chart elements. All methods for updating axes, series or
|
|
477
|
+
* points have a parameter for redrawing the chart. This is `true` by
|
|
478
|
+
* default. But in many cases you want to do more than one operation on the
|
|
479
|
+
* chart before redrawing, for example add a number of points. In those
|
|
480
|
+
* cases it is a waste of resources to redraw the chart for each new point
|
|
481
|
+
* added. So you add the points and call `chart.redraw()` after.
|
|
482
|
+
*
|
|
483
|
+
* @function Highcharts.Chart#redraw
|
|
484
|
+
*
|
|
485
|
+
* @param {boolean|Partial<Highcharts.AnimationOptionsObject>} [animation]
|
|
486
|
+
* If or how to apply animation to the redraw. When `undefined`, it applies
|
|
487
|
+
* the animation that is set in the `chart.animation` option.
|
|
488
|
+
*
|
|
489
|
+
* @emits Highcharts.Chart#event:afterSetExtremes
|
|
490
|
+
* @emits Highcharts.Chart#event:beforeRedraw
|
|
491
|
+
* @emits Highcharts.Chart#event:predraw
|
|
492
|
+
* @emits Highcharts.Chart#event:redraw
|
|
493
|
+
* @emits Highcharts.Chart#event:render
|
|
494
|
+
* @emits Highcharts.Chart#event:updatedData
|
|
495
|
+
*/
|
|
496
|
+
redraw(animation) {
|
|
497
|
+
fireEvent(this, 'beforeRedraw');
|
|
498
|
+
const chart = this, axes = chart.hasCartesianSeries ? chart.axes : chart.colorAxis || [], series = chart.series, pointer = chart.pointer, legend = chart.legend, legendUserOptions = chart.userOptions.legend, renderer = chart.renderer, isHiddenChart = renderer.isHidden(), afterRedraw = [];
|
|
499
|
+
let hasDirtyStacks, hasStackedSeries, i, isDirtyBox = chart.isDirtyBox, redrawLegend = chart.isDirtyLegend, serie;
|
|
500
|
+
renderer.rootFontSize = renderer.boxWrapper.getStyle('font-size');
|
|
501
|
+
// Handle responsive rules, not only on resize (#6130)
|
|
502
|
+
if (chart.setResponsive) {
|
|
503
|
+
chart.setResponsive(false);
|
|
504
|
+
}
|
|
505
|
+
// Set the global animation. When chart.hasRendered is not true, the
|
|
506
|
+
// redraw call comes from a responsive rule and animation should not
|
|
507
|
+
// occur.
|
|
508
|
+
setAnimation(chart.hasRendered ? animation : false, chart);
|
|
509
|
+
if (isHiddenChart) {
|
|
510
|
+
chart.temporaryDisplay();
|
|
511
|
+
}
|
|
512
|
+
// Adjust title layout (reflow multiline text)
|
|
513
|
+
chart.layOutTitles(false);
|
|
514
|
+
// Link stacked series
|
|
515
|
+
i = series.length;
|
|
516
|
+
while (i--) {
|
|
517
|
+
serie = series[i];
|
|
518
|
+
if (serie.options.stacking || serie.options.centerInCategory) {
|
|
519
|
+
hasStackedSeries = true;
|
|
520
|
+
if (serie.isDirty) {
|
|
521
|
+
hasDirtyStacks = true;
|
|
522
|
+
break;
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
if (hasDirtyStacks) { // Mark others as dirty
|
|
527
|
+
i = series.length;
|
|
528
|
+
while (i--) {
|
|
529
|
+
serie = series[i];
|
|
530
|
+
if (serie.options.stacking) {
|
|
531
|
+
serie.isDirty = true;
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
// Handle updated data in the series
|
|
536
|
+
series.forEach(function (serie) {
|
|
537
|
+
if (serie.isDirty) {
|
|
538
|
+
if (serie.options.legendType === 'point') {
|
|
539
|
+
if (typeof serie.updateTotals === 'function') {
|
|
540
|
+
serie.updateTotals();
|
|
541
|
+
}
|
|
542
|
+
redrawLegend = true;
|
|
543
|
+
}
|
|
544
|
+
else if (legendUserOptions &&
|
|
545
|
+
(!!legendUserOptions.labelFormatter ||
|
|
546
|
+
legendUserOptions.labelFormat)) {
|
|
547
|
+
redrawLegend = true; // #2165
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
if (serie.isDirtyData) {
|
|
551
|
+
fireEvent(serie, 'updatedData');
|
|
552
|
+
}
|
|
553
|
+
});
|
|
554
|
+
// Handle added or removed series
|
|
555
|
+
if (redrawLegend && legend && legend.options.enabled) {
|
|
556
|
+
// Draw legend graphics
|
|
557
|
+
legend.render();
|
|
558
|
+
chart.isDirtyLegend = false;
|
|
559
|
+
}
|
|
560
|
+
// Reset stacks
|
|
561
|
+
if (hasStackedSeries) {
|
|
562
|
+
chart.getStacks();
|
|
563
|
+
}
|
|
564
|
+
// Set axes scales
|
|
565
|
+
axes.forEach(function (axis) {
|
|
566
|
+
axis.updateNames();
|
|
567
|
+
axis.setScale();
|
|
568
|
+
});
|
|
569
|
+
chart.getMargins(); // #3098
|
|
570
|
+
// If one axis is dirty, all axes must be redrawn (#792, #2169)
|
|
571
|
+
axes.forEach(function (axis) {
|
|
572
|
+
if (axis.isDirty) {
|
|
573
|
+
isDirtyBox = true;
|
|
574
|
+
}
|
|
575
|
+
});
|
|
576
|
+
// Redraw axes
|
|
577
|
+
axes.forEach(function (axis) {
|
|
578
|
+
// Fire 'afterSetExtremes' only if extremes are set
|
|
579
|
+
const key = axis.min + ',' + axis.max;
|
|
580
|
+
if (axis.extKey !== key) { // #821, #4452
|
|
581
|
+
axis.extKey = key;
|
|
582
|
+
// Prevent a recursive call to chart.redraw() (#1119)
|
|
583
|
+
afterRedraw.push(function () {
|
|
584
|
+
fireEvent(axis, 'afterSetExtremes', extend(axis.eventArgs, axis.getExtremes())); // #747, #751
|
|
585
|
+
delete axis.eventArgs;
|
|
586
|
+
});
|
|
587
|
+
}
|
|
588
|
+
if (isDirtyBox || hasStackedSeries) {
|
|
589
|
+
axis.redraw();
|
|
590
|
+
}
|
|
591
|
+
});
|
|
592
|
+
// The plot areas size has changed
|
|
593
|
+
if (isDirtyBox) {
|
|
594
|
+
chart.drawChartBox();
|
|
595
|
+
}
|
|
596
|
+
// Fire an event before redrawing series, used by the boost module to
|
|
597
|
+
// clear previous series renderings.
|
|
598
|
+
fireEvent(chart, 'predraw');
|
|
599
|
+
// Redraw affected series
|
|
600
|
+
series.forEach(function (serie) {
|
|
601
|
+
if ((isDirtyBox || serie.isDirty) && serie.visible) {
|
|
602
|
+
serie.redraw();
|
|
603
|
+
}
|
|
604
|
+
// Set it here, otherwise we will have unlimited 'updatedData' calls
|
|
605
|
+
// for a hidden series after setData(). Fixes #6012
|
|
606
|
+
serie.isDirtyData = false;
|
|
607
|
+
});
|
|
608
|
+
// Move tooltip or reset
|
|
609
|
+
if (pointer) {
|
|
610
|
+
pointer.reset(true);
|
|
611
|
+
}
|
|
612
|
+
// Redraw if canvas
|
|
613
|
+
renderer.draw();
|
|
614
|
+
// Fire the events
|
|
615
|
+
fireEvent(chart, 'redraw');
|
|
616
|
+
fireEvent(chart, 'render');
|
|
617
|
+
if (isHiddenChart) {
|
|
618
|
+
chart.temporaryDisplay(true);
|
|
619
|
+
}
|
|
620
|
+
// Fire callbacks that are put on hold until after the redraw
|
|
621
|
+
afterRedraw.forEach(function (callback) {
|
|
622
|
+
callback.call();
|
|
623
|
+
});
|
|
624
|
+
}
|
|
625
|
+
/**
|
|
626
|
+
* Get an axis, series or point object by `id` as given in the configuration
|
|
627
|
+
* options. Returns `undefined` if no item is found.
|
|
628
|
+
*
|
|
629
|
+
* @sample highcharts/plotoptions/series-id/
|
|
630
|
+
* Get series by id
|
|
631
|
+
*
|
|
632
|
+
* @function Highcharts.Chart#get
|
|
633
|
+
*
|
|
634
|
+
* @param {string} id
|
|
635
|
+
* The id as given in the configuration options.
|
|
636
|
+
*
|
|
637
|
+
* @return {Highcharts.Axis|Highcharts.Series|Highcharts.Point|undefined}
|
|
638
|
+
* The retrieved item.
|
|
639
|
+
*/
|
|
640
|
+
get(id) {
|
|
641
|
+
const series = this.series;
|
|
642
|
+
/**
|
|
643
|
+
* @private
|
|
644
|
+
*/
|
|
645
|
+
function itemById(item) {
|
|
646
|
+
return (item.id === id ||
|
|
647
|
+
(item.options && item.options.id === id));
|
|
648
|
+
}
|
|
649
|
+
let ret =
|
|
650
|
+
// Search axes
|
|
651
|
+
find(this.axes, itemById) ||
|
|
652
|
+
// Search series
|
|
653
|
+
find(this.series, itemById);
|
|
654
|
+
// Search points
|
|
655
|
+
for (let i = 0; !ret && i < series.length; i++) {
|
|
656
|
+
ret = find(series[i].points || [], itemById);
|
|
657
|
+
}
|
|
658
|
+
return ret;
|
|
659
|
+
}
|
|
660
|
+
/**
|
|
661
|
+
* Create the Axis instances based on the config options.
|
|
662
|
+
*
|
|
663
|
+
* @private
|
|
664
|
+
* @function Highcharts.Chart#createAxes
|
|
665
|
+
* @emits Highcharts.Chart#event:afterCreateAxes
|
|
666
|
+
* @emits Highcharts.Chart#event:createAxes
|
|
667
|
+
*/
|
|
668
|
+
createAxes() {
|
|
669
|
+
const options = this.userOptions;
|
|
670
|
+
fireEvent(this, 'createAxes');
|
|
671
|
+
for (const coll of ['xAxis', 'yAxis']) {
|
|
672
|
+
const arr = options[coll] = splat(options[coll] || {});
|
|
673
|
+
for (const axisOptions of arr) {
|
|
674
|
+
// eslint-disable-next-line no-new
|
|
675
|
+
new Axis(this, axisOptions, coll);
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
fireEvent(this, 'afterCreateAxes');
|
|
679
|
+
}
|
|
680
|
+
/**
|
|
681
|
+
* Returns an array of all currently selected points in the chart. Points
|
|
682
|
+
* can be selected by clicking or programmatically by the
|
|
683
|
+
* {@link Highcharts.Point#select}
|
|
684
|
+
* function.
|
|
685
|
+
*
|
|
686
|
+
* @sample highcharts/plotoptions/series-allowpointselect-line/
|
|
687
|
+
* Get selected points
|
|
688
|
+
* @sample highcharts/members/point-select-lasso/
|
|
689
|
+
* Lasso selection
|
|
690
|
+
* @sample highcharts/chart/events-selection-points/
|
|
691
|
+
* Rectangle selection
|
|
692
|
+
*
|
|
693
|
+
* @function Highcharts.Chart#getSelectedPoints
|
|
694
|
+
*
|
|
695
|
+
* @return {Array<Highcharts.Point>}
|
|
696
|
+
* The currently selected points.
|
|
697
|
+
*/
|
|
698
|
+
getSelectedPoints() {
|
|
699
|
+
return this.series.reduce((acc, series) => {
|
|
700
|
+
// For one-to-one points inspect series.data in order to retrieve
|
|
701
|
+
// points outside the visible range (#6445). For grouped data,
|
|
702
|
+
// inspect the generated series.points.
|
|
703
|
+
series.getPointsCollection()
|
|
704
|
+
.forEach((point) => {
|
|
705
|
+
if (pick(point.selectedStaging, point.selected)) {
|
|
706
|
+
acc.push(point);
|
|
707
|
+
}
|
|
708
|
+
});
|
|
709
|
+
return acc;
|
|
710
|
+
}, []);
|
|
711
|
+
}
|
|
712
|
+
/**
|
|
713
|
+
* Returns an array of all currently selected series in the chart. Series
|
|
714
|
+
* can be selected either programmatically by the
|
|
715
|
+
* {@link Highcharts.Series#select}
|
|
716
|
+
* function or by checking the checkbox next to the legend item if
|
|
717
|
+
* [series.showCheckBox](https://api.highcharts.com/highcharts/plotOptions.series.showCheckbox)
|
|
718
|
+
* is true.
|
|
719
|
+
*
|
|
720
|
+
* @sample highcharts/members/chart-getselectedseries/
|
|
721
|
+
* Get selected series
|
|
722
|
+
*
|
|
723
|
+
* @function Highcharts.Chart#getSelectedSeries
|
|
724
|
+
*
|
|
725
|
+
* @return {Array<Highcharts.Series>}
|
|
726
|
+
* The currently selected series.
|
|
727
|
+
*/
|
|
728
|
+
getSelectedSeries() {
|
|
729
|
+
return this.series.filter((s) => s.selected);
|
|
730
|
+
}
|
|
731
|
+
/**
|
|
732
|
+
* Set a new title or subtitle for the chart.
|
|
733
|
+
*
|
|
734
|
+
* @sample highcharts/members/chart-settitle/
|
|
735
|
+
* Set title text and styles
|
|
736
|
+
*
|
|
737
|
+
* @function Highcharts.Chart#setTitle
|
|
738
|
+
*
|
|
739
|
+
* @param {Highcharts.TitleOptions} [titleOptions]
|
|
740
|
+
* New title options. The title text itself is set by the
|
|
741
|
+
* `titleOptions.text` property.
|
|
742
|
+
*
|
|
743
|
+
* @param {Highcharts.SubtitleOptions} [subtitleOptions]
|
|
744
|
+
* New subtitle options. The subtitle text itself is set by the
|
|
745
|
+
* `subtitleOptions.text` property.
|
|
746
|
+
*
|
|
747
|
+
* @param {boolean} [redraw]
|
|
748
|
+
* Whether to redraw the chart or wait for a later call to
|
|
749
|
+
* `chart.redraw()`.
|
|
750
|
+
*/
|
|
751
|
+
setTitle(titleOptions, subtitleOptions, redraw) {
|
|
752
|
+
this.applyDescription('title', titleOptions);
|
|
753
|
+
this.applyDescription('subtitle', subtitleOptions);
|
|
754
|
+
// The initial call also adds the caption. On update, chart.update will
|
|
755
|
+
// relay to Chart.setCaption.
|
|
756
|
+
this.applyDescription('caption', void 0);
|
|
757
|
+
this.layOutTitles(redraw);
|
|
758
|
+
}
|
|
759
|
+
/**
|
|
760
|
+
* Apply a title, subtitle or caption for the chart
|
|
761
|
+
*
|
|
762
|
+
* @private
|
|
763
|
+
* @function Highcharts.Chart#applyDescription
|
|
764
|
+
* @param key {string}
|
|
765
|
+
* Either title, subtitle or caption
|
|
766
|
+
* @param {Highcharts.TitleOptions|Highcharts.SubtitleOptions|Highcharts.CaptionOptions|undefined} explicitOptions
|
|
767
|
+
* The options to set, will be merged with default options.
|
|
768
|
+
*/
|
|
769
|
+
applyDescription(key, explicitOptions) {
|
|
770
|
+
const chart = this;
|
|
771
|
+
// Merge default options with explicit options
|
|
772
|
+
const options = this.options[key] = merge(this.options[key], explicitOptions);
|
|
773
|
+
let elem = this[key];
|
|
774
|
+
if (elem && explicitOptions) {
|
|
775
|
+
this[key] = elem = elem.destroy(); // Remove old
|
|
776
|
+
}
|
|
777
|
+
if (options && !elem) {
|
|
778
|
+
elem = this.renderer.text(options.text, 0, 0, options.useHTML)
|
|
779
|
+
.attr({
|
|
780
|
+
align: options.align,
|
|
781
|
+
'class': 'highcharts-' + key,
|
|
782
|
+
zIndex: options.zIndex || 4
|
|
783
|
+
})
|
|
784
|
+
.css({
|
|
785
|
+
textOverflow: 'ellipsis',
|
|
786
|
+
whiteSpace: 'nowrap'
|
|
787
|
+
})
|
|
788
|
+
.add();
|
|
789
|
+
// Update methods, relay to `applyDescription`
|
|
790
|
+
elem.update = function (updateOptions, redraw) {
|
|
791
|
+
chart.applyDescription(key, updateOptions);
|
|
792
|
+
chart.layOutTitles(redraw);
|
|
793
|
+
};
|
|
794
|
+
// Presentational
|
|
795
|
+
if (!this.styledMode) {
|
|
796
|
+
elem.css(extend(key === 'title' ? {
|
|
797
|
+
// #2944
|
|
798
|
+
fontSize: this.options.isStock ? '1em' : '1.2em'
|
|
799
|
+
} : {}, options.style));
|
|
800
|
+
}
|
|
801
|
+
// Get unwrapped text length and reset
|
|
802
|
+
elem.textPxLength = elem.getBBox().width;
|
|
803
|
+
elem.css({ whiteSpace: options.style?.whiteSpace });
|
|
804
|
+
/**
|
|
805
|
+
* The chart title. The title has an `update` method that allows
|
|
806
|
+
* modifying the options directly or indirectly via
|
|
807
|
+
* `chart.update`.
|
|
808
|
+
*
|
|
809
|
+
* @sample highcharts/members/title-update/
|
|
810
|
+
* Updating titles
|
|
811
|
+
*
|
|
812
|
+
* @name Highcharts.Chart#title
|
|
813
|
+
* @type {Highcharts.TitleObject}
|
|
814
|
+
*/
|
|
815
|
+
/**
|
|
816
|
+
* The chart subtitle. The subtitle has an `update` method that
|
|
817
|
+
* allows modifying the options directly or indirectly via
|
|
818
|
+
* `chart.update`.
|
|
819
|
+
*
|
|
820
|
+
* @name Highcharts.Chart#subtitle
|
|
821
|
+
* @type {Highcharts.SubtitleObject}
|
|
822
|
+
*/
|
|
823
|
+
this[key] = elem;
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
/**
|
|
827
|
+
* Internal function to lay out the chart title, subtitle and caption, and
|
|
828
|
+
* cache the full offset height for use in `getMargins`. The result is
|
|
829
|
+
* stored in `this.titleOffset`.
|
|
830
|
+
*
|
|
831
|
+
* @private
|
|
832
|
+
* @function Highcharts.Chart#layOutTitles
|
|
833
|
+
*
|
|
834
|
+
* @param {boolean} [redraw=true]
|
|
835
|
+
* @emits Highcharts.Chart#event:afterLayOutTitles
|
|
836
|
+
*/
|
|
837
|
+
layOutTitles(redraw = true) {
|
|
838
|
+
const titleOffset = [0, 0, 0], { options, renderer, spacingBox } = this;
|
|
839
|
+
// Lay out the title, subtitle and caption respectively
|
|
840
|
+
['title', 'subtitle', 'caption'].forEach((key) => {
|
|
841
|
+
const desc = this[key], descOptions = this.options[key], alignTo = merge(spacingBox), textPxLength = desc?.textPxLength || 0;
|
|
842
|
+
if (desc && descOptions) {
|
|
843
|
+
// Provide a hook for the exporting button to shift the title
|
|
844
|
+
fireEvent(this, 'layOutTitle', { alignTo, key, textPxLength });
|
|
845
|
+
const fontMetrics = renderer.fontMetrics(desc), baseline = fontMetrics.b, lineHeight = fontMetrics.h, verticalAlign = descOptions.verticalAlign || 'top', topAligned = verticalAlign === 'top',
|
|
846
|
+
// Use minScale only for top-aligned titles. It is not
|
|
847
|
+
// likely that we will need scaling for other positions, but
|
|
848
|
+
// if it is requested, we need to adjust the vertical
|
|
849
|
+
// position to the scale.
|
|
850
|
+
minScale = topAligned && descOptions.minScale || 1, offset = key === 'title' ?
|
|
851
|
+
topAligned ? -3 : 0 :
|
|
852
|
+
// Floating subtitle (#6574)
|
|
853
|
+
topAligned ? titleOffset[0] + 2 : 0, uncappedScale = Math.min(alignTo.width / textPxLength, 1), scale = Math.max(minScale, uncappedScale), alignAttr = merge({
|
|
854
|
+
y: verticalAlign === 'bottom' ?
|
|
855
|
+
baseline :
|
|
856
|
+
offset + baseline
|
|
857
|
+
}, {
|
|
858
|
+
align: key === 'title' ?
|
|
859
|
+
// Title defaults to center for short titles,
|
|
860
|
+
// left for word-wrapped titles
|
|
861
|
+
(uncappedScale < minScale ? 'left' : 'center') :
|
|
862
|
+
// Subtitle defaults to the title.align
|
|
863
|
+
this.title?.alignValue
|
|
864
|
+
}, descOptions), width = (descOptions.width || ((uncappedScale > minScale ?
|
|
865
|
+
// One line
|
|
866
|
+
this.chartWidth :
|
|
867
|
+
// Allow word wrap
|
|
868
|
+
alignTo.width) / scale)) + 'px';
|
|
869
|
+
// No animation when switching alignment
|
|
870
|
+
if (desc.alignValue !== alignAttr.align) {
|
|
871
|
+
desc.placed = false;
|
|
872
|
+
}
|
|
873
|
+
// Set the width and read the height
|
|
874
|
+
const height = Math.round(desc
|
|
875
|
+
.css({ width })
|
|
876
|
+
// Skip the cache for HTML (#3481, #11666)
|
|
877
|
+
.getBBox(descOptions.useHTML).height);
|
|
878
|
+
alignAttr.height = height;
|
|
879
|
+
// Perform scaling and alignment
|
|
880
|
+
desc
|
|
881
|
+
.align(alignAttr, false, alignTo)
|
|
882
|
+
.attr({
|
|
883
|
+
align: alignAttr.align,
|
|
884
|
+
scaleX: scale,
|
|
885
|
+
scaleY: scale,
|
|
886
|
+
'transform-origin': `${alignTo.x +
|
|
887
|
+
textPxLength *
|
|
888
|
+
scale *
|
|
889
|
+
getAlignFactor(alignAttr.align)} ${lineHeight}`
|
|
890
|
+
});
|
|
891
|
+
// Adjust the rendered title offset
|
|
892
|
+
if (!descOptions.floating) {
|
|
893
|
+
const offset = height * (
|
|
894
|
+
// When scaling down the title, preserve the offset as
|
|
895
|
+
// long as it's only one line, but scale down the offset
|
|
896
|
+
// if the title wraps to multiple lines.
|
|
897
|
+
height < lineHeight * 1.2 ? 1 : scale);
|
|
898
|
+
if (verticalAlign === 'top') {
|
|
899
|
+
titleOffset[0] = Math.ceil(titleOffset[0] + offset);
|
|
900
|
+
}
|
|
901
|
+
else if (verticalAlign === 'bottom') {
|
|
902
|
+
titleOffset[2] = Math.ceil(titleOffset[2] + offset);
|
|
903
|
+
}
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
}, this);
|
|
907
|
+
// Handle title.margin and caption.margin
|
|
908
|
+
if (titleOffset[0] &&
|
|
909
|
+
(options.title?.verticalAlign || 'top') === 'top') {
|
|
910
|
+
titleOffset[0] += options.title?.margin || 0;
|
|
911
|
+
}
|
|
912
|
+
if (titleOffset[2] &&
|
|
913
|
+
options.caption?.verticalAlign === 'bottom') {
|
|
914
|
+
titleOffset[2] += options.caption?.margin || 0;
|
|
915
|
+
}
|
|
916
|
+
const requiresDirtyBox = (!this.titleOffset ||
|
|
917
|
+
this.titleOffset.join(',') !== titleOffset.join(','));
|
|
918
|
+
// Used in getMargins
|
|
919
|
+
this.titleOffset = titleOffset;
|
|
920
|
+
fireEvent(this, 'afterLayOutTitles');
|
|
921
|
+
if (!this.isDirtyBox && requiresDirtyBox) {
|
|
922
|
+
this.isDirtyBox = this.isDirtyLegend = requiresDirtyBox;
|
|
923
|
+
// Redraw if necessary (#2719, #2744)
|
|
924
|
+
if (this.hasRendered && redraw && this.isDirtyBox) {
|
|
925
|
+
this.redraw();
|
|
926
|
+
}
|
|
927
|
+
}
|
|
928
|
+
}
|
|
929
|
+
/**
|
|
930
|
+
* Internal function to get the available size of the container element
|
|
931
|
+
*
|
|
932
|
+
* @private
|
|
933
|
+
* @function Highcharts.Chart#getContainerBox
|
|
934
|
+
*/
|
|
935
|
+
getContainerBox() {
|
|
936
|
+
// Temporarily hide support divs from a11y and others, #21888
|
|
937
|
+
const nonContainers = [].map.call(this.renderTo.children, (child) => {
|
|
938
|
+
if (child !== this.container) {
|
|
939
|
+
const display = child.style.display;
|
|
940
|
+
child.style.display = 'none';
|
|
941
|
+
return [child, display];
|
|
942
|
+
}
|
|
943
|
+
}), box = {
|
|
944
|
+
width: getStyle(this.renderTo, 'width', true) || 0,
|
|
945
|
+
height: (getStyle(this.renderTo, 'height', true) || 0)
|
|
946
|
+
};
|
|
947
|
+
// Restore the non-containers
|
|
948
|
+
nonContainers.filter(Boolean).forEach(([div, display]) => {
|
|
949
|
+
div.style.display = display;
|
|
950
|
+
});
|
|
951
|
+
return box;
|
|
952
|
+
}
|
|
953
|
+
/**
|
|
954
|
+
* Internal function to get the chart width and height according to options
|
|
955
|
+
* and container size. Sets {@link Chart.chartWidth} and
|
|
956
|
+
* {@link Chart.chartHeight}.
|
|
957
|
+
*
|
|
958
|
+
* @private
|
|
959
|
+
* @function Highcharts.Chart#getChartSize
|
|
960
|
+
*/
|
|
961
|
+
getChartSize() {
|
|
962
|
+
const chart = this, optionsChart = chart.options.chart, widthOption = optionsChart.width, heightOption = optionsChart.height, containerBox = chart.getContainerBox(), enableDefaultHeight = containerBox.height <= 1 ||
|
|
963
|
+
( // #21510, prevent infinite reflow
|
|
964
|
+
!chart.renderTo.parentElement?.style.height &&
|
|
965
|
+
chart.renderTo.style.height === '100%');
|
|
966
|
+
/**
|
|
967
|
+
* The current pixel width of the chart.
|
|
968
|
+
*
|
|
969
|
+
* @name Highcharts.Chart#chartWidth
|
|
970
|
+
* @type {number}
|
|
971
|
+
*/
|
|
972
|
+
chart.chartWidth = Math.max(// #1393
|
|
973
|
+
0, widthOption || containerBox.width || 600 // #1460
|
|
974
|
+
);
|
|
975
|
+
/**
|
|
976
|
+
* The current pixel height of the chart.
|
|
977
|
+
*
|
|
978
|
+
* @name Highcharts.Chart#chartHeight
|
|
979
|
+
* @type {number}
|
|
980
|
+
*/
|
|
981
|
+
chart.chartHeight = Math.max(0, relativeLength(heightOption, chart.chartWidth) ||
|
|
982
|
+
(enableDefaultHeight ? 400 : containerBox.height));
|
|
983
|
+
chart.containerBox = containerBox;
|
|
984
|
+
}
|
|
985
|
+
/**
|
|
986
|
+
* If the renderTo element has no offsetWidth, most likely one or more of
|
|
987
|
+
* its parents are hidden. Loop up the DOM tree to temporarily display the
|
|
988
|
+
* parents, then save the original display properties, and when the true
|
|
989
|
+
* size is retrieved, reset them. Used on first render and on redraws.
|
|
990
|
+
*
|
|
991
|
+
* @private
|
|
992
|
+
* @function Highcharts.Chart#temporaryDisplay
|
|
993
|
+
*
|
|
994
|
+
* @param {boolean} [revert]
|
|
995
|
+
* Revert to the saved original styles.
|
|
996
|
+
*/
|
|
997
|
+
temporaryDisplay(revert) {
|
|
998
|
+
let node = this.renderTo, tempStyle;
|
|
999
|
+
if (!revert) {
|
|
1000
|
+
while (node?.style) {
|
|
1001
|
+
// When rendering to a detached node, it needs to be temporarily
|
|
1002
|
+
// attached in order to read styling and bounding boxes (#5783,
|
|
1003
|
+
// #7024).
|
|
1004
|
+
if (!doc.body.contains(node) && !node.parentNode) {
|
|
1005
|
+
node.hcOrigDetached = true;
|
|
1006
|
+
doc.body.appendChild(node);
|
|
1007
|
+
}
|
|
1008
|
+
if (getStyle(node, 'display', false) === 'none' ||
|
|
1009
|
+
node.hcOricDetached) {
|
|
1010
|
+
node.hcOrigStyle = {
|
|
1011
|
+
display: node.style.display,
|
|
1012
|
+
height: node.style.height,
|
|
1013
|
+
overflow: node.style.overflow
|
|
1014
|
+
};
|
|
1015
|
+
tempStyle = {
|
|
1016
|
+
display: 'block',
|
|
1017
|
+
overflow: 'hidden'
|
|
1018
|
+
};
|
|
1019
|
+
if (node !== this.renderTo) {
|
|
1020
|
+
tempStyle.height = 0;
|
|
1021
|
+
}
|
|
1022
|
+
css(node, tempStyle);
|
|
1023
|
+
// If it still doesn't have an offset width after setting
|
|
1024
|
+
// display to block, it probably has an !important priority
|
|
1025
|
+
// #2631, 6803
|
|
1026
|
+
if (!node.offsetWidth) {
|
|
1027
|
+
node.style.setProperty('display', 'block', 'important');
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1030
|
+
node = node.parentNode;
|
|
1031
|
+
if (node === doc.body) {
|
|
1032
|
+
break;
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1036
|
+
else {
|
|
1037
|
+
while (node?.style) {
|
|
1038
|
+
if (node.hcOrigStyle) {
|
|
1039
|
+
css(node, node.hcOrigStyle);
|
|
1040
|
+
delete node.hcOrigStyle;
|
|
1041
|
+
}
|
|
1042
|
+
if (node.hcOrigDetached) {
|
|
1043
|
+
doc.body.removeChild(node);
|
|
1044
|
+
node.hcOrigDetached = false;
|
|
1045
|
+
}
|
|
1046
|
+
node = node.parentNode;
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
1050
|
+
/**
|
|
1051
|
+
* Set the {@link Chart.container|chart container's} class name, in
|
|
1052
|
+
* addition to `highcharts-container`.
|
|
1053
|
+
*
|
|
1054
|
+
* @function Highcharts.Chart#setClassName
|
|
1055
|
+
*
|
|
1056
|
+
* @param {string} [className]
|
|
1057
|
+
* The additional class name.
|
|
1058
|
+
*/
|
|
1059
|
+
setClassName(className) {
|
|
1060
|
+
this.container.className = 'highcharts-container ' + (className || '');
|
|
1061
|
+
}
|
|
1062
|
+
/**
|
|
1063
|
+
* Get the containing element, determine the size and create the inner
|
|
1064
|
+
* container div to hold the chart.
|
|
1065
|
+
*
|
|
1066
|
+
* @private
|
|
1067
|
+
* @function Highcharts.Chart#afterGetContainer
|
|
1068
|
+
* @emits Highcharts.Chart#event:afterGetContainer
|
|
1069
|
+
*/
|
|
1070
|
+
getContainer() {
|
|
1071
|
+
const chart = this, options = chart.options, optionsChart = options.chart, indexAttrName = 'data-highcharts-chart', containerId = uniqueKey(), renderTo = chart.renderTo;
|
|
1072
|
+
let containerStyle;
|
|
1073
|
+
// If the container already holds a chart, destroy it. The check for
|
|
1074
|
+
// hasRendered is there because web pages that are saved to disk from
|
|
1075
|
+
// the browser, will preserve the data-highcharts-chart attribute and
|
|
1076
|
+
// the SVG contents, but not an interactive chart. So in this case,
|
|
1077
|
+
// charts[oldChartIndex] will point to the wrong chart if any (#2609).
|
|
1078
|
+
const oldChartIndex = pInt(attr(renderTo, indexAttrName));
|
|
1079
|
+
if (isNumber(oldChartIndex) &&
|
|
1080
|
+
charts[oldChartIndex] &&
|
|
1081
|
+
charts[oldChartIndex].hasRendered) {
|
|
1082
|
+
charts[oldChartIndex].destroy();
|
|
1083
|
+
}
|
|
1084
|
+
// Make a reference to the chart from the div
|
|
1085
|
+
attr(renderTo, indexAttrName, chart.index);
|
|
1086
|
+
// Remove previous chart
|
|
1087
|
+
renderTo.innerHTML = AST.emptyHTML;
|
|
1088
|
+
// If the container doesn't have an offsetWidth, it has or is a child of
|
|
1089
|
+
// a node that has display:none. We need to temporarily move it out to a
|
|
1090
|
+
// visible state to determine the size, else the legend and tooltips
|
|
1091
|
+
// won't render properly. The skipClone option is used in sparklines as
|
|
1092
|
+
// a micro optimization, saving about 1-2 ms each chart.
|
|
1093
|
+
if (!optionsChart.skipClone && !renderTo.offsetWidth) {
|
|
1094
|
+
chart.temporaryDisplay();
|
|
1095
|
+
}
|
|
1096
|
+
// Get the width and height
|
|
1097
|
+
chart.getChartSize();
|
|
1098
|
+
const chartHeight = chart.chartHeight;
|
|
1099
|
+
let chartWidth = chart.chartWidth;
|
|
1100
|
+
// Allow table cells and flex-boxes to shrink without the chart blocking
|
|
1101
|
+
// them out (#6427)
|
|
1102
|
+
css(renderTo, { overflow: 'hidden' });
|
|
1103
|
+
// Create the inner container
|
|
1104
|
+
if (!chart.styledMode) {
|
|
1105
|
+
containerStyle = extend({
|
|
1106
|
+
position: 'relative',
|
|
1107
|
+
// Needed for context menu (avoidscrollbars) and content
|
|
1108
|
+
// overflow in IE
|
|
1109
|
+
overflow: 'hidden',
|
|
1110
|
+
width: chartWidth + 'px',
|
|
1111
|
+
height: chartHeight + 'px',
|
|
1112
|
+
textAlign: 'left',
|
|
1113
|
+
lineHeight: 'normal', // #427
|
|
1114
|
+
zIndex: 0, // #1072
|
|
1115
|
+
'-webkit-tap-highlight-color': 'rgba(0,0,0,0)',
|
|
1116
|
+
userSelect: 'none', // #13503
|
|
1117
|
+
'touch-action': 'manipulation',
|
|
1118
|
+
outline: 'none',
|
|
1119
|
+
padding: '0px'
|
|
1120
|
+
}, optionsChart.style || {});
|
|
1121
|
+
}
|
|
1122
|
+
/**
|
|
1123
|
+
* The containing HTML element of the chart. The container is
|
|
1124
|
+
* dynamically inserted into the element given as the `renderTo`
|
|
1125
|
+
* parameter in the {@link Highcharts#chart} constructor.
|
|
1126
|
+
*
|
|
1127
|
+
* @name Highcharts.Chart#container
|
|
1128
|
+
* @type {Highcharts.HTMLDOMElement}
|
|
1129
|
+
*/
|
|
1130
|
+
const container = createElement('div', {
|
|
1131
|
+
id: containerId
|
|
1132
|
+
}, containerStyle, renderTo);
|
|
1133
|
+
chart.container = container;
|
|
1134
|
+
// Adjust width if setting height affected it (#20334)
|
|
1135
|
+
chart.getChartSize();
|
|
1136
|
+
if (chartWidth !== chart.chartWidth) {
|
|
1137
|
+
chartWidth = chart.chartWidth;
|
|
1138
|
+
if (!chart.styledMode) {
|
|
1139
|
+
css(container, {
|
|
1140
|
+
width: pick(optionsChart.style?.width, chartWidth + 'px')
|
|
1141
|
+
});
|
|
1142
|
+
}
|
|
1143
|
+
}
|
|
1144
|
+
chart.containerBox = chart.getContainerBox();
|
|
1145
|
+
// Cache the cursor (#1650)
|
|
1146
|
+
chart._cursor = container.style.cursor;
|
|
1147
|
+
// Initialize the renderer
|
|
1148
|
+
const Renderer = optionsChart.renderer || !svg ?
|
|
1149
|
+
RendererRegistry.getRendererType(optionsChart.renderer) :
|
|
1150
|
+
SVGRenderer;
|
|
1151
|
+
/**
|
|
1152
|
+
* The renderer instance of the chart. Each chart instance has only one
|
|
1153
|
+
* associated renderer.
|
|
1154
|
+
*
|
|
1155
|
+
* @name Highcharts.Chart#renderer
|
|
1156
|
+
* @type {Highcharts.SVGRenderer}
|
|
1157
|
+
*/
|
|
1158
|
+
chart.renderer = new Renderer(container, chartWidth, chartHeight, void 0, optionsChart.forExport, options.exporting?.allowHTML, chart.styledMode);
|
|
1159
|
+
// Set the initial animation from the options
|
|
1160
|
+
setAnimation(void 0, chart);
|
|
1161
|
+
chart.setClassName(optionsChart.className);
|
|
1162
|
+
if (!chart.styledMode) {
|
|
1163
|
+
chart.renderer.setStyle(optionsChart.style);
|
|
1164
|
+
}
|
|
1165
|
+
else {
|
|
1166
|
+
// Initialize definitions
|
|
1167
|
+
for (const key in options.defs) { // eslint-disable-line guard-for-in
|
|
1168
|
+
this.renderer.definition(options.defs[key]);
|
|
1169
|
+
}
|
|
1170
|
+
}
|
|
1171
|
+
// Add a reference to the charts index
|
|
1172
|
+
chart.renderer.chartIndex = chart.index;
|
|
1173
|
+
fireEvent(this, 'afterGetContainer');
|
|
1174
|
+
}
|
|
1175
|
+
/**
|
|
1176
|
+
* Calculate margins by rendering axis labels in a preliminary position.
|
|
1177
|
+
* Title, subtitle and legend have already been rendered at this stage, but
|
|
1178
|
+
* will be moved into their final positions.
|
|
1179
|
+
*
|
|
1180
|
+
* @private
|
|
1181
|
+
* @function Highcharts.Chart#getMargins
|
|
1182
|
+
* @emits Highcharts.Chart#event:getMargins
|
|
1183
|
+
*/
|
|
1184
|
+
getMargins(skipAxes) {
|
|
1185
|
+
const { spacing, margin, titleOffset } = this;
|
|
1186
|
+
this.resetMargins();
|
|
1187
|
+
// Adjust for title and subtitle
|
|
1188
|
+
if (titleOffset[0] && !defined(margin[0])) {
|
|
1189
|
+
this.plotTop = Math.max(this.plotTop, titleOffset[0] + spacing[0]);
|
|
1190
|
+
}
|
|
1191
|
+
if (titleOffset[2] && !defined(margin[2])) {
|
|
1192
|
+
this.marginBottom = Math.max(this.marginBottom, titleOffset[2] + spacing[2]);
|
|
1193
|
+
}
|
|
1194
|
+
// Adjust for legend
|
|
1195
|
+
if (this.legend?.display) {
|
|
1196
|
+
this.legend.adjustMargins(margin, spacing);
|
|
1197
|
+
}
|
|
1198
|
+
fireEvent(this, 'getMargins');
|
|
1199
|
+
if (!skipAxes) {
|
|
1200
|
+
this.getAxisMargins();
|
|
1201
|
+
}
|
|
1202
|
+
}
|
|
1203
|
+
/**
|
|
1204
|
+
* @private
|
|
1205
|
+
* @function Highcharts.Chart#getAxisMargins
|
|
1206
|
+
*/
|
|
1207
|
+
getAxisMargins() {
|
|
1208
|
+
const chart = this,
|
|
1209
|
+
// [top, right, bottom, left]
|
|
1210
|
+
axisOffset = chart.axisOffset = [0, 0, 0, 0], colorAxis = chart.colorAxis, margin = chart.margin, getOffset = (axes) => {
|
|
1211
|
+
axes.forEach((axis) => {
|
|
1212
|
+
if (axis.visible) {
|
|
1213
|
+
axis.getOffset();
|
|
1214
|
+
}
|
|
1215
|
+
});
|
|
1216
|
+
};
|
|
1217
|
+
// Pre-render axes to get labels offset width
|
|
1218
|
+
if (chart.hasCartesianSeries) {
|
|
1219
|
+
getOffset(chart.axes);
|
|
1220
|
+
}
|
|
1221
|
+
else if (colorAxis?.length) {
|
|
1222
|
+
getOffset(colorAxis);
|
|
1223
|
+
}
|
|
1224
|
+
// Add the axis offsets
|
|
1225
|
+
marginNames.forEach((marginName, side) => {
|
|
1226
|
+
if (!defined(margin[side])) {
|
|
1227
|
+
chart[marginName] += axisOffset[side];
|
|
1228
|
+
}
|
|
1229
|
+
});
|
|
1230
|
+
chart.setChartSize();
|
|
1231
|
+
}
|
|
1232
|
+
/**
|
|
1233
|
+
* Return the current options of the chart, but only those that differ from
|
|
1234
|
+
* default options. Items that can be either an object or an array of
|
|
1235
|
+
* objects, like `series`, `xAxis` and `yAxis`, are always returned as
|
|
1236
|
+
* array.
|
|
1237
|
+
*
|
|
1238
|
+
* @sample highcharts/members/chart-getoptions
|
|
1239
|
+
*
|
|
1240
|
+
* @function Highcharts.Chart#getOptions
|
|
1241
|
+
*
|
|
1242
|
+
* @since 11.1.0
|
|
1243
|
+
*/
|
|
1244
|
+
getOptions() {
|
|
1245
|
+
return diffObjects(this.userOptions, defaultOptions);
|
|
1246
|
+
}
|
|
1247
|
+
/**
|
|
1248
|
+
* Reflows the chart to its container. By default, the Resize Observer is
|
|
1249
|
+
* attached to the chart's div which allows to reflows the chart
|
|
1250
|
+
* automatically to its container, as per the
|
|
1251
|
+
* [chart.reflow](https://api.highcharts.com/highcharts/chart.reflow)
|
|
1252
|
+
* option.
|
|
1253
|
+
*
|
|
1254
|
+
* @sample highcharts/chart/events-container/
|
|
1255
|
+
* Pop up and reflow
|
|
1256
|
+
*
|
|
1257
|
+
* @function Highcharts.Chart#reflow
|
|
1258
|
+
*
|
|
1259
|
+
* @param {global.Event} [e]
|
|
1260
|
+
* Event arguments. Used primarily when the function is called
|
|
1261
|
+
* internally as a response to window resize.
|
|
1262
|
+
*/
|
|
1263
|
+
reflow(e) {
|
|
1264
|
+
const chart = this, oldBox = chart.containerBox, containerBox = chart.getContainerBox();
|
|
1265
|
+
delete chart.pointer?.chartPosition;
|
|
1266
|
+
// Width and height checks for display:none. Target is doc in Opera
|
|
1267
|
+
// and win in Firefox, Chrome and IE9.
|
|
1268
|
+
if (!chart.exporting?.isPrinting &&
|
|
1269
|
+
!chart.isResizing &&
|
|
1270
|
+
oldBox &&
|
|
1271
|
+
// When fired by resize observer inside hidden container
|
|
1272
|
+
containerBox.width) {
|
|
1273
|
+
if (containerBox.width !== oldBox.width ||
|
|
1274
|
+
containerBox.height !== oldBox.height) {
|
|
1275
|
+
U.clearTimeout(chart.reflowTimeout);
|
|
1276
|
+
// When called from window.resize, e is set, else it's called
|
|
1277
|
+
// directly (#2224)
|
|
1278
|
+
chart.reflowTimeout = syncTimeout(function () {
|
|
1279
|
+
// Set size, it may have been destroyed in the meantime
|
|
1280
|
+
// (#1257)
|
|
1281
|
+
if (chart.container) {
|
|
1282
|
+
chart.setSize(void 0, void 0, false);
|
|
1283
|
+
}
|
|
1284
|
+
}, e ? 100 : 0);
|
|
1285
|
+
}
|
|
1286
|
+
chart.containerBox = containerBox;
|
|
1287
|
+
}
|
|
1288
|
+
}
|
|
1289
|
+
/**
|
|
1290
|
+
* Toggle the event handlers necessary for auto resizing, depending on the
|
|
1291
|
+
* `chart.reflow` option.
|
|
1292
|
+
*
|
|
1293
|
+
* @private
|
|
1294
|
+
* @function Highcharts.Chart#setReflow
|
|
1295
|
+
*/
|
|
1296
|
+
setReflow() {
|
|
1297
|
+
const chart = this;
|
|
1298
|
+
const runReflow = (e) => {
|
|
1299
|
+
if (chart.options?.chart.reflow && chart.hasLoaded) {
|
|
1300
|
+
chart.reflow(e);
|
|
1301
|
+
}
|
|
1302
|
+
};
|
|
1303
|
+
if (typeof ResizeObserver === 'function') {
|
|
1304
|
+
(new ResizeObserver(runReflow)).observe(chart.renderTo);
|
|
1305
|
+
// Fallback for more legacy browser versions.
|
|
1306
|
+
}
|
|
1307
|
+
else {
|
|
1308
|
+
const unbind = addEvent(win, 'resize', runReflow);
|
|
1309
|
+
addEvent(this, 'destroy', unbind);
|
|
1310
|
+
}
|
|
1311
|
+
}
|
|
1312
|
+
/**
|
|
1313
|
+
* Resize the chart to a given width and height. In order to set the width
|
|
1314
|
+
* only, the height argument may be skipped. To set the height only, pass
|
|
1315
|
+
* `undefined` for the width.
|
|
1316
|
+
*
|
|
1317
|
+
* @sample highcharts/members/chart-setsize-button/
|
|
1318
|
+
* Test resizing from buttons
|
|
1319
|
+
* @sample highcharts/members/chart-setsize-jquery-resizable/
|
|
1320
|
+
* Add a jQuery UI resizable
|
|
1321
|
+
* @sample stock/members/chart-setsize/
|
|
1322
|
+
* Highcharts Stock with UI resizable
|
|
1323
|
+
*
|
|
1324
|
+
* @function Highcharts.Chart#setSize
|
|
1325
|
+
*
|
|
1326
|
+
* @param {number|null} [width]
|
|
1327
|
+
* The new pixel width of the chart. Since v4.2.6, the argument can
|
|
1328
|
+
* be `undefined` in order to preserve the current value (when
|
|
1329
|
+
* setting height only), or `null` to adapt to the width of the
|
|
1330
|
+
* containing element.
|
|
1331
|
+
*
|
|
1332
|
+
* @param {number|null} [height]
|
|
1333
|
+
* The new pixel height of the chart. Since v4.2.6, the argument can
|
|
1334
|
+
* be `undefined` in order to preserve the current value, or `null`
|
|
1335
|
+
* in order to adapt to the height of the containing element.
|
|
1336
|
+
*
|
|
1337
|
+
* @param {boolean|Partial<Highcharts.AnimationOptionsObject>} [animation]
|
|
1338
|
+
* Whether and how to apply animation. When `undefined`, it applies
|
|
1339
|
+
* the animation that is set in the `chart.animation` option.
|
|
1340
|
+
*
|
|
1341
|
+
*
|
|
1342
|
+
* @emits Highcharts.Chart#event:endResize
|
|
1343
|
+
* @emits Highcharts.Chart#event:resize
|
|
1344
|
+
*/
|
|
1345
|
+
setSize(width, height, animation) {
|
|
1346
|
+
const chart = this, renderer = chart.renderer;
|
|
1347
|
+
// Handle the isResizing counter
|
|
1348
|
+
chart.isResizing += 1;
|
|
1349
|
+
// Set the animation for the current process
|
|
1350
|
+
setAnimation(animation, chart);
|
|
1351
|
+
const globalAnimation = renderer.globalAnimation;
|
|
1352
|
+
chart.oldChartHeight = chart.chartHeight;
|
|
1353
|
+
chart.oldChartWidth = chart.chartWidth;
|
|
1354
|
+
if (typeof width !== 'undefined') {
|
|
1355
|
+
chart.options.chart.width = width;
|
|
1356
|
+
}
|
|
1357
|
+
if (typeof height !== 'undefined') {
|
|
1358
|
+
chart.options.chart.height = height;
|
|
1359
|
+
}
|
|
1360
|
+
chart.getChartSize();
|
|
1361
|
+
const { chartWidth, chartHeight, scrollablePixelsX = 0, scrollablePixelsY = 0 } = chart;
|
|
1362
|
+
// Avoid expensive redrawing if the computed size didn't change
|
|
1363
|
+
if (chart.isDirtyBox ||
|
|
1364
|
+
chartWidth !== chart.oldChartWidth ||
|
|
1365
|
+
chartHeight !== chart.oldChartHeight) {
|
|
1366
|
+
// Resize the container with the global animation applied if enabled
|
|
1367
|
+
// (#2503)
|
|
1368
|
+
if (!chart.styledMode) {
|
|
1369
|
+
(globalAnimation ? animate : css)(chart.container, {
|
|
1370
|
+
width: `${chartWidth + scrollablePixelsX}px`,
|
|
1371
|
+
height: `${chartHeight + scrollablePixelsY}px`
|
|
1372
|
+
}, globalAnimation);
|
|
1373
|
+
}
|
|
1374
|
+
chart.setChartSize(true);
|
|
1375
|
+
renderer.setSize(chartWidth, chartHeight, globalAnimation);
|
|
1376
|
+
// Handle axes
|
|
1377
|
+
chart.axes.forEach(function (axis) {
|
|
1378
|
+
axis.isDirty = true;
|
|
1379
|
+
axis.setScale();
|
|
1380
|
+
});
|
|
1381
|
+
chart.isDirtyLegend = true; // Force legend redraw
|
|
1382
|
+
chart.isDirtyBox = true; // Force redraw of plot and chart border
|
|
1383
|
+
chart.layOutTitles(); // #2857
|
|
1384
|
+
chart.getMargins();
|
|
1385
|
+
chart.redraw(globalAnimation);
|
|
1386
|
+
chart.oldChartHeight = void 0;
|
|
1387
|
+
fireEvent(chart, 'resize');
|
|
1388
|
+
// Fire endResize and set isResizing back. If animation is disabled,
|
|
1389
|
+
// fire without delay, but in a new thread to avoid triggering the
|
|
1390
|
+
// resize observer (#19027).
|
|
1391
|
+
setTimeout(() => {
|
|
1392
|
+
if (chart) {
|
|
1393
|
+
fireEvent(chart, 'endResize');
|
|
1394
|
+
}
|
|
1395
|
+
}, animObject(globalAnimation).duration);
|
|
1396
|
+
}
|
|
1397
|
+
// Handle resizing counter even if we've re-rendered or not (#20548).
|
|
1398
|
+
chart.isResizing -= 1;
|
|
1399
|
+
}
|
|
1400
|
+
/**
|
|
1401
|
+
* Set the public chart properties. This is done before and after the
|
|
1402
|
+
* pre-render to determine margin sizes.
|
|
1403
|
+
*
|
|
1404
|
+
* @private
|
|
1405
|
+
* @function Highcharts.Chart#setChartSize
|
|
1406
|
+
* @emits Highcharts.Chart#event:afterSetChartSize
|
|
1407
|
+
*/
|
|
1408
|
+
setChartSize(skipAxes) {
|
|
1409
|
+
const chart = this, { chartHeight, chartWidth, inverted, spacing, renderer } = chart, clipOffset = chart.clipOffset, clipRoundFunc = Math[inverted ? 'floor' : 'round'];
|
|
1410
|
+
let plotLeft, plotTop, plotWidth, plotHeight;
|
|
1411
|
+
/**
|
|
1412
|
+
* The current left position of the plot area in pixels.
|
|
1413
|
+
*
|
|
1414
|
+
* @name Highcharts.Chart#plotLeft
|
|
1415
|
+
* @type {number}
|
|
1416
|
+
*/
|
|
1417
|
+
chart.plotLeft = plotLeft = Math.round(chart.plotLeft);
|
|
1418
|
+
/**
|
|
1419
|
+
* The current top position of the plot area in pixels.
|
|
1420
|
+
*
|
|
1421
|
+
* @name Highcharts.Chart#plotTop
|
|
1422
|
+
* @type {number}
|
|
1423
|
+
*/
|
|
1424
|
+
chart.plotTop = plotTop = Math.round(chart.plotTop);
|
|
1425
|
+
/**
|
|
1426
|
+
* The current width of the plot area in pixels.
|
|
1427
|
+
*
|
|
1428
|
+
* @name Highcharts.Chart#plotWidth
|
|
1429
|
+
* @type {number}
|
|
1430
|
+
*/
|
|
1431
|
+
chart.plotWidth = plotWidth = Math.max(0, Math.round(chartWidth - plotLeft - (chart.marginRight ?? 0)));
|
|
1432
|
+
/**
|
|
1433
|
+
* The current height of the plot area in pixels.
|
|
1434
|
+
*
|
|
1435
|
+
* @name Highcharts.Chart#plotHeight
|
|
1436
|
+
* @type {number}
|
|
1437
|
+
*/
|
|
1438
|
+
chart.plotHeight = plotHeight = Math.max(0, Math.round(chartHeight - plotTop - (chart.marginBottom ?? 0)));
|
|
1439
|
+
chart.plotSizeX = inverted ? plotHeight : plotWidth;
|
|
1440
|
+
chart.plotSizeY = inverted ? plotWidth : plotHeight;
|
|
1441
|
+
// Set boxes used for alignment
|
|
1442
|
+
chart.spacingBox = renderer.spacingBox = {
|
|
1443
|
+
x: spacing[3],
|
|
1444
|
+
y: spacing[0],
|
|
1445
|
+
width: chartWidth - spacing[3] - spacing[1],
|
|
1446
|
+
height: chartHeight - spacing[0] - spacing[2]
|
|
1447
|
+
};
|
|
1448
|
+
chart.plotBox = renderer.plotBox = {
|
|
1449
|
+
x: plotLeft,
|
|
1450
|
+
y: plotTop,
|
|
1451
|
+
width: plotWidth,
|
|
1452
|
+
height: plotHeight
|
|
1453
|
+
};
|
|
1454
|
+
// Compute the clipping box
|
|
1455
|
+
if (clipOffset) {
|
|
1456
|
+
chart.clipBox = {
|
|
1457
|
+
x: clipRoundFunc(clipOffset[3]),
|
|
1458
|
+
y: clipRoundFunc(clipOffset[0]),
|
|
1459
|
+
width: clipRoundFunc(chart.plotSizeX - clipOffset[1] - clipOffset[3]),
|
|
1460
|
+
height: clipRoundFunc(chart.plotSizeY - clipOffset[0] - clipOffset[2])
|
|
1461
|
+
};
|
|
1462
|
+
}
|
|
1463
|
+
if (!skipAxes) {
|
|
1464
|
+
chart.axes.forEach(function (axis) {
|
|
1465
|
+
axis.setAxisSize();
|
|
1466
|
+
axis.setAxisTranslation();
|
|
1467
|
+
});
|
|
1468
|
+
renderer.alignElements();
|
|
1469
|
+
}
|
|
1470
|
+
fireEvent(chart, 'afterSetChartSize', { skipAxes: skipAxes });
|
|
1471
|
+
}
|
|
1472
|
+
/**
|
|
1473
|
+
* Initial margins before auto size margins are applied.
|
|
1474
|
+
*
|
|
1475
|
+
* @private
|
|
1476
|
+
* @function Highcharts.Chart#resetMargins
|
|
1477
|
+
*/
|
|
1478
|
+
resetMargins() {
|
|
1479
|
+
fireEvent(this, 'resetMargins');
|
|
1480
|
+
const chart = this, chartOptions = chart.options.chart, plotBorderWidth = chartOptions.plotBorderWidth || 0, halfWidth = Math.round(plotBorderWidth) / 2;
|
|
1481
|
+
// Create margin and spacing array
|
|
1482
|
+
['margin', 'spacing'].forEach((target) => {
|
|
1483
|
+
const value = chartOptions[target], values = isObject(value) ? value : [value, value, value, value];
|
|
1484
|
+
[
|
|
1485
|
+
'Top',
|
|
1486
|
+
'Right',
|
|
1487
|
+
'Bottom',
|
|
1488
|
+
'Left'
|
|
1489
|
+
].forEach((sideName, side) => {
|
|
1490
|
+
chart[target][side] = (chartOptions[`${target}${sideName}`] ??
|
|
1491
|
+
values[side]);
|
|
1492
|
+
});
|
|
1493
|
+
});
|
|
1494
|
+
// Set margin names like chart.plotTop, chart.plotLeft,
|
|
1495
|
+
// chart.marginRight, chart.marginBottom.
|
|
1496
|
+
marginNames.forEach((marginName, side) => {
|
|
1497
|
+
chart[marginName] = chart.margin[side] ?? chart.spacing[side];
|
|
1498
|
+
});
|
|
1499
|
+
chart.axisOffset = [0, 0, 0, 0]; // Top, right, bottom, left
|
|
1500
|
+
chart.clipOffset = [
|
|
1501
|
+
halfWidth,
|
|
1502
|
+
halfWidth,
|
|
1503
|
+
halfWidth,
|
|
1504
|
+
halfWidth
|
|
1505
|
+
];
|
|
1506
|
+
chart.plotBorderWidth = plotBorderWidth;
|
|
1507
|
+
}
|
|
1508
|
+
/**
|
|
1509
|
+
* Internal function to draw or redraw the borders and backgrounds for chart
|
|
1510
|
+
* and plot area.
|
|
1511
|
+
*
|
|
1512
|
+
* @private
|
|
1513
|
+
* @function Highcharts.Chart#drawChartBox
|
|
1514
|
+
* @emits Highcharts.Chart#event:afterDrawChartBox
|
|
1515
|
+
*/
|
|
1516
|
+
drawChartBox() {
|
|
1517
|
+
const chart = this, optionsChart = chart.options.chart, renderer = chart.renderer, chartWidth = chart.chartWidth, chartHeight = chart.chartHeight, styledMode = chart.styledMode, plotBGImage = chart.plotBGImage, chartBackgroundColor = optionsChart.backgroundColor, plotBackgroundColor = optionsChart.plotBackgroundColor, plotBackgroundImage = optionsChart.plotBackgroundImage, plotLeft = chart.plotLeft, plotTop = chart.plotTop, plotWidth = chart.plotWidth, plotHeight = chart.plotHeight, plotBox = chart.plotBox, clipRect = chart.clipRect, clipBox = chart.clipBox;
|
|
1518
|
+
let chartBackground = chart.chartBackground, plotBackground = chart.plotBackground, plotBorder = chart.plotBorder, chartBorderWidth, mgn, bgAttr, verb = 'animate';
|
|
1519
|
+
// Chart area
|
|
1520
|
+
if (!chartBackground) {
|
|
1521
|
+
chart.chartBackground = chartBackground = renderer.rect()
|
|
1522
|
+
.addClass('highcharts-background')
|
|
1523
|
+
.add();
|
|
1524
|
+
verb = 'attr';
|
|
1525
|
+
}
|
|
1526
|
+
if (!styledMode) {
|
|
1527
|
+
// Presentational
|
|
1528
|
+
chartBorderWidth = optionsChart.borderWidth || 0;
|
|
1529
|
+
mgn = chartBorderWidth + (optionsChart.shadow ? 8 : 0);
|
|
1530
|
+
bgAttr = {
|
|
1531
|
+
fill: chartBackgroundColor || 'none'
|
|
1532
|
+
};
|
|
1533
|
+
if (chartBorderWidth || chartBackground['stroke-width']) { // #980
|
|
1534
|
+
bgAttr.stroke = optionsChart.borderColor;
|
|
1535
|
+
bgAttr['stroke-width'] = chartBorderWidth;
|
|
1536
|
+
}
|
|
1537
|
+
chartBackground
|
|
1538
|
+
.attr(bgAttr)
|
|
1539
|
+
.shadow(optionsChart.shadow);
|
|
1540
|
+
}
|
|
1541
|
+
else {
|
|
1542
|
+
chartBorderWidth = mgn = chartBackground.strokeWidth();
|
|
1543
|
+
}
|
|
1544
|
+
chartBackground[verb]({
|
|
1545
|
+
x: mgn / 2,
|
|
1546
|
+
y: mgn / 2,
|
|
1547
|
+
width: chartWidth - mgn - chartBorderWidth % 2,
|
|
1548
|
+
height: chartHeight - mgn - chartBorderWidth % 2,
|
|
1549
|
+
r: optionsChart.borderRadius
|
|
1550
|
+
});
|
|
1551
|
+
// Plot background
|
|
1552
|
+
verb = 'animate';
|
|
1553
|
+
if (!plotBackground) {
|
|
1554
|
+
verb = 'attr';
|
|
1555
|
+
chart.plotBackground = plotBackground = renderer.rect()
|
|
1556
|
+
.addClass('highcharts-plot-background')
|
|
1557
|
+
.add();
|
|
1558
|
+
}
|
|
1559
|
+
plotBackground[verb](plotBox);
|
|
1560
|
+
if (!styledMode) {
|
|
1561
|
+
// Presentational attributes for the background
|
|
1562
|
+
plotBackground
|
|
1563
|
+
.attr({
|
|
1564
|
+
fill: plotBackgroundColor || 'none'
|
|
1565
|
+
})
|
|
1566
|
+
.shadow(optionsChart.plotShadow);
|
|
1567
|
+
// Create the background image
|
|
1568
|
+
if (plotBackgroundImage) {
|
|
1569
|
+
if (!plotBGImage) {
|
|
1570
|
+
chart.plotBGImage = renderer.image(plotBackgroundImage, plotLeft, plotTop, plotWidth, plotHeight).add();
|
|
1571
|
+
}
|
|
1572
|
+
else {
|
|
1573
|
+
if (plotBackgroundImage !== plotBGImage.attr('href')) {
|
|
1574
|
+
plotBGImage.attr('href', plotBackgroundImage);
|
|
1575
|
+
}
|
|
1576
|
+
plotBGImage.animate(plotBox);
|
|
1577
|
+
}
|
|
1578
|
+
}
|
|
1579
|
+
}
|
|
1580
|
+
// Plot clip
|
|
1581
|
+
if (!clipRect) {
|
|
1582
|
+
chart.clipRect = renderer.clipRect(clipBox);
|
|
1583
|
+
}
|
|
1584
|
+
else {
|
|
1585
|
+
clipRect.animate({
|
|
1586
|
+
width: clipBox.width,
|
|
1587
|
+
height: clipBox.height
|
|
1588
|
+
});
|
|
1589
|
+
}
|
|
1590
|
+
// Plot area border
|
|
1591
|
+
verb = 'animate';
|
|
1592
|
+
if (!plotBorder) {
|
|
1593
|
+
verb = 'attr';
|
|
1594
|
+
chart.plotBorder = plotBorder = renderer.rect()
|
|
1595
|
+
.addClass('highcharts-plot-border')
|
|
1596
|
+
.attr({
|
|
1597
|
+
zIndex: 1 // Above the grid
|
|
1598
|
+
})
|
|
1599
|
+
.add();
|
|
1600
|
+
}
|
|
1601
|
+
if (!styledMode) {
|
|
1602
|
+
// Presentational
|
|
1603
|
+
plotBorder.attr({
|
|
1604
|
+
stroke: optionsChart.plotBorderColor,
|
|
1605
|
+
'stroke-width': optionsChart.plotBorderWidth || 0,
|
|
1606
|
+
fill: 'none'
|
|
1607
|
+
});
|
|
1608
|
+
}
|
|
1609
|
+
plotBorder[verb](plotBorder.crisp(plotBox,
|
|
1610
|
+
// #3282 plotBorder should be negative
|
|
1611
|
+
-plotBorder.strokeWidth()));
|
|
1612
|
+
// Reset
|
|
1613
|
+
chart.isDirtyBox = false;
|
|
1614
|
+
fireEvent(this, 'afterDrawChartBox');
|
|
1615
|
+
}
|
|
1616
|
+
/**
|
|
1617
|
+
* Detect whether a certain chart property is needed based on inspecting its
|
|
1618
|
+
* options and series. This mainly applies to the chart.inverted property,
|
|
1619
|
+
* and in extensions to the chart.angular and chart.polar properties.
|
|
1620
|
+
*
|
|
1621
|
+
* @private
|
|
1622
|
+
* @function Highcharts.Chart#propFromSeries
|
|
1623
|
+
*/
|
|
1624
|
+
propFromSeries() {
|
|
1625
|
+
const chart = this, optionsChart = chart.options.chart, seriesOptions = chart.options.series;
|
|
1626
|
+
let i, klass, value;
|
|
1627
|
+
/**
|
|
1628
|
+
* The flag is set to `true` if a series of the chart is inverted.
|
|
1629
|
+
*
|
|
1630
|
+
* @name Highcharts.Chart#inverted
|
|
1631
|
+
* @type {boolean|undefined}
|
|
1632
|
+
*/
|
|
1633
|
+
['inverted', 'angular', 'polar'].forEach(function (key) {
|
|
1634
|
+
// The default series type's class
|
|
1635
|
+
klass = seriesTypes[optionsChart.type];
|
|
1636
|
+
// Get the value from available chart-wide properties
|
|
1637
|
+
value =
|
|
1638
|
+
// It is set in the options:
|
|
1639
|
+
optionsChart[key] ||
|
|
1640
|
+
// The default series class:
|
|
1641
|
+
(klass && klass.prototype[key]);
|
|
1642
|
+
// Requires it
|
|
1643
|
+
// 4. Check if any the chart's series require it
|
|
1644
|
+
i = seriesOptions?.length;
|
|
1645
|
+
while (!value && i--) {
|
|
1646
|
+
klass = seriesTypes[seriesOptions[i].type];
|
|
1647
|
+
if (klass && klass.prototype[key]) {
|
|
1648
|
+
value = true;
|
|
1649
|
+
}
|
|
1650
|
+
}
|
|
1651
|
+
// Set the chart property
|
|
1652
|
+
chart[key] = value;
|
|
1653
|
+
});
|
|
1654
|
+
}
|
|
1655
|
+
/**
|
|
1656
|
+
* Internal function to link two or more series together, based on the
|
|
1657
|
+
* `linkedTo` option. This is done from `Chart.render`, and after
|
|
1658
|
+
* `Chart.addSeries` and `Series.remove`.
|
|
1659
|
+
*
|
|
1660
|
+
* @private
|
|
1661
|
+
* @function Highcharts.Chart#linkSeries
|
|
1662
|
+
* @emits Highcharts.Chart#event:afterLinkSeries
|
|
1663
|
+
*/
|
|
1664
|
+
linkSeries(isUpdating) {
|
|
1665
|
+
const chart = this, chartSeries = chart.series;
|
|
1666
|
+
// Reset links
|
|
1667
|
+
chartSeries.forEach(function (series) {
|
|
1668
|
+
series.linkedSeries.length = 0;
|
|
1669
|
+
});
|
|
1670
|
+
// Apply new links
|
|
1671
|
+
chartSeries.forEach(function (series) {
|
|
1672
|
+
const { linkedTo } = series.options, linkedParent = isString(linkedTo) && (linkedTo === ':previous' ?
|
|
1673
|
+
chartSeries[series.index - 1] :
|
|
1674
|
+
chart.get(linkedTo));
|
|
1675
|
+
if (linkedParent &&
|
|
1676
|
+
// #3341 avoid mutual linking
|
|
1677
|
+
linkedParent.linkedParent !== series) {
|
|
1678
|
+
linkedParent.linkedSeries.push(series);
|
|
1679
|
+
/**
|
|
1680
|
+
* The parent series of the current series, if the current
|
|
1681
|
+
* series has a [linkedTo](https://api.highcharts.com/highcharts/series.line.linkedTo)
|
|
1682
|
+
* setting.
|
|
1683
|
+
*
|
|
1684
|
+
* @name Highcharts.Series#linkedParent
|
|
1685
|
+
* @type {Highcharts.Series}
|
|
1686
|
+
* @readonly
|
|
1687
|
+
*/
|
|
1688
|
+
series.linkedParent = linkedParent;
|
|
1689
|
+
if (linkedParent.enabledDataSorting) {
|
|
1690
|
+
series.setDataSortingOptions();
|
|
1691
|
+
}
|
|
1692
|
+
series.visible = (series.options.visible ??
|
|
1693
|
+
linkedParent.options.visible ??
|
|
1694
|
+
series.visible); // #3879
|
|
1695
|
+
}
|
|
1696
|
+
});
|
|
1697
|
+
fireEvent(this, 'afterLinkSeries', { isUpdating });
|
|
1698
|
+
}
|
|
1699
|
+
/**
|
|
1700
|
+
* Render series for the chart.
|
|
1701
|
+
*
|
|
1702
|
+
* @private
|
|
1703
|
+
* @function Highcharts.Chart#renderSeries
|
|
1704
|
+
*/
|
|
1705
|
+
renderSeries() {
|
|
1706
|
+
this.series.forEach(function (serie) {
|
|
1707
|
+
serie.translate();
|
|
1708
|
+
serie.render();
|
|
1709
|
+
});
|
|
1710
|
+
}
|
|
1711
|
+
/**
|
|
1712
|
+
* Render all graphics for the chart. Runs internally on initialization.
|
|
1713
|
+
*
|
|
1714
|
+
* @private
|
|
1715
|
+
* @function Highcharts.Chart#render
|
|
1716
|
+
*/
|
|
1717
|
+
render() {
|
|
1718
|
+
const chart = this, axes = chart.axes, colorAxis = chart.colorAxis, renderer = chart.renderer, axisLayoutRuns = chart.options.chart.axisLayoutRuns || 2, renderAxes = (axes) => {
|
|
1719
|
+
axes.forEach((axis) => {
|
|
1720
|
+
if (axis.visible) {
|
|
1721
|
+
axis.render();
|
|
1722
|
+
}
|
|
1723
|
+
});
|
|
1724
|
+
};
|
|
1725
|
+
let expectedSpace = 0, // Correction for X axis labels
|
|
1726
|
+
// If the plot area size has changed significantly, calculate tick
|
|
1727
|
+
// positions again
|
|
1728
|
+
redoHorizontal = true, redoVertical, run = 0;
|
|
1729
|
+
// Title
|
|
1730
|
+
chart.setTitle();
|
|
1731
|
+
// Fire an event before the margins are computed. This is where the
|
|
1732
|
+
// legend is assigned.
|
|
1733
|
+
fireEvent(chart, 'beforeMargins');
|
|
1734
|
+
// Get stacks
|
|
1735
|
+
chart.getStacks?.();
|
|
1736
|
+
// Get chart margins
|
|
1737
|
+
chart.getMargins(true);
|
|
1738
|
+
chart.setChartSize();
|
|
1739
|
+
for (const axis of axes) {
|
|
1740
|
+
const { options } = axis, { labels } = options;
|
|
1741
|
+
if (chart.hasCartesianSeries && // #20948
|
|
1742
|
+
axis.horiz &&
|
|
1743
|
+
axis.visible &&
|
|
1744
|
+
labels.enabled &&
|
|
1745
|
+
axis.series.length &&
|
|
1746
|
+
axis.coll !== 'colorAxis' &&
|
|
1747
|
+
!chart.polar) {
|
|
1748
|
+
expectedSpace = options.tickLength;
|
|
1749
|
+
axis.createGroups();
|
|
1750
|
+
// Calculate expected space based on dummy tick
|
|
1751
|
+
const mockTick = new Tick(axis, 0, '', true), label = mockTick.createLabel('x', labels);
|
|
1752
|
+
mockTick.destroy();
|
|
1753
|
+
if (label &&
|
|
1754
|
+
pick(labels.reserveSpace, !isNumber(options.crossing))) {
|
|
1755
|
+
expectedSpace = label.getBBox().height +
|
|
1756
|
+
labels.distance +
|
|
1757
|
+
Math.max(options.offset || 0, 0);
|
|
1758
|
+
}
|
|
1759
|
+
if (expectedSpace) {
|
|
1760
|
+
label?.destroy();
|
|
1761
|
+
break;
|
|
1762
|
+
}
|
|
1763
|
+
}
|
|
1764
|
+
}
|
|
1765
|
+
// Use Math.max to prevent negative plotHeight
|
|
1766
|
+
chart.plotHeight = Math.max(chart.plotHeight - expectedSpace, 0);
|
|
1767
|
+
while ((redoHorizontal || redoVertical || axisLayoutRuns > 1) &&
|
|
1768
|
+
run < axisLayoutRuns // #19794
|
|
1769
|
+
) {
|
|
1770
|
+
const tempWidth = chart.plotWidth, tempHeight = chart.plotHeight;
|
|
1771
|
+
for (const axis of axes) {
|
|
1772
|
+
if (run === 0) {
|
|
1773
|
+
// Get margins by pre-rendering axes
|
|
1774
|
+
axis.setScale();
|
|
1775
|
+
}
|
|
1776
|
+
else if ((axis.horiz && redoHorizontal) ||
|
|
1777
|
+
(!axis.horiz && redoVertical)) {
|
|
1778
|
+
// Update to reflect the new margins
|
|
1779
|
+
axis.setTickInterval(true);
|
|
1780
|
+
}
|
|
1781
|
+
}
|
|
1782
|
+
if (run === 0) {
|
|
1783
|
+
chart.getAxisMargins();
|
|
1784
|
+
}
|
|
1785
|
+
else {
|
|
1786
|
+
// Check again for new, rotated or moved labels
|
|
1787
|
+
chart.getMargins();
|
|
1788
|
+
}
|
|
1789
|
+
redoHorizontal = (tempWidth / chart.plotWidth) > (run ? 1 : 1.1);
|
|
1790
|
+
redoVertical = (tempHeight / chart.plotHeight) > (run ? 1 : 1.05);
|
|
1791
|
+
run++;
|
|
1792
|
+
}
|
|
1793
|
+
// Draw the borders and backgrounds
|
|
1794
|
+
chart.drawChartBox();
|
|
1795
|
+
// Axes
|
|
1796
|
+
if (chart.hasCartesianSeries) {
|
|
1797
|
+
renderAxes(axes);
|
|
1798
|
+
}
|
|
1799
|
+
else if (colorAxis?.length) {
|
|
1800
|
+
renderAxes(colorAxis);
|
|
1801
|
+
}
|
|
1802
|
+
// The series
|
|
1803
|
+
chart.seriesGroup || (chart.seriesGroup = renderer.g('series-group')
|
|
1804
|
+
.attr({ zIndex: 3 })
|
|
1805
|
+
.shadow(chart.options.chart.seriesGroupShadow)
|
|
1806
|
+
.add());
|
|
1807
|
+
chart.renderSeries();
|
|
1808
|
+
// Credits
|
|
1809
|
+
chart.addCredits();
|
|
1810
|
+
// Handle responsiveness
|
|
1811
|
+
if (chart.setResponsive) {
|
|
1812
|
+
chart.setResponsive();
|
|
1813
|
+
}
|
|
1814
|
+
// Set flag
|
|
1815
|
+
chart.hasRendered = true;
|
|
1816
|
+
}
|
|
1817
|
+
/**
|
|
1818
|
+
* Set a new credits label for the chart.
|
|
1819
|
+
*
|
|
1820
|
+
* @sample highcharts/credits/credits-update/
|
|
1821
|
+
* Add and update credits
|
|
1822
|
+
*
|
|
1823
|
+
* @function Highcharts.Chart#addCredits
|
|
1824
|
+
*
|
|
1825
|
+
* @param {Highcharts.CreditsOptions} [credits]
|
|
1826
|
+
* A configuration object for the new credits.
|
|
1827
|
+
*/
|
|
1828
|
+
addCredits(credits) {
|
|
1829
|
+
const chart = this, creds = merge(true, this.options.credits, credits);
|
|
1830
|
+
if (creds.enabled && !this.credits) {
|
|
1831
|
+
/**
|
|
1832
|
+
* The chart's credits label. The label has an `update` method that
|
|
1833
|
+
* allows setting new options as per the
|
|
1834
|
+
* [credits options set](https://api.highcharts.com/highcharts/credits).
|
|
1835
|
+
*
|
|
1836
|
+
* @name Highcharts.Chart#credits
|
|
1837
|
+
* @type {Highcharts.SVGElement}
|
|
1838
|
+
*/
|
|
1839
|
+
this.credits = this.renderer.text(creds.text + (this.mapCredits || ''), 0, 0)
|
|
1840
|
+
.addClass('highcharts-credits')
|
|
1841
|
+
.on('click', function () {
|
|
1842
|
+
if (creds.href) {
|
|
1843
|
+
win.location.href = creds.href;
|
|
1844
|
+
}
|
|
1845
|
+
})
|
|
1846
|
+
.attr({
|
|
1847
|
+
align: creds.position.align,
|
|
1848
|
+
zIndex: 8
|
|
1849
|
+
});
|
|
1850
|
+
if (!chart.styledMode) {
|
|
1851
|
+
this.credits.css(creds.style);
|
|
1852
|
+
}
|
|
1853
|
+
this.credits
|
|
1854
|
+
.add()
|
|
1855
|
+
.align(creds.position);
|
|
1856
|
+
// Dynamically update
|
|
1857
|
+
this.credits.update = function (options) {
|
|
1858
|
+
chart.credits = chart.credits.destroy();
|
|
1859
|
+
chart.addCredits(options);
|
|
1860
|
+
};
|
|
1861
|
+
}
|
|
1862
|
+
}
|
|
1863
|
+
/**
|
|
1864
|
+
* Remove the chart and purge memory. This method is called internally
|
|
1865
|
+
* before adding a second chart into the same container, as well as on
|
|
1866
|
+
* window unload to prevent leaks.
|
|
1867
|
+
*
|
|
1868
|
+
* @sample highcharts/members/chart-destroy/
|
|
1869
|
+
* Destroy the chart from a button
|
|
1870
|
+
* @sample stock/members/chart-destroy/
|
|
1871
|
+
* Destroy with Highcharts Stock
|
|
1872
|
+
*
|
|
1873
|
+
* @function Highcharts.Chart#destroy
|
|
1874
|
+
*
|
|
1875
|
+
* @emits Highcharts.Chart#event:destroy
|
|
1876
|
+
*/
|
|
1877
|
+
destroy() {
|
|
1878
|
+
const chart = this, axes = chart.axes, series = chart.series, container = chart.container, parentNode = container?.parentNode;
|
|
1879
|
+
let i;
|
|
1880
|
+
// Fire the chart.destroy event
|
|
1881
|
+
fireEvent(chart, 'destroy');
|
|
1882
|
+
// Delete the chart from charts lookup array
|
|
1883
|
+
if (chart.renderer.forExport) {
|
|
1884
|
+
erase(charts, chart); // #6569
|
|
1885
|
+
}
|
|
1886
|
+
else {
|
|
1887
|
+
charts[chart.index] = void 0;
|
|
1888
|
+
}
|
|
1889
|
+
H.chartCount--;
|
|
1890
|
+
chart.renderTo.removeAttribute('data-highcharts-chart');
|
|
1891
|
+
// Remove events
|
|
1892
|
+
removeEvent(chart);
|
|
1893
|
+
// ==== Destroy collections:
|
|
1894
|
+
// Destroy axes
|
|
1895
|
+
i = axes.length;
|
|
1896
|
+
while (i--) {
|
|
1897
|
+
axes[i] = axes[i].destroy();
|
|
1898
|
+
}
|
|
1899
|
+
// Destroy scroller & scroller series before destroying base series
|
|
1900
|
+
this.scroller?.destroy?.();
|
|
1901
|
+
// Destroy each series
|
|
1902
|
+
i = series.length;
|
|
1903
|
+
while (i--) {
|
|
1904
|
+
series[i] = series[i].destroy();
|
|
1905
|
+
}
|
|
1906
|
+
// ==== Destroy chart properties:
|
|
1907
|
+
[
|
|
1908
|
+
'title', 'subtitle', 'chartBackground', 'plotBackground',
|
|
1909
|
+
'plotBGImage', 'plotBorder', 'seriesGroup', 'clipRect', 'credits',
|
|
1910
|
+
'pointer', 'rangeSelector', 'legend', 'resetZoomButton', 'tooltip',
|
|
1911
|
+
'renderer'
|
|
1912
|
+
].forEach((name) => {
|
|
1913
|
+
chart[name] = chart[name]?.destroy?.();
|
|
1914
|
+
});
|
|
1915
|
+
// Remove container and all SVG, check container as it can break in IE
|
|
1916
|
+
// when destroyed before finished loading
|
|
1917
|
+
if (container) {
|
|
1918
|
+
container.innerHTML = AST.emptyHTML;
|
|
1919
|
+
removeEvent(container);
|
|
1920
|
+
if (parentNode) {
|
|
1921
|
+
discardElement(container);
|
|
1922
|
+
}
|
|
1923
|
+
}
|
|
1924
|
+
// Clean it all up
|
|
1925
|
+
objectEach(chart, function (val, key) {
|
|
1926
|
+
delete chart[key];
|
|
1927
|
+
});
|
|
1928
|
+
}
|
|
1929
|
+
/**
|
|
1930
|
+
* Prepare for first rendering after all data are loaded.
|
|
1931
|
+
*
|
|
1932
|
+
* @private
|
|
1933
|
+
* @function Highcharts.Chart#firstRender
|
|
1934
|
+
* @emits Highcharts.Chart#event:beforeRender
|
|
1935
|
+
*/
|
|
1936
|
+
firstRender() {
|
|
1937
|
+
const chart = this, options = chart.options;
|
|
1938
|
+
// Create the container
|
|
1939
|
+
chart.getContainer();
|
|
1940
|
+
chart.resetMargins();
|
|
1941
|
+
chart.setChartSize();
|
|
1942
|
+
// Set the common chart properties (mainly invert) from the given series
|
|
1943
|
+
chart.propFromSeries();
|
|
1944
|
+
// Get axes
|
|
1945
|
+
chart.createAxes();
|
|
1946
|
+
// Initialize the series
|
|
1947
|
+
const series = isArray(options.series) ? options.series : [];
|
|
1948
|
+
options.series = []; // Avoid mutation
|
|
1949
|
+
series.forEach(
|
|
1950
|
+
// #9680
|
|
1951
|
+
function (serieOptions) {
|
|
1952
|
+
chart.initSeries(serieOptions);
|
|
1953
|
+
});
|
|
1954
|
+
chart.linkSeries();
|
|
1955
|
+
chart.setSortedData();
|
|
1956
|
+
// Run an event after axes and series are initialized, but before
|
|
1957
|
+
// render. At this stage, the series data is indexed and cached in the
|
|
1958
|
+
// xData and yData arrays, so we can access those before rendering. Used
|
|
1959
|
+
// in Highcharts Stock.
|
|
1960
|
+
fireEvent(chart, 'beforeRender');
|
|
1961
|
+
chart.render();
|
|
1962
|
+
chart.pointer?.getChartPosition(); // #14973
|
|
1963
|
+
// Fire the load event if there are no external images
|
|
1964
|
+
if (!chart.renderer.imgCount && !chart.hasLoaded) {
|
|
1965
|
+
chart.onload();
|
|
1966
|
+
}
|
|
1967
|
+
// If the chart was rendered outside the top container, put it back in
|
|
1968
|
+
// (#3679)
|
|
1969
|
+
chart.temporaryDisplay(true);
|
|
1970
|
+
}
|
|
1971
|
+
/**
|
|
1972
|
+
* Internal function that runs on chart load, async if any images are loaded
|
|
1973
|
+
* in the chart. Runs the callbacks and triggers the `load` and `render`
|
|
1974
|
+
* events.
|
|
1975
|
+
*
|
|
1976
|
+
* @private
|
|
1977
|
+
* @function Highcharts.Chart#onload
|
|
1978
|
+
* @emits Highcharts.Chart#event:load
|
|
1979
|
+
* @emits Highcharts.Chart#event:render
|
|
1980
|
+
*/
|
|
1981
|
+
onload() {
|
|
1982
|
+
// Run callbacks, first the ones registered by modules, then user's one
|
|
1983
|
+
this.callbacks.concat([this.callback]).forEach(function (fn) {
|
|
1984
|
+
// Chart destroyed in its own callback (#3600)
|
|
1985
|
+
if (fn && typeof this.index !== 'undefined') {
|
|
1986
|
+
fn.apply(this, [this]);
|
|
1987
|
+
}
|
|
1988
|
+
}, this);
|
|
1989
|
+
fireEvent(this, 'load');
|
|
1990
|
+
fireEvent(this, 'render');
|
|
1991
|
+
// Set up auto resize, check for not destroyed (#6068)
|
|
1992
|
+
if (defined(this.index)) {
|
|
1993
|
+
this.setReflow();
|
|
1994
|
+
}
|
|
1995
|
+
this.warnIfA11yModuleNotLoaded();
|
|
1996
|
+
this.warnIfCSSNotLoaded();
|
|
1997
|
+
// Don't run again
|
|
1998
|
+
this.hasLoaded = true;
|
|
1999
|
+
}
|
|
2000
|
+
/**
|
|
2001
|
+
* Emit console warning if the a11y module is not loaded.
|
|
2002
|
+
* @private
|
|
2003
|
+
*/
|
|
2004
|
+
warnIfA11yModuleNotLoaded() {
|
|
2005
|
+
const { options, title } = this;
|
|
2006
|
+
if (options && !this.accessibility) {
|
|
2007
|
+
// Make chart behave as an image with the title as alt text
|
|
2008
|
+
this.renderer.boxWrapper.attr({
|
|
2009
|
+
role: 'img',
|
|
2010
|
+
'aria-label': (title?.element.textContent || ''
|
|
2011
|
+
// #17753, < is not allowed in SVG attributes
|
|
2012
|
+
).replace(/</g, '<')
|
|
2013
|
+
});
|
|
2014
|
+
if (!(options.accessibility && options.accessibility.enabled === false)) {
|
|
2015
|
+
error('Highcharts warning: Consider including the ' +
|
|
2016
|
+
'"accessibility.js" module to make your chart more ' +
|
|
2017
|
+
'usable for people with disabilities. Set the ' +
|
|
2018
|
+
'"accessibility.enabled" option to false to remove this ' +
|
|
2019
|
+
'warning. See https://www.highcharts.com/docs/accessibility/accessibility-module.', false, this);
|
|
2020
|
+
}
|
|
2021
|
+
}
|
|
2022
|
+
}
|
|
2023
|
+
/**
|
|
2024
|
+
* Emit console warning if the highcharts.css file is not loaded.
|
|
2025
|
+
* @private
|
|
2026
|
+
*/
|
|
2027
|
+
warnIfCSSNotLoaded() {
|
|
2028
|
+
if (this.styledMode) {
|
|
2029
|
+
const containerStyle = win.getComputedStyle(this.container);
|
|
2030
|
+
if (containerStyle.zIndex !== '0') {
|
|
2031
|
+
error(35, false, this);
|
|
2032
|
+
}
|
|
2033
|
+
}
|
|
2034
|
+
}
|
|
2035
|
+
/**
|
|
2036
|
+
* Add a series to the chart after render time. Note that this method should
|
|
2037
|
+
* never be used when adding data synchronously at chart render time, as it
|
|
2038
|
+
* adds expense to the calculations and rendering. When adding data at the
|
|
2039
|
+
* same time as the chart is initialized, add the series as a configuration
|
|
2040
|
+
* option instead. With multiple axes, the `offset` is dynamically adjusted.
|
|
2041
|
+
*
|
|
2042
|
+
* @sample highcharts/members/chart-addseries/
|
|
2043
|
+
* Add a series from a button
|
|
2044
|
+
* @sample stock/members/chart-addseries/
|
|
2045
|
+
* Add a series in Highcharts Stock
|
|
2046
|
+
*
|
|
2047
|
+
* @function Highcharts.Chart#addSeries
|
|
2048
|
+
*
|
|
2049
|
+
* @param {Highcharts.SeriesOptionsType} options
|
|
2050
|
+
* The config options for the series.
|
|
2051
|
+
*
|
|
2052
|
+
* @param {boolean} [redraw=true]
|
|
2053
|
+
* Whether to redraw the chart after adding.
|
|
2054
|
+
*
|
|
2055
|
+
* @param {boolean|Partial<Highcharts.AnimationOptionsObject>} [animation]
|
|
2056
|
+
* Whether to apply animation, and optionally animation
|
|
2057
|
+
* configuration. When `undefined`, it applies the animation that is
|
|
2058
|
+
* set in the `chart.animation` option.
|
|
2059
|
+
*
|
|
2060
|
+
* @return {Highcharts.Series}
|
|
2061
|
+
* The newly created series object.
|
|
2062
|
+
*
|
|
2063
|
+
* @emits Highcharts.Chart#event:addSeries
|
|
2064
|
+
* @emits Highcharts.Chart#event:afterAddSeries
|
|
2065
|
+
*/
|
|
2066
|
+
addSeries(options, redraw, animation) {
|
|
2067
|
+
const chart = this;
|
|
2068
|
+
let series;
|
|
2069
|
+
if (options) { // <- not necessary
|
|
2070
|
+
redraw = pick(redraw, true); // Defaults to true
|
|
2071
|
+
fireEvent(chart, 'addSeries', { options: options }, function () {
|
|
2072
|
+
series = chart.initSeries(options);
|
|
2073
|
+
chart.isDirtyLegend = true;
|
|
2074
|
+
chart.linkSeries();
|
|
2075
|
+
if (series.enabledDataSorting) {
|
|
2076
|
+
// We need to call `setData` after `linkSeries`
|
|
2077
|
+
series.setData(options.data, false);
|
|
2078
|
+
}
|
|
2079
|
+
fireEvent(chart, 'afterAddSeries', { series: series });
|
|
2080
|
+
if (redraw) {
|
|
2081
|
+
chart.redraw(animation);
|
|
2082
|
+
}
|
|
2083
|
+
});
|
|
2084
|
+
}
|
|
2085
|
+
return series;
|
|
2086
|
+
}
|
|
2087
|
+
/**
|
|
2088
|
+
* Add an axis to the chart after render time. Note that this method should
|
|
2089
|
+
* never be used when adding data synchronously at chart render time, as it
|
|
2090
|
+
* adds expense to the calculations and rendering. When adding data at the
|
|
2091
|
+
* same time as the chart is initialized, add the axis as a configuration
|
|
2092
|
+
* option instead.
|
|
2093
|
+
*
|
|
2094
|
+
* @sample highcharts/members/chart-addaxis/
|
|
2095
|
+
* Add and remove axes
|
|
2096
|
+
*
|
|
2097
|
+
* @function Highcharts.Chart#addAxis
|
|
2098
|
+
*
|
|
2099
|
+
* @param {Highcharts.AxisOptions} options
|
|
2100
|
+
* The axis options.
|
|
2101
|
+
*
|
|
2102
|
+
* @param {boolean} [isX=false]
|
|
2103
|
+
* Whether it is an X axis or a value axis.
|
|
2104
|
+
*
|
|
2105
|
+
* @param {boolean} [redraw=true]
|
|
2106
|
+
* Whether to redraw the chart after adding.
|
|
2107
|
+
*
|
|
2108
|
+
* @param {boolean|Partial<Highcharts.AnimationOptionsObject>} [animation]
|
|
2109
|
+
* Whether and how to apply animation in the redraw. When
|
|
2110
|
+
* `undefined`, it applies the animation that is set in the
|
|
2111
|
+
* `chart.animation` option.
|
|
2112
|
+
*
|
|
2113
|
+
* @return {Highcharts.Axis}
|
|
2114
|
+
* The newly generated Axis object.
|
|
2115
|
+
*/
|
|
2116
|
+
addAxis(options, isX, redraw, animation) {
|
|
2117
|
+
return this.createAxis(isX ? 'xAxis' : 'yAxis', { axis: options, redraw: redraw, animation: animation });
|
|
2118
|
+
}
|
|
2119
|
+
/**
|
|
2120
|
+
* Add a color axis to the chart after render time. Note that this method
|
|
2121
|
+
* should never be used when adding data synchronously at chart render time,
|
|
2122
|
+
* as it adds expense to the calculations and rendering. When adding data at
|
|
2123
|
+
* the same time as the chart is initialized, add the axis as a
|
|
2124
|
+
* configuration option instead.
|
|
2125
|
+
*
|
|
2126
|
+
* @sample highcharts/members/chart-addaxis/
|
|
2127
|
+
* Add and remove axes
|
|
2128
|
+
*
|
|
2129
|
+
* @function Highcharts.Chart#addColorAxis
|
|
2130
|
+
*
|
|
2131
|
+
* @param {Highcharts.ColorAxisOptions} options
|
|
2132
|
+
* The axis options.
|
|
2133
|
+
*
|
|
2134
|
+
* @param {boolean} [redraw=true]
|
|
2135
|
+
* Whether to redraw the chart after adding.
|
|
2136
|
+
*
|
|
2137
|
+
* @param {boolean|Partial<Highcharts.AnimationOptionsObject>} [animation]
|
|
2138
|
+
* Whether and how to apply animation in the redraw. When
|
|
2139
|
+
* `undefined`, it applies the animation that is set in the
|
|
2140
|
+
* `chart.animation` option.
|
|
2141
|
+
*
|
|
2142
|
+
* @return {Highcharts.Axis}
|
|
2143
|
+
* The newly generated Axis object.
|
|
2144
|
+
*/
|
|
2145
|
+
addColorAxis(options, redraw, animation) {
|
|
2146
|
+
return this.createAxis('colorAxis', { axis: options, redraw: redraw, animation: animation });
|
|
2147
|
+
}
|
|
2148
|
+
/**
|
|
2149
|
+
* Factory for creating different axis types.
|
|
2150
|
+
*
|
|
2151
|
+
* @private
|
|
2152
|
+
* @function Highcharts.Chart#createAxis
|
|
2153
|
+
*
|
|
2154
|
+
* @param {string} coll
|
|
2155
|
+
* An axis type.
|
|
2156
|
+
*
|
|
2157
|
+
* @param {...Array<*>} arguments
|
|
2158
|
+
* All arguments for the constructor.
|
|
2159
|
+
*
|
|
2160
|
+
* @return {Highcharts.Axis}
|
|
2161
|
+
* The newly generated Axis object.
|
|
2162
|
+
*/
|
|
2163
|
+
createAxis(coll, options) {
|
|
2164
|
+
const axis = new Axis(this, options.axis, coll);
|
|
2165
|
+
if (pick(options.redraw, true)) {
|
|
2166
|
+
this.redraw(options.animation);
|
|
2167
|
+
}
|
|
2168
|
+
return axis;
|
|
2169
|
+
}
|
|
2170
|
+
/**
|
|
2171
|
+
* Dim the chart and show a loading text or symbol. Options for the loading
|
|
2172
|
+
* screen are defined in {@link
|
|
2173
|
+
* https://api.highcharts.com/highcharts/loading|the loading options}.
|
|
2174
|
+
*
|
|
2175
|
+
* @sample highcharts/members/chart-hideloading/
|
|
2176
|
+
* Show and hide loading from a button
|
|
2177
|
+
* @sample highcharts/members/chart-showloading/
|
|
2178
|
+
* Apply different text labels
|
|
2179
|
+
* @sample stock/members/chart-show-hide-loading/
|
|
2180
|
+
* Toggle loading in Highcharts Stock
|
|
2181
|
+
*
|
|
2182
|
+
* @function Highcharts.Chart#showLoading
|
|
2183
|
+
*
|
|
2184
|
+
* @param {string} [str]
|
|
2185
|
+
* An optional text to show in the loading label instead of the
|
|
2186
|
+
* default one. The default text is set in
|
|
2187
|
+
* [lang.loading](https://api.highcharts.com/highcharts/lang.loading).
|
|
2188
|
+
*/
|
|
2189
|
+
showLoading(str) {
|
|
2190
|
+
const chart = this, options = chart.options, loadingOptions = options.loading, setLoadingSize = function () {
|
|
2191
|
+
if (loadingDiv) {
|
|
2192
|
+
css(loadingDiv, {
|
|
2193
|
+
left: chart.plotLeft + 'px',
|
|
2194
|
+
top: chart.plotTop + 'px',
|
|
2195
|
+
width: chart.plotWidth + 'px',
|
|
2196
|
+
height: chart.plotHeight + 'px'
|
|
2197
|
+
});
|
|
2198
|
+
}
|
|
2199
|
+
};
|
|
2200
|
+
let loadingDiv = chart.loadingDiv, loadingSpan = chart.loadingSpan;
|
|
2201
|
+
// Create the layer at the first call
|
|
2202
|
+
if (!loadingDiv) {
|
|
2203
|
+
chart.loadingDiv = loadingDiv = createElement('div', {
|
|
2204
|
+
className: 'highcharts-loading highcharts-loading-hidden'
|
|
2205
|
+
}, null, chart.container);
|
|
2206
|
+
}
|
|
2207
|
+
if (!loadingSpan) {
|
|
2208
|
+
chart.loadingSpan = loadingSpan = createElement('span', { className: 'highcharts-loading-inner' }, null, loadingDiv);
|
|
2209
|
+
addEvent(chart, 'redraw', setLoadingSize); // #1080
|
|
2210
|
+
}
|
|
2211
|
+
loadingDiv.className = 'highcharts-loading';
|
|
2212
|
+
// Update text
|
|
2213
|
+
AST.setElementHTML(loadingSpan, pick(str, options.lang.loading, ''));
|
|
2214
|
+
if (!chart.styledMode) {
|
|
2215
|
+
// Update visuals
|
|
2216
|
+
css(loadingDiv, extend(loadingOptions.style, {
|
|
2217
|
+
zIndex: 10
|
|
2218
|
+
}));
|
|
2219
|
+
css(loadingSpan, loadingOptions.labelStyle);
|
|
2220
|
+
// Show it
|
|
2221
|
+
if (!chart.loadingShown) {
|
|
2222
|
+
css(loadingDiv, {
|
|
2223
|
+
opacity: 0,
|
|
2224
|
+
display: ''
|
|
2225
|
+
});
|
|
2226
|
+
animate(loadingDiv, {
|
|
2227
|
+
opacity: loadingOptions.style.opacity || 0.5
|
|
2228
|
+
}, {
|
|
2229
|
+
duration: loadingOptions.showDuration || 0
|
|
2230
|
+
});
|
|
2231
|
+
}
|
|
2232
|
+
}
|
|
2233
|
+
chart.loadingShown = true;
|
|
2234
|
+
setLoadingSize();
|
|
2235
|
+
}
|
|
2236
|
+
/**
|
|
2237
|
+
* Hide the loading layer.
|
|
2238
|
+
*
|
|
2239
|
+
* @see Highcharts.Chart#showLoading
|
|
2240
|
+
*
|
|
2241
|
+
* @sample highcharts/members/chart-hideloading/
|
|
2242
|
+
* Show and hide loading from a button
|
|
2243
|
+
* @sample stock/members/chart-show-hide-loading/
|
|
2244
|
+
* Toggle loading in Highcharts Stock
|
|
2245
|
+
*
|
|
2246
|
+
* @function Highcharts.Chart#hideLoading
|
|
2247
|
+
*/
|
|
2248
|
+
hideLoading() {
|
|
2249
|
+
const options = this.options, loadingDiv = this.loadingDiv;
|
|
2250
|
+
if (loadingDiv) {
|
|
2251
|
+
loadingDiv.className =
|
|
2252
|
+
'highcharts-loading highcharts-loading-hidden';
|
|
2253
|
+
if (!this.styledMode) {
|
|
2254
|
+
animate(loadingDiv, {
|
|
2255
|
+
opacity: 0
|
|
2256
|
+
}, {
|
|
2257
|
+
duration: options.loading.hideDuration || 100,
|
|
2258
|
+
complete: function () {
|
|
2259
|
+
css(loadingDiv, { display: 'none' });
|
|
2260
|
+
}
|
|
2261
|
+
});
|
|
2262
|
+
}
|
|
2263
|
+
}
|
|
2264
|
+
this.loadingShown = false;
|
|
2265
|
+
}
|
|
2266
|
+
/**
|
|
2267
|
+
* A generic function to update any element of the chart. Elements can be
|
|
2268
|
+
* enabled and disabled, moved, re-styled, re-formatted etc.
|
|
2269
|
+
*
|
|
2270
|
+
* A special case is configuration objects that take arrays, for example
|
|
2271
|
+
* [xAxis](https://api.highcharts.com/highcharts/xAxis),
|
|
2272
|
+
* [yAxis](https://api.highcharts.com/highcharts/yAxis) or
|
|
2273
|
+
* [series](https://api.highcharts.com/highcharts/series). For these
|
|
2274
|
+
* collections, an `id` option is used to map the new option set to an
|
|
2275
|
+
* existing object. If an existing object of the same id is not found, the
|
|
2276
|
+
* corresponding item is updated. So for example, running `chart.update`
|
|
2277
|
+
* with a series item without an id, will cause the existing chart's series
|
|
2278
|
+
* with the same index in the series array to be updated. When the
|
|
2279
|
+
* `oneToOne` parameter is true, `chart.update` will also take care of
|
|
2280
|
+
* adding and removing items from the collection. Read more under the
|
|
2281
|
+
* parameter description below.
|
|
2282
|
+
*
|
|
2283
|
+
* Note that when changing series data, `chart.update` may mutate the passed
|
|
2284
|
+
* data options.
|
|
2285
|
+
*
|
|
2286
|
+
* See also the
|
|
2287
|
+
* [responsive option set](https://api.highcharts.com/highcharts/responsive).
|
|
2288
|
+
* Switching between `responsive.rules` basically runs `chart.update` under
|
|
2289
|
+
* the hood.
|
|
2290
|
+
*
|
|
2291
|
+
* @sample highcharts/members/chart-update/
|
|
2292
|
+
* Update chart geometry
|
|
2293
|
+
*
|
|
2294
|
+
* @function Highcharts.Chart#update
|
|
2295
|
+
*
|
|
2296
|
+
* @param {Highcharts.Options} options
|
|
2297
|
+
* A configuration object for the new chart options.
|
|
2298
|
+
*
|
|
2299
|
+
* @param {boolean} [redraw=true]
|
|
2300
|
+
* Whether to redraw the chart.
|
|
2301
|
+
*
|
|
2302
|
+
* @param {boolean} [oneToOne=false]
|
|
2303
|
+
* When `true`, the `series`, `xAxis`, `yAxis` and `annotations`
|
|
2304
|
+
* collections will be updated one to one, and items will be either
|
|
2305
|
+
* added or removed to match the new updated options. For example,
|
|
2306
|
+
* if the chart has two series and we call `chart.update` with a
|
|
2307
|
+
* configuration containing three series, one will be added. If we
|
|
2308
|
+
* call `chart.update` with one series, one will be removed. Setting
|
|
2309
|
+
* an empty `series` array will remove all series, but leaving out
|
|
2310
|
+
* the`series` property will leave all series untouched. If the
|
|
2311
|
+
* series have id's, the new series options will be matched by id,
|
|
2312
|
+
* and the remaining ones removed.
|
|
2313
|
+
*
|
|
2314
|
+
* @param {boolean|Partial<Highcharts.AnimationOptionsObject>} [animation]
|
|
2315
|
+
* Whether to apply animation, and optionally animation
|
|
2316
|
+
* configuration. When `undefined`, it applies the animation that is
|
|
2317
|
+
* set in the `chart.animation` option.
|
|
2318
|
+
*
|
|
2319
|
+
* @emits Highcharts.Chart#event:update
|
|
2320
|
+
* @emits Highcharts.Chart#event:afterUpdate
|
|
2321
|
+
*/
|
|
2322
|
+
update(options, redraw, oneToOne, animation) {
|
|
2323
|
+
const chart = this, adders = {
|
|
2324
|
+
credits: 'addCredits',
|
|
2325
|
+
title: 'setTitle',
|
|
2326
|
+
subtitle: 'setSubtitle',
|
|
2327
|
+
caption: 'setCaption'
|
|
2328
|
+
}, isResponsiveOptions = options.isResponsiveOptions, itemsForRemoval = [];
|
|
2329
|
+
let updateAllAxes, updateAllSeries, runSetSize;
|
|
2330
|
+
fireEvent(chart, 'update', { options: options });
|
|
2331
|
+
// If there are responsive rules in action, undo the responsive rules
|
|
2332
|
+
// before we apply the updated options and replay the responsive rules
|
|
2333
|
+
// on top from the chart.redraw function (#9617).
|
|
2334
|
+
if (!isResponsiveOptions) {
|
|
2335
|
+
chart.setResponsive(false, true);
|
|
2336
|
+
}
|
|
2337
|
+
options = diffObjects(options, chart.options);
|
|
2338
|
+
chart.userOptions = merge(chart.userOptions, options);
|
|
2339
|
+
// If the top-level chart option is present, some special updates are
|
|
2340
|
+
// required
|
|
2341
|
+
const optionsChart = options.chart;
|
|
2342
|
+
if (optionsChart) {
|
|
2343
|
+
merge(true, chart.options.chart, optionsChart);
|
|
2344
|
+
// Add support for deprecated zooming options like zoomType, #17861
|
|
2345
|
+
this.setZoomOptions();
|
|
2346
|
+
// Setter function
|
|
2347
|
+
if ('className' in optionsChart) {
|
|
2348
|
+
chart.setClassName(optionsChart.className);
|
|
2349
|
+
}
|
|
2350
|
+
if ('inverted' in optionsChart ||
|
|
2351
|
+
'polar' in optionsChart ||
|
|
2352
|
+
'type' in optionsChart) {
|
|
2353
|
+
// Parse options.chart.inverted and options.chart.polar together
|
|
2354
|
+
// with the available series.
|
|
2355
|
+
chart.propFromSeries();
|
|
2356
|
+
updateAllAxes = true;
|
|
2357
|
+
}
|
|
2358
|
+
if ('alignTicks' in optionsChart) { // #6452
|
|
2359
|
+
updateAllAxes = true;
|
|
2360
|
+
}
|
|
2361
|
+
if ('events' in optionsChart) {
|
|
2362
|
+
// Chart event handlers
|
|
2363
|
+
registerEventOptions(this, optionsChart);
|
|
2364
|
+
}
|
|
2365
|
+
objectEach(optionsChart, function (val, key) {
|
|
2366
|
+
if (chart.propsRequireUpdateSeries.indexOf('chart.' + key) !==
|
|
2367
|
+
-1) {
|
|
2368
|
+
updateAllSeries = true;
|
|
2369
|
+
}
|
|
2370
|
+
// Only dirty box
|
|
2371
|
+
if (chart.propsRequireDirtyBox.indexOf(key) !== -1) {
|
|
2372
|
+
chart.isDirtyBox = true;
|
|
2373
|
+
}
|
|
2374
|
+
// Chart setSize
|
|
2375
|
+
if (chart.propsRequireReflow.indexOf(key) !== -1) {
|
|
2376
|
+
chart.isDirtyBox = true;
|
|
2377
|
+
if (!isResponsiveOptions) {
|
|
2378
|
+
runSetSize = true;
|
|
2379
|
+
}
|
|
2380
|
+
}
|
|
2381
|
+
});
|
|
2382
|
+
if (!chart.styledMode && optionsChart.style) {
|
|
2383
|
+
chart.renderer.setStyle(chart.options.chart.style || {});
|
|
2384
|
+
}
|
|
2385
|
+
}
|
|
2386
|
+
// Moved up, because tooltip needs updated plotOptions (#6218)
|
|
2387
|
+
if (!chart.styledMode && options.colors) {
|
|
2388
|
+
this.options.colors = options.colors;
|
|
2389
|
+
}
|
|
2390
|
+
// Some option structures correspond one-to-one to chart objects that
|
|
2391
|
+
// have update methods, for example
|
|
2392
|
+
// options.credits => chart.credits
|
|
2393
|
+
// options.legend => chart.legend
|
|
2394
|
+
// options.title => chart.title
|
|
2395
|
+
// options.tooltip => chart.tooltip
|
|
2396
|
+
// options.subtitle => chart.subtitle
|
|
2397
|
+
// options.mapNavigation => chart.mapNavigation
|
|
2398
|
+
// options.navigator => chart.navigator
|
|
2399
|
+
// options.scrollbar => chart.scrollbar
|
|
2400
|
+
objectEach(options, function (val, key) {
|
|
2401
|
+
if (chart[key] &&
|
|
2402
|
+
typeof chart[key].update === 'function') {
|
|
2403
|
+
chart[key].update(val, false);
|
|
2404
|
+
// If a one-to-one object does not exist, look for an adder function
|
|
2405
|
+
}
|
|
2406
|
+
else if (typeof chart[adders[key]] === 'function') {
|
|
2407
|
+
chart[adders[key]](val);
|
|
2408
|
+
// Else, just merge the options. For nodes like loading, noData,
|
|
2409
|
+
// plotOptions
|
|
2410
|
+
}
|
|
2411
|
+
else if (key !== 'colors' &&
|
|
2412
|
+
chart.collectionsWithUpdate.indexOf(key) === -1) {
|
|
2413
|
+
merge(true, chart.options[key], options[key]);
|
|
2414
|
+
}
|
|
2415
|
+
if (key !== 'chart' &&
|
|
2416
|
+
chart.propsRequireUpdateSeries.indexOf(key) !== -1) {
|
|
2417
|
+
updateAllSeries = true;
|
|
2418
|
+
}
|
|
2419
|
+
});
|
|
2420
|
+
// Setters for collections. For axes and series, each item is referred
|
|
2421
|
+
// by an id. If the id is not found, it defaults to the corresponding
|
|
2422
|
+
// item in the collection, so setting one series without an id, will
|
|
2423
|
+
// update the first series in the chart. Setting two series without
|
|
2424
|
+
// an id will update the first and the second respectively (#6019)
|
|
2425
|
+
// chart.update and responsive.
|
|
2426
|
+
this.collectionsWithUpdate.forEach(function (coll) {
|
|
2427
|
+
if (options[coll]) {
|
|
2428
|
+
splat(options[coll]).forEach(function (newOptions, i) {
|
|
2429
|
+
const hasId = defined(newOptions.id);
|
|
2430
|
+
let item;
|
|
2431
|
+
// Match by id
|
|
2432
|
+
if (hasId) {
|
|
2433
|
+
item = chart.get(newOptions.id);
|
|
2434
|
+
}
|
|
2435
|
+
// No match by id found, match by index instead
|
|
2436
|
+
if (!item && chart[coll]) {
|
|
2437
|
+
item = chart[coll][pick(newOptions.index, i)];
|
|
2438
|
+
// Check if we grabbed an item with an existing but
|
|
2439
|
+
// different id (#13541). Check that the item in this
|
|
2440
|
+
// position is not internal (navigator).
|
|
2441
|
+
if (item && ((hasId && defined(item.options.id)) ||
|
|
2442
|
+
item.options.isInternal)) {
|
|
2443
|
+
item = void 0;
|
|
2444
|
+
}
|
|
2445
|
+
}
|
|
2446
|
+
if (item && item.coll === coll) {
|
|
2447
|
+
item.update(newOptions, false);
|
|
2448
|
+
if (oneToOne) {
|
|
2449
|
+
item.touched = true;
|
|
2450
|
+
}
|
|
2451
|
+
}
|
|
2452
|
+
// If oneToOne and no matching item is found, add one
|
|
2453
|
+
if (!item && oneToOne && chart.collectionsWithInit[coll]) {
|
|
2454
|
+
chart.collectionsWithInit[coll][0].apply(chart,
|
|
2455
|
+
// [newOptions, ...extraArguments, redraw=false]
|
|
2456
|
+
[
|
|
2457
|
+
newOptions
|
|
2458
|
+
].concat(
|
|
2459
|
+
// Not all initializers require extra args
|
|
2460
|
+
chart.collectionsWithInit[coll][1] || []).concat([
|
|
2461
|
+
false
|
|
2462
|
+
])).touched = true;
|
|
2463
|
+
}
|
|
2464
|
+
});
|
|
2465
|
+
// Add items for removal
|
|
2466
|
+
if (oneToOne) {
|
|
2467
|
+
chart[coll].forEach(function (item) {
|
|
2468
|
+
if (!item.touched && !item.options.isInternal) {
|
|
2469
|
+
itemsForRemoval.push(item);
|
|
2470
|
+
}
|
|
2471
|
+
else {
|
|
2472
|
+
delete item.touched;
|
|
2473
|
+
}
|
|
2474
|
+
});
|
|
2475
|
+
}
|
|
2476
|
+
}
|
|
2477
|
+
});
|
|
2478
|
+
itemsForRemoval.forEach(function (item) {
|
|
2479
|
+
if (item.chart && item.remove) { // #9097, avoid removing twice
|
|
2480
|
+
item.remove(false);
|
|
2481
|
+
}
|
|
2482
|
+
});
|
|
2483
|
+
if (updateAllAxes) {
|
|
2484
|
+
chart.axes.forEach(function (axis) {
|
|
2485
|
+
axis.update({}, false);
|
|
2486
|
+
});
|
|
2487
|
+
}
|
|
2488
|
+
// Certain options require the whole series structure to be thrown away
|
|
2489
|
+
// and rebuilt
|
|
2490
|
+
if (updateAllSeries) {
|
|
2491
|
+
chart.getSeriesOrderByLinks().forEach(function (series) {
|
|
2492
|
+
// Avoid removed navigator series
|
|
2493
|
+
if (series.chart) {
|
|
2494
|
+
series.update({}, false);
|
|
2495
|
+
}
|
|
2496
|
+
}, this);
|
|
2497
|
+
}
|
|
2498
|
+
// Update size. Redraw is forced.
|
|
2499
|
+
const newWidth = optionsChart?.width;
|
|
2500
|
+
const newHeight = optionsChart && (isString(optionsChart.height) ?
|
|
2501
|
+
relativeLength(optionsChart.height, newWidth || chart.chartWidth) :
|
|
2502
|
+
optionsChart.height);
|
|
2503
|
+
if (
|
|
2504
|
+
// In this case, run chart.setSize with newWidth and newHeight which
|
|
2505
|
+
// are undefined, only for reflowing chart elements because margin
|
|
2506
|
+
// or spacing has been set (#8190)
|
|
2507
|
+
runSetSize ||
|
|
2508
|
+
// In this case, the size is actually set
|
|
2509
|
+
(isNumber(newWidth) && newWidth !== chart.chartWidth) ||
|
|
2510
|
+
(isNumber(newHeight) && newHeight !== chart.chartHeight)) {
|
|
2511
|
+
chart.setSize(newWidth, newHeight, animation);
|
|
2512
|
+
}
|
|
2513
|
+
else if (pick(redraw, true)) {
|
|
2514
|
+
chart.redraw(animation);
|
|
2515
|
+
}
|
|
2516
|
+
fireEvent(chart, 'afterUpdate', {
|
|
2517
|
+
options: options,
|
|
2518
|
+
redraw: redraw,
|
|
2519
|
+
animation: animation
|
|
2520
|
+
});
|
|
2521
|
+
}
|
|
2522
|
+
/**
|
|
2523
|
+
* Shortcut to set the subtitle options. This can also be done from {@link
|
|
2524
|
+
* Chart#update} or {@link Chart#setTitle}.
|
|
2525
|
+
*
|
|
2526
|
+
* @function Highcharts.Chart#setSubtitle
|
|
2527
|
+
*
|
|
2528
|
+
* @param {Highcharts.SubtitleOptions} options
|
|
2529
|
+
* New subtitle options. The subtitle text itself is set by the
|
|
2530
|
+
* `options.text` property.
|
|
2531
|
+
*/
|
|
2532
|
+
setSubtitle(options, redraw) {
|
|
2533
|
+
this.applyDescription('subtitle', options);
|
|
2534
|
+
this.layOutTitles(redraw);
|
|
2535
|
+
}
|
|
2536
|
+
/**
|
|
2537
|
+
* Set the caption options. This can also be done from {@link
|
|
2538
|
+
* Chart#update}.
|
|
2539
|
+
*
|
|
2540
|
+
* @function Highcharts.Chart#setCaption
|
|
2541
|
+
*
|
|
2542
|
+
* @param {Highcharts.CaptionOptions} options
|
|
2543
|
+
* New caption options. The caption text itself is set by the
|
|
2544
|
+
* `options.text` property.
|
|
2545
|
+
*/
|
|
2546
|
+
setCaption(options, redraw) {
|
|
2547
|
+
this.applyDescription('caption', options);
|
|
2548
|
+
this.layOutTitles(redraw);
|
|
2549
|
+
}
|
|
2550
|
+
/**
|
|
2551
|
+
* Display the zoom button, so users can reset zoom to the default view
|
|
2552
|
+
* settings.
|
|
2553
|
+
*
|
|
2554
|
+
* @function Highcharts.Chart#showResetZoom
|
|
2555
|
+
*
|
|
2556
|
+
* @emits Highcharts.Chart#event:afterShowResetZoom
|
|
2557
|
+
* @emits Highcharts.Chart#event:beforeShowResetZoom
|
|
2558
|
+
*/
|
|
2559
|
+
showResetZoom() {
|
|
2560
|
+
const chart = this, lang = defaultOptions.lang, btnOptions = chart.zooming.resetButton, theme = btnOptions.theme, alignTo = (btnOptions.relativeTo === 'chart' ||
|
|
2561
|
+
btnOptions.relativeTo === 'spacingBox' ?
|
|
2562
|
+
null :
|
|
2563
|
+
'plotBox');
|
|
2564
|
+
/**
|
|
2565
|
+
* @private
|
|
2566
|
+
*/
|
|
2567
|
+
function zoomOut() {
|
|
2568
|
+
chart.zoomOut();
|
|
2569
|
+
}
|
|
2570
|
+
fireEvent(this, 'beforeShowResetZoom', null, function () {
|
|
2571
|
+
chart.resetZoomButton = chart.renderer
|
|
2572
|
+
.button(lang.resetZoom, null, null, zoomOut, theme)
|
|
2573
|
+
.attr({
|
|
2574
|
+
align: btnOptions.position.align,
|
|
2575
|
+
title: lang.resetZoomTitle
|
|
2576
|
+
})
|
|
2577
|
+
.addClass('highcharts-reset-zoom')
|
|
2578
|
+
.add()
|
|
2579
|
+
.align(btnOptions.position, false, alignTo);
|
|
2580
|
+
});
|
|
2581
|
+
fireEvent(this, 'afterShowResetZoom');
|
|
2582
|
+
}
|
|
2583
|
+
/**
|
|
2584
|
+
* Zoom the chart out after a user has zoomed in. See also
|
|
2585
|
+
* [Axis.setExtremes](/class-reference/Highcharts.Axis#setExtremes).
|
|
2586
|
+
*
|
|
2587
|
+
* @function Highcharts.Chart#zoomOut
|
|
2588
|
+
*
|
|
2589
|
+
* @emits Highcharts.Chart#event:selection
|
|
2590
|
+
*/
|
|
2591
|
+
zoomOut() {
|
|
2592
|
+
fireEvent(this, 'selection', { resetSelection: true }, () => this.transform({ reset: true, trigger: 'zoom' }));
|
|
2593
|
+
}
|
|
2594
|
+
/**
|
|
2595
|
+
* Pan the chart by dragging the mouse across the pane. This function is
|
|
2596
|
+
* called on mouse move, and the distance to pan is computed from chartX
|
|
2597
|
+
* compared to the first chartX position in the dragging operation.
|
|
2598
|
+
*
|
|
2599
|
+
* @private
|
|
2600
|
+
* @function Highcharts.Chart#pan
|
|
2601
|
+
* @param {Highcharts.PointerEventObject} event
|
|
2602
|
+
* @param {string} panning
|
|
2603
|
+
*/
|
|
2604
|
+
pan(event, panning) {
|
|
2605
|
+
const chart = this, panningOptions = (typeof panning === 'object' ?
|
|
2606
|
+
panning :
|
|
2607
|
+
{
|
|
2608
|
+
enabled: panning,
|
|
2609
|
+
type: 'x'
|
|
2610
|
+
}), type = panningOptions.type, axes = type && chart[{
|
|
2611
|
+
x: 'xAxis',
|
|
2612
|
+
xy: 'axes',
|
|
2613
|
+
y: 'yAxis'
|
|
2614
|
+
}[type]]
|
|
2615
|
+
.filter((axis) => axis.options.panningEnabled && !axis.options.isInternal), chartOptions = chart.options.chart;
|
|
2616
|
+
if (chartOptions?.panning) {
|
|
2617
|
+
chartOptions.panning = panningOptions;
|
|
2618
|
+
}
|
|
2619
|
+
fireEvent(this, 'pan', { originalEvent: event }, () => {
|
|
2620
|
+
chart.transform({
|
|
2621
|
+
axes,
|
|
2622
|
+
event,
|
|
2623
|
+
to: {
|
|
2624
|
+
x: event.chartX - (chart.mouseDownX || 0),
|
|
2625
|
+
y: event.chartY - (chart.mouseDownY || 0)
|
|
2626
|
+
},
|
|
2627
|
+
trigger: 'pan'
|
|
2628
|
+
});
|
|
2629
|
+
css(chart.container, { cursor: 'move' });
|
|
2630
|
+
});
|
|
2631
|
+
}
|
|
2632
|
+
/**
|
|
2633
|
+
* Pan and scale the chart. Used internally by mouse-pan, touch-pan,
|
|
2634
|
+
* touch-zoom, and mousewheel zoom.
|
|
2635
|
+
*
|
|
2636
|
+
* The main positioning logic is created around two imaginary boxes. What is
|
|
2637
|
+
* currently within the `from` rectangle, should be transformed to fill up
|
|
2638
|
+
* the `to` rectangle.
|
|
2639
|
+
* - In a mouse zoom, the `from` rectangle is the selection, while the `to`
|
|
2640
|
+
* rectangle is the full plot area.
|
|
2641
|
+
* - In a touch zoom, the `from` rectangle is made up of the last two-finger
|
|
2642
|
+
* touch, while the `to`` rectangle is the current touch.
|
|
2643
|
+
* - In a mousewheel zoom, the `to` rectangle is a 10x10 px square,
|
|
2644
|
+
* while the `to` rectangle reflects the scale around that.
|
|
2645
|
+
*
|
|
2646
|
+
* @private
|
|
2647
|
+
* @function Highcharts.Chart#transform
|
|
2648
|
+
*/
|
|
2649
|
+
transform(params) {
|
|
2650
|
+
const { axes = this.axes, event, from = {}, reset, selection, to = {}, trigger, allowResetButton = true } = params, { inverted, time } = this;
|
|
2651
|
+
// Remove active points for shared tooltip
|
|
2652
|
+
this.hoverPoints?.forEach((point) => point.setState());
|
|
2653
|
+
fireEvent(this, 'transform', params);
|
|
2654
|
+
let hasZoomed = params.hasZoomed || false, displayButton, isAnyAxisPanning;
|
|
2655
|
+
for (const axis of axes) {
|
|
2656
|
+
const { horiz, len, minPointOffset = 0, options, reversed } = axis, wh = horiz ? 'width' : 'height', xy = horiz ? 'x' : 'y', toLength = pick(to[wh], axis.len), fromLength = pick(from[wh], axis.len),
|
|
2657
|
+
// If fingers pinched very close on this axis, treat as pan
|
|
2658
|
+
scale = Math.abs(toLength) < 10 ?
|
|
2659
|
+
1 :
|
|
2660
|
+
toLength / fromLength, fromCenter = (from[xy] || 0) + fromLength / 2 - axis.pos, toCenter = (to[xy] ?? axis.pos) +
|
|
2661
|
+
toLength / 2 - axis.pos, move = fromCenter - toCenter / scale, pointRangeDirection = (reversed && !inverted) ||
|
|
2662
|
+
(!reversed && inverted) ?
|
|
2663
|
+
-1 :
|
|
2664
|
+
1, minPx = move;
|
|
2665
|
+
// Zooming in multiple panes, zoom only in the pane that receives
|
|
2666
|
+
// the input
|
|
2667
|
+
if (!reset && (fromCenter < 0 || fromCenter > axis.len)) {
|
|
2668
|
+
continue;
|
|
2669
|
+
}
|
|
2670
|
+
// Adjust offset to ensure selection zoom triggers correctly
|
|
2671
|
+
// (#22945)
|
|
2672
|
+
const offset = (axis.chart.polar || axis.isOrdinal) ?
|
|
2673
|
+
0 :
|
|
2674
|
+
(minPointOffset * pointRangeDirection || 0), eventMin = axis.toValue(minPx, true), eventMax = axis.toValue(minPx + len / scale, true);
|
|
2675
|
+
let newMin = eventMin + offset, newMax = eventMax - offset, allExtremes = axis.allExtremes;
|
|
2676
|
+
if (selection) {
|
|
2677
|
+
selection[axis.coll].push({
|
|
2678
|
+
axis,
|
|
2679
|
+
min: Math.min(eventMin, eventMax),
|
|
2680
|
+
max: Math.max(eventMin, eventMax)
|
|
2681
|
+
});
|
|
2682
|
+
}
|
|
2683
|
+
if (newMin > newMax) {
|
|
2684
|
+
[newMin, newMax] = [newMax, newMin];
|
|
2685
|
+
}
|
|
2686
|
+
// General calculations of the full data extremes. It is calculated
|
|
2687
|
+
// on the first call to transform, then reused for subsequent
|
|
2688
|
+
// touch/pan calls. (#11315).
|
|
2689
|
+
if (scale === 1 &&
|
|
2690
|
+
!reset &&
|
|
2691
|
+
axis.coll === 'yAxis' &&
|
|
2692
|
+
!allExtremes) {
|
|
2693
|
+
for (const series of axis.series) {
|
|
2694
|
+
const seriesExtremes = series.getExtremes(series.getProcessedData(true).modified
|
|
2695
|
+
.getColumn('y') || [], true);
|
|
2696
|
+
allExtremes ?? (allExtremes = {
|
|
2697
|
+
dataMin: Number.MAX_VALUE,
|
|
2698
|
+
dataMax: -Number.MAX_VALUE
|
|
2699
|
+
});
|
|
2700
|
+
if (isNumber(seriesExtremes.dataMin) &&
|
|
2701
|
+
isNumber(seriesExtremes.dataMax)) {
|
|
2702
|
+
allExtremes.dataMin = Math.min(seriesExtremes.dataMin, allExtremes.dataMin);
|
|
2703
|
+
allExtremes.dataMax = Math.max(seriesExtremes.dataMax, allExtremes.dataMax);
|
|
2704
|
+
}
|
|
2705
|
+
}
|
|
2706
|
+
axis.allExtremes = allExtremes;
|
|
2707
|
+
}
|
|
2708
|
+
const { dataMin, dataMax, min, max } = extend(axis.getExtremes(), allExtremes || {}), optionsMin = time.parse(options.min), optionsMax = time.parse(options.max),
|
|
2709
|
+
// For boosted chart where data extremes are skipped
|
|
2710
|
+
safeDataMin = dataMin ?? optionsMin, safeDataMax = dataMax ?? optionsMax, range = newMax - newMin, padRange = axis.categories ? 0 : Math.min(range, safeDataMax - safeDataMin), paddedMin = safeDataMin - padRange * (defined(optionsMin) ? 0 : options.minPadding), paddedMax = safeDataMax + padRange * (defined(optionsMax) ? 0 : options.maxPadding),
|
|
2711
|
+
// We're allowed to zoom outside the data extremes if we're
|
|
2712
|
+
// dealing with a bubble chart, if we're panning, or if we're
|
|
2713
|
+
// pinching or mousewheeling in.
|
|
2714
|
+
allowZoomOutside = axis.allowZoomOutside ||
|
|
2715
|
+
scale === 1 ||
|
|
2716
|
+
(trigger !== 'zoom' && scale > 1),
|
|
2717
|
+
// Calculate the floor and the ceiling
|
|
2718
|
+
floor = Math.min(optionsMin ?? paddedMin, paddedMin, allowZoomOutside ? min : paddedMin), ceiling = Math.max(optionsMax ?? paddedMax, paddedMax, allowZoomOutside ? max : paddedMax);
|
|
2719
|
+
// It is not necessary to calculate extremes on ordinal axis,
|
|
2720
|
+
// because they are already calculated, so we don't want to override
|
|
2721
|
+
// them.
|
|
2722
|
+
if (!axis.isOrdinal || scale !== 1 || reset) {
|
|
2723
|
+
// If the new range spills over, either to the min or max,
|
|
2724
|
+
// adjust it.
|
|
2725
|
+
if (newMin < floor) {
|
|
2726
|
+
newMin = floor;
|
|
2727
|
+
if (scale >= 1) {
|
|
2728
|
+
newMax = newMin + range;
|
|
2729
|
+
}
|
|
2730
|
+
}
|
|
2731
|
+
if (newMax > ceiling) {
|
|
2732
|
+
newMax = ceiling;
|
|
2733
|
+
if (scale >= 1) {
|
|
2734
|
+
newMin = newMax - range;
|
|
2735
|
+
}
|
|
2736
|
+
}
|
|
2737
|
+
// Set new extremes if they are actually new
|
|
2738
|
+
if (reset || (axis.series.length &&
|
|
2739
|
+
(newMin !== min || newMax !== max) &&
|
|
2740
|
+
newMin >= floor &&
|
|
2741
|
+
newMax <= ceiling)) {
|
|
2742
|
+
if (selection) {
|
|
2743
|
+
selection[axis.coll].push({
|
|
2744
|
+
axis,
|
|
2745
|
+
min: newMin,
|
|
2746
|
+
max: newMax
|
|
2747
|
+
});
|
|
2748
|
+
}
|
|
2749
|
+
else {
|
|
2750
|
+
// Temporarily flag the axis as `isPanning` in order to
|
|
2751
|
+
// disallow certain axis padding options that would make
|
|
2752
|
+
// panning/zooming hard. Reset and redraw after the
|
|
2753
|
+
// operation has finished.
|
|
2754
|
+
axis.isPanning = trigger !== 'zoom';
|
|
2755
|
+
if (axis.isPanning && trigger !== 'mousewheel') {
|
|
2756
|
+
isAnyAxisPanning = true; // #21319
|
|
2757
|
+
}
|
|
2758
|
+
axis.setExtremes(reset ? void 0 : newMin, reset ? void 0 : newMax, false, false, { move, trigger, scale });
|
|
2759
|
+
if (!reset &&
|
|
2760
|
+
(newMin > floor || newMax < ceiling)) {
|
|
2761
|
+
displayButton = allowResetButton;
|
|
2762
|
+
}
|
|
2763
|
+
}
|
|
2764
|
+
hasZoomed = true;
|
|
2765
|
+
}
|
|
2766
|
+
// Show the resetZoom button for non-cartesian series.
|
|
2767
|
+
if (!this.hasCartesianSeries &&
|
|
2768
|
+
!reset) {
|
|
2769
|
+
displayButton = allowResetButton;
|
|
2770
|
+
}
|
|
2771
|
+
if (event) {
|
|
2772
|
+
this[horiz ? 'mouseDownX' : 'mouseDownY'] =
|
|
2773
|
+
event[horiz ? 'chartX' : 'chartY'];
|
|
2774
|
+
}
|
|
2775
|
+
}
|
|
2776
|
+
}
|
|
2777
|
+
if (hasZoomed) {
|
|
2778
|
+
if (selection) {
|
|
2779
|
+
fireEvent(this, 'selection', selection,
|
|
2780
|
+
// Run transform again, this time without the selection data
|
|
2781
|
+
// so that the transform is applied.
|
|
2782
|
+
() => {
|
|
2783
|
+
delete params.selection;
|
|
2784
|
+
params.trigger = 'zoom';
|
|
2785
|
+
this.transform(params);
|
|
2786
|
+
});
|
|
2787
|
+
}
|
|
2788
|
+
else {
|
|
2789
|
+
// Show or hide the Reset zoom button, but not while panning
|
|
2790
|
+
if (displayButton &&
|
|
2791
|
+
!isAnyAxisPanning &&
|
|
2792
|
+
!this.resetZoomButton) {
|
|
2793
|
+
this.showResetZoom();
|
|
2794
|
+
}
|
|
2795
|
+
else if (!displayButton && this.resetZoomButton) {
|
|
2796
|
+
this.resetZoomButton = this.resetZoomButton.destroy();
|
|
2797
|
+
}
|
|
2798
|
+
this.redraw(trigger === 'zoom' &&
|
|
2799
|
+
(this.options.chart.animation ?? this.pointCount < 100));
|
|
2800
|
+
}
|
|
2801
|
+
}
|
|
2802
|
+
return hasZoomed;
|
|
2803
|
+
}
|
|
2804
|
+
}
|
|
2805
|
+
extend(Chart.prototype, {
|
|
2806
|
+
// Hook for adding callbacks in modules
|
|
2807
|
+
callbacks: [],
|
|
2808
|
+
/**
|
|
2809
|
+
* These collections (arrays) implement `Chart.addSomething` method used in
|
|
2810
|
+
* chart.update() to create new object in the collection. Equivalent for
|
|
2811
|
+
* deleting is resolved by simple `Something.remove()`.
|
|
2812
|
+
*
|
|
2813
|
+
* Note: We need to define these references after initializers are bound to
|
|
2814
|
+
* chart's prototype.
|
|
2815
|
+
*
|
|
2816
|
+
* @private
|
|
2817
|
+
*/
|
|
2818
|
+
collectionsWithInit: {
|
|
2819
|
+
// CollectionName: [ initializingMethod, [extraArguments] ]
|
|
2820
|
+
xAxis: [Chart.prototype.addAxis, [true]],
|
|
2821
|
+
yAxis: [Chart.prototype.addAxis, [false]],
|
|
2822
|
+
series: [Chart.prototype.addSeries]
|
|
2823
|
+
},
|
|
2824
|
+
/**
|
|
2825
|
+
* These collections (arrays) implement update() methods with support for
|
|
2826
|
+
* one-to-one option.
|
|
2827
|
+
* @private
|
|
2828
|
+
*/
|
|
2829
|
+
collectionsWithUpdate: [
|
|
2830
|
+
'xAxis',
|
|
2831
|
+
'yAxis',
|
|
2832
|
+
'series'
|
|
2833
|
+
],
|
|
2834
|
+
/**
|
|
2835
|
+
* These properties cause isDirtyBox to be set to true when updating. Can be
|
|
2836
|
+
* extended from plugins.
|
|
2837
|
+
* @private
|
|
2838
|
+
*/
|
|
2839
|
+
propsRequireDirtyBox: [
|
|
2840
|
+
'backgroundColor',
|
|
2841
|
+
'borderColor',
|
|
2842
|
+
'borderWidth',
|
|
2843
|
+
'borderRadius',
|
|
2844
|
+
'plotBackgroundColor',
|
|
2845
|
+
'plotBackgroundImage',
|
|
2846
|
+
'plotBorderColor',
|
|
2847
|
+
'plotBorderWidth',
|
|
2848
|
+
'plotShadow',
|
|
2849
|
+
'shadow'
|
|
2850
|
+
],
|
|
2851
|
+
/**
|
|
2852
|
+
* These properties require a full reflow of chart elements, best
|
|
2853
|
+
* implemented through running `Chart.setSize` internally (#8190).
|
|
2854
|
+
* @private
|
|
2855
|
+
*/
|
|
2856
|
+
propsRequireReflow: [
|
|
2857
|
+
'margin',
|
|
2858
|
+
'marginTop',
|
|
2859
|
+
'marginRight',
|
|
2860
|
+
'marginBottom',
|
|
2861
|
+
'marginLeft',
|
|
2862
|
+
'spacing',
|
|
2863
|
+
'spacingTop',
|
|
2864
|
+
'spacingRight',
|
|
2865
|
+
'spacingBottom',
|
|
2866
|
+
'spacingLeft'
|
|
2867
|
+
],
|
|
2868
|
+
/**
|
|
2869
|
+
* These properties cause all series to be updated when updating. Can be
|
|
2870
|
+
* extended from plugins.
|
|
2871
|
+
* @private
|
|
2872
|
+
*/
|
|
2873
|
+
propsRequireUpdateSeries: [
|
|
2874
|
+
'chart.inverted',
|
|
2875
|
+
'chart.polar',
|
|
2876
|
+
'chart.ignoreHiddenSeries',
|
|
2877
|
+
'chart.type',
|
|
2878
|
+
'colors',
|
|
2879
|
+
'plotOptions',
|
|
2880
|
+
'time',
|
|
2881
|
+
'tooltip'
|
|
2882
|
+
]
|
|
2883
|
+
});
|
|
2884
|
+
/* *
|
|
2885
|
+
*
|
|
2886
|
+
* Default Export
|
|
2887
|
+
*
|
|
2888
|
+
* */
|
|
2889
|
+
export default Chart;
|
|
2890
|
+
/* *
|
|
2891
|
+
*
|
|
2892
|
+
* API Declarations
|
|
2893
|
+
*
|
|
2894
|
+
* */
|
|
2895
|
+
/**
|
|
2896
|
+
* Callback for chart constructors.
|
|
2897
|
+
*
|
|
2898
|
+
* @callback Highcharts.ChartCallbackFunction
|
|
2899
|
+
*
|
|
2900
|
+
* @param {Highcharts.Chart} chart
|
|
2901
|
+
* Created chart.
|
|
2902
|
+
*/
|
|
2903
|
+
/**
|
|
2904
|
+
* Format a number and return a string based on input settings.
|
|
2905
|
+
*
|
|
2906
|
+
* @callback Highcharts.NumberFormatterCallbackFunction
|
|
2907
|
+
*
|
|
2908
|
+
* @param {number} number
|
|
2909
|
+
* The input number to format.
|
|
2910
|
+
*
|
|
2911
|
+
* @param {number} decimals
|
|
2912
|
+
* The amount of decimals. A value of -1 preserves the amount in the
|
|
2913
|
+
* input number.
|
|
2914
|
+
*
|
|
2915
|
+
* @param {string} [decimalPoint]
|
|
2916
|
+
* The decimal point, defaults to the one given in the lang options, or
|
|
2917
|
+
* a dot.
|
|
2918
|
+
*
|
|
2919
|
+
* @param {string} [thousandsSep]
|
|
2920
|
+
* The thousands separator, defaults to the one given in the lang
|
|
2921
|
+
* options, or a space character.
|
|
2922
|
+
*
|
|
2923
|
+
* @return {string} The formatted number.
|
|
2924
|
+
*/
|
|
2925
|
+
/**
|
|
2926
|
+
* The chart title. The title has an `update` method that allows modifying the
|
|
2927
|
+
* options directly or indirectly via `chart.update`.
|
|
2928
|
+
*
|
|
2929
|
+
* @interface Highcharts.TitleObject
|
|
2930
|
+
* @extends Highcharts.SVGElement
|
|
2931
|
+
*/ /**
|
|
2932
|
+
* Modify options for the title.
|
|
2933
|
+
*
|
|
2934
|
+
* @function Highcharts.TitleObject#update
|
|
2935
|
+
*
|
|
2936
|
+
* @param {Highcharts.TitleOptions} titleOptions
|
|
2937
|
+
* Options to modify.
|
|
2938
|
+
*
|
|
2939
|
+
* @param {boolean} [redraw=true]
|
|
2940
|
+
* Whether to redraw the chart after the title is altered. If doing more
|
|
2941
|
+
* operations on the chart, it is a good idea to set redraw to false and
|
|
2942
|
+
* call {@link Chart#redraw} after.
|
|
2943
|
+
*/
|
|
2944
|
+
/**
|
|
2945
|
+
* The chart subtitle. The subtitle has an `update` method that
|
|
2946
|
+
* allows modifying the options directly or indirectly via
|
|
2947
|
+
* `chart.update`.
|
|
2948
|
+
*
|
|
2949
|
+
* @interface Highcharts.SubtitleObject
|
|
2950
|
+
* @extends Highcharts.SVGElement
|
|
2951
|
+
*/ /**
|
|
2952
|
+
* Modify options for the subtitle.
|
|
2953
|
+
*
|
|
2954
|
+
* @function Highcharts.SubtitleObject#update
|
|
2955
|
+
*
|
|
2956
|
+
* @param {Highcharts.SubtitleOptions} subtitleOptions
|
|
2957
|
+
* Options to modify.
|
|
2958
|
+
*
|
|
2959
|
+
* @param {boolean} [redraw=true]
|
|
2960
|
+
* Whether to redraw the chart after the subtitle is altered. If doing
|
|
2961
|
+
* more operations on the chart, it is a good idea to set redraw to false
|
|
2962
|
+
* and call {@link Chart#redraw} after.
|
|
2963
|
+
*/
|
|
2964
|
+
/**
|
|
2965
|
+
* The chart caption. The caption has an `update` method that
|
|
2966
|
+
* allows modifying the options directly or indirectly via
|
|
2967
|
+
* `chart.update`.
|
|
2968
|
+
*
|
|
2969
|
+
* @interface Highcharts.CaptionObject
|
|
2970
|
+
* @extends Highcharts.SVGElement
|
|
2971
|
+
*/ /**
|
|
2972
|
+
* Modify options for the caption.
|
|
2973
|
+
*
|
|
2974
|
+
* @function Highcharts.CaptionObject#update
|
|
2975
|
+
*
|
|
2976
|
+
* @param {Highcharts.CaptionOptions} captionOptions
|
|
2977
|
+
* Options to modify.
|
|
2978
|
+
*
|
|
2979
|
+
* @param {boolean} [redraw=true]
|
|
2980
|
+
* Whether to redraw the chart after the caption is altered. If doing
|
|
2981
|
+
* more operations on the chart, it is a good idea to set redraw to false
|
|
2982
|
+
* and call {@link Chart#redraw} after.
|
|
2983
|
+
*/
|
|
2984
|
+
/**
|
|
2985
|
+
* @interface Highcharts.ChartIsInsideOptionsObject
|
|
2986
|
+
*/ /**
|
|
2987
|
+
* @name Highcharts.ChartIsInsideOptionsObject#axis
|
|
2988
|
+
* @type {Highcharts.Axis|undefined}
|
|
2989
|
+
*/ /**
|
|
2990
|
+
* @name Highcharts.ChartIsInsideOptionsObject#ignoreX
|
|
2991
|
+
* @type {boolean|undefined}
|
|
2992
|
+
*/ /**
|
|
2993
|
+
* @name Highcharts.ChartIsInsideOptionsObject#ignoreY
|
|
2994
|
+
* @type {boolean|undefined}
|
|
2995
|
+
*/ /**
|
|
2996
|
+
* @name Highcharts.ChartIsInsideOptionsObject#inverted
|
|
2997
|
+
* @type {boolean|undefined}
|
|
2998
|
+
*/ /**
|
|
2999
|
+
* @name Highcharts.ChartIsInsideOptionsObject#paneCoordinates
|
|
3000
|
+
* @type {boolean|undefined}
|
|
3001
|
+
*/ /**
|
|
3002
|
+
* @name Highcharts.ChartIsInsideOptionsObject#series
|
|
3003
|
+
* @type {Highcharts.Series|undefined}
|
|
3004
|
+
*/ /**
|
|
3005
|
+
* @name Highcharts.ChartIsInsideOptionsObject#visiblePlotOnly
|
|
3006
|
+
* @type {boolean|undefined}
|
|
3007
|
+
*/
|
|
3008
|
+
''; // Keeps doclets above in JS file
|