highcharts 10.2.0 → 10.2.1
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/bower.json +1 -1
- package/css/highcharts.css +10 -20
- package/css/themes/dark-unica.css +10 -20
- package/css/themes/grid-light.css +10 -20
- package/css/themes/sand-signika.css +10 -20
- package/es-modules/Accessibility/Accessibility.js +6 -0
- package/es-modules/Accessibility/Components/LegendComponent.js +8 -8
- package/es-modules/Accessibility/Components/SeriesComponent/SeriesDescriber.js +3 -2
- package/es-modules/Accessibility/Options/A11yDefaults.js +1 -1
- package/es-modules/Core/Axis/Axis.js +3 -0
- package/es-modules/Core/Axis/Axis3D.js +1 -1
- package/es-modules/Core/Axis/AxisDefaults.js +1 -1
- package/es-modules/Core/Axis/BrokenAxis.js +1 -1
- package/es-modules/Core/Axis/Color/ColorAxisDefaults.js +4 -0
- package/es-modules/Core/Axis/NavigatorAxis.js +2 -2
- package/es-modules/Core/Axis/OrdinalAxis.js +2 -2
- package/es-modules/Core/Axis/RadialAxis.js +1 -1
- package/es-modules/Core/Axis/Stacking/StackItem.js +262 -0
- package/es-modules/Core/Axis/Stacking/StackingAxis.js +468 -0
- package/es-modules/Core/Axis/TreeGrid/TreeGridAxis.js +732 -0
- package/es-modules/Core/Axis/TreeGrid/TreeGridTick.js +313 -0
- package/es-modules/Core/Axis/WaterfallAxis.js +1 -1
- package/es-modules/Core/Axis/ZAxis.js +73 -70
- package/es-modules/Core/Chart/Chart.js +16 -2
- package/es-modules/Core/Chart/Chart3D.js +2 -2
- package/es-modules/Core/Chart/ChartDefaults.js +151 -2
- package/es-modules/Core/Chart/StockChart.js +5 -3
- package/es-modules/Core/DefaultOptions.js +2 -1
- package/es-modules/Core/Geometry/CircleUtilities.js +4 -4
- package/es-modules/Core/Globals.js +2 -1
- package/es-modules/{Extensions → Core}/Math3D.js +48 -43
- package/es-modules/Core/Navigator.js +24 -7
- package/es-modules/Core/Pointer.js +7 -9
- package/es-modules/Core/Renderer/HTML/AST.js +4 -1
- package/es-modules/Core/Renderer/SVG/SVGElement.js +103 -163
- package/es-modules/Core/Renderer/SVG/SVGLabel.js +29 -27
- package/es-modules/Core/Renderer/SVG/SVGRenderer.js +3 -3
- package/es-modules/Core/Renderer/SVG/SVGRenderer3D.js +1 -1
- package/es-modules/Core/Renderer/SVG/TextBuilder.js +5 -3
- package/es-modules/Core/Scrollbar.js +3 -1
- package/es-modules/Core/Series/DataLabel.js +8 -6
- package/es-modules/Core/Series/Point.js +2 -2
- package/es-modules/Core/Series/Series.js +36 -31
- package/es-modules/Core/Series/Series3D.js +1 -1
- package/es-modules/Core/Series/SeriesDefaults.js +8 -3
- package/es-modules/Core/Series/SeriesRegistry.js +6 -29
- package/es-modules/Core/Tooltip.js +14 -3
- package/es-modules/Core/Utilities.js +1 -3
- package/es-modules/Data/DataConverter.js +5 -0
- package/es-modules/Data/DataPromise.js +1 -1
- package/es-modules/Data/DataSeriesComposition.js +288 -0
- package/es-modules/Data/DataSeriesConverter.js +1 -1
- package/es-modules/Data/DataTable.js +2 -2
- package/es-modules/Data/Modifiers/ChainModifier.js +1 -1
- package/es-modules/Data/Modifiers/DataModifier.js +1 -1
- package/es-modules/Data/Modifiers/GroupModifier.js +1 -1
- package/es-modules/Data/Modifiers/InvertModifier.js +1 -1
- package/es-modules/Data/Modifiers/RangeModifier.js +1 -1
- package/es-modules/Data/Modifiers/SeriesPointsModifier.js +1 -1
- package/es-modules/Data/Modifiers/SortModifier.js +1 -1
- package/es-modules/Data/Parsers/DataParser.js +1 -1
- package/es-modules/Data/Stores/DataStore.js +1 -1
- package/es-modules/Extensions/Annotations/Annotation.js +347 -1156
- package/es-modules/Extensions/Annotations/AnnotationChart.js +291 -0
- package/es-modules/Extensions/Annotations/AnnotationDefaults.js +624 -0
- package/es-modules/Extensions/Annotations/ControlPoint.js +89 -64
- package/es-modules/Extensions/Annotations/{Mixins/ControllableMixin.js → Controllables/Controllable.js} +300 -241
- package/es-modules/Extensions/Annotations/Controllables/ControllableCircle.js +63 -50
- package/es-modules/Extensions/Annotations/Controllables/ControllableDefaults.js +95 -0
- package/es-modules/Extensions/Annotations/Controllables/ControllableEllipse.js +90 -61
- package/es-modules/Extensions/Annotations/Controllables/ControllableImage.js +50 -44
- package/es-modules/Extensions/Annotations/Controllables/ControllableLabel.js +95 -78
- package/es-modules/Extensions/Annotations/Controllables/ControllablePath.js +167 -51
- package/es-modules/Extensions/Annotations/Controllables/ControllableRect.js +53 -52
- package/es-modules/Extensions/Annotations/{Mixins/EventEmitterMixin.js → EventEmitter.js} +136 -116
- package/es-modules/Extensions/Annotations/MockPoint.js +210 -145
- package/es-modules/Extensions/Annotations/NavigationBindings.js +272 -674
- package/es-modules/Extensions/Annotations/NavigationBindingsDefaults.js +396 -0
- package/es-modules/Extensions/Annotations/NavigationBindingsUtilities.js +98 -0
- package/es-modules/Extensions/Annotations/Popup/Popup.js +295 -0
- package/es-modules/Extensions/Annotations/Popup/PopupAnnotations.js +177 -0
- package/es-modules/Extensions/Annotations/Popup/PopupComposition.js +81 -0
- package/es-modules/Extensions/Annotations/Popup/PopupIndicators.js +609 -0
- package/es-modules/Extensions/Annotations/Popup/PopupTabs.js +134 -0
- package/es-modules/Extensions/Annotations/Types/BasicAnnotation.js +10 -14
- package/es-modules/Extensions/Annotations/Types/CrookedLine.js +11 -19
- package/es-modules/Extensions/Annotations/Types/ElliottWave.js +10 -10
- package/es-modules/Extensions/Annotations/Types/Fibonacci.js +28 -20
- package/es-modules/Extensions/Annotations/Types/FibonacciTimeZones.js +63 -63
- package/es-modules/Extensions/Annotations/Types/InfinityLine.js +10 -19
- package/es-modules/Extensions/Annotations/Types/Measure.js +255 -249
- package/es-modules/Extensions/Annotations/Types/Pitchfork.js +11 -17
- package/es-modules/Extensions/Annotations/Types/TimeCycles.js +20 -17
- package/es-modules/Extensions/Annotations/Types/Tunnel.js +12 -13
- package/es-modules/Extensions/Annotations/Types/VerticalLine.js +11 -15
- package/es-modules/Extensions/Boost/Boost.js +320 -15
- package/es-modules/Extensions/Boost/BoostChart.js +245 -0
- package/es-modules/Extensions/Boost/BoostSeries.js +927 -0
- package/es-modules/Extensions/Boost/BoostableMap.js +21 -5
- package/es-modules/Extensions/Boost/Boostables.js +13 -2
- package/es-modules/Extensions/Boost/NamedColors.js +15 -6
- package/es-modules/Extensions/Boost/WGLDrawMode.js +36 -0
- package/es-modules/Extensions/Boost/WGLRenderer.js +288 -295
- package/es-modules/Extensions/Boost/WGLShader.js +370 -376
- package/es-modules/Extensions/Boost/WGLVertexBuffer.js +192 -0
- package/es-modules/Extensions/BoostCanvas.js +62 -46
- package/es-modules/Extensions/Breadcrumbs.js +4 -0
- package/es-modules/Extensions/DataGrouping.js +65 -27
- package/es-modules/Extensions/Debugger/Debugger.js +60 -22
- package/es-modules/Extensions/DraggablePoints.js +4 -3
- package/es-modules/Extensions/Drilldown.js +7 -8
- package/es-modules/Extensions/{ExportData.js → ExportData/ExportData.js} +341 -530
- package/es-modules/Extensions/ExportData/ExportDataDefaults.js +272 -0
- package/es-modules/Extensions/Exporting/Exporting.js +5 -1
- package/es-modules/Extensions/Exporting/ExportingDefaults.js +3 -1
- package/es-modules/Extensions/{FullScreen.js → Exporting/Fullscreen.js} +72 -27
- package/es-modules/Extensions/MarkerClusters.js +2 -0
- package/es-modules/Extensions/OfflineExporting/OfflineExportingDefaults.js +1 -1
- package/es-modules/Extensions/Oldie/Oldie.js +1 -1
- package/es-modules/Extensions/ParallelCoordinates.js +11 -7
- package/es-modules/Extensions/ScrollablePlotArea.js +1 -1
- package/es-modules/Extensions/SeriesLabel/SeriesLabel.js +2 -2
- package/es-modules/Extensions/Sonification/ChartSonify.js +1 -1
- package/es-modules/Maps/MapPointer.js +1 -1
- package/es-modules/Maps/MapView.js +2 -1
- package/es-modules/Series/{Area3DSeries.js → Area3D/Area3DSeries.js} +42 -20
- package/es-modules/Series/AreaRange/AreaRangeSeries.js +8 -2
- package/es-modules/Series/Bubble/BubbleLegendComposition.js +223 -231
- package/es-modules/Series/Bubble/BubbleLegendItem.js +46 -45
- package/es-modules/Series/Bubble/BubbleSeries.js +85 -66
- package/es-modules/Series/Column/ColumnSeries.js +2 -0
- package/es-modules/Series/Column3D/Column3DComposition.js +2 -2
- package/es-modules/Series/ColumnPyramid/ColumnPyramidSeries.js +1 -1
- package/es-modules/Series/Cylinder/CylinderComposition.js +1 -1
- package/es-modules/Series/DependencyWheel/DependencyWheelPoint.js +24 -11
- package/es-modules/Series/DependencyWheel/DependencyWheelSeries.js +16 -2
- package/es-modules/Series/DragNodesComposition.js +166 -0
- package/es-modules/Series/Funnel3D/Funnel3DSeries.js +1 -1
- package/es-modules/Series/Gantt/GanttSeries.js +1 -1
- package/es-modules/Series/GraphLayoutComposition.js +130 -0
- package/es-modules/Series/Heatmap/HeatmapSeries.js +5 -1
- package/es-modules/Series/Lollipop/LollipopPoint.js +21 -11
- package/es-modules/Series/Lollipop/LollipopSeries.js +15 -10
- package/es-modules/Series/Map/MapSeries.js +6 -1
- package/es-modules/Series/MapBubble/MapBubblePoint.js +15 -17
- package/es-modules/Series/MapBubble/MapBubbleSeries.js +19 -19
- package/es-modules/Series/Networkgraph/EulerIntegration.js +199 -0
- package/es-modules/Series/Networkgraph/NetworkgraphPoint.js +290 -0
- package/es-modules/Series/Networkgraph/NetworkgraphSeries.js +401 -0
- package/es-modules/Series/Networkgraph/NetworkgraphSeriesDefaults.js +545 -0
- package/es-modules/Series/Networkgraph/QuadTree.js +66 -272
- package/es-modules/Series/Networkgraph/QuadTreeNode.js +271 -0
- package/es-modules/Series/Networkgraph/{Layouts.js → ReingoldFruchtermanLayout.js} +240 -259
- package/es-modules/Series/Networkgraph/VerletIntegration.js +193 -0
- package/es-modules/Series/Organization/OrganizationSeries.js +9 -1
- package/es-modules/Series/PackedBubble/PackedBubbleIntegration.js +81 -0
- package/es-modules/Series/PackedBubble/{PackedBubbleComposition.js → PackedBubbleLayout.js} +114 -77
- package/es-modules/Series/PackedBubble/PackedBubblePoint.js +2 -2
- package/es-modules/Series/PackedBubble/PackedBubbleSeries.js +197 -570
- package/es-modules/Series/PackedBubble/PackedBubbleSeriesDefaults.js +394 -0
- package/es-modules/Series/Pie/PieSeries.js +3 -1
- package/es-modules/Series/PolarComposition.js +12 -12
- package/es-modules/Series/Sankey/SankeySeries.js +13 -1
- package/es-modules/Series/Scatter/ScatterSeries.js +4 -1
- package/es-modules/Series/Scatter3D/Scatter3DSeries.js +1 -1
- package/es-modules/Series/SeriesOnPointComposition.js +5 -1
- package/es-modules/Series/SolidGauge/SolidGaugeSeries.js +1 -1
- package/es-modules/Series/Sunburst/SunburstPoint.js +5 -6
- package/es-modules/Series/Sunburst/SunburstSeries.js +24 -2
- package/es-modules/Series/Timeline/TimelineSeries.js +2 -0
- package/es-modules/Series/Treemap/TreemapSeries.js +3 -3
- package/es-modules/Series/Vector/VectorSeries.js +2 -4
- package/es-modules/Series/Wordcloud/WordcloudSeries.js +1 -1
- package/es-modules/Series/Wordcloud/WordcloudUtils.js +1 -1
- package/es-modules/Series/XRange/XRangePoint.js +54 -45
- package/es-modules/Series/XRange/XRangeSeries.js +121 -273
- package/es-modules/Series/XRange/XRangeSeriesDefaults.js +211 -0
- package/es-modules/Stock/Indicators/ABands/ABandsIndicator.js +10 -2
- package/es-modules/Stock/Indicators/AD/ADIndicator.js +5 -0
- package/es-modules/Stock/Indicators/AO/AOIndicator.js +22 -11
- package/es-modules/Stock/Indicators/APO/APOIndicator.js +6 -1
- package/es-modules/Stock/Indicators/ATR/ATRIndicator.js +16 -3
- package/es-modules/Stock/Indicators/Aroon/AroonIndicator.js +15 -2
- package/es-modules/Stock/Indicators/AroonOscillator/AroonOscillatorIndicator.js +6 -2
- package/es-modules/Stock/Indicators/BB/BBIndicator.js +5 -1
- package/es-modules/Stock/Indicators/CCI/CCIIndicator.js +16 -3
- package/es-modules/Stock/Indicators/CMF/CMFIndicator.js +20 -0
- package/es-modules/Stock/Indicators/CMO/CMOIndicator.js +15 -1
- package/es-modules/Stock/Indicators/Chaikin/ChaikinIndicator.js +7 -2
- package/es-modules/Stock/Indicators/DEMA/DEMAIndicator.js +25 -0
- package/es-modules/Stock/Indicators/DMI/DMIIndicator.js +5 -0
- package/es-modules/Stock/Indicators/DPO/DPOIndicator.js +19 -8
- package/es-modules/Stock/Indicators/EMA/EMAIndicator.js +10 -0
- package/es-modules/Stock/Indicators/IKH/IKHIndicator.js +34 -15
- package/es-modules/Stock/Indicators/KeltnerChannels/KeltnerChannelsIndicator.js +25 -0
- package/es-modules/Stock/Indicators/Klinger/KlingerIndicator.js +12 -1
- package/es-modules/Stock/Indicators/LinearRegression/{LinearRegression.js → LinearRegressionIndicator.js} +11 -1
- package/es-modules/Stock/Indicators/LinearRegressionAngle/{LinearRegressionAngle.js → LinearRegressionAngleIndicator.js} +12 -7
- package/es-modules/Stock/Indicators/LinearRegressionIntercept/{LinearRegressionIntercept.js → LinearRegressionInterceptIndicator.js} +11 -1
- package/es-modules/Stock/Indicators/LinearRegressionSlopes/{LinearRegressionSlopes.js → LinearRegressionSlopesIndicator.js} +11 -1
- package/es-modules/Stock/Indicators/MACD/MACDIndicator.js +21 -10
- package/es-modules/Stock/Indicators/MFI/MFIIndicator.js +23 -10
- package/es-modules/Stock/Indicators/Momentum/MomentumIndicator.js +30 -2
- package/es-modules/Stock/Indicators/NATR/NATRIndicator.js +16 -1
- package/es-modules/Stock/Indicators/OBV/OBVIndicator.js +10 -0
- package/es-modules/Stock/Indicators/PC/PCIndicator.js +13 -8
- package/es-modules/Stock/Indicators/PPO/PPOIndicator.js +14 -4
- package/es-modules/Stock/Indicators/PSAR/PSARIndicator.js +16 -3
- package/es-modules/Stock/Indicators/PivotPoints/PivotPointsIndicator.js +16 -6
- package/es-modules/Stock/Indicators/PivotPoints/PivotPointsPoint.js +16 -12
- package/es-modules/Stock/Indicators/PriceEnvelopes/PriceEnvelopesIndicator.js +25 -0
- package/es-modules/Stock/Indicators/ROC/ROCIndicator.js +15 -2
- package/es-modules/Stock/Indicators/RSI/RSIIndicator.js +20 -2
- package/es-modules/Stock/Indicators/SMA/SMAIndicator.js +1 -1
- package/es-modules/Stock/Indicators/SlowStochastic/SlowStochasticIndicator.js +25 -0
- package/es-modules/Stock/Indicators/Stochastic/StochasticIndicator.js +15 -0
- package/es-modules/Stock/Indicators/Supertrend/SupertrendIndicator.js +17 -3
- package/es-modules/Stock/Indicators/TRIX/TRIXIndicator.js +25 -0
- package/es-modules/Stock/Indicators/TrendLine/TrendLineIndicator.js +14 -4
- package/es-modules/Stock/Indicators/VBP/VBPIndicator.js +32 -3
- package/es-modules/Stock/Indicators/VBP/VBPPoint.js +6 -6
- package/es-modules/Stock/Indicators/VWAP/VWAPIndicator.js +11 -1
- package/es-modules/Stock/Indicators/WMA/WMAIndicator.js +30 -2
- package/es-modules/Stock/Indicators/WilliamsR/WilliamsRIndicator.js +10 -0
- package/es-modules/Stock/Indicators/Zigzag/ZigzagIndicator.js +11 -1
- package/es-modules/Stock/StockToolbar.js +568 -0
- package/es-modules/Stock/StockTools.js +256 -0
- package/es-modules/Stock/StockToolsBindings.js +114 -629
- package/es-modules/Stock/StockToolsDefaults.js +1190 -0
- package/es-modules/Stock/StockToolsGui.js +150 -1771
- package/es-modules/Stock/StockToolsUtilities.js +423 -0
- package/es-modules/masters/highcharts-3d.src.js +5 -4
- package/es-modules/masters/highcharts-gantt.src.js +1 -1
- package/es-modules/masters/highcharts-more.src.js +4 -3
- package/es-modules/masters/highcharts.src.js +5 -2
- package/es-modules/masters/highmaps.src.js +1 -1
- package/es-modules/masters/highstock.src.js +1 -1
- package/es-modules/masters/indicators/acceleration-bands.src.js +1 -1
- package/es-modules/masters/indicators/accumulation-distribution.src.js +1 -1
- package/es-modules/masters/indicators/ao.src.js +1 -1
- package/es-modules/masters/indicators/apo.src.js +1 -1
- package/es-modules/masters/indicators/aroon-oscillator.src.js +1 -1
- package/es-modules/masters/indicators/aroon.src.js +1 -1
- package/es-modules/masters/indicators/atr.src.js +1 -1
- package/es-modules/masters/indicators/bollinger-bands.src.js +1 -1
- package/es-modules/masters/indicators/cci.src.js +1 -1
- package/es-modules/masters/indicators/chaikin.src.js +1 -1
- package/es-modules/masters/indicators/cmf.src.js +1 -1
- package/es-modules/masters/indicators/cmo.src.js +1 -1
- package/es-modules/masters/indicators/dema.src.js +1 -1
- package/es-modules/masters/indicators/disparity-index.src.js +1 -1
- package/es-modules/masters/indicators/dmi.src.js +1 -1
- package/es-modules/masters/indicators/dpo.src.js +1 -1
- package/es-modules/masters/indicators/ichimoku-kinko-hyo.src.js +1 -1
- package/es-modules/masters/indicators/indicators-all.src.js +5 -7
- package/es-modules/masters/indicators/indicators.src.js +1 -1
- package/es-modules/masters/indicators/keltner-channels.src.js +1 -1
- package/es-modules/masters/indicators/klinger.src.js +1 -1
- package/es-modules/masters/indicators/macd.src.js +1 -1
- package/es-modules/masters/indicators/mfi.src.js +1 -1
- package/es-modules/masters/indicators/momentum.src.js +1 -1
- package/es-modules/masters/indicators/natr.src.js +1 -1
- package/es-modules/masters/indicators/obv.src.js +1 -1
- package/es-modules/masters/indicators/pivot-points.src.js +1 -1
- package/es-modules/masters/indicators/ppo.src.js +1 -1
- package/es-modules/masters/indicators/price-channel.src.js +1 -1
- package/es-modules/masters/indicators/price-envelopes.src.js +1 -1
- package/es-modules/masters/indicators/psar.src.js +1 -1
- package/es-modules/masters/indicators/regressions.src.js +5 -5
- package/es-modules/masters/indicators/roc.src.js +1 -1
- package/es-modules/masters/indicators/rsi.src.js +1 -1
- package/es-modules/masters/indicators/slow-stochastic.src.js +1 -1
- package/es-modules/masters/indicators/stochastic.src.js +1 -1
- package/es-modules/masters/indicators/supertrend.src.js +1 -1
- package/es-modules/masters/indicators/tema.src.js +1 -1
- package/es-modules/masters/indicators/trendline.src.js +1 -1
- package/es-modules/masters/indicators/trix.src.js +1 -1
- package/es-modules/masters/indicators/volume-by-price.src.js +1 -1
- package/es-modules/masters/indicators/vwap.src.js +1 -1
- package/es-modules/masters/indicators/williams-r.src.js +1 -1
- package/es-modules/masters/indicators/wma.src.js +1 -1
- package/es-modules/masters/indicators/zigzag.src.js +1 -1
- package/es-modules/masters/modules/accessibility.src.js +1 -1
- package/es-modules/masters/modules/annotations-advanced.src.js +6 -4
- package/es-modules/masters/modules/annotations.src.js +6 -4
- package/es-modules/masters/modules/arc-diagram.src.js +1 -1
- package/es-modules/masters/modules/arrow-symbols.src.js +1 -1
- package/es-modules/masters/modules/boost-canvas.src.js +1 -1
- package/es-modules/masters/modules/boost.src.js +6 -2
- package/es-modules/masters/modules/broken-axis.src.js +1 -1
- package/es-modules/masters/modules/bullet.src.js +1 -1
- package/es-modules/masters/modules/coloraxis.src.js +1 -1
- package/es-modules/masters/modules/current-date-indicator.src.js +1 -1
- package/es-modules/masters/modules/cylinder.src.js +1 -1
- package/es-modules/masters/modules/data.src.js +1 -1
- package/es-modules/masters/modules/datagrouping.src.js +1 -1
- package/es-modules/masters/modules/debugger.src.js +5 -3
- package/es-modules/masters/modules/dependency-wheel.src.js +1 -1
- package/es-modules/masters/modules/dotplot.src.js +1 -1
- package/es-modules/masters/modules/drag-panes.src.js +1 -1
- package/es-modules/masters/modules/draggable-points.src.js +1 -1
- package/es-modules/masters/modules/drilldown.src.js +1 -1
- package/es-modules/masters/modules/dumbbell.src.js +1 -1
- package/es-modules/masters/modules/export-data.src.js +5 -2
- package/es-modules/masters/modules/exporting.src.js +1 -2
- package/es-modules/masters/modules/full-screen.src.js +6 -2
- package/es-modules/masters/modules/funnel.src.js +1 -1
- package/es-modules/masters/modules/funnel3d.src.js +1 -1
- package/es-modules/masters/modules/gantt.src.js +3 -2
- package/es-modules/masters/modules/grid-axis.src.js +1 -1
- package/es-modules/masters/modules/heatmap.src.js +1 -1
- package/es-modules/masters/modules/heikinashi.src.js +1 -1
- package/es-modules/masters/modules/histogram-bellcurve.src.js +1 -1
- package/es-modules/masters/modules/hollowcandlestick.src.js +1 -1
- package/es-modules/masters/modules/item-series.src.js +1 -1
- package/es-modules/masters/modules/lollipop.src.js +1 -1
- package/es-modules/masters/modules/map.src.js +2 -2
- package/es-modules/masters/modules/marker-clusters.src.js +1 -1
- package/es-modules/masters/modules/networkgraph.src.js +5 -2
- package/es-modules/masters/modules/no-data-to-display.src.js +1 -1
- package/es-modules/masters/modules/offline-exporting.src.js +1 -1
- package/es-modules/masters/modules/oldie-polyfills.src.js +1 -1
- package/es-modules/masters/modules/oldie.src.js +1 -1
- package/es-modules/masters/modules/organization.src.js +1 -1
- package/es-modules/masters/modules/overlapping-datalabels.src.js +1 -1
- package/es-modules/masters/modules/parallel-coordinates.src.js +1 -1
- package/es-modules/masters/modules/pareto.src.js +1 -1
- package/es-modules/masters/modules/pathfinder.src.js +1 -1
- package/es-modules/masters/modules/pattern-fill.src.js +1 -1
- package/es-modules/masters/modules/price-indicator.src.js +1 -1
- package/es-modules/masters/modules/pyramid3d.src.js +1 -1
- package/es-modules/masters/modules/sankey.src.js +1 -1
- package/es-modules/masters/modules/series-label.src.js +1 -1
- package/es-modules/masters/modules/series-on-point.src.js +1 -1
- package/es-modules/masters/modules/solid-gauge.src.js +1 -1
- package/es-modules/masters/modules/sonification.src.js +1 -1
- package/es-modules/masters/modules/static-scale.src.js +1 -1
- package/es-modules/masters/modules/stock-tools.src.js +10 -3
- package/es-modules/masters/modules/stock.src.js +1 -1
- package/es-modules/masters/modules/streamgraph.src.js +1 -1
- package/es-modules/masters/modules/sunburst.src.js +1 -1
- package/es-modules/masters/modules/tilemap.src.js +1 -1
- package/es-modules/masters/modules/timeline.src.js +1 -1
- package/es-modules/masters/modules/treegrid.src.js +2 -2
- package/es-modules/masters/modules/treemap.src.js +1 -1
- package/es-modules/masters/modules/variable-pie.src.js +1 -1
- package/es-modules/masters/modules/variwide.src.js +1 -1
- package/es-modules/masters/modules/vector.src.js +1 -1
- package/es-modules/masters/modules/venn.src.js +1 -1
- package/es-modules/masters/modules/windbarb.src.js +1 -1
- package/es-modules/masters/modules/wordcloud.src.js +1 -1
- package/es-modules/masters/modules/xrange.src.js +5 -2
- package/es-modules/masters/themes/avocado.src.js +1 -1
- package/es-modules/masters/themes/brand-dark.src.js +1 -1
- package/es-modules/masters/themes/brand-light.src.js +1 -1
- package/es-modules/masters/themes/dark-blue.src.js +1 -1
- package/es-modules/masters/themes/dark-green.src.js +1 -1
- package/es-modules/masters/themes/dark-unica.src.js +1 -1
- package/es-modules/masters/themes/gray.src.js +1 -1
- package/es-modules/masters/themes/grid-light.src.js +1 -1
- package/es-modules/masters/themes/grid.src.js +1 -1
- package/es-modules/masters/themes/high-contrast-dark.src.js +1 -1
- package/es-modules/masters/themes/high-contrast-light.src.js +1 -1
- package/es-modules/masters/themes/sand-signika.src.js +1 -1
- package/es-modules/masters/themes/skies.src.js +1 -1
- package/es-modules/masters/themes/sunset.src.js +1 -1
- package/highcharts-3d.js +98 -99
- package/highcharts-3d.js.map +1 -1
- package/highcharts-3d.src.js +232 -211
- package/highcharts-gantt.js +808 -809
- package/highcharts-gantt.js.map +1 -1
- package/highcharts-gantt.src.js +2308 -2136
- package/highcharts-more.d.ts +5 -8
- package/highcharts-more.js +201 -194
- package/highcharts-more.js.map +1 -1
- package/highcharts-more.src.d.ts +5 -8
- package/highcharts-more.src.js +3671 -3275
- package/highcharts.d.ts +1400 -885
- package/highcharts.js +593 -595
- package/highcharts.js.map +1 -1
- package/highcharts.src.d.ts +1400 -885
- package/highcharts.src.js +847 -716
- package/highmaps.js +762 -763
- package/highmaps.js.map +1 -1
- package/highmaps.src.js +1288 -1129
- package/highstock.js +796 -798
- package/highstock.js.map +1 -1
- package/highstock.src.js +953 -762
- package/indicators/acceleration-bands.js +1 -1
- package/indicators/acceleration-bands.js.map +1 -1
- package/indicators/acceleration-bands.src.js +11 -3
- package/indicators/accumulation-distribution.js +1 -1
- package/indicators/accumulation-distribution.js.map +1 -1
- package/indicators/accumulation-distribution.src.js +6 -1
- package/indicators/ao.js +6 -6
- package/indicators/ao.js.map +1 -1
- package/indicators/ao.src.js +23 -14
- package/indicators/apo.js +1 -1
- package/indicators/apo.js.map +1 -1
- package/indicators/apo.src.js +6 -1
- package/indicators/aroon-oscillator.js +10 -10
- package/indicators/aroon-oscillator.js.map +1 -1
- package/indicators/aroon-oscillator.src.js +7 -3
- package/indicators/aroon.js +1 -1
- package/indicators/aroon.js.map +1 -1
- package/indicators/aroon.src.js +16 -3
- package/indicators/atr.js +1 -1
- package/indicators/atr.js.map +1 -1
- package/indicators/atr.src.js +17 -4
- package/indicators/bollinger-bands.js +1 -1
- package/indicators/bollinger-bands.js.map +1 -1
- package/indicators/bollinger-bands.src.js +6 -2
- package/indicators/cci.js +1 -1
- package/indicators/cci.js.map +1 -1
- package/indicators/cci.src.js +17 -4
- package/indicators/chaikin.js +8 -8
- package/indicators/chaikin.js.map +1 -1
- package/indicators/chaikin.src.js +13 -5
- package/indicators/cmf.js +1 -1
- package/indicators/cmf.js.map +1 -1
- package/indicators/cmf.src.js +21 -1
- package/indicators/cmo.js +1 -1
- package/indicators/cmo.js.map +1 -1
- package/indicators/cmo.src.js +16 -2
- package/indicators/dema.js +1 -1
- package/indicators/dema.js.map +1 -1
- package/indicators/dema.src.js +26 -1
- package/indicators/disparity-index.js +1 -1
- package/indicators/disparity-index.src.js +1 -1
- package/indicators/dmi.js +1 -1
- package/indicators/dmi.js.map +1 -1
- package/indicators/dmi.src.js +6 -1
- package/indicators/dpo.js +1 -1
- package/indicators/dpo.js.map +1 -1
- package/indicators/dpo.src.js +20 -9
- package/indicators/ichimoku-kinko-hyo.js +1 -1
- package/indicators/ichimoku-kinko-hyo.js.map +1 -1
- package/indicators/ichimoku-kinko-hyo.src.js +35 -16
- package/indicators/indicators-all.js +199 -199
- package/indicators/indicators-all.js.map +1 -1
- package/indicators/indicators-all.src.js +754 -162
- package/indicators/indicators.js +1 -1
- package/indicators/indicators.js.map +1 -1
- package/indicators/indicators.src.js +12 -2
- package/indicators/keltner-channels.js +1 -1
- package/indicators/keltner-channels.js.map +1 -1
- package/indicators/keltner-channels.src.js +26 -1
- package/indicators/klinger.js +12 -12
- package/indicators/klinger.js.map +1 -1
- package/indicators/klinger.src.js +13 -4
- package/indicators/macd.js +1 -1
- package/indicators/macd.js.map +1 -1
- package/indicators/macd.src.js +22 -13
- package/indicators/mfi.js +1 -1
- package/indicators/mfi.js.map +1 -1
- package/indicators/mfi.src.js +24 -11
- package/indicators/momentum.js +1 -1
- package/indicators/momentum.js.map +1 -1
- package/indicators/momentum.src.js +31 -3
- package/indicators/natr.js +1 -1
- package/indicators/natr.js.map +1 -1
- package/indicators/natr.src.js +17 -3
- package/indicators/obv.js +1 -1
- package/indicators/obv.js.map +1 -1
- package/indicators/obv.src.js +11 -1
- package/indicators/pivot-points.js +1 -1
- package/indicators/pivot-points.js.map +1 -1
- package/indicators/pivot-points.src.js +32 -19
- package/indicators/ppo.js +1 -1
- package/indicators/ppo.js.map +1 -1
- package/indicators/ppo.src.js +15 -5
- package/indicators/price-channel.js +1 -1
- package/indicators/price-channel.js.map +1 -1
- package/indicators/price-channel.src.js +14 -9
- package/indicators/price-envelopes.js +1 -1
- package/indicators/price-envelopes.js.map +1 -1
- package/indicators/price-envelopes.src.js +26 -1
- package/indicators/psar.js +1 -1
- package/indicators/psar.js.map +1 -1
- package/indicators/psar.src.js +17 -4
- package/indicators/regressions.js +12 -11
- package/indicators/regressions.js.map +1 -1
- package/indicators/regressions.src.js +50 -15
- package/indicators/roc.js +1 -1
- package/indicators/roc.js.map +1 -1
- package/indicators/roc.src.js +16 -3
- package/indicators/rsi.js +1 -1
- package/indicators/rsi.js.map +1 -1
- package/indicators/rsi.src.js +21 -3
- package/indicators/slow-stochastic.js +1 -1
- package/indicators/slow-stochastic.js.map +1 -1
- package/indicators/slow-stochastic.src.js +26 -1
- package/indicators/stochastic.js +1 -1
- package/indicators/stochastic.js.map +1 -1
- package/indicators/stochastic.src.js +16 -1
- package/indicators/supertrend.js +7 -7
- package/indicators/supertrend.js.map +1 -1
- package/indicators/supertrend.src.js +18 -6
- package/indicators/tema.js +1 -1
- package/indicators/tema.src.js +1 -1
- package/indicators/trendline.js +1 -1
- package/indicators/trendline.js.map +1 -1
- package/indicators/trendline.src.js +15 -5
- package/indicators/trix.js +1 -1
- package/indicators/trix.js.map +1 -1
- package/indicators/trix.src.js +26 -1
- package/indicators/volume-by-price.js +17 -17
- package/indicators/volume-by-price.js.map +1 -1
- package/indicators/volume-by-price.src.js +38 -10
- package/indicators/vwap.js +1 -1
- package/indicators/vwap.js.map +1 -1
- package/indicators/vwap.src.js +12 -2
- package/indicators/williams-r.js +1 -1
- package/indicators/williams-r.js.map +1 -1
- package/indicators/williams-r.src.js +11 -1
- package/indicators/wma.js +1 -1
- package/indicators/wma.js.map +1 -1
- package/indicators/wma.src.js +31 -3
- package/indicators/zigzag.js +1 -1
- package/indicators/zigzag.js.map +1 -1
- package/indicators/zigzag.src.js +12 -2
- package/modules/accessibility.js +183 -182
- package/modules/accessibility.js.map +1 -1
- package/modules/accessibility.src.js +559 -554
- package/modules/annotations-advanced.d.ts +1 -1
- package/modules/annotations-advanced.js +193 -192
- package/modules/annotations-advanced.js.map +1 -1
- package/modules/annotations-advanced.src.d.ts +1 -1
- package/modules/annotations-advanced.src.js +9263 -8654
- package/modules/annotations.d.ts +1 -1
- package/modules/annotations.js +128 -126
- package/modules/annotations.js.map +1 -1
- package/modules/annotations.src.d.ts +1 -1
- package/modules/annotations.src.js +6699 -6063
- package/modules/arc-diagram.js +1 -1
- package/modules/arc-diagram.src.js +1 -1
- package/modules/arrow-symbols.js +1 -1
- package/modules/arrow-symbols.src.js +1 -1
- package/modules/boost-canvas.d.ts +19 -0
- package/modules/boost-canvas.js +81 -16
- package/modules/boost-canvas.js.map +1 -1
- package/modules/boost-canvas.src.d.ts +19 -0
- package/modules/boost-canvas.src.js +3334 -50
- package/modules/boost.d.ts +8 -26
- package/modules/boost.js +84 -77
- package/modules/boost.js.map +1 -1
- package/modules/boost.src.d.ts +8 -26
- package/modules/boost.src.js +2423 -1888
- package/modules/broken-axis.js +2 -2
- package/modules/broken-axis.js.map +1 -1
- package/modules/broken-axis.src.js +2 -2
- package/modules/bullet.js +1 -1
- package/modules/bullet.src.js +1 -1
- package/modules/coloraxis.js +1 -1
- package/modules/coloraxis.js.map +1 -1
- package/modules/coloraxis.src.js +5 -1
- package/modules/current-date-indicator.js +1 -1
- package/modules/current-date-indicator.src.js +1 -1
- package/modules/cylinder.js +9 -9
- package/modules/cylinder.js.map +1 -1
- package/modules/cylinder.src.js +2 -2
- package/modules/data.js +1 -1
- package/modules/data.src.js +1 -1
- package/modules/datagrouping.d.ts +22 -0
- package/modules/datagrouping.js +4 -4
- package/modules/datagrouping.js.map +1 -1
- package/modules/datagrouping.src.d.ts +22 -0
- package/modules/datagrouping.src.js +66 -28
- package/modules/debugger.js +6 -5
- package/modules/debugger.js.map +1 -1
- package/modules/debugger.src.js +81 -40
- package/modules/dependency-wheel.js +12 -12
- package/modules/dependency-wheel.js.map +1 -1
- package/modules/dependency-wheel.src.js +41 -14
- package/modules/dotplot.js +1 -1
- package/modules/dotplot.src.js +1 -1
- package/modules/drag-panes.js +1 -1
- package/modules/drag-panes.src.js +1 -1
- package/modules/draggable-points.js +5 -5
- package/modules/draggable-points.js.map +1 -1
- package/modules/draggable-points.src.js +5 -4
- package/modules/drilldown.d.ts +0 -10
- package/modules/drilldown.js +29 -29
- package/modules/drilldown.js.map +1 -1
- package/modules/drilldown.src.d.ts +0 -10
- package/modules/drilldown.src.js +12 -9
- package/modules/dumbbell.js +1 -1
- package/modules/dumbbell.src.js +1 -1
- package/modules/export-data.js +25 -24
- package/modules/export-data.js.map +1 -1
- package/modules/export-data.src.js +607 -499
- package/modules/exporting.js +38 -38
- package/modules/exporting.js.map +1 -1
- package/modules/exporting.src.js +559 -507
- package/modules/full-screen.js +8 -8
- package/modules/full-screen.js.map +1 -1
- package/modules/full-screen.src.js +76 -26
- package/modules/funnel.js +1 -1
- package/modules/funnel.src.js +1 -1
- package/modules/funnel3d.js +2 -2
- package/modules/funnel3d.js.map +1 -1
- package/modules/funnel3d.src.js +2 -2
- package/modules/gantt.js +217 -216
- package/modules/gantt.js.map +1 -1
- package/modules/gantt.src.js +1481 -1440
- package/modules/grid-axis.js +1 -1
- package/modules/grid-axis.src.js +1 -1
- package/modules/heatmap.js +1 -1
- package/modules/heatmap.js.map +1 -1
- package/modules/heatmap.src.js +10 -2
- package/modules/heikinashi.js +1 -1
- package/modules/heikinashi.src.js +1 -1
- package/modules/histogram-bellcurve.js +1 -1
- package/modules/histogram-bellcurve.src.js +1 -1
- package/modules/hollowcandlestick.js +1 -1
- package/modules/hollowcandlestick.src.js +1 -1
- package/modules/item-series.js +1 -1
- package/modules/item-series.src.js +1 -1
- package/modules/lollipop.js +6 -6
- package/modules/lollipop.js.map +1 -1
- package/modules/lollipop.src.js +37 -22
- package/modules/map.d.ts +3 -3
- package/modules/map.js +171 -171
- package/modules/map.js.map +1 -1
- package/modules/map.src.d.ts +3 -3
- package/modules/map.src.js +442 -414
- package/modules/marker-clusters.js +1 -1
- package/modules/marker-clusters.js.map +1 -1
- package/modules/marker-clusters.src.js +3 -1
- package/modules/networkgraph.js +55 -50
- package/modules/networkgraph.js.map +1 -1
- package/modules/networkgraph.src.js +2259 -1938
- package/modules/no-data-to-display.js +1 -1
- package/modules/no-data-to-display.src.js +1 -1
- package/modules/offline-exporting.js +2 -2
- package/modules/offline-exporting.src.js +2 -2
- package/modules/oldie-polyfills.js +1 -1
- package/modules/oldie-polyfills.src.js +1 -1
- package/modules/oldie.js +2 -2
- package/modules/oldie.src.js +2 -2
- package/modules/organization.js +15 -15
- package/modules/organization.js.map +1 -1
- package/modules/organization.src.js +10 -2
- package/modules/overlapping-datalabels.js +1 -1
- package/modules/overlapping-datalabels.src.js +1 -1
- package/modules/parallel-coordinates.js +11 -11
- package/modules/parallel-coordinates.js.map +1 -1
- package/modules/parallel-coordinates.src.js +13 -8
- package/modules/pareto.js +1 -1
- package/modules/pareto.src.js +1 -1
- package/modules/pathfinder.js +1 -1
- package/modules/pathfinder.src.js +1 -1
- package/modules/pattern-fill.js +1 -1
- package/modules/pattern-fill.src.js +1 -1
- package/modules/price-indicator.js +1 -1
- package/modules/price-indicator.src.js +1 -1
- package/modules/pyramid3d.js +1 -1
- package/modules/pyramid3d.src.js +1 -1
- package/modules/sankey.js +1 -1
- package/modules/sankey.js.map +1 -1
- package/modules/sankey.src.js +14 -2
- package/modules/series-label.js +5 -5
- package/modules/series-label.js.map +1 -1
- package/modules/series-label.src.js +3 -3
- package/modules/series-on-point.js +1 -1
- package/modules/series-on-point.js.map +1 -1
- package/modules/series-on-point.src.js +6 -2
- package/modules/solid-gauge.js +1 -1
- package/modules/solid-gauge.src.js +2 -2
- package/modules/sonification.d.ts +2 -2
- package/modules/sonification.js +1 -1
- package/modules/sonification.src.d.ts +2 -2
- package/modules/sonification.src.js +2 -2
- package/modules/static-scale.js +1 -1
- package/modules/static-scale.src.js +1 -1
- package/modules/stock-tools.d.ts +1 -23
- package/modules/stock-tools.js +109 -179
- package/modules/stock-tools.js.map +1 -1
- package/modules/stock-tools.src.d.ts +1 -23
- package/modules/stock-tools.src.js +2605 -6335
- package/modules/stock.d.ts +8 -0
- package/modules/stock.js +105 -105
- package/modules/stock.js.map +1 -1
- package/modules/stock.src.d.ts +8 -0
- package/modules/stock.src.js +105 -45
- package/modules/streamgraph.js +1 -1
- package/modules/streamgraph.src.js +1 -1
- package/modules/sunburst.js +72 -72
- package/modules/sunburst.js.map +1 -1
- package/modules/sunburst.src.js +38 -12
- package/modules/tilemap.js +1 -1
- package/modules/tilemap.src.js +1 -1
- package/modules/timeline.js +1 -1
- package/modules/timeline.js.map +1 -1
- package/modules/timeline.src.js +3 -1
- package/modules/treegrid.js +57 -57
- package/modules/treegrid.js.map +1 -1
- package/modules/treegrid.src.js +1022 -1014
- package/modules/treemap.js +1 -1
- package/modules/treemap.js.map +1 -1
- package/modules/treemap.src.js +8 -4
- package/modules/variable-pie.js +1 -1
- package/modules/variable-pie.src.js +1 -1
- package/modules/variwide.js +1 -1
- package/modules/variwide.src.js +1 -1
- package/modules/vector.js +2 -2
- package/modules/vector.js.map +1 -1
- package/modules/vector.src.js +3 -5
- package/modules/venn.js +1 -1
- package/modules/venn.src.js +5 -5
- package/modules/windbarb.js +1 -1
- package/modules/windbarb.src.js +1 -1
- package/modules/wordcloud.js +1 -1
- package/modules/wordcloud.src.js +3 -3
- package/modules/xrange.js +17 -17
- package/modules/xrange.js.map +1 -1
- package/modules/xrange.src.js +411 -397
- package/package.json +1 -1
- package/themes/avocado.js +1 -1
- package/themes/avocado.src.js +1 -1
- package/themes/brand-dark.js +1 -1
- package/themes/brand-dark.src.js +1 -1
- package/themes/brand-light.js +1 -1
- package/themes/brand-light.src.js +1 -1
- package/themes/dark-blue.js +1 -1
- package/themes/dark-blue.src.js +1 -1
- package/themes/dark-green.js +1 -1
- package/themes/dark-green.src.js +1 -1
- package/themes/dark-unica.js +1 -1
- package/themes/dark-unica.src.js +1 -1
- package/themes/gray.js +1 -1
- package/themes/gray.src.js +1 -1
- package/themes/grid-light.js +1 -1
- package/themes/grid-light.src.js +1 -1
- package/themes/grid.js +1 -1
- package/themes/grid.src.js +1 -1
- package/themes/high-contrast-dark.js +1 -1
- package/themes/high-contrast-dark.src.js +1 -1
- package/themes/high-contrast-light.js +1 -1
- package/themes/high-contrast-light.src.js +1 -1
- package/themes/sand-signika.js +1 -1
- package/themes/sand-signika.src.js +1 -1
- package/themes/skies.js +1 -1
- package/themes/skies.src.js +1 -1
- package/themes/sunset.js +1 -1
- package/themes/sunset.src.js +1 -1
- package/es-modules/Core/Axis/StackingAxis.js +0 -215
- package/es-modules/Core/Axis/TreeGridAxis.js +0 -720
- package/es-modules/Core/Axis/TreeGridTick.js +0 -317
- package/es-modules/Extensions/Annotations/AnnotationsDefaults.js +0 -0
- package/es-modules/Extensions/Annotations/Mixins/MarkerMixin.js +0 -179
- package/es-modules/Extensions/Annotations/Popup.js +0 -1123
- package/es-modules/Extensions/Boost/BoostAttach.js +0 -154
- package/es-modules/Extensions/Boost/BoostInit.js +0 -324
- package/es-modules/Extensions/Boost/BoostOptions.js +0 -245
- package/es-modules/Extensions/Boost/BoostOverrides.js +0 -386
- package/es-modules/Extensions/Boost/BoostUtils.js +0 -255
- package/es-modules/Extensions/Boost/WGLVBuffer.js +0 -153
- package/es-modules/Extensions/Stacking.js +0 -517
- package/es-modules/Series/Networkgraph/DraggableNodes.js +0 -132
- package/es-modules/Series/Networkgraph/Integrations.js +0 -348
- package/es-modules/Series/Networkgraph/Networkgraph.js +0 -1180
- package/es-modules/Series/XRange/XRangeComposition.js +0 -49
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @license Highcharts JS v10.2.
|
|
2
|
+
* @license Highcharts JS v10.2.1 (2022-08-29)
|
|
3
3
|
*
|
|
4
4
|
* Boost module
|
|
5
5
|
*
|
|
@@ -38,7 +38,3277 @@
|
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
|
-
_registerModule(_modules, 'Extensions/
|
|
41
|
+
_registerModule(_modules, 'Extensions/Boost/Boostables.js', [], function () {
|
|
42
|
+
/* *
|
|
43
|
+
*
|
|
44
|
+
* Copyright (c) 2019-2021 Highsoft AS
|
|
45
|
+
*
|
|
46
|
+
* Boost module: stripped-down renderer for higher performance
|
|
47
|
+
*
|
|
48
|
+
* License: highcharts.com/license
|
|
49
|
+
*
|
|
50
|
+
* !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
|
|
51
|
+
*
|
|
52
|
+
* */
|
|
53
|
+
/* *
|
|
54
|
+
*
|
|
55
|
+
* Constants
|
|
56
|
+
*
|
|
57
|
+
* */
|
|
58
|
+
// These are the series we allow boosting for.
|
|
59
|
+
var Boostables = [
|
|
60
|
+
'area',
|
|
61
|
+
'areaspline',
|
|
62
|
+
'arearange',
|
|
63
|
+
'column',
|
|
64
|
+
'columnrange',
|
|
65
|
+
'bar',
|
|
66
|
+
'line',
|
|
67
|
+
'scatter',
|
|
68
|
+
'heatmap',
|
|
69
|
+
'bubble',
|
|
70
|
+
'treemap'
|
|
71
|
+
];
|
|
72
|
+
/* *
|
|
73
|
+
*
|
|
74
|
+
* Default Export
|
|
75
|
+
*
|
|
76
|
+
* */
|
|
77
|
+
|
|
78
|
+
return Boostables;
|
|
79
|
+
});
|
|
80
|
+
_registerModule(_modules, 'Extensions/Boost/BoostableMap.js', [_modules['Extensions/Boost/Boostables.js']], function (Boostables) {
|
|
81
|
+
/* *
|
|
82
|
+
*
|
|
83
|
+
* Copyright (c) 2019-2021 Highsoft AS
|
|
84
|
+
*
|
|
85
|
+
* Boost module: stripped-down renderer for higher performance
|
|
86
|
+
*
|
|
87
|
+
* License: highcharts.com/license
|
|
88
|
+
*
|
|
89
|
+
* !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
|
|
90
|
+
*
|
|
91
|
+
* */
|
|
92
|
+
/* *
|
|
93
|
+
*
|
|
94
|
+
* Imports
|
|
95
|
+
*
|
|
96
|
+
* */
|
|
97
|
+
/* *
|
|
98
|
+
*
|
|
99
|
+
* Constants
|
|
100
|
+
*
|
|
101
|
+
* */
|
|
102
|
+
// These are the series we allow boosting for.
|
|
103
|
+
var BoostableMap = {};
|
|
104
|
+
Boostables.forEach(function (item) {
|
|
105
|
+
BoostableMap[item] = true;
|
|
106
|
+
});
|
|
107
|
+
/* *
|
|
108
|
+
*
|
|
109
|
+
* Default Export
|
|
110
|
+
*
|
|
111
|
+
* */
|
|
112
|
+
|
|
113
|
+
return BoostableMap;
|
|
114
|
+
});
|
|
115
|
+
_registerModule(_modules, 'Extensions/Boost/BoostChart.js', [_modules['Extensions/Boost/BoostableMap.js'], _modules['Core/Utilities.js']], function (BoostableMap, U) {
|
|
116
|
+
/* *
|
|
117
|
+
*
|
|
118
|
+
* Copyright (c) 2019-2021 Highsoft AS
|
|
119
|
+
*
|
|
120
|
+
* Boost module: stripped-down renderer for higher performance
|
|
121
|
+
*
|
|
122
|
+
* License: highcharts.com/license
|
|
123
|
+
*
|
|
124
|
+
* !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
|
|
125
|
+
*
|
|
126
|
+
* */
|
|
127
|
+
var addEvent = U.addEvent,
|
|
128
|
+
pick = U.pick;
|
|
129
|
+
/* *
|
|
130
|
+
*
|
|
131
|
+
* Constants
|
|
132
|
+
*
|
|
133
|
+
* */
|
|
134
|
+
var composedClasses = [];
|
|
135
|
+
/* *
|
|
136
|
+
*
|
|
137
|
+
* Functions
|
|
138
|
+
*
|
|
139
|
+
* */
|
|
140
|
+
/**
|
|
141
|
+
* @private
|
|
142
|
+
*/
|
|
143
|
+
function compose(ChartClass, wglMode) {
|
|
144
|
+
if (wglMode && composedClasses.indexOf(ChartClass) === -1) {
|
|
145
|
+
composedClasses.push(ChartClass);
|
|
146
|
+
ChartClass.prototype.callbacks.push(onChartCallback);
|
|
147
|
+
}
|
|
148
|
+
return ChartClass;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Get the clip rectangle for a target, either a series or the chart.
|
|
152
|
+
* For the chart, we need to consider the maximum extent of its Y axes,
|
|
153
|
+
* in case of Highcharts Stock panes and navigator.
|
|
154
|
+
*
|
|
155
|
+
* @private
|
|
156
|
+
* @function Highcharts.Chart#getBoostClipRect
|
|
157
|
+
*/
|
|
158
|
+
function getBoostClipRect(chart, target) {
|
|
159
|
+
var clipBox = {
|
|
160
|
+
x: chart.plotLeft,
|
|
161
|
+
y: chart.plotTop,
|
|
162
|
+
width: chart.plotWidth,
|
|
163
|
+
height: chart.plotHeight
|
|
164
|
+
};
|
|
165
|
+
if (target === chart) {
|
|
166
|
+
var verticalAxes = chart.inverted ? chart.xAxis : chart.yAxis; // #14444
|
|
167
|
+
if (verticalAxes.length <= 1) {
|
|
168
|
+
clipBox.y = Math.min(verticalAxes[0].pos,
|
|
169
|
+
clipBox.y);
|
|
170
|
+
clipBox.height = (verticalAxes[0].pos -
|
|
171
|
+
chart.plotTop +
|
|
172
|
+
verticalAxes[0].len);
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
clipBox.height = chart.plotHeight;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
return clipBox;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Returns true if the chart is in series boost mode.
|
|
182
|
+
*
|
|
183
|
+
* @function Highcharts.Chart#isChartSeriesBoosting
|
|
184
|
+
*
|
|
185
|
+
* @param {Highcharts.Chart} chart
|
|
186
|
+
* the chart to check
|
|
187
|
+
*
|
|
188
|
+
* @return {boolean}
|
|
189
|
+
* true if the chart is in series boost mode
|
|
190
|
+
*/
|
|
191
|
+
function isChartSeriesBoosting(chart) {
|
|
192
|
+
var allSeries = chart.series,
|
|
193
|
+
boost = chart.boost = chart.boost || {},
|
|
194
|
+
boostOptions = chart.options.boost || {},
|
|
195
|
+
threshold = pick(boostOptions.seriesThreshold, 50);
|
|
196
|
+
if (allSeries.length >= threshold) {
|
|
197
|
+
return true;
|
|
198
|
+
}
|
|
199
|
+
if (allSeries.length === 1) {
|
|
200
|
+
return false;
|
|
201
|
+
}
|
|
202
|
+
var allowBoostForce = boostOptions.allowForce;
|
|
203
|
+
if (typeof allowBoostForce === 'undefined') {
|
|
204
|
+
allowBoostForce = true;
|
|
205
|
+
for (var _i = 0, _a = chart.xAxis; _i < _a.length; _i++) {
|
|
206
|
+
var axis = _a[_i];
|
|
207
|
+
if (pick(axis.min, -Infinity) > pick(axis.dataMin, -Infinity) ||
|
|
208
|
+
pick(axis.max, Infinity) < pick(axis.dataMax, Infinity)) {
|
|
209
|
+
allowBoostForce = false;
|
|
210
|
+
break;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
if (typeof boost.forceChartBoost !== 'undefined') {
|
|
215
|
+
if (allowBoostForce) {
|
|
216
|
+
return boost.forceChartBoost;
|
|
217
|
+
}
|
|
218
|
+
boost.forceChartBoost = void 0;
|
|
219
|
+
}
|
|
220
|
+
// If there are more than five series currently boosting,
|
|
221
|
+
// we should boost the whole chart to avoid running out of webgl contexts.
|
|
222
|
+
var canBoostCount = 0,
|
|
223
|
+
needBoostCount = 0,
|
|
224
|
+
seriesOptions;
|
|
225
|
+
for (var _b = 0, allSeries_1 = allSeries; _b < allSeries_1.length; _b++) {
|
|
226
|
+
var series = allSeries_1[_b];
|
|
227
|
+
seriesOptions = series.options;
|
|
228
|
+
// Don't count series with boostThreshold set to 0
|
|
229
|
+
// See #8950
|
|
230
|
+
// Also don't count if the series is hidden.
|
|
231
|
+
// See #9046
|
|
232
|
+
if (seriesOptions.boostThreshold === 0 ||
|
|
233
|
+
series.visible === false) {
|
|
234
|
+
continue;
|
|
235
|
+
}
|
|
236
|
+
// Don't count heatmap series as they are handled differently.
|
|
237
|
+
// In the future we should make the heatmap/treemap path compatible
|
|
238
|
+
// with forcing. See #9636.
|
|
239
|
+
if (series.type === 'heatmap') {
|
|
240
|
+
continue;
|
|
241
|
+
}
|
|
242
|
+
if (BoostableMap[series.type]) {
|
|
243
|
+
++canBoostCount;
|
|
244
|
+
}
|
|
245
|
+
if (patientMax(series.processedXData, seriesOptions.data,
|
|
246
|
+
// series.xData,
|
|
247
|
+
series.points) >= (seriesOptions.boostThreshold || Number.MAX_VALUE)) {
|
|
248
|
+
++needBoostCount;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
boost.forceChartBoost = allowBoostForce && ((canBoostCount === allSeries.length &&
|
|
252
|
+
needBoostCount > 0) ||
|
|
253
|
+
needBoostCount > 5);
|
|
254
|
+
return boost.forceChartBoost;
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Take care of the canvas blitting
|
|
258
|
+
* @private
|
|
259
|
+
*/
|
|
260
|
+
function onChartCallback(chart) {
|
|
261
|
+
/**
|
|
262
|
+
* Convert chart-level canvas to image.
|
|
263
|
+
* @private
|
|
264
|
+
*/
|
|
265
|
+
function canvasToSVG() {
|
|
266
|
+
if (chart.boost &&
|
|
267
|
+
chart.boost.wgl &&
|
|
268
|
+
isChartSeriesBoosting(chart)) {
|
|
269
|
+
chart.boost.wgl.render(chart);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Clear chart-level canvas.
|
|
274
|
+
* @private
|
|
275
|
+
*/
|
|
276
|
+
function preRender() {
|
|
277
|
+
// Reset force state
|
|
278
|
+
chart.boost = chart.boost || {};
|
|
279
|
+
chart.boost.forceChartBoost = void 0;
|
|
280
|
+
chart.boosted = false;
|
|
281
|
+
// Clear the canvas
|
|
282
|
+
if (chart.boost.clear) {
|
|
283
|
+
chart.boost.clear();
|
|
284
|
+
}
|
|
285
|
+
if (chart.boost.canvas &&
|
|
286
|
+
chart.boost.wgl &&
|
|
287
|
+
isChartSeriesBoosting(chart)) {
|
|
288
|
+
// Allocate
|
|
289
|
+
chart.boost.wgl.allocateBuffer(chart);
|
|
290
|
+
}
|
|
291
|
+
// see #6518 + #6739
|
|
292
|
+
if (chart.boost.markerGroup &&
|
|
293
|
+
chart.xAxis &&
|
|
294
|
+
chart.xAxis.length > 0 &&
|
|
295
|
+
chart.yAxis &&
|
|
296
|
+
chart.yAxis.length > 0) {
|
|
297
|
+
chart.boost.markerGroup.translate(chart.xAxis[0].pos, chart.yAxis[0].pos);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
addEvent(chart, 'predraw', preRender);
|
|
301
|
+
addEvent(chart, 'render', canvasToSVG);
|
|
302
|
+
// addEvent(chart, 'zoom', function () {
|
|
303
|
+
// chart.boostForceChartBoost =
|
|
304
|
+
// shouldForceChartSeriesBoosting(chart);
|
|
305
|
+
// });
|
|
306
|
+
var prevX = -1;
|
|
307
|
+
var prevY = -1;
|
|
308
|
+
addEvent(chart.pointer, 'afterGetHoverData', function () {
|
|
309
|
+
var series = chart.hoverSeries;
|
|
310
|
+
chart.boost = chart.boost || {};
|
|
311
|
+
if (chart.boost.markerGroup && series) {
|
|
312
|
+
var xAxis = chart.inverted ? series.yAxis : series.xAxis;
|
|
313
|
+
var yAxis = chart.inverted ? series.xAxis : series.yAxis;
|
|
314
|
+
if ((xAxis && xAxis.pos !== prevX) ||
|
|
315
|
+
(yAxis && yAxis.pos !== prevY)) {
|
|
316
|
+
// #10464: Keep the marker group position in sync with the
|
|
317
|
+
// position of the hovered series axes since there is only
|
|
318
|
+
// one shared marker group when boosting.
|
|
319
|
+
chart.boost.markerGroup.translate(xAxis.pos, yAxis.pos);
|
|
320
|
+
prevX = xAxis.pos;
|
|
321
|
+
prevY = yAxis.pos;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
/**
|
|
327
|
+
* Tolerant max() function.
|
|
328
|
+
*
|
|
329
|
+
* @private
|
|
330
|
+
* @param {...Array<Array<unknown>>} args
|
|
331
|
+
* Max arguments
|
|
332
|
+
* @return {number}
|
|
333
|
+
* Max value
|
|
334
|
+
*/
|
|
335
|
+
function patientMax() {
|
|
336
|
+
var args = [];
|
|
337
|
+
for (var _i = 0; _i < arguments.length; _i++) {
|
|
338
|
+
args[_i] = arguments[_i];
|
|
339
|
+
}
|
|
340
|
+
var r = -Number.MAX_VALUE;
|
|
341
|
+
args.forEach(function (t) {
|
|
342
|
+
if (typeof t !== 'undefined' &&
|
|
343
|
+
t !== null &&
|
|
344
|
+
typeof t.length !== 'undefined') {
|
|
345
|
+
// r = r < t.length ? t.length : r;
|
|
346
|
+
if (t.length > 0) {
|
|
347
|
+
r = t.length;
|
|
348
|
+
return true;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
});
|
|
352
|
+
return r;
|
|
353
|
+
}
|
|
354
|
+
/* *
|
|
355
|
+
*
|
|
356
|
+
* Default Export
|
|
357
|
+
*
|
|
358
|
+
* */
|
|
359
|
+
var BoostChart = {
|
|
360
|
+
compose: compose,
|
|
361
|
+
getBoostClipRect: getBoostClipRect,
|
|
362
|
+
isChartSeriesBoosting: isChartSeriesBoosting
|
|
363
|
+
};
|
|
364
|
+
|
|
365
|
+
return BoostChart;
|
|
366
|
+
});
|
|
367
|
+
_registerModule(_modules, 'Extensions/Boost/WGLDrawMode.js', [], function () {
|
|
368
|
+
/* *
|
|
369
|
+
*
|
|
370
|
+
* Copyright (c) 2019-2021 Highsoft AS
|
|
371
|
+
*
|
|
372
|
+
* Boost module: stripped-down renderer for higher performance
|
|
373
|
+
*
|
|
374
|
+
* License: highcharts.com/license
|
|
375
|
+
*
|
|
376
|
+
* !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
|
|
377
|
+
*
|
|
378
|
+
* */
|
|
379
|
+
/* *
|
|
380
|
+
*
|
|
381
|
+
* Constants
|
|
382
|
+
*
|
|
383
|
+
* */
|
|
384
|
+
var WGLDrawMode = {
|
|
385
|
+
'area': 'LINES',
|
|
386
|
+
'arearange': 'LINES',
|
|
387
|
+
'areaspline': 'LINES',
|
|
388
|
+
'column': 'LINES',
|
|
389
|
+
'columnrange': 'LINES',
|
|
390
|
+
'bar': 'LINES',
|
|
391
|
+
'line': 'LINE_STRIP',
|
|
392
|
+
'scatter': 'POINTS',
|
|
393
|
+
'heatmap': 'TRIANGLES',
|
|
394
|
+
'treemap': 'TRIANGLES',
|
|
395
|
+
'bubble': 'POINTS'
|
|
396
|
+
};
|
|
397
|
+
/* *
|
|
398
|
+
*
|
|
399
|
+
* Default Export
|
|
400
|
+
*
|
|
401
|
+
* */
|
|
402
|
+
|
|
403
|
+
return WGLDrawMode;
|
|
404
|
+
});
|
|
405
|
+
_registerModule(_modules, 'Extensions/Boost/WGLShader.js', [_modules['Core/Utilities.js']], function (U) {
|
|
406
|
+
/* *
|
|
407
|
+
*
|
|
408
|
+
* Copyright (c) 2019-2021 Highsoft AS
|
|
409
|
+
*
|
|
410
|
+
* Boost module: stripped-down renderer for higher performance
|
|
411
|
+
*
|
|
412
|
+
* License: highcharts.com/license
|
|
413
|
+
*
|
|
414
|
+
* !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
|
|
415
|
+
*
|
|
416
|
+
* */
|
|
417
|
+
var clamp = U.clamp,
|
|
418
|
+
error = U.error,
|
|
419
|
+
pick = U.pick;
|
|
420
|
+
/* *
|
|
421
|
+
*
|
|
422
|
+
* Constants
|
|
423
|
+
*
|
|
424
|
+
* */
|
|
425
|
+
var fragmentShader = [
|
|
426
|
+
/* eslint-disable max-len, @typescript-eslint/indent */
|
|
427
|
+
'precision highp float;',
|
|
428
|
+
'uniform vec4 fillColor;',
|
|
429
|
+
'varying highp vec2 position;',
|
|
430
|
+
'varying highp vec4 vColor;',
|
|
431
|
+
'uniform sampler2D uSampler;',
|
|
432
|
+
'uniform bool isCircle;',
|
|
433
|
+
'uniform bool hasColor;',
|
|
434
|
+
// 'vec4 toColor(float value, vec2 point) {',
|
|
435
|
+
// 'return vec4(0.0, 0.0, 0.0, 0.0);',
|
|
436
|
+
// '}',
|
|
437
|
+
'void main(void) {',
|
|
438
|
+
'vec4 col = fillColor;',
|
|
439
|
+
'vec4 tcol = texture2D(uSampler, gl_PointCoord.st);',
|
|
440
|
+
'if (hasColor) {',
|
|
441
|
+
'col = vColor;',
|
|
442
|
+
'}',
|
|
443
|
+
'if (isCircle) {',
|
|
444
|
+
'col *= tcol;',
|
|
445
|
+
'if (tcol.r < 0.0) {',
|
|
446
|
+
'discard;',
|
|
447
|
+
'} else {',
|
|
448
|
+
'gl_FragColor = col;',
|
|
449
|
+
'}',
|
|
450
|
+
'} else {',
|
|
451
|
+
'gl_FragColor = col;',
|
|
452
|
+
'}',
|
|
453
|
+
'}'
|
|
454
|
+
/* eslint-enable max-len, @typescript-eslint/indent */
|
|
455
|
+
].join('\n');
|
|
456
|
+
var vertexShader = [
|
|
457
|
+
/* eslint-disable max-len, @typescript-eslint/indent */
|
|
458
|
+
'#version 100',
|
|
459
|
+
'#define LN10 2.302585092994046',
|
|
460
|
+
'precision highp float;',
|
|
461
|
+
'attribute vec4 aVertexPosition;',
|
|
462
|
+
'attribute vec4 aColor;',
|
|
463
|
+
'varying highp vec2 position;',
|
|
464
|
+
'varying highp vec4 vColor;',
|
|
465
|
+
'uniform mat4 uPMatrix;',
|
|
466
|
+
'uniform float pSize;',
|
|
467
|
+
'uniform float translatedThreshold;',
|
|
468
|
+
'uniform bool hasThreshold;',
|
|
469
|
+
'uniform bool skipTranslation;',
|
|
470
|
+
'uniform float xAxisTrans;',
|
|
471
|
+
'uniform float xAxisMin;',
|
|
472
|
+
'uniform float xAxisMinPad;',
|
|
473
|
+
'uniform float xAxisPointRange;',
|
|
474
|
+
'uniform float xAxisLen;',
|
|
475
|
+
'uniform bool xAxisPostTranslate;',
|
|
476
|
+
'uniform float xAxisOrdinalSlope;',
|
|
477
|
+
'uniform float xAxisOrdinalOffset;',
|
|
478
|
+
'uniform float xAxisPos;',
|
|
479
|
+
'uniform bool xAxisCVSCoord;',
|
|
480
|
+
'uniform bool xAxisIsLog;',
|
|
481
|
+
'uniform bool xAxisReversed;',
|
|
482
|
+
'uniform float yAxisTrans;',
|
|
483
|
+
'uniform float yAxisMin;',
|
|
484
|
+
'uniform float yAxisMinPad;',
|
|
485
|
+
'uniform float yAxisPointRange;',
|
|
486
|
+
'uniform float yAxisLen;',
|
|
487
|
+
'uniform bool yAxisPostTranslate;',
|
|
488
|
+
'uniform float yAxisOrdinalSlope;',
|
|
489
|
+
'uniform float yAxisOrdinalOffset;',
|
|
490
|
+
'uniform float yAxisPos;',
|
|
491
|
+
'uniform bool yAxisCVSCoord;',
|
|
492
|
+
'uniform bool yAxisIsLog;',
|
|
493
|
+
'uniform bool yAxisReversed;',
|
|
494
|
+
'uniform bool isBubble;',
|
|
495
|
+
'uniform bool bubbleSizeByArea;',
|
|
496
|
+
'uniform float bubbleZMin;',
|
|
497
|
+
'uniform float bubbleZMax;',
|
|
498
|
+
'uniform float bubbleZThreshold;',
|
|
499
|
+
'uniform float bubbleMinSize;',
|
|
500
|
+
'uniform float bubbleMaxSize;',
|
|
501
|
+
'uniform bool bubbleSizeAbs;',
|
|
502
|
+
'uniform bool isInverted;',
|
|
503
|
+
'float bubbleRadius(){',
|
|
504
|
+
'float value = aVertexPosition.w;',
|
|
505
|
+
'float zMax = bubbleZMax;',
|
|
506
|
+
'float zMin = bubbleZMin;',
|
|
507
|
+
'float radius = 0.0;',
|
|
508
|
+
'float pos = 0.0;',
|
|
509
|
+
'float zRange = zMax - zMin;',
|
|
510
|
+
'if (bubbleSizeAbs){',
|
|
511
|
+
'value = value - bubbleZThreshold;',
|
|
512
|
+
'zMax = max(zMax - bubbleZThreshold, zMin - bubbleZThreshold);',
|
|
513
|
+
'zMin = 0.0;',
|
|
514
|
+
'}',
|
|
515
|
+
'if (value < zMin){',
|
|
516
|
+
'radius = bubbleZMin / 2.0 - 1.0;',
|
|
517
|
+
'} else {',
|
|
518
|
+
'pos = zRange > 0.0 ? (value - zMin) / zRange : 0.5;',
|
|
519
|
+
'if (bubbleSizeByArea && pos > 0.0){',
|
|
520
|
+
'pos = sqrt(pos);',
|
|
521
|
+
'}',
|
|
522
|
+
'radius = ceil(bubbleMinSize + pos * (bubbleMaxSize - bubbleMinSize)) / 2.0;',
|
|
523
|
+
'}',
|
|
524
|
+
'return radius * 2.0;',
|
|
525
|
+
'}',
|
|
526
|
+
'float translate(float val,',
|
|
527
|
+
'float pointPlacement,',
|
|
528
|
+
'float localA,',
|
|
529
|
+
'float localMin,',
|
|
530
|
+
'float minPixelPadding,',
|
|
531
|
+
'float pointRange,',
|
|
532
|
+
'float len,',
|
|
533
|
+
'bool cvsCoord,',
|
|
534
|
+
'bool isLog,',
|
|
535
|
+
'bool reversed',
|
|
536
|
+
'){',
|
|
537
|
+
'float sign = 1.0;',
|
|
538
|
+
'float cvsOffset = 0.0;',
|
|
539
|
+
'if (cvsCoord) {',
|
|
540
|
+
'sign *= -1.0;',
|
|
541
|
+
'cvsOffset = len;',
|
|
542
|
+
'}',
|
|
543
|
+
'if (isLog) {',
|
|
544
|
+
'val = log(val) / LN10;',
|
|
545
|
+
'}',
|
|
546
|
+
'if (reversed) {',
|
|
547
|
+
'sign *= -1.0;',
|
|
548
|
+
'cvsOffset -= sign * len;',
|
|
549
|
+
'}',
|
|
550
|
+
'return sign * (val - localMin) * localA + cvsOffset + ',
|
|
551
|
+
'(sign * minPixelPadding);',
|
|
552
|
+
'}',
|
|
553
|
+
'float xToPixels(float value) {',
|
|
554
|
+
'if (skipTranslation){',
|
|
555
|
+
'return value;// + xAxisPos;',
|
|
556
|
+
'}',
|
|
557
|
+
'return translate(value, 0.0, xAxisTrans, xAxisMin, xAxisMinPad, xAxisPointRange, xAxisLen, xAxisCVSCoord, xAxisIsLog, xAxisReversed);// + xAxisPos;',
|
|
558
|
+
'}',
|
|
559
|
+
'float yToPixels(float value, float checkTreshold) {',
|
|
560
|
+
'float v;',
|
|
561
|
+
'if (skipTranslation){',
|
|
562
|
+
'v = value;// + yAxisPos;',
|
|
563
|
+
'} else {',
|
|
564
|
+
'v = translate(value, 0.0, yAxisTrans, yAxisMin, yAxisMinPad, yAxisPointRange, yAxisLen, yAxisCVSCoord, yAxisIsLog, yAxisReversed);// + yAxisPos;',
|
|
565
|
+
'if (v > yAxisLen) {',
|
|
566
|
+
'v = yAxisLen;',
|
|
567
|
+
'}',
|
|
568
|
+
'}',
|
|
569
|
+
'if (checkTreshold > 0.0 && hasThreshold) {',
|
|
570
|
+
'v = min(v, translatedThreshold);',
|
|
571
|
+
'}',
|
|
572
|
+
'return v;',
|
|
573
|
+
'}',
|
|
574
|
+
'void main(void) {',
|
|
575
|
+
'if (isBubble){',
|
|
576
|
+
'gl_PointSize = bubbleRadius();',
|
|
577
|
+
'} else {',
|
|
578
|
+
'gl_PointSize = pSize;',
|
|
579
|
+
'}',
|
|
580
|
+
// 'gl_PointSize = 10.0;',
|
|
581
|
+
'vColor = aColor;',
|
|
582
|
+
'if (skipTranslation && isInverted) {',
|
|
583
|
+
// If we get translated values from JS, just swap them (x, y)
|
|
584
|
+
'gl_Position = uPMatrix * vec4(aVertexPosition.y + yAxisPos, aVertexPosition.x + xAxisPos, 0.0, 1.0);',
|
|
585
|
+
'} else if (isInverted) {',
|
|
586
|
+
// But when calculating pixel positions directly,
|
|
587
|
+
// swap axes and values (x, y)
|
|
588
|
+
'gl_Position = uPMatrix * vec4(yToPixels(aVertexPosition.y, aVertexPosition.z) + yAxisPos, xToPixels(aVertexPosition.x) + xAxisPos, 0.0, 1.0);',
|
|
589
|
+
'} else {',
|
|
590
|
+
'gl_Position = uPMatrix * vec4(xToPixels(aVertexPosition.x) + xAxisPos, yToPixels(aVertexPosition.y, aVertexPosition.z) + yAxisPos, 0.0, 1.0);',
|
|
591
|
+
'}',
|
|
592
|
+
// 'gl_Position = uPMatrix * vec4(aVertexPosition.x, aVertexPosition.y, 0.0, 1.0);',
|
|
593
|
+
'}'
|
|
594
|
+
/* eslint-enable max-len, @typescript-eslint/indent */
|
|
595
|
+
].join('\n');
|
|
596
|
+
/* *
|
|
597
|
+
*
|
|
598
|
+
* Class
|
|
599
|
+
*
|
|
600
|
+
* */
|
|
601
|
+
/* eslint-disable valid-jsdoc */
|
|
602
|
+
/**
|
|
603
|
+
* A static shader mimicing axis translation functions found in Core/Axis
|
|
604
|
+
*
|
|
605
|
+
* @private
|
|
606
|
+
*
|
|
607
|
+
* @param {WebGLContext} gl
|
|
608
|
+
* the context in which the shader is active
|
|
609
|
+
*/
|
|
610
|
+
var WGLShader = /** @class */ (function () {
|
|
611
|
+
/* *
|
|
612
|
+
*
|
|
613
|
+
* Constructor
|
|
614
|
+
*
|
|
615
|
+
* */
|
|
616
|
+
function WGLShader(gl) {
|
|
617
|
+
// Error stack
|
|
618
|
+
this.errors = [];
|
|
619
|
+
this.uLocations = {};
|
|
620
|
+
this.gl = gl;
|
|
621
|
+
if (gl && !this.createShader()) {
|
|
622
|
+
return void 0;
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
/* *
|
|
626
|
+
*
|
|
627
|
+
* Functions
|
|
628
|
+
*
|
|
629
|
+
* */
|
|
630
|
+
/**
|
|
631
|
+
* Bind the shader.
|
|
632
|
+
* This makes the shader the active one until another one is bound,
|
|
633
|
+
* or until 0 is bound.
|
|
634
|
+
* @private
|
|
635
|
+
*/
|
|
636
|
+
WGLShader.prototype.bind = function () {
|
|
637
|
+
if (this.gl && this.shaderProgram) {
|
|
638
|
+
this.gl.useProgram(this.shaderProgram);
|
|
639
|
+
}
|
|
640
|
+
};
|
|
641
|
+
/**
|
|
642
|
+
* Create the shader.
|
|
643
|
+
* Loads the shader program statically defined above
|
|
644
|
+
* @private
|
|
645
|
+
*/
|
|
646
|
+
WGLShader.prototype.createShader = function () {
|
|
647
|
+
var _this = this;
|
|
648
|
+
var v = this.stringToProgram(vertexShader, 'vertex'), f = this.stringToProgram(fragmentShader, 'fragment'), uloc = function (n) { return (_this.gl.getUniformLocation(_this.shaderProgram, n)); };
|
|
649
|
+
if (!v || !f) {
|
|
650
|
+
this.shaderProgram = false;
|
|
651
|
+
this.handleErrors();
|
|
652
|
+
return false;
|
|
653
|
+
}
|
|
654
|
+
this.shaderProgram = this.gl.createProgram();
|
|
655
|
+
this.gl.attachShader(this.shaderProgram, v);
|
|
656
|
+
this.gl.attachShader(this.shaderProgram, f);
|
|
657
|
+
this.gl.linkProgram(this.shaderProgram);
|
|
658
|
+
if (!this.gl.getProgramParameter(this.shaderProgram, this.gl.LINK_STATUS)) {
|
|
659
|
+
this.errors.push(this.gl.getProgramInfoLog(this.shaderProgram));
|
|
660
|
+
this.handleErrors();
|
|
661
|
+
this.shaderProgram = false;
|
|
662
|
+
return false;
|
|
663
|
+
}
|
|
664
|
+
this.gl.useProgram(this.shaderProgram);
|
|
665
|
+
this.gl.bindAttribLocation(this.shaderProgram, 0, 'aVertexPosition');
|
|
666
|
+
this.pUniform = uloc('uPMatrix');
|
|
667
|
+
this.psUniform = uloc('pSize');
|
|
668
|
+
this.fcUniform = uloc('fillColor');
|
|
669
|
+
this.isBubbleUniform = uloc('isBubble');
|
|
670
|
+
this.bubbleSizeAbsUniform = uloc('bubbleSizeAbs');
|
|
671
|
+
this.bubbleSizeAreaUniform = uloc('bubbleSizeByArea');
|
|
672
|
+
this.uSamplerUniform = uloc('uSampler');
|
|
673
|
+
this.skipTranslationUniform = uloc('skipTranslation');
|
|
674
|
+
this.isCircleUniform = uloc('isCircle');
|
|
675
|
+
this.isInverted = uloc('isInverted');
|
|
676
|
+
return true;
|
|
677
|
+
};
|
|
678
|
+
/**
|
|
679
|
+
* Handle errors accumulated in errors stack
|
|
680
|
+
* @private
|
|
681
|
+
*/
|
|
682
|
+
WGLShader.prototype.handleErrors = function () {
|
|
683
|
+
if (this.errors.length) {
|
|
684
|
+
error('[highcharts boost] shader error - ' +
|
|
685
|
+
this.errors.join('\n'));
|
|
686
|
+
}
|
|
687
|
+
};
|
|
688
|
+
/**
|
|
689
|
+
* String to shader program
|
|
690
|
+
* @private
|
|
691
|
+
* @param {string} str
|
|
692
|
+
* Program source
|
|
693
|
+
* @param {string} type
|
|
694
|
+
* Program type: either `vertex` or `fragment`
|
|
695
|
+
*/
|
|
696
|
+
WGLShader.prototype.stringToProgram = function (str, type) {
|
|
697
|
+
var shader = this.gl.createShader(type === 'vertex' ? this.gl.VERTEX_SHADER : this.gl.FRAGMENT_SHADER);
|
|
698
|
+
this.gl.shaderSource(shader, str);
|
|
699
|
+
this.gl.compileShader(shader);
|
|
700
|
+
if (!this.gl.getShaderParameter(shader, this.gl.COMPILE_STATUS)) {
|
|
701
|
+
this.errors.push('when compiling ' +
|
|
702
|
+
type +
|
|
703
|
+
' shader:\n' +
|
|
704
|
+
this.gl.getShaderInfoLog(shader));
|
|
705
|
+
return false;
|
|
706
|
+
}
|
|
707
|
+
return shader;
|
|
708
|
+
};
|
|
709
|
+
/**
|
|
710
|
+
* Destroy the shader
|
|
711
|
+
* @private
|
|
712
|
+
*/
|
|
713
|
+
WGLShader.prototype.destroy = function () {
|
|
714
|
+
if (this.gl && this.shaderProgram) {
|
|
715
|
+
this.gl.deleteProgram(this.shaderProgram);
|
|
716
|
+
this.shaderProgram = false;
|
|
717
|
+
}
|
|
718
|
+
};
|
|
719
|
+
WGLShader.prototype.fillColorUniform = function () {
|
|
720
|
+
return this.fcUniform;
|
|
721
|
+
};
|
|
722
|
+
/**
|
|
723
|
+
* Get the shader program handle
|
|
724
|
+
* @private
|
|
725
|
+
* @return {WebGLProgram}
|
|
726
|
+
* The handle for the program
|
|
727
|
+
*/
|
|
728
|
+
WGLShader.prototype.getProgram = function () {
|
|
729
|
+
return this.shaderProgram;
|
|
730
|
+
};
|
|
731
|
+
WGLShader.prototype.pointSizeUniform = function () {
|
|
732
|
+
return this.psUniform;
|
|
733
|
+
};
|
|
734
|
+
WGLShader.prototype.perspectiveUniform = function () {
|
|
735
|
+
return this.pUniform;
|
|
736
|
+
};
|
|
737
|
+
/**
|
|
738
|
+
* Flush
|
|
739
|
+
* @private
|
|
740
|
+
*/
|
|
741
|
+
WGLShader.prototype.reset = function () {
|
|
742
|
+
if (this.gl && this.shaderProgram) {
|
|
743
|
+
this.gl.uniform1i(this.isBubbleUniform, 0);
|
|
744
|
+
this.gl.uniform1i(this.isCircleUniform, 0);
|
|
745
|
+
}
|
|
746
|
+
};
|
|
747
|
+
/**
|
|
748
|
+
* Set bubble uniforms
|
|
749
|
+
* @private
|
|
750
|
+
* @param {Highcharts.Series} series
|
|
751
|
+
* Series to use
|
|
752
|
+
*/
|
|
753
|
+
WGLShader.prototype.setBubbleUniforms = function (series, zCalcMin, zCalcMax, pixelRatio) {
|
|
754
|
+
if (pixelRatio === void 0) { pixelRatio = 1; }
|
|
755
|
+
var seriesOptions = series.options;
|
|
756
|
+
var zMin = Number.MAX_VALUE,
|
|
757
|
+
zMax = -Number.MAX_VALUE;
|
|
758
|
+
if (this.gl && this.shaderProgram && series.is('bubble')) {
|
|
759
|
+
var pxSizes = series.getPxExtremes();
|
|
760
|
+
zMin = pick(seriesOptions.zMin, clamp(zCalcMin, seriesOptions.displayNegative === false ?
|
|
761
|
+
seriesOptions.zThreshold : -Number.MAX_VALUE, zMin));
|
|
762
|
+
zMax = pick(seriesOptions.zMax, Math.max(zMax, zCalcMax));
|
|
763
|
+
this.gl.uniform1i(this.isBubbleUniform, 1);
|
|
764
|
+
this.gl.uniform1i(this.isCircleUniform, 1);
|
|
765
|
+
this.gl.uniform1i(this.bubbleSizeAreaUniform, (series.options.sizeBy !== 'width'));
|
|
766
|
+
this.gl.uniform1i(this.bubbleSizeAbsUniform, series.options
|
|
767
|
+
.sizeByAbsoluteValue);
|
|
768
|
+
this.setUniform('bubbleMinSize', pxSizes.minPxSize * pixelRatio);
|
|
769
|
+
this.setUniform('bubbleMaxSize', pxSizes.maxPxSize * pixelRatio);
|
|
770
|
+
this.setUniform('bubbleZMin', zMin);
|
|
771
|
+
this.setUniform('bubbleZMax', zMax);
|
|
772
|
+
this.setUniform('bubbleZThreshold', series.options.zThreshold);
|
|
773
|
+
}
|
|
774
|
+
};
|
|
775
|
+
/**
|
|
776
|
+
* Set the Color uniform.
|
|
777
|
+
* @private
|
|
778
|
+
* @param {Array<number>} color
|
|
779
|
+
* Array with RGBA values.
|
|
780
|
+
*/
|
|
781
|
+
WGLShader.prototype.setColor = function (color) {
|
|
782
|
+
if (this.gl && this.shaderProgram) {
|
|
783
|
+
this.gl.uniform4f(this.fcUniform, color[0] / 255.0, color[1] / 255.0, color[2] / 255.0, color[3]);
|
|
784
|
+
}
|
|
785
|
+
};
|
|
786
|
+
/**
|
|
787
|
+
* Enable/disable circle drawing
|
|
788
|
+
* @private
|
|
789
|
+
*/
|
|
790
|
+
WGLShader.prototype.setDrawAsCircle = function (flag) {
|
|
791
|
+
if (this.gl && this.shaderProgram) {
|
|
792
|
+
this.gl.uniform1i(this.isCircleUniform, flag ? 1 : 0);
|
|
793
|
+
}
|
|
794
|
+
};
|
|
795
|
+
/**
|
|
796
|
+
* Set if inversion state
|
|
797
|
+
* @private
|
|
798
|
+
* @param {number} flag
|
|
799
|
+
* Inversion flag
|
|
800
|
+
*/
|
|
801
|
+
WGLShader.prototype.setInverted = function (flag) {
|
|
802
|
+
if (this.gl && this.shaderProgram) {
|
|
803
|
+
this.gl.uniform1i(this.isInverted, flag);
|
|
804
|
+
}
|
|
805
|
+
};
|
|
806
|
+
/**
|
|
807
|
+
* Set the perspective matrix
|
|
808
|
+
* @private
|
|
809
|
+
* @param {Float32List} m
|
|
810
|
+
* Matrix 4 x 4
|
|
811
|
+
*/
|
|
812
|
+
WGLShader.prototype.setPMatrix = function (m) {
|
|
813
|
+
if (this.gl && this.shaderProgram) {
|
|
814
|
+
this.gl.uniformMatrix4fv(this.pUniform, false, m);
|
|
815
|
+
}
|
|
816
|
+
};
|
|
817
|
+
/**
|
|
818
|
+
* Set the point size.
|
|
819
|
+
* @private
|
|
820
|
+
* @param {number} p
|
|
821
|
+
* Point size
|
|
822
|
+
*/
|
|
823
|
+
WGLShader.prototype.setPointSize = function (p) {
|
|
824
|
+
if (this.gl && this.shaderProgram) {
|
|
825
|
+
this.gl.uniform1f(this.psUniform, p);
|
|
826
|
+
}
|
|
827
|
+
};
|
|
828
|
+
/**
|
|
829
|
+
* Set skip translation
|
|
830
|
+
* @private
|
|
831
|
+
*/
|
|
832
|
+
WGLShader.prototype.setSkipTranslation = function (flag) {
|
|
833
|
+
if (this.gl && this.shaderProgram) {
|
|
834
|
+
this.gl.uniform1i(this.skipTranslationUniform, flag === true ? 1 : 0);
|
|
835
|
+
}
|
|
836
|
+
};
|
|
837
|
+
/**
|
|
838
|
+
* Set the active texture
|
|
839
|
+
* @private
|
|
840
|
+
* @param {number} texture
|
|
841
|
+
* Texture to activate
|
|
842
|
+
*/
|
|
843
|
+
WGLShader.prototype.setTexture = function (texture) {
|
|
844
|
+
if (this.gl && this.shaderProgram) {
|
|
845
|
+
this.gl.uniform1i(this.uSamplerUniform, texture);
|
|
846
|
+
}
|
|
847
|
+
};
|
|
848
|
+
/**
|
|
849
|
+
* Set a uniform value.
|
|
850
|
+
* This uses a hash map to cache uniform locations.
|
|
851
|
+
* @private
|
|
852
|
+
* @param {string} name
|
|
853
|
+
* Name of the uniform to set.
|
|
854
|
+
* @param {number} val
|
|
855
|
+
* Value to set
|
|
856
|
+
*/
|
|
857
|
+
WGLShader.prototype.setUniform = function (name, val) {
|
|
858
|
+
if (this.gl && this.shaderProgram) {
|
|
859
|
+
var u = this.uLocations[name] = (this.uLocations[name] ||
|
|
860
|
+
this.gl.getUniformLocation(this.shaderProgram,
|
|
861
|
+
name));
|
|
862
|
+
this.gl.uniform1f(u, val);
|
|
863
|
+
}
|
|
864
|
+
};
|
|
865
|
+
return WGLShader;
|
|
866
|
+
}());
|
|
867
|
+
/* *
|
|
868
|
+
*
|
|
869
|
+
* Default Export
|
|
870
|
+
*
|
|
871
|
+
* */
|
|
872
|
+
|
|
873
|
+
return WGLShader;
|
|
874
|
+
});
|
|
875
|
+
_registerModule(_modules, 'Extensions/Boost/WGLVertexBuffer.js', [], function () {
|
|
876
|
+
/* *
|
|
877
|
+
*
|
|
878
|
+
* Copyright (c) 2019-2021 Highsoft AS
|
|
879
|
+
*
|
|
880
|
+
* Boost module: stripped-down renderer for higher performance
|
|
881
|
+
*
|
|
882
|
+
* License: highcharts.com/license
|
|
883
|
+
*
|
|
884
|
+
* !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
|
|
885
|
+
*
|
|
886
|
+
* */
|
|
887
|
+
/* *
|
|
888
|
+
*
|
|
889
|
+
* Class
|
|
890
|
+
*
|
|
891
|
+
* */
|
|
892
|
+
/**
|
|
893
|
+
* Vertex Buffer abstraction.
|
|
894
|
+
* A vertex buffer is a set of vertices which are passed to the GPU
|
|
895
|
+
* in a single call.
|
|
896
|
+
*
|
|
897
|
+
* @private
|
|
898
|
+
* @class
|
|
899
|
+
* @name WGLVertexBuffer
|
|
900
|
+
*
|
|
901
|
+
* @param {WebGLContext} gl
|
|
902
|
+
* Context in which to create the buffer.
|
|
903
|
+
* @param {WGLShader} shader
|
|
904
|
+
* Shader to use.
|
|
905
|
+
*/
|
|
906
|
+
var WGLVertexBuffer = /** @class */ (function () {
|
|
907
|
+
/* *
|
|
908
|
+
*
|
|
909
|
+
* Constructor
|
|
910
|
+
*
|
|
911
|
+
* */
|
|
912
|
+
function WGLVertexBuffer(gl, shader, dataComponents
|
|
913
|
+
/* , type */
|
|
914
|
+
) {
|
|
915
|
+
/* *
|
|
916
|
+
*
|
|
917
|
+
* Properties
|
|
918
|
+
*
|
|
919
|
+
* */
|
|
920
|
+
this.buffer = false;
|
|
921
|
+
this.iterator = 0;
|
|
922
|
+
this.preAllocated = false;
|
|
923
|
+
this.vertAttribute = false;
|
|
924
|
+
this.components = dataComponents || 2;
|
|
925
|
+
this.dataComponents = dataComponents;
|
|
926
|
+
this.gl = gl;
|
|
927
|
+
this.shader = shader;
|
|
928
|
+
}
|
|
929
|
+
/* *
|
|
930
|
+
*
|
|
931
|
+
* Functions
|
|
932
|
+
*
|
|
933
|
+
* */
|
|
934
|
+
/**
|
|
935
|
+
* Note about pre-allocated buffers:
|
|
936
|
+
* - This is slower for charts with many series
|
|
937
|
+
* @private
|
|
938
|
+
*/
|
|
939
|
+
WGLVertexBuffer.prototype.allocate = function (size) {
|
|
940
|
+
this.iterator = -1;
|
|
941
|
+
this.preAllocated = new Float32Array(size * 4);
|
|
942
|
+
};
|
|
943
|
+
/**
|
|
944
|
+
* Bind the buffer
|
|
945
|
+
* @private
|
|
946
|
+
*/
|
|
947
|
+
WGLVertexBuffer.prototype.bind = function () {
|
|
948
|
+
if (!this.buffer) {
|
|
949
|
+
return false;
|
|
950
|
+
}
|
|
951
|
+
// gl.bindAttribLocation(shader.program(), 0, 'aVertexPosition');
|
|
952
|
+
// gl.enableVertexAttribArray(vertAttribute);
|
|
953
|
+
// gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
|
|
954
|
+
this.gl.vertexAttribPointer(this.vertAttribute, this.components, this.gl.FLOAT, false, 0, 0);
|
|
955
|
+
// gl.enableVertexAttribArray(vertAttribute);
|
|
956
|
+
};
|
|
957
|
+
/**
|
|
958
|
+
* Build the buffer
|
|
959
|
+
* @private
|
|
960
|
+
* @param {Array<number>} dataIn
|
|
961
|
+
* Zero padded array of indices
|
|
962
|
+
* @param {string} attrib
|
|
963
|
+
* Name of the Attribute to bind the buffer to
|
|
964
|
+
* @param {number} dataComponents
|
|
965
|
+
* Mumber of components per. indice
|
|
966
|
+
*/
|
|
967
|
+
WGLVertexBuffer.prototype.build = function (dataIn, attrib, dataComponents) {
|
|
968
|
+
var farray;
|
|
969
|
+
this.data = dataIn || [];
|
|
970
|
+
if ((!this.data || this.data.length === 0) && !this.preAllocated) {
|
|
971
|
+
// console.error('trying to render empty vbuffer');
|
|
972
|
+
this.destroy();
|
|
973
|
+
return false;
|
|
974
|
+
}
|
|
975
|
+
this.components = dataComponents || this.components;
|
|
976
|
+
if (this.buffer) {
|
|
977
|
+
this.gl.deleteBuffer(this.buffer);
|
|
978
|
+
}
|
|
979
|
+
if (!this.preAllocated) {
|
|
980
|
+
farray = new Float32Array(this.data);
|
|
981
|
+
}
|
|
982
|
+
this.buffer = this.gl.createBuffer();
|
|
983
|
+
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.buffer);
|
|
984
|
+
this.gl.bufferData(this.gl.ARRAY_BUFFER, this.preAllocated || farray, this.gl.STATIC_DRAW);
|
|
985
|
+
// gl.bindAttribLocation(shader.program(), 0, 'aVertexPosition');
|
|
986
|
+
this.vertAttribute = this.gl
|
|
987
|
+
.getAttribLocation(this.shader.getProgram(), attrib);
|
|
988
|
+
this.gl.enableVertexAttribArray(this.vertAttribute);
|
|
989
|
+
// Trigger cleanup
|
|
990
|
+
farray = false;
|
|
991
|
+
return true;
|
|
992
|
+
};
|
|
993
|
+
/**
|
|
994
|
+
* @private
|
|
995
|
+
*/
|
|
996
|
+
WGLVertexBuffer.prototype.destroy = function () {
|
|
997
|
+
if (this.buffer) {
|
|
998
|
+
this.gl.deleteBuffer(this.buffer);
|
|
999
|
+
this.buffer = false;
|
|
1000
|
+
this.vertAttribute = false;
|
|
1001
|
+
}
|
|
1002
|
+
this.iterator = 0;
|
|
1003
|
+
this.components = this.dataComponents || 2;
|
|
1004
|
+
this.data = [];
|
|
1005
|
+
};
|
|
1006
|
+
/**
|
|
1007
|
+
* Adds data to the pre-allocated buffer.
|
|
1008
|
+
* @private
|
|
1009
|
+
* @param {number} x
|
|
1010
|
+
* X data
|
|
1011
|
+
* @param {number} y
|
|
1012
|
+
* Y data
|
|
1013
|
+
* @param {number} a
|
|
1014
|
+
* A data
|
|
1015
|
+
* @param {number} b
|
|
1016
|
+
* B data
|
|
1017
|
+
*/
|
|
1018
|
+
WGLVertexBuffer.prototype.push = function (x, y, a, b) {
|
|
1019
|
+
if (this.preAllocated) { // && iterator <= preAllocated.length - 4) {
|
|
1020
|
+
this.preAllocated[++this.iterator] = x;
|
|
1021
|
+
this.preAllocated[++this.iterator] = y;
|
|
1022
|
+
this.preAllocated[++this.iterator] = a;
|
|
1023
|
+
this.preAllocated[++this.iterator] = b;
|
|
1024
|
+
}
|
|
1025
|
+
};
|
|
1026
|
+
/**
|
|
1027
|
+
* Render the buffer
|
|
1028
|
+
*
|
|
1029
|
+
* @private
|
|
1030
|
+
* @param {number} from
|
|
1031
|
+
* Start indice.
|
|
1032
|
+
* @param {number} to
|
|
1033
|
+
* End indice.
|
|
1034
|
+
* @param {WGLDrawModeValue} drawMode
|
|
1035
|
+
* Draw mode.
|
|
1036
|
+
*/
|
|
1037
|
+
WGLVertexBuffer.prototype.render = function (from, to, drawMode) {
|
|
1038
|
+
var length = this.preAllocated ?
|
|
1039
|
+
this.preAllocated.length : this.data.length;
|
|
1040
|
+
if (!this.buffer) {
|
|
1041
|
+
return false;
|
|
1042
|
+
}
|
|
1043
|
+
if (!length) {
|
|
1044
|
+
return false;
|
|
1045
|
+
}
|
|
1046
|
+
if (!from || from > length || from < 0) {
|
|
1047
|
+
from = 0;
|
|
1048
|
+
}
|
|
1049
|
+
if (!to || to > length) {
|
|
1050
|
+
to = length;
|
|
1051
|
+
}
|
|
1052
|
+
if (from >= to) {
|
|
1053
|
+
return false;
|
|
1054
|
+
}
|
|
1055
|
+
drawMode = drawMode || 'POINTS';
|
|
1056
|
+
this.gl.drawArrays(this.gl[drawMode], from / this.components, (to - from) / this.components);
|
|
1057
|
+
return true;
|
|
1058
|
+
};
|
|
1059
|
+
return WGLVertexBuffer;
|
|
1060
|
+
}());
|
|
1061
|
+
/* *
|
|
1062
|
+
*
|
|
1063
|
+
* Default Export
|
|
1064
|
+
*
|
|
1065
|
+
* */
|
|
1066
|
+
|
|
1067
|
+
return WGLVertexBuffer;
|
|
1068
|
+
});
|
|
1069
|
+
_registerModule(_modules, 'Extensions/Boost/WGLRenderer.js', [_modules['Core/Color/Color.js'], _modules['Core/Globals.js'], _modules['Core/Utilities.js'], _modules['Extensions/Boost/WGLDrawMode.js'], _modules['Extensions/Boost/WGLShader.js'], _modules['Extensions/Boost/WGLVertexBuffer.js']], function (Color, H, U, WGLDrawMode, WGLShader, WGLVertexBuffer) {
|
|
1070
|
+
/* *
|
|
1071
|
+
*
|
|
1072
|
+
* Copyright (c) 2019-2021 Highsoft AS
|
|
1073
|
+
*
|
|
1074
|
+
* Boost module: stripped-down renderer for higher performance
|
|
1075
|
+
*
|
|
1076
|
+
* License: highcharts.com/license
|
|
1077
|
+
*
|
|
1078
|
+
* !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
|
|
1079
|
+
*
|
|
1080
|
+
* */
|
|
1081
|
+
var color = Color.parse;
|
|
1082
|
+
var doc = H.doc,
|
|
1083
|
+
win = H.win;
|
|
1084
|
+
var isNumber = U.isNumber,
|
|
1085
|
+
isObject = U.isObject,
|
|
1086
|
+
merge = U.merge,
|
|
1087
|
+
objectEach = U.objectEach,
|
|
1088
|
+
pick = U.pick;
|
|
1089
|
+
/* *
|
|
1090
|
+
*
|
|
1091
|
+
* Constants
|
|
1092
|
+
*
|
|
1093
|
+
* */
|
|
1094
|
+
// Things to draw as "rectangles" (i.e lines)
|
|
1095
|
+
var asBar = {
|
|
1096
|
+
'column': true,
|
|
1097
|
+
'columnrange': true,
|
|
1098
|
+
'bar': true,
|
|
1099
|
+
'area': true,
|
|
1100
|
+
'areaspline': true,
|
|
1101
|
+
'arearange': true
|
|
1102
|
+
};
|
|
1103
|
+
var asCircle = {
|
|
1104
|
+
'scatter': true,
|
|
1105
|
+
'bubble': true
|
|
1106
|
+
};
|
|
1107
|
+
var contexts = [
|
|
1108
|
+
'webgl',
|
|
1109
|
+
'experimental-webgl',
|
|
1110
|
+
'moz-webgl',
|
|
1111
|
+
'webkit-3d'
|
|
1112
|
+
];
|
|
1113
|
+
/* *
|
|
1114
|
+
*
|
|
1115
|
+
* Class
|
|
1116
|
+
*
|
|
1117
|
+
* */
|
|
1118
|
+
/* eslint-disable valid-jsdoc */
|
|
1119
|
+
/**
|
|
1120
|
+
* Main renderer. Used to render series.
|
|
1121
|
+
*
|
|
1122
|
+
* Notes to self:
|
|
1123
|
+
* - May be able to build a point map by rendering to a separate canvas and
|
|
1124
|
+
* encoding values in the color data.
|
|
1125
|
+
* - Need to figure out a way to transform the data quicker
|
|
1126
|
+
*
|
|
1127
|
+
* @private
|
|
1128
|
+
*
|
|
1129
|
+
* @param {Function} postRenderCallback
|
|
1130
|
+
*/
|
|
1131
|
+
var WGLRenderer = /** @class */ (function () {
|
|
1132
|
+
/* *
|
|
1133
|
+
*
|
|
1134
|
+
* Constructor
|
|
1135
|
+
*
|
|
1136
|
+
* */
|
|
1137
|
+
function WGLRenderer(postRenderCallback) {
|
|
1138
|
+
// The data to render - array of coordinates
|
|
1139
|
+
this.data = [];
|
|
1140
|
+
// Height of our viewport in pixels
|
|
1141
|
+
this.height = 0;
|
|
1142
|
+
// Is it inited?
|
|
1143
|
+
this.isInited = false;
|
|
1144
|
+
// The marker data
|
|
1145
|
+
this.markerData = [];
|
|
1146
|
+
// The series stack
|
|
1147
|
+
this.series = [];
|
|
1148
|
+
// Texture handles
|
|
1149
|
+
this.textureHandles = {};
|
|
1150
|
+
// Width of our viewport in pixels
|
|
1151
|
+
this.width = 0;
|
|
1152
|
+
this.postRenderCallback = postRenderCallback;
|
|
1153
|
+
this.settings = {
|
|
1154
|
+
pointSize: 1,
|
|
1155
|
+
lineWidth: 1,
|
|
1156
|
+
fillColor: '#AA00AA',
|
|
1157
|
+
useAlpha: true,
|
|
1158
|
+
usePreallocated: false,
|
|
1159
|
+
useGPUTranslations: false,
|
|
1160
|
+
debug: {
|
|
1161
|
+
timeRendering: false,
|
|
1162
|
+
timeSeriesProcessing: false,
|
|
1163
|
+
timeSetup: false,
|
|
1164
|
+
timeBufferCopy: false,
|
|
1165
|
+
timeKDTree: false,
|
|
1166
|
+
showSkipSummary: false
|
|
1167
|
+
}
|
|
1168
|
+
};
|
|
1169
|
+
}
|
|
1170
|
+
/* *
|
|
1171
|
+
*
|
|
1172
|
+
* Static Functions
|
|
1173
|
+
*
|
|
1174
|
+
* */
|
|
1175
|
+
/**
|
|
1176
|
+
* Returns an orthographic perspective matrix
|
|
1177
|
+
* @private
|
|
1178
|
+
* @param {number} width
|
|
1179
|
+
* the width of the viewport in pixels
|
|
1180
|
+
* @param {number} height
|
|
1181
|
+
* the height of the viewport in pixels
|
|
1182
|
+
*/
|
|
1183
|
+
WGLRenderer.orthoMatrix = function (width, height) {
|
|
1184
|
+
var near = 0,
|
|
1185
|
+
far = 1;
|
|
1186
|
+
return [
|
|
1187
|
+
2 / width, 0, 0, 0,
|
|
1188
|
+
0, -(2 / height), 0, 0,
|
|
1189
|
+
0, 0, -2 / (far - near), 0,
|
|
1190
|
+
-1, 1, -(far + near) / (far - near), 1
|
|
1191
|
+
];
|
|
1192
|
+
};
|
|
1193
|
+
/**
|
|
1194
|
+
* @private
|
|
1195
|
+
*/
|
|
1196
|
+
WGLRenderer.seriesPointCount = function (series) {
|
|
1197
|
+
var isStacked,
|
|
1198
|
+
xData,
|
|
1199
|
+
s;
|
|
1200
|
+
if (series.boosted) {
|
|
1201
|
+
isStacked = !!series.options.stacking;
|
|
1202
|
+
xData = (series.xData ||
|
|
1203
|
+
series.options.xData ||
|
|
1204
|
+
series.processedXData);
|
|
1205
|
+
s = (isStacked ? series.data : (xData || series.options.data))
|
|
1206
|
+
.length;
|
|
1207
|
+
if (series.type === 'treemap') {
|
|
1208
|
+
s *= 12;
|
|
1209
|
+
}
|
|
1210
|
+
else if (series.type === 'heatmap') {
|
|
1211
|
+
s *= 6;
|
|
1212
|
+
}
|
|
1213
|
+
else if (asBar[series.type]) {
|
|
1214
|
+
s *= 2;
|
|
1215
|
+
}
|
|
1216
|
+
return s;
|
|
1217
|
+
}
|
|
1218
|
+
return 0;
|
|
1219
|
+
};
|
|
1220
|
+
/* *
|
|
1221
|
+
*
|
|
1222
|
+
* Functions
|
|
1223
|
+
*
|
|
1224
|
+
* */
|
|
1225
|
+
/**
|
|
1226
|
+
* @private
|
|
1227
|
+
*/
|
|
1228
|
+
WGLRenderer.prototype.getPixelRatio = function () {
|
|
1229
|
+
return this.settings.pixelRatio || win.devicePixelRatio || 1;
|
|
1230
|
+
};
|
|
1231
|
+
/**
|
|
1232
|
+
* @private
|
|
1233
|
+
*/
|
|
1234
|
+
WGLRenderer.prototype.setOptions = function (options) {
|
|
1235
|
+
// The pixelRatio defaults to 1. This is an antipattern, we should
|
|
1236
|
+
// refactor the Boost options to include an object of default options as
|
|
1237
|
+
// base for the merge, like other components.
|
|
1238
|
+
if (!('pixelRatio' in options)) {
|
|
1239
|
+
options.pixelRatio = 1;
|
|
1240
|
+
}
|
|
1241
|
+
merge(true, this.settings, options);
|
|
1242
|
+
};
|
|
1243
|
+
/**
|
|
1244
|
+
* Allocate a float buffer to fit all series
|
|
1245
|
+
* @private
|
|
1246
|
+
*/
|
|
1247
|
+
WGLRenderer.prototype.allocateBuffer = function (chart) {
|
|
1248
|
+
var vbuffer = this.vbuffer;
|
|
1249
|
+
var s = 0;
|
|
1250
|
+
if (!this.settings.usePreallocated) {
|
|
1251
|
+
return;
|
|
1252
|
+
}
|
|
1253
|
+
chart.series.forEach(function (series) {
|
|
1254
|
+
if (series.boosted) {
|
|
1255
|
+
s += WGLRenderer.seriesPointCount(series);
|
|
1256
|
+
}
|
|
1257
|
+
});
|
|
1258
|
+
vbuffer && vbuffer.allocate(s);
|
|
1259
|
+
};
|
|
1260
|
+
/**
|
|
1261
|
+
* @private
|
|
1262
|
+
*/
|
|
1263
|
+
WGLRenderer.prototype.allocateBufferForSingleSeries = function (series) {
|
|
1264
|
+
var vbuffer = this.vbuffer;
|
|
1265
|
+
var s = 0;
|
|
1266
|
+
if (!this.settings.usePreallocated) {
|
|
1267
|
+
return;
|
|
1268
|
+
}
|
|
1269
|
+
if (series.boosted) {
|
|
1270
|
+
s = WGLRenderer.seriesPointCount(series);
|
|
1271
|
+
}
|
|
1272
|
+
vbuffer && vbuffer.allocate(s);
|
|
1273
|
+
};
|
|
1274
|
+
/**
|
|
1275
|
+
* Clear the depth and color buffer
|
|
1276
|
+
* @private
|
|
1277
|
+
*/
|
|
1278
|
+
WGLRenderer.prototype.clear = function () {
|
|
1279
|
+
var gl = this.gl;
|
|
1280
|
+
gl && gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
|
1281
|
+
};
|
|
1282
|
+
/**
|
|
1283
|
+
* Push data for a single series
|
|
1284
|
+
* This calculates additional vertices and transforms the data to be
|
|
1285
|
+
* aligned correctly in memory
|
|
1286
|
+
* @private
|
|
1287
|
+
*/
|
|
1288
|
+
WGLRenderer.prototype.pushSeriesData = function (series, inst) {
|
|
1289
|
+
var _this = this;
|
|
1290
|
+
var data = this.data, settings = this.settings, vbuffer = this.vbuffer, isRange = (series.pointArrayMap &&
|
|
1291
|
+
series.pointArrayMap.join(',') === 'low,high'), chart = series.chart, options = series.options, isStacked = !!options.stacking, rawData = options.data, xExtremes = series.xAxis.getExtremes(), xMin = xExtremes.min, xMax = xExtremes.max, yExtremes = series.yAxis.getExtremes(), yMin = yExtremes.min, yMax = yExtremes.max, xData = series.xData || options.xData || series.processedXData, yData = series.yData || options.yData || series.processedYData, zData = (series.zData || options.zData ||
|
|
1292
|
+
series.processedZData), yAxis = series.yAxis, xAxis = series.xAxis, useRaw = !xData || xData.length === 0,
|
|
1293
|
+
// threshold = options.threshold,
|
|
1294
|
+
// yBottom = chart.yAxis[0].getThreshold(threshold),
|
|
1295
|
+
// hasThreshold = isNumber(threshold),
|
|
1296
|
+
// colorByPoint = series.options.colorByPoint,
|
|
1297
|
+
// This is required for color by point, so make sure this is
|
|
1298
|
+
// uncommented if enabling that
|
|
1299
|
+
// colorIndex = 0,
|
|
1300
|
+
// Required for color axis support
|
|
1301
|
+
// caxis,
|
|
1302
|
+
connectNulls = options.connectNulls,
|
|
1303
|
+
// For some reason eslint/TypeScript don't pick up that this is
|
|
1304
|
+
// actually used: --- bre1470: it is never read, just set
|
|
1305
|
+
// maxVal: (number|undefined), // eslint-disable-line no-unused-vars
|
|
1306
|
+
points = series.points || false, sdata = isStacked ? series.data : (xData || rawData), closestLeft = { x: Number.MAX_VALUE, y: 0 }, closestRight = { x: -Number.MAX_VALUE, y: 0 }, cullXThreshold = 1, cullYThreshold = 1, chartDestroyed = typeof chart.index === 'undefined', drawAsBar = asBar[series.type], zoneAxis = options.zoneAxis || 'y', zones = options.zones || false, threshold = options.threshold, pixelRatio = this.getPixelRatio();
|
|
1307
|
+
var // plotHeight = series.chart.plotHeight,
|
|
1308
|
+
plotWidth = series.chart.plotWidth,
|
|
1309
|
+
lastX = false,
|
|
1310
|
+
lastY = false,
|
|
1311
|
+
minVal,
|
|
1312
|
+
scolor,
|
|
1313
|
+
//
|
|
1314
|
+
skipped = 0,
|
|
1315
|
+
hadPoints = false,
|
|
1316
|
+
// The following are used in the builder while loop
|
|
1317
|
+
x,
|
|
1318
|
+
y,
|
|
1319
|
+
d,
|
|
1320
|
+
z,
|
|
1321
|
+
i = -1,
|
|
1322
|
+
px = false,
|
|
1323
|
+
nx = false,
|
|
1324
|
+
low,
|
|
1325
|
+
nextInside = false,
|
|
1326
|
+
prevInside = false,
|
|
1327
|
+
pcolor = false,
|
|
1328
|
+
isXInside = false,
|
|
1329
|
+
isYInside = true,
|
|
1330
|
+
firstPoint = true,
|
|
1331
|
+
zoneColors,
|
|
1332
|
+
zoneDefColor = false,
|
|
1333
|
+
gapSize = false,
|
|
1334
|
+
vlen = 0;
|
|
1335
|
+
if (options.boostData && options.boostData.length > 0) {
|
|
1336
|
+
return;
|
|
1337
|
+
}
|
|
1338
|
+
if (options.gapSize) {
|
|
1339
|
+
gapSize = options.gapUnit !== 'value' ?
|
|
1340
|
+
options.gapSize * series.closestPointRange :
|
|
1341
|
+
options.gapSize;
|
|
1342
|
+
}
|
|
1343
|
+
if (zones) {
|
|
1344
|
+
zoneColors = [];
|
|
1345
|
+
zones.forEach(function (zone, i) {
|
|
1346
|
+
if (zone.color) {
|
|
1347
|
+
var zoneColor = color(zone.color).rgba;
|
|
1348
|
+
zoneColor[0] /= 255.0;
|
|
1349
|
+
zoneColor[1] /= 255.0;
|
|
1350
|
+
zoneColor[2] /= 255.0;
|
|
1351
|
+
zoneColors[i] = zoneColor;
|
|
1352
|
+
if (!zoneDefColor && typeof zone.value === 'undefined') {
|
|
1353
|
+
zoneDefColor = zoneColor;
|
|
1354
|
+
}
|
|
1355
|
+
}
|
|
1356
|
+
});
|
|
1357
|
+
if (!zoneDefColor) {
|
|
1358
|
+
var seriesColor = ((series.pointAttribs && series.pointAttribs().fill) ||
|
|
1359
|
+
series.color);
|
|
1360
|
+
zoneDefColor = color(seriesColor).rgba;
|
|
1361
|
+
zoneDefColor[0] /= 255.0;
|
|
1362
|
+
zoneDefColor[1] /= 255.0;
|
|
1363
|
+
zoneDefColor[2] /= 255.0;
|
|
1364
|
+
}
|
|
1365
|
+
}
|
|
1366
|
+
if (chart.inverted) {
|
|
1367
|
+
// plotHeight = series.chart.plotWidth;
|
|
1368
|
+
plotWidth = series.chart.plotHeight;
|
|
1369
|
+
}
|
|
1370
|
+
series.closestPointRangePx = Number.MAX_VALUE;
|
|
1371
|
+
/**
|
|
1372
|
+
* Push color to color buffer - need to do this per vertex.
|
|
1373
|
+
* @private
|
|
1374
|
+
*/
|
|
1375
|
+
var pushColor = function (color) {
|
|
1376
|
+
if (color) {
|
|
1377
|
+
inst.colorData.push(color[0]);
|
|
1378
|
+
inst.colorData.push(color[1]);
|
|
1379
|
+
inst.colorData.push(color[2]);
|
|
1380
|
+
inst.colorData.push(color[3]);
|
|
1381
|
+
}
|
|
1382
|
+
};
|
|
1383
|
+
/**
|
|
1384
|
+
* Push a vertice to the data buffer.
|
|
1385
|
+
* @private
|
|
1386
|
+
*/
|
|
1387
|
+
var vertice = function (x,
|
|
1388
|
+
y,
|
|
1389
|
+
checkTreshold,
|
|
1390
|
+
pointSize,
|
|
1391
|
+
color) {
|
|
1392
|
+
if (pointSize === void 0) { pointSize = 1; }
|
|
1393
|
+
pushColor(color);
|
|
1394
|
+
// Correct for pixel ratio
|
|
1395
|
+
if (pixelRatio !== 1 && (!settings.useGPUTranslations ||
|
|
1396
|
+
inst.skipTranslation)) {
|
|
1397
|
+
x *= pixelRatio;
|
|
1398
|
+
y *= pixelRatio;
|
|
1399
|
+
pointSize *= pixelRatio;
|
|
1400
|
+
}
|
|
1401
|
+
if (settings.usePreallocated && vbuffer) {
|
|
1402
|
+
vbuffer.push(x, y, checkTreshold ? 1 : 0, pointSize);
|
|
1403
|
+
vlen += 4;
|
|
1404
|
+
}
|
|
1405
|
+
else {
|
|
1406
|
+
data.push(x);
|
|
1407
|
+
data.push(y);
|
|
1408
|
+
data.push(checkTreshold ? pixelRatio : 0);
|
|
1409
|
+
data.push(pointSize);
|
|
1410
|
+
}
|
|
1411
|
+
};
|
|
1412
|
+
/**
|
|
1413
|
+
* @private
|
|
1414
|
+
*/
|
|
1415
|
+
var closeSegment = function () {
|
|
1416
|
+
if (inst.segments.length) {
|
|
1417
|
+
inst.segments[inst.segments.length - 1].to = data.length || vlen;
|
|
1418
|
+
}
|
|
1419
|
+
};
|
|
1420
|
+
/**
|
|
1421
|
+
* Create a new segment for the current set.
|
|
1422
|
+
* @private
|
|
1423
|
+
*/
|
|
1424
|
+
var beginSegment = function () {
|
|
1425
|
+
// Insert a segment on the series.
|
|
1426
|
+
// A segment is just a start indice.
|
|
1427
|
+
// When adding a segment, if one exists from before, it should
|
|
1428
|
+
// set the previous segment's end
|
|
1429
|
+
if (inst.segments.length &&
|
|
1430
|
+
inst.segments[inst.segments.length - 1].from === (data.length || vlen)) {
|
|
1431
|
+
return;
|
|
1432
|
+
}
|
|
1433
|
+
closeSegment();
|
|
1434
|
+
inst.segments.push({
|
|
1435
|
+
from: data.length || vlen
|
|
1436
|
+
});
|
|
1437
|
+
};
|
|
1438
|
+
/**
|
|
1439
|
+
* Push a rectangle to the data buffer.
|
|
1440
|
+
* @private
|
|
1441
|
+
*/
|
|
1442
|
+
var pushRect = function (x,
|
|
1443
|
+
y,
|
|
1444
|
+
w,
|
|
1445
|
+
h,
|
|
1446
|
+
color) {
|
|
1447
|
+
pushColor(color);
|
|
1448
|
+
vertice(x + w, y);
|
|
1449
|
+
pushColor(color);
|
|
1450
|
+
vertice(x, y);
|
|
1451
|
+
pushColor(color);
|
|
1452
|
+
vertice(x, y + h);
|
|
1453
|
+
pushColor(color);
|
|
1454
|
+
vertice(x, y + h);
|
|
1455
|
+
pushColor(color);
|
|
1456
|
+
vertice(x + w, y + h);
|
|
1457
|
+
pushColor(color);
|
|
1458
|
+
vertice(x + w, y);
|
|
1459
|
+
};
|
|
1460
|
+
// Create the first segment
|
|
1461
|
+
beginSegment();
|
|
1462
|
+
// Special case for point shapes
|
|
1463
|
+
if (points && points.length > 0) {
|
|
1464
|
+
// If we're doing points, we assume that the points are already
|
|
1465
|
+
// translated, so we skip the shader translation.
|
|
1466
|
+
inst.skipTranslation = true;
|
|
1467
|
+
// Force triangle draw mode
|
|
1468
|
+
inst.drawMode = 'TRIANGLES';
|
|
1469
|
+
// We don't have a z component in the shader, so we need to sort.
|
|
1470
|
+
if (points[0].node && points[0].node.levelDynamic) {
|
|
1471
|
+
points.sort(function (a, b) {
|
|
1472
|
+
if (a.node) {
|
|
1473
|
+
if (a.node.levelDynamic >
|
|
1474
|
+
b.node.levelDynamic) {
|
|
1475
|
+
return 1;
|
|
1476
|
+
}
|
|
1477
|
+
if (a.node.levelDynamic <
|
|
1478
|
+
b.node.levelDynamic) {
|
|
1479
|
+
return -1;
|
|
1480
|
+
}
|
|
1481
|
+
}
|
|
1482
|
+
return 0;
|
|
1483
|
+
});
|
|
1484
|
+
}
|
|
1485
|
+
points.forEach(function (point) {
|
|
1486
|
+
var plotY = point.plotY;
|
|
1487
|
+
var swidth,
|
|
1488
|
+
pointAttr;
|
|
1489
|
+
if (typeof plotY !== 'undefined' &&
|
|
1490
|
+
!isNaN(plotY) &&
|
|
1491
|
+
point.y !== null &&
|
|
1492
|
+
point.shapeArgs) {
|
|
1493
|
+
var _a = point.shapeArgs,
|
|
1494
|
+
_b = _a.x,
|
|
1495
|
+
x_1 = _b === void 0 ? 0 : _b,
|
|
1496
|
+
_c = _a.y,
|
|
1497
|
+
y_1 = _c === void 0 ? 0 : _c,
|
|
1498
|
+
_d = _a.width,
|
|
1499
|
+
width = _d === void 0 ? 0 : _d,
|
|
1500
|
+
_e = _a.height,
|
|
1501
|
+
height = _e === void 0 ? 0 : _e;
|
|
1502
|
+
pointAttr = chart.styledMode ?
|
|
1503
|
+
point.series
|
|
1504
|
+
.colorAttribs(point) :
|
|
1505
|
+
pointAttr = point.series.pointAttribs(point);
|
|
1506
|
+
swidth = pointAttr['stroke-width'] || 0;
|
|
1507
|
+
// Handle point colors
|
|
1508
|
+
pcolor = color(pointAttr.fill).rgba;
|
|
1509
|
+
pcolor[0] /= 255.0;
|
|
1510
|
+
pcolor[1] /= 255.0;
|
|
1511
|
+
pcolor[2] /= 255.0;
|
|
1512
|
+
// So there are two ways of doing this. Either we can
|
|
1513
|
+
// create a rectangle of two triangles, or we can do a
|
|
1514
|
+
// point and use point size. Latter is faster, but
|
|
1515
|
+
// only supports squares. So we're doing triangles.
|
|
1516
|
+
// We could also use one color per. vertice to get
|
|
1517
|
+
// better color interpolation.
|
|
1518
|
+
// If there's stroking, we do an additional rect
|
|
1519
|
+
if (series.is('treemap')) {
|
|
1520
|
+
swidth = swidth || 1;
|
|
1521
|
+
scolor = color(pointAttr.stroke).rgba;
|
|
1522
|
+
scolor[0] /= 255.0;
|
|
1523
|
+
scolor[1] /= 255.0;
|
|
1524
|
+
scolor[2] /= 255.0;
|
|
1525
|
+
pushRect(x_1, y_1, width, height, scolor);
|
|
1526
|
+
swidth /= 2;
|
|
1527
|
+
}
|
|
1528
|
+
// } else {
|
|
1529
|
+
// swidth = 0;
|
|
1530
|
+
// }
|
|
1531
|
+
// Fixes issues with inverted heatmaps (see #6981). The root
|
|
1532
|
+
// cause is that the coordinate system is flipped. In other
|
|
1533
|
+
// words, instead of [0,0] being top-left, it's
|
|
1534
|
+
// bottom-right. This causes a vertical and horizontal flip
|
|
1535
|
+
// in the resulting image, making it rotated 180 degrees.
|
|
1536
|
+
if (series.is('heatmap') && chart.inverted) {
|
|
1537
|
+
x_1 = xAxis.len - x_1;
|
|
1538
|
+
y_1 = yAxis.len - y_1;
|
|
1539
|
+
width = -width;
|
|
1540
|
+
height = -height;
|
|
1541
|
+
}
|
|
1542
|
+
pushRect(x_1 + swidth, y_1 + swidth, width - (swidth * 2), height - (swidth * 2), pcolor);
|
|
1543
|
+
}
|
|
1544
|
+
});
|
|
1545
|
+
closeSegment();
|
|
1546
|
+
return;
|
|
1547
|
+
}
|
|
1548
|
+
var _loop_1 = function () {
|
|
1549
|
+
d = sdata[++i];
|
|
1550
|
+
if (typeof d === 'undefined') {
|
|
1551
|
+
return "continue";
|
|
1552
|
+
}
|
|
1553
|
+
// px = x = y = z = nx = low = false;
|
|
1554
|
+
// chartDestroyed = typeof chart.index === 'undefined';
|
|
1555
|
+
// nextInside = prevInside = pcolor = isXInside = isYInside = false;
|
|
1556
|
+
// drawAsBar = asBar[series.type];
|
|
1557
|
+
if (chartDestroyed) {
|
|
1558
|
+
return "break";
|
|
1559
|
+
}
|
|
1560
|
+
// Uncomment this to enable color by point.
|
|
1561
|
+
// This currently left disabled as the charts look really ugly
|
|
1562
|
+
// when enabled and there's a lot of points.
|
|
1563
|
+
// Leaving in for the future (tm).
|
|
1564
|
+
// if (colorByPoint) {
|
|
1565
|
+
// colorIndex = ++colorIndex %
|
|
1566
|
+
// series.chart.options.colors.length;
|
|
1567
|
+
// pcolor = toRGBAFast(series.chart.options.colors[colorIndex]);
|
|
1568
|
+
// pcolor[0] /= 255.0;
|
|
1569
|
+
// pcolor[1] /= 255.0;
|
|
1570
|
+
// pcolor[2] /= 255.0;
|
|
1571
|
+
// }
|
|
1572
|
+
// Handle the point.color option (#5999)
|
|
1573
|
+
var pointOptions = rawData && rawData[i];
|
|
1574
|
+
if (!useRaw && isObject(pointOptions, true)) {
|
|
1575
|
+
if (pointOptions.color) {
|
|
1576
|
+
pcolor = color(pointOptions.color).rgba;
|
|
1577
|
+
pcolor[0] /= 255.0;
|
|
1578
|
+
pcolor[1] /= 255.0;
|
|
1579
|
+
pcolor[2] /= 255.0;
|
|
1580
|
+
}
|
|
1581
|
+
}
|
|
1582
|
+
if (useRaw) {
|
|
1583
|
+
x = d[0];
|
|
1584
|
+
y = d[1];
|
|
1585
|
+
if (sdata[i + 1]) {
|
|
1586
|
+
nx = sdata[i + 1][0];
|
|
1587
|
+
}
|
|
1588
|
+
if (sdata[i - 1]) {
|
|
1589
|
+
px = sdata[i - 1][0];
|
|
1590
|
+
}
|
|
1591
|
+
if (d.length >= 3) {
|
|
1592
|
+
z = d[2];
|
|
1593
|
+
if (d[2] > inst.zMax) {
|
|
1594
|
+
inst.zMax = d[2];
|
|
1595
|
+
}
|
|
1596
|
+
if (d[2] < inst.zMin) {
|
|
1597
|
+
inst.zMin = d[2];
|
|
1598
|
+
}
|
|
1599
|
+
}
|
|
1600
|
+
}
|
|
1601
|
+
else {
|
|
1602
|
+
x = d;
|
|
1603
|
+
y = yData[i];
|
|
1604
|
+
if (sdata[i + 1]) {
|
|
1605
|
+
nx = sdata[i + 1];
|
|
1606
|
+
}
|
|
1607
|
+
if (sdata[i - 1]) {
|
|
1608
|
+
px = sdata[i - 1];
|
|
1609
|
+
}
|
|
1610
|
+
if (zData && zData.length) {
|
|
1611
|
+
z = zData[i];
|
|
1612
|
+
if (zData[i] > inst.zMax) {
|
|
1613
|
+
inst.zMax = zData[i];
|
|
1614
|
+
}
|
|
1615
|
+
if (zData[i] < inst.zMin) {
|
|
1616
|
+
inst.zMin = zData[i];
|
|
1617
|
+
}
|
|
1618
|
+
}
|
|
1619
|
+
}
|
|
1620
|
+
if (!connectNulls && (x === null || y === null)) {
|
|
1621
|
+
beginSegment();
|
|
1622
|
+
return "continue";
|
|
1623
|
+
}
|
|
1624
|
+
if (nx && nx >= xMin && nx <= xMax) {
|
|
1625
|
+
nextInside = true;
|
|
1626
|
+
}
|
|
1627
|
+
if (px && px >= xMin && px <= xMax) {
|
|
1628
|
+
prevInside = true;
|
|
1629
|
+
}
|
|
1630
|
+
if (isRange) {
|
|
1631
|
+
if (useRaw) {
|
|
1632
|
+
y = d.slice(1, 3);
|
|
1633
|
+
}
|
|
1634
|
+
low = y[0];
|
|
1635
|
+
y = y[1];
|
|
1636
|
+
}
|
|
1637
|
+
else if (isStacked) {
|
|
1638
|
+
x = d.x;
|
|
1639
|
+
y = d.stackY;
|
|
1640
|
+
low = y - d.y;
|
|
1641
|
+
}
|
|
1642
|
+
if (yMin !== null &&
|
|
1643
|
+
typeof yMin !== 'undefined' &&
|
|
1644
|
+
yMax !== null &&
|
|
1645
|
+
typeof yMax !== 'undefined') {
|
|
1646
|
+
isYInside = y >= yMin && y <= yMax;
|
|
1647
|
+
}
|
|
1648
|
+
if (x > xMax && closestRight.x < xMax) {
|
|
1649
|
+
closestRight.x = x;
|
|
1650
|
+
closestRight.y = y;
|
|
1651
|
+
}
|
|
1652
|
+
if (x < xMin && closestLeft.x > xMin) {
|
|
1653
|
+
closestLeft.x = x;
|
|
1654
|
+
closestLeft.y = y;
|
|
1655
|
+
}
|
|
1656
|
+
if (y === null && connectNulls) {
|
|
1657
|
+
return "continue";
|
|
1658
|
+
}
|
|
1659
|
+
// Cull points outside the extremes
|
|
1660
|
+
if (y === null || (!isYInside && !nextInside && !prevInside)) {
|
|
1661
|
+
beginSegment();
|
|
1662
|
+
return "continue";
|
|
1663
|
+
}
|
|
1664
|
+
// The first point before and first after extremes should be
|
|
1665
|
+
// rendered (#9962)
|
|
1666
|
+
if ((nx >= xMin || x >= xMin) &&
|
|
1667
|
+
(px <= xMax || x <= xMax)) {
|
|
1668
|
+
isXInside = true;
|
|
1669
|
+
}
|
|
1670
|
+
if (!isXInside && !nextInside && !prevInside) {
|
|
1671
|
+
return "continue";
|
|
1672
|
+
}
|
|
1673
|
+
if (gapSize && x - px > gapSize) {
|
|
1674
|
+
beginSegment();
|
|
1675
|
+
}
|
|
1676
|
+
// Note: Boost requires that zones are sorted!
|
|
1677
|
+
if (zones) {
|
|
1678
|
+
var zoneColor_1;
|
|
1679
|
+
zones.some(function (// eslint-disable-line no-loop-func
|
|
1680
|
+
zone, i) {
|
|
1681
|
+
var last = zones[i - 1];
|
|
1682
|
+
if (zoneAxis === 'x') {
|
|
1683
|
+
if (typeof zone.value !== 'undefined' &&
|
|
1684
|
+
x <= zone.value) {
|
|
1685
|
+
if (zoneColors[i] &&
|
|
1686
|
+
(!last || x >= last.value)) {
|
|
1687
|
+
zoneColor_1 = zoneColors[i];
|
|
1688
|
+
}
|
|
1689
|
+
return true;
|
|
1690
|
+
}
|
|
1691
|
+
return false;
|
|
1692
|
+
}
|
|
1693
|
+
if (typeof zone.value !== 'undefined' && y <= zone.value) {
|
|
1694
|
+
if (zoneColors[i] &&
|
|
1695
|
+
(!last || y >= last.value)) {
|
|
1696
|
+
zoneColor_1 = zoneColors[i];
|
|
1697
|
+
}
|
|
1698
|
+
return true;
|
|
1699
|
+
}
|
|
1700
|
+
return false;
|
|
1701
|
+
});
|
|
1702
|
+
pcolor = zoneColor_1 || zoneDefColor || pcolor;
|
|
1703
|
+
}
|
|
1704
|
+
// Skip translations - temporary floating point fix
|
|
1705
|
+
if (!settings.useGPUTranslations) {
|
|
1706
|
+
inst.skipTranslation = true;
|
|
1707
|
+
x = xAxis.toPixels(x, true);
|
|
1708
|
+
y = yAxis.toPixels(y, true);
|
|
1709
|
+
// Make sure we're not drawing outside of the chart area.
|
|
1710
|
+
// See #6594. Update: this is no longer required as far as I
|
|
1711
|
+
// can tell. Leaving in for git blame in case there are edge
|
|
1712
|
+
// cases I've not found. Having this in breaks #10246.
|
|
1713
|
+
// if (y > plotHeight) {
|
|
1714
|
+
// y = plotHeight;
|
|
1715
|
+
// }
|
|
1716
|
+
if (x > plotWidth) {
|
|
1717
|
+
// If this is rendered as a point, just skip drawing it
|
|
1718
|
+
// entirely, as we're not dependandt on lineTo'ing to it.
|
|
1719
|
+
// See #8197
|
|
1720
|
+
if (inst.drawMode === 'POINTS') {
|
|
1721
|
+
return "continue";
|
|
1722
|
+
}
|
|
1723
|
+
// Having this here will clamp markers and make the angle
|
|
1724
|
+
// of the last line wrong. See 9166.
|
|
1725
|
+
// x = plotWidth;
|
|
1726
|
+
}
|
|
1727
|
+
}
|
|
1728
|
+
// No markers on out of bounds things.
|
|
1729
|
+
// Out of bound things are shown if and only if the next
|
|
1730
|
+
// or previous point is inside the rect.
|
|
1731
|
+
if (inst.hasMarkers && isXInside) {
|
|
1732
|
+
// x = Highcharts.correctFloat(
|
|
1733
|
+
// Math.min(Math.max(-1e5, xAxis.translate(
|
|
1734
|
+
// x,
|
|
1735
|
+
// 0,
|
|
1736
|
+
// 0,
|
|
1737
|
+
// 0,
|
|
1738
|
+
// 1,
|
|
1739
|
+
// 0.5,
|
|
1740
|
+
// false
|
|
1741
|
+
// )), 1e5)
|
|
1742
|
+
// );
|
|
1743
|
+
if (lastX !== false) {
|
|
1744
|
+
series.closestPointRangePx = Math.min(series.closestPointRangePx, Math.abs(x - lastX));
|
|
1745
|
+
}
|
|
1746
|
+
}
|
|
1747
|
+
// If the last _drawn_ point is closer to this point than the
|
|
1748
|
+
// threshold, skip it. Shaves off 20-100ms in processing.
|
|
1749
|
+
if (!settings.useGPUTranslations &&
|
|
1750
|
+
!settings.usePreallocated &&
|
|
1751
|
+
(lastX && Math.abs(x - lastX) < cullXThreshold) &&
|
|
1752
|
+
(lastY && Math.abs(y - lastY) < cullYThreshold)) {
|
|
1753
|
+
if (settings.debug.showSkipSummary) {
|
|
1754
|
+
++skipped;
|
|
1755
|
+
}
|
|
1756
|
+
return "continue";
|
|
1757
|
+
}
|
|
1758
|
+
if (drawAsBar) {
|
|
1759
|
+
// maxVal = y;
|
|
1760
|
+
minVal = low;
|
|
1761
|
+
if (low === false || typeof low === 'undefined') {
|
|
1762
|
+
if (y < 0) {
|
|
1763
|
+
minVal = y;
|
|
1764
|
+
}
|
|
1765
|
+
else {
|
|
1766
|
+
minVal = 0;
|
|
1767
|
+
}
|
|
1768
|
+
}
|
|
1769
|
+
if (!isRange && !isStacked) {
|
|
1770
|
+
minVal = Math.max(threshold === null ? yMin : threshold, // #5268
|
|
1771
|
+
yMin); // #8731
|
|
1772
|
+
}
|
|
1773
|
+
if (!settings.useGPUTranslations) {
|
|
1774
|
+
minVal = yAxis.toPixels(minVal, true);
|
|
1775
|
+
}
|
|
1776
|
+
// Need to add an extra point here
|
|
1777
|
+
vertice(x, minVal, 0, 0, pcolor);
|
|
1778
|
+
}
|
|
1779
|
+
// Do step line if enabled.
|
|
1780
|
+
// Draws an additional point at the old Y at the new X.
|
|
1781
|
+
// See #6976.
|
|
1782
|
+
if (options.step && !firstPoint) {
|
|
1783
|
+
vertice(x, lastY, 0, 2, pcolor);
|
|
1784
|
+
}
|
|
1785
|
+
vertice(x, y, 0, series.type === 'bubble' ? (z || 1) : 2, pcolor);
|
|
1786
|
+
// Uncomment this to support color axis.
|
|
1787
|
+
// if (caxis) {
|
|
1788
|
+
// pcolor = color(caxis.toColor(y)).rgba;
|
|
1789
|
+
// inst.colorData.push(color[0] / 255.0);
|
|
1790
|
+
// inst.colorData.push(color[1] / 255.0);
|
|
1791
|
+
// inst.colorData.push(color[2] / 255.0);
|
|
1792
|
+
// inst.colorData.push(color[3]);
|
|
1793
|
+
// }
|
|
1794
|
+
lastX = x;
|
|
1795
|
+
lastY = y;
|
|
1796
|
+
hadPoints = true;
|
|
1797
|
+
firstPoint = false;
|
|
1798
|
+
};
|
|
1799
|
+
// Extract color axis
|
|
1800
|
+
// (chart.axes || []).forEach((a): void => {
|
|
1801
|
+
// if (H.ColorAxis && a instanceof H.ColorAxis) {
|
|
1802
|
+
// caxis = a;
|
|
1803
|
+
// }
|
|
1804
|
+
// });
|
|
1805
|
+
while (i < sdata.length - 1) {
|
|
1806
|
+
var state_1 = _loop_1();
|
|
1807
|
+
if (state_1 === "break")
|
|
1808
|
+
break;
|
|
1809
|
+
}
|
|
1810
|
+
if (settings.debug.showSkipSummary) {
|
|
1811
|
+
console.log('skipped points:', skipped); // eslint-disable-line no-console
|
|
1812
|
+
}
|
|
1813
|
+
var pushSupplementPoint = function (point,
|
|
1814
|
+
atStart) {
|
|
1815
|
+
if (!settings.useGPUTranslations) {
|
|
1816
|
+
inst.skipTranslation = true;
|
|
1817
|
+
point.x = xAxis.toPixels(point.x, true);
|
|
1818
|
+
point.y = yAxis.toPixels(point.y, true);
|
|
1819
|
+
}
|
|
1820
|
+
// We should only do this for lines, and we should ignore markers
|
|
1821
|
+
// since there's no point here that would have a marker.
|
|
1822
|
+
if (atStart) {
|
|
1823
|
+
_this.data = [point.x, point.y, 0, 2].concat(_this.data);
|
|
1824
|
+
return;
|
|
1825
|
+
}
|
|
1826
|
+
vertice(point.x, point.y, 0, 2);
|
|
1827
|
+
};
|
|
1828
|
+
if (!hadPoints &&
|
|
1829
|
+
connectNulls !== false &&
|
|
1830
|
+
series.drawMode === 'line_strip') {
|
|
1831
|
+
if (closestLeft.x < Number.MAX_VALUE) {
|
|
1832
|
+
// We actually need to push this *before* the complete buffer.
|
|
1833
|
+
pushSupplementPoint(closestLeft, true);
|
|
1834
|
+
}
|
|
1835
|
+
if (closestRight.x > -Number.MAX_VALUE) {
|
|
1836
|
+
pushSupplementPoint(closestRight);
|
|
1837
|
+
}
|
|
1838
|
+
}
|
|
1839
|
+
closeSegment();
|
|
1840
|
+
};
|
|
1841
|
+
/**
|
|
1842
|
+
* Push a series to the renderer
|
|
1843
|
+
* If we render the series immediatly, we don't have to loop later
|
|
1844
|
+
* @private
|
|
1845
|
+
* @param {Highchart.Series} s
|
|
1846
|
+
* The series to push.
|
|
1847
|
+
*/
|
|
1848
|
+
WGLRenderer.prototype.pushSeries = function (s) {
|
|
1849
|
+
var markerData = this.markerData,
|
|
1850
|
+
series = this.series,
|
|
1851
|
+
settings = this.settings;
|
|
1852
|
+
if (series.length > 0) {
|
|
1853
|
+
// series[series.length - 1].to = data.length;
|
|
1854
|
+
if (series[series.length - 1].hasMarkers) {
|
|
1855
|
+
series[series.length - 1].markerTo = markerData.length;
|
|
1856
|
+
}
|
|
1857
|
+
}
|
|
1858
|
+
if (settings.debug.timeSeriesProcessing) {
|
|
1859
|
+
console.time('building ' + s.type + ' series'); // eslint-disable-line no-console
|
|
1860
|
+
}
|
|
1861
|
+
var obj = {
|
|
1862
|
+
segments: [],
|
|
1863
|
+
// from: data.length,
|
|
1864
|
+
markerFrom: markerData.length,
|
|
1865
|
+
// Push RGBA values to this array to use per. point coloring.
|
|
1866
|
+
// It should be 0-padded, so each component should be pushed in
|
|
1867
|
+
// succession.
|
|
1868
|
+
colorData: [],
|
|
1869
|
+
series: s,
|
|
1870
|
+
zMin: Number.MAX_VALUE,
|
|
1871
|
+
zMax: -Number.MAX_VALUE,
|
|
1872
|
+
hasMarkers: s.options.marker ?
|
|
1873
|
+
s.options.marker.enabled !== false :
|
|
1874
|
+
false,
|
|
1875
|
+
showMarkers: true,
|
|
1876
|
+
drawMode: WGLDrawMode[s.type] || 'LINE_STRIP'
|
|
1877
|
+
};
|
|
1878
|
+
if (s.index >= series.length) {
|
|
1879
|
+
series.push(obj);
|
|
1880
|
+
}
|
|
1881
|
+
else {
|
|
1882
|
+
series[s.index] = obj;
|
|
1883
|
+
}
|
|
1884
|
+
// Add the series data to our buffer(s)
|
|
1885
|
+
this.pushSeriesData(s, obj);
|
|
1886
|
+
if (settings.debug.timeSeriesProcessing) {
|
|
1887
|
+
console.timeEnd('building ' + s.type + ' series'); // eslint-disable-line no-console
|
|
1888
|
+
}
|
|
1889
|
+
};
|
|
1890
|
+
/**
|
|
1891
|
+
* Flush the renderer.
|
|
1892
|
+
* This removes pushed series and vertices.
|
|
1893
|
+
* Should be called after clearing and before rendering
|
|
1894
|
+
* @private
|
|
1895
|
+
*/
|
|
1896
|
+
WGLRenderer.prototype.flush = function () {
|
|
1897
|
+
var vbuffer = this.vbuffer;
|
|
1898
|
+
this.data = [];
|
|
1899
|
+
this.markerData = [];
|
|
1900
|
+
this.series = [];
|
|
1901
|
+
if (vbuffer) {
|
|
1902
|
+
vbuffer.destroy();
|
|
1903
|
+
}
|
|
1904
|
+
};
|
|
1905
|
+
/**
|
|
1906
|
+
* Pass x-axis to shader
|
|
1907
|
+
* @private
|
|
1908
|
+
* @param {Highcharts.Axis} axis
|
|
1909
|
+
* The x-axis.
|
|
1910
|
+
*/
|
|
1911
|
+
WGLRenderer.prototype.setXAxis = function (axis) {
|
|
1912
|
+
var shader = this.shader;
|
|
1913
|
+
if (!shader) {
|
|
1914
|
+
return;
|
|
1915
|
+
}
|
|
1916
|
+
var pixelRatio = this.getPixelRatio();
|
|
1917
|
+
shader.setUniform('xAxisTrans', axis.transA * pixelRatio);
|
|
1918
|
+
shader.setUniform('xAxisMin', axis.min);
|
|
1919
|
+
shader.setUniform('xAxisMinPad', axis.minPixelPadding * pixelRatio);
|
|
1920
|
+
shader.setUniform('xAxisPointRange', axis.pointRange);
|
|
1921
|
+
shader.setUniform('xAxisLen', axis.len * pixelRatio);
|
|
1922
|
+
shader.setUniform('xAxisPos', axis.pos * pixelRatio);
|
|
1923
|
+
shader.setUniform('xAxisCVSCoord', (!axis.horiz));
|
|
1924
|
+
shader.setUniform('xAxisIsLog', (!!axis.logarithmic));
|
|
1925
|
+
shader.setUniform('xAxisReversed', (!!axis.reversed));
|
|
1926
|
+
};
|
|
1927
|
+
/**
|
|
1928
|
+
* Pass y-axis to shader
|
|
1929
|
+
* @private
|
|
1930
|
+
* @param {Highcharts.Axis} axis
|
|
1931
|
+
* The y-axis.
|
|
1932
|
+
*/
|
|
1933
|
+
WGLRenderer.prototype.setYAxis = function (axis) {
|
|
1934
|
+
var shader = this.shader;
|
|
1935
|
+
if (!shader) {
|
|
1936
|
+
return;
|
|
1937
|
+
}
|
|
1938
|
+
var pixelRatio = this.getPixelRatio();
|
|
1939
|
+
shader.setUniform('yAxisTrans', axis.transA * pixelRatio);
|
|
1940
|
+
shader.setUniform('yAxisMin', axis.min);
|
|
1941
|
+
shader.setUniform('yAxisMinPad', axis.minPixelPadding * pixelRatio);
|
|
1942
|
+
shader.setUniform('yAxisPointRange', axis.pointRange);
|
|
1943
|
+
shader.setUniform('yAxisLen', axis.len * pixelRatio);
|
|
1944
|
+
shader.setUniform('yAxisPos', axis.pos * pixelRatio);
|
|
1945
|
+
shader.setUniform('yAxisCVSCoord', (!axis.horiz));
|
|
1946
|
+
shader.setUniform('yAxisIsLog', (!!axis.logarithmic));
|
|
1947
|
+
shader.setUniform('yAxisReversed', (!!axis.reversed));
|
|
1948
|
+
};
|
|
1949
|
+
/**
|
|
1950
|
+
* Set the translation threshold
|
|
1951
|
+
* @private
|
|
1952
|
+
* @param {boolean} has
|
|
1953
|
+
* Has threshold flag.
|
|
1954
|
+
* @param {numbe} translation
|
|
1955
|
+
* The threshold.
|
|
1956
|
+
*/
|
|
1957
|
+
WGLRenderer.prototype.setThreshold = function (has, translation) {
|
|
1958
|
+
var shader = this.shader;
|
|
1959
|
+
if (!shader) {
|
|
1960
|
+
return;
|
|
1961
|
+
}
|
|
1962
|
+
shader.setUniform('hasThreshold', has);
|
|
1963
|
+
shader.setUniform('translatedThreshold', translation);
|
|
1964
|
+
};
|
|
1965
|
+
/**
|
|
1966
|
+
* Render the data
|
|
1967
|
+
* This renders all pushed series.
|
|
1968
|
+
* @private
|
|
1969
|
+
*/
|
|
1970
|
+
WGLRenderer.prototype.renderChart = function (chart) {
|
|
1971
|
+
var _this = this;
|
|
1972
|
+
var gl = this.gl,
|
|
1973
|
+
settings = this.settings,
|
|
1974
|
+
shader = this.shader,
|
|
1975
|
+
vbuffer = this.vbuffer;
|
|
1976
|
+
var pixelRatio = this.getPixelRatio();
|
|
1977
|
+
if (chart) {
|
|
1978
|
+
this.width = chart.chartWidth * pixelRatio;
|
|
1979
|
+
this.height = chart.chartHeight * pixelRatio;
|
|
1980
|
+
}
|
|
1981
|
+
else {
|
|
1982
|
+
return false;
|
|
1983
|
+
}
|
|
1984
|
+
var height = this.height,
|
|
1985
|
+
width = this.width;
|
|
1986
|
+
if (!gl || !shader || !width || !height) {
|
|
1987
|
+
return false;
|
|
1988
|
+
}
|
|
1989
|
+
if (settings.debug.timeRendering) {
|
|
1990
|
+
console.time('gl rendering'); // eslint-disable-line no-console
|
|
1991
|
+
}
|
|
1992
|
+
gl.canvas.width = width;
|
|
1993
|
+
gl.canvas.height = height;
|
|
1994
|
+
shader.bind();
|
|
1995
|
+
gl.viewport(0, 0, width, height);
|
|
1996
|
+
shader.setPMatrix(WGLRenderer.orthoMatrix(width, height));
|
|
1997
|
+
if (settings.lineWidth > 1 && !H.isMS) {
|
|
1998
|
+
gl.lineWidth(settings.lineWidth);
|
|
1999
|
+
}
|
|
2000
|
+
if (vbuffer) {
|
|
2001
|
+
vbuffer.build(this.data, 'aVertexPosition', 4);
|
|
2002
|
+
vbuffer.bind();
|
|
2003
|
+
}
|
|
2004
|
+
shader.setInverted(chart.inverted);
|
|
2005
|
+
// Render the series
|
|
2006
|
+
this.series.forEach(function (s, si) {
|
|
2007
|
+
var options = s.series.options,
|
|
2008
|
+
shapeOptions = options.marker,
|
|
2009
|
+
lineWidth = (typeof options.lineWidth !== 'undefined' ?
|
|
2010
|
+
options.lineWidth :
|
|
2011
|
+
1),
|
|
2012
|
+
threshold = options.threshold,
|
|
2013
|
+
hasThreshold = isNumber(threshold),
|
|
2014
|
+
yBottom = s.series.yAxis.getThreshold(threshold),
|
|
2015
|
+
translatedThreshold = yBottom,
|
|
2016
|
+
showMarkers = pick(options.marker ? options.marker.enabled : null,
|
|
2017
|
+
s.series.xAxis.isRadial ? true : null,
|
|
2018
|
+
s.series.closestPointRangePx >
|
|
2019
|
+
2 * ((options.marker ?
|
|
2020
|
+
options.marker.radius :
|
|
2021
|
+
10) || 10)),
|
|
2022
|
+
shapeTexture = _this.textureHandles[(shapeOptions && shapeOptions.symbol) ||
|
|
2023
|
+
s.series.symbol] || _this.textureHandles.circle;
|
|
2024
|
+
var sindex,
|
|
2025
|
+
cbuffer,
|
|
2026
|
+
fillColor,
|
|
2027
|
+
scolor = [];
|
|
2028
|
+
if (s.segments.length === 0 ||
|
|
2029
|
+
s.segments[0].from === s.segments[0].to) {
|
|
2030
|
+
return;
|
|
2031
|
+
}
|
|
2032
|
+
if (shapeTexture.isReady) {
|
|
2033
|
+
gl.bindTexture(gl.TEXTURE_2D, shapeTexture.handle);
|
|
2034
|
+
shader.setTexture(shapeTexture.handle);
|
|
2035
|
+
}
|
|
2036
|
+
if (chart.styledMode) {
|
|
2037
|
+
fillColor = (s.series.markerGroup &&
|
|
2038
|
+
s.series.markerGroup.getStyle('fill'));
|
|
2039
|
+
}
|
|
2040
|
+
else {
|
|
2041
|
+
fillColor =
|
|
2042
|
+
(s.drawMode === 'POINTS' && // #14260
|
|
2043
|
+
s.series.pointAttribs &&
|
|
2044
|
+
s.series.pointAttribs().fill) ||
|
|
2045
|
+
s.series.color;
|
|
2046
|
+
if (options.colorByPoint) {
|
|
2047
|
+
fillColor = s.series.chart.options.colors[si];
|
|
2048
|
+
}
|
|
2049
|
+
}
|
|
2050
|
+
if (s.series.fillOpacity && options.fillOpacity) {
|
|
2051
|
+
fillColor = new Color(fillColor).setOpacity(pick(options.fillOpacity, 1.0)).get();
|
|
2052
|
+
}
|
|
2053
|
+
scolor = color(fillColor).rgba;
|
|
2054
|
+
if (!settings.useAlpha) {
|
|
2055
|
+
scolor[3] = 1.0;
|
|
2056
|
+
}
|
|
2057
|
+
// This is very much temporary
|
|
2058
|
+
if (s.drawMode === 'LINES' &&
|
|
2059
|
+
settings.useAlpha &&
|
|
2060
|
+
scolor[3] < 1) {
|
|
2061
|
+
scolor[3] /= 10;
|
|
2062
|
+
}
|
|
2063
|
+
// Blending
|
|
2064
|
+
if (options.boostBlending === 'add') {
|
|
2065
|
+
gl.blendFunc(gl.SRC_ALPHA, gl.ONE);
|
|
2066
|
+
gl.blendEquation(gl.FUNC_ADD);
|
|
2067
|
+
}
|
|
2068
|
+
else if (options.boostBlending === 'mult' ||
|
|
2069
|
+
options.boostBlending === 'multiply') {
|
|
2070
|
+
gl.blendFunc(gl.DST_COLOR, gl.ZERO);
|
|
2071
|
+
}
|
|
2072
|
+
else if (options.boostBlending === 'darken') {
|
|
2073
|
+
gl.blendFunc(gl.ONE, gl.ONE);
|
|
2074
|
+
gl.blendEquation(gl.FUNC_MIN);
|
|
2075
|
+
}
|
|
2076
|
+
else {
|
|
2077
|
+
// gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
|
|
2078
|
+
// gl.blendEquation(gl.FUNC_ADD);
|
|
2079
|
+
gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
|
|
2080
|
+
}
|
|
2081
|
+
shader.reset();
|
|
2082
|
+
// If there are entries in the colorData buffer, build and bind it.
|
|
2083
|
+
if (s.colorData.length > 0) {
|
|
2084
|
+
shader.setUniform('hasColor', 1.0);
|
|
2085
|
+
cbuffer = new WGLVertexBuffer(gl, shader);
|
|
2086
|
+
cbuffer.build(s.colorData, 'aColor', 4);
|
|
2087
|
+
cbuffer.bind();
|
|
2088
|
+
}
|
|
2089
|
+
else {
|
|
2090
|
+
// #15869, a buffer with fewer points might already be bound by
|
|
2091
|
+
// a different series/chart causing out of range errors
|
|
2092
|
+
gl.disableVertexAttribArray(gl.getAttribLocation(shader.getProgram(), 'aColor'));
|
|
2093
|
+
}
|
|
2094
|
+
// Set series specific uniforms
|
|
2095
|
+
shader.setColor(scolor);
|
|
2096
|
+
_this.setXAxis(s.series.xAxis);
|
|
2097
|
+
_this.setYAxis(s.series.yAxis);
|
|
2098
|
+
_this.setThreshold(hasThreshold, translatedThreshold);
|
|
2099
|
+
if (s.drawMode === 'POINTS') {
|
|
2100
|
+
shader.setPointSize(pick(options.marker && options.marker.radius, 0.5) * 2 * pixelRatio);
|
|
2101
|
+
}
|
|
2102
|
+
// If set to true, the toPixels translations in the shader
|
|
2103
|
+
// is skipped, i.e it's assumed that the value is a pixel coord.
|
|
2104
|
+
shader.setSkipTranslation(s.skipTranslation);
|
|
2105
|
+
if (s.series.type === 'bubble') {
|
|
2106
|
+
shader.setBubbleUniforms(s.series, s.zMin, s.zMax, pixelRatio);
|
|
2107
|
+
}
|
|
2108
|
+
shader.setDrawAsCircle(asCircle[s.series.type] || false);
|
|
2109
|
+
if (!vbuffer) {
|
|
2110
|
+
return;
|
|
2111
|
+
}
|
|
2112
|
+
// Do the actual rendering
|
|
2113
|
+
// If the line width is < 0, skip rendering of the lines. See #7833.
|
|
2114
|
+
if (lineWidth > 0 || s.drawMode !== 'LINE_STRIP') {
|
|
2115
|
+
for (sindex = 0; sindex < s.segments.length; sindex++) {
|
|
2116
|
+
vbuffer.render(s.segments[sindex].from, s.segments[sindex].to, s.drawMode);
|
|
2117
|
+
}
|
|
2118
|
+
}
|
|
2119
|
+
if (s.hasMarkers && showMarkers) {
|
|
2120
|
+
shader.setPointSize(pick(options.marker && options.marker.radius, 5) * 2 * pixelRatio);
|
|
2121
|
+
shader.setDrawAsCircle(true);
|
|
2122
|
+
for (sindex = 0; sindex < s.segments.length; sindex++) {
|
|
2123
|
+
vbuffer.render(s.segments[sindex].from, s.segments[sindex].to, 'POINTS');
|
|
2124
|
+
}
|
|
2125
|
+
}
|
|
2126
|
+
});
|
|
2127
|
+
if (settings.debug.timeRendering) {
|
|
2128
|
+
console.timeEnd('gl rendering'); // eslint-disable-line no-console
|
|
2129
|
+
}
|
|
2130
|
+
if (this.postRenderCallback) {
|
|
2131
|
+
this.postRenderCallback(this);
|
|
2132
|
+
}
|
|
2133
|
+
this.flush();
|
|
2134
|
+
};
|
|
2135
|
+
/**
|
|
2136
|
+
* Render the data when ready
|
|
2137
|
+
* @private
|
|
2138
|
+
*/
|
|
2139
|
+
WGLRenderer.prototype.render = function (chart) {
|
|
2140
|
+
var _this = this;
|
|
2141
|
+
this.clear();
|
|
2142
|
+
if (chart.renderer.forExport) {
|
|
2143
|
+
return this.renderChart(chart);
|
|
2144
|
+
}
|
|
2145
|
+
if (this.isInited) {
|
|
2146
|
+
this.renderChart(chart);
|
|
2147
|
+
}
|
|
2148
|
+
else {
|
|
2149
|
+
setTimeout(function () {
|
|
2150
|
+
_this.render(chart);
|
|
2151
|
+
}, 1);
|
|
2152
|
+
}
|
|
2153
|
+
};
|
|
2154
|
+
/**
|
|
2155
|
+
* Set the viewport size in pixels
|
|
2156
|
+
* Creates an orthographic perspective matrix and applies it.
|
|
2157
|
+
* @private
|
|
2158
|
+
*/
|
|
2159
|
+
WGLRenderer.prototype.setSize = function (width, height) {
|
|
2160
|
+
var shader = this.shader;
|
|
2161
|
+
// Skip if there's no change, or if we have no valid shader
|
|
2162
|
+
if (!shader || (this.width === width && this.height === height)) {
|
|
2163
|
+
return;
|
|
2164
|
+
}
|
|
2165
|
+
this.width = width;
|
|
2166
|
+
this.height = height;
|
|
2167
|
+
shader.bind();
|
|
2168
|
+
shader.setPMatrix(WGLRenderer.orthoMatrix(width, height));
|
|
2169
|
+
};
|
|
2170
|
+
/**
|
|
2171
|
+
* Init OpenGL
|
|
2172
|
+
* @private
|
|
2173
|
+
*/
|
|
2174
|
+
WGLRenderer.prototype.init = function (canvas, noFlush) {
|
|
2175
|
+
var _this = this;
|
|
2176
|
+
var settings = this.settings;
|
|
2177
|
+
this.isInited = false;
|
|
2178
|
+
if (!canvas) {
|
|
2179
|
+
return false;
|
|
2180
|
+
}
|
|
2181
|
+
if (settings.debug.timeSetup) {
|
|
2182
|
+
console.time('gl setup'); // eslint-disable-line no-console
|
|
2183
|
+
}
|
|
2184
|
+
for (var i = 0; i < contexts.length; ++i) {
|
|
2185
|
+
this.gl = canvas.getContext(contexts[i], {
|
|
2186
|
+
// premultipliedAlpha: false
|
|
2187
|
+
});
|
|
2188
|
+
if (this.gl) {
|
|
2189
|
+
break;
|
|
2190
|
+
}
|
|
2191
|
+
}
|
|
2192
|
+
var gl = this.gl;
|
|
2193
|
+
if (gl) {
|
|
2194
|
+
if (!noFlush) {
|
|
2195
|
+
this.flush();
|
|
2196
|
+
}
|
|
2197
|
+
}
|
|
2198
|
+
else {
|
|
2199
|
+
return false;
|
|
2200
|
+
}
|
|
2201
|
+
gl.enable(gl.BLEND);
|
|
2202
|
+
// gl.blendFunc(gl.SRC_ALPHA, gl.ONE);
|
|
2203
|
+
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
|
|
2204
|
+
gl.disable(gl.DEPTH_TEST);
|
|
2205
|
+
// gl.depthMask(gl.FALSE);
|
|
2206
|
+
gl.depthFunc(gl.LESS);
|
|
2207
|
+
var shader = this.shader = new WGLShader(gl);
|
|
2208
|
+
if (!shader) {
|
|
2209
|
+
// We need to abort, there's no shader context
|
|
2210
|
+
return false;
|
|
2211
|
+
}
|
|
2212
|
+
this.vbuffer = new WGLVertexBuffer(gl, shader);
|
|
2213
|
+
var createTexture = function (name,
|
|
2214
|
+
fn) {
|
|
2215
|
+
var props = {
|
|
2216
|
+
isReady: false,
|
|
2217
|
+
texture: doc.createElement('canvas'),
|
|
2218
|
+
handle: gl.createTexture()
|
|
2219
|
+
},
|
|
2220
|
+
ctx = props.texture.getContext('2d');
|
|
2221
|
+
_this.textureHandles[name] = props;
|
|
2222
|
+
props.texture.width = 512;
|
|
2223
|
+
props.texture.height = 512;
|
|
2224
|
+
ctx.mozImageSmoothingEnabled = false;
|
|
2225
|
+
ctx.webkitImageSmoothingEnabled = false;
|
|
2226
|
+
ctx.msImageSmoothingEnabled = false;
|
|
2227
|
+
ctx.imageSmoothingEnabled = false;
|
|
2228
|
+
ctx.strokeStyle = 'rgba(255, 255, 255, 0)';
|
|
2229
|
+
ctx.fillStyle = '#FFF';
|
|
2230
|
+
fn(ctx);
|
|
2231
|
+
try {
|
|
2232
|
+
gl.activeTexture(gl.TEXTURE0);
|
|
2233
|
+
gl.bindTexture(gl.TEXTURE_2D, props.handle);
|
|
2234
|
+
// gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
|
|
2235
|
+
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, props.texture);
|
|
2236
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
2237
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
2238
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
|
2239
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
|
2240
|
+
// gl.generateMipmap(gl.TEXTURE_2D);
|
|
2241
|
+
gl.bindTexture(gl.TEXTURE_2D, null);
|
|
2242
|
+
props.isReady = true;
|
|
2243
|
+
}
|
|
2244
|
+
catch (e) {
|
|
2245
|
+
// silent error
|
|
2246
|
+
}
|
|
2247
|
+
};
|
|
2248
|
+
// Circle shape
|
|
2249
|
+
createTexture('circle', function (ctx) {
|
|
2250
|
+
ctx.beginPath();
|
|
2251
|
+
ctx.arc(256, 256, 256, 0, 2 * Math.PI);
|
|
2252
|
+
ctx.stroke();
|
|
2253
|
+
ctx.fill();
|
|
2254
|
+
});
|
|
2255
|
+
// Square shape
|
|
2256
|
+
createTexture('square', function (ctx) {
|
|
2257
|
+
ctx.fillRect(0, 0, 512, 512);
|
|
2258
|
+
});
|
|
2259
|
+
// Diamond shape
|
|
2260
|
+
createTexture('diamond', function (ctx) {
|
|
2261
|
+
ctx.beginPath();
|
|
2262
|
+
ctx.moveTo(256, 0);
|
|
2263
|
+
ctx.lineTo(512, 256);
|
|
2264
|
+
ctx.lineTo(256, 512);
|
|
2265
|
+
ctx.lineTo(0, 256);
|
|
2266
|
+
ctx.lineTo(256, 0);
|
|
2267
|
+
ctx.fill();
|
|
2268
|
+
});
|
|
2269
|
+
// Triangle shape
|
|
2270
|
+
createTexture('triangle', function (ctx) {
|
|
2271
|
+
ctx.beginPath();
|
|
2272
|
+
ctx.moveTo(0, 512);
|
|
2273
|
+
ctx.lineTo(256, 0);
|
|
2274
|
+
ctx.lineTo(512, 512);
|
|
2275
|
+
ctx.lineTo(0, 512);
|
|
2276
|
+
ctx.fill();
|
|
2277
|
+
});
|
|
2278
|
+
// Triangle shape (rotated)
|
|
2279
|
+
createTexture('triangle-down', function (ctx) {
|
|
2280
|
+
ctx.beginPath();
|
|
2281
|
+
ctx.moveTo(0, 0);
|
|
2282
|
+
ctx.lineTo(256, 512);
|
|
2283
|
+
ctx.lineTo(512, 0);
|
|
2284
|
+
ctx.lineTo(0, 0);
|
|
2285
|
+
ctx.fill();
|
|
2286
|
+
});
|
|
2287
|
+
this.isInited = true;
|
|
2288
|
+
if (settings.debug.timeSetup) {
|
|
2289
|
+
console.timeEnd('gl setup'); // eslint-disable-line no-console
|
|
2290
|
+
}
|
|
2291
|
+
return true;
|
|
2292
|
+
};
|
|
2293
|
+
/**
|
|
2294
|
+
* @private
|
|
2295
|
+
* @todo use it
|
|
2296
|
+
*/
|
|
2297
|
+
WGLRenderer.prototype.destroy = function () {
|
|
2298
|
+
var gl = this.gl,
|
|
2299
|
+
shader = this.shader,
|
|
2300
|
+
vbuffer = this.vbuffer;
|
|
2301
|
+
this.flush();
|
|
2302
|
+
if (vbuffer) {
|
|
2303
|
+
vbuffer.destroy();
|
|
2304
|
+
}
|
|
2305
|
+
if (shader) {
|
|
2306
|
+
shader.destroy();
|
|
2307
|
+
}
|
|
2308
|
+
if (gl) {
|
|
2309
|
+
objectEach(this.textureHandles, function (texture) {
|
|
2310
|
+
if (texture.handle) {
|
|
2311
|
+
gl.deleteTexture(texture.handle);
|
|
2312
|
+
}
|
|
2313
|
+
});
|
|
2314
|
+
gl.canvas.width = 1;
|
|
2315
|
+
gl.canvas.height = 1;
|
|
2316
|
+
}
|
|
2317
|
+
};
|
|
2318
|
+
return WGLRenderer;
|
|
2319
|
+
}());
|
|
2320
|
+
/* *
|
|
2321
|
+
*
|
|
2322
|
+
* Default Export
|
|
2323
|
+
*
|
|
2324
|
+
* */
|
|
2325
|
+
|
|
2326
|
+
return WGLRenderer;
|
|
2327
|
+
});
|
|
2328
|
+
_registerModule(_modules, 'Extensions/Boost/BoostSeries.js', [_modules['Extensions/Boost/BoostableMap.js'], _modules['Extensions/Boost/Boostables.js'], _modules['Extensions/Boost/BoostChart.js'], _modules['Core/DefaultOptions.js'], _modules['Core/Globals.js'], _modules['Core/Utilities.js'], _modules['Extensions/Boost/WGLRenderer.js']], function (BoostableMap, Boostables, BoostChart, DefaultOptions, H, U, WGLRenderer) {
|
|
2329
|
+
/* *
|
|
2330
|
+
*
|
|
2331
|
+
* Copyright (c) 2019-2021 Highsoft AS
|
|
2332
|
+
*
|
|
2333
|
+
* Boost module: stripped-down renderer for higher performance
|
|
2334
|
+
*
|
|
2335
|
+
* License: highcharts.com/license
|
|
2336
|
+
*
|
|
2337
|
+
* !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
|
|
2338
|
+
*
|
|
2339
|
+
* */
|
|
2340
|
+
var getBoostClipRect = BoostChart.getBoostClipRect,
|
|
2341
|
+
isChartSeriesBoosting = BoostChart.isChartSeriesBoosting;
|
|
2342
|
+
var getOptions = DefaultOptions.getOptions;
|
|
2343
|
+
var doc = H.doc,
|
|
2344
|
+
noop = H.noop,
|
|
2345
|
+
win = H.win;
|
|
2346
|
+
var addEvent = U.addEvent,
|
|
2347
|
+
error = U.error,
|
|
2348
|
+
extend = U.extend,
|
|
2349
|
+
fireEvent = U.fireEvent,
|
|
2350
|
+
isArray = U.isArray,
|
|
2351
|
+
isNumber = U.isNumber,
|
|
2352
|
+
pick = U.pick,
|
|
2353
|
+
wrap = U.wrap;
|
|
2354
|
+
/* *
|
|
2355
|
+
*
|
|
2356
|
+
* Constants
|
|
2357
|
+
*
|
|
2358
|
+
* */
|
|
2359
|
+
var CHUNK_SIZE = 3000;
|
|
2360
|
+
var composedClasses = [];
|
|
2361
|
+
/* *
|
|
2362
|
+
*
|
|
2363
|
+
* Variables
|
|
2364
|
+
*
|
|
2365
|
+
* */
|
|
2366
|
+
var index,
|
|
2367
|
+
mainCanvas;
|
|
2368
|
+
/* *
|
|
2369
|
+
*
|
|
2370
|
+
* Functions
|
|
2371
|
+
*
|
|
2372
|
+
* */
|
|
2373
|
+
/**
|
|
2374
|
+
* @private
|
|
2375
|
+
*/
|
|
2376
|
+
function allocateIfNotSeriesBoosting(renderer, series) {
|
|
2377
|
+
var boost = series.boost;
|
|
2378
|
+
if (renderer &&
|
|
2379
|
+
boost &&
|
|
2380
|
+
boost.target &&
|
|
2381
|
+
boost.canvas &&
|
|
2382
|
+
!isChartSeriesBoosting(series.chart)) {
|
|
2383
|
+
renderer.allocateBufferForSingleSeries(series);
|
|
2384
|
+
}
|
|
2385
|
+
}
|
|
2386
|
+
/**
|
|
2387
|
+
* Return true if ths boost.enabled option is true
|
|
2388
|
+
*
|
|
2389
|
+
* @private
|
|
2390
|
+
* @param {Highcharts.Chart} chart
|
|
2391
|
+
* The chart
|
|
2392
|
+
* @return {boolean}
|
|
2393
|
+
* True, if boost is enabled.
|
|
2394
|
+
*/
|
|
2395
|
+
function boostEnabled(chart) {
|
|
2396
|
+
return pick((chart &&
|
|
2397
|
+
chart.options &&
|
|
2398
|
+
chart.options.boost &&
|
|
2399
|
+
chart.options.boost.enabled), true);
|
|
2400
|
+
}
|
|
2401
|
+
/**
|
|
2402
|
+
* @private
|
|
2403
|
+
*/
|
|
2404
|
+
function compose(SeriesClass, seriesTypes, wglMode) {
|
|
2405
|
+
var PointClass = SeriesClass.prototype.pointClass;
|
|
2406
|
+
if (composedClasses.indexOf(PointClass) === -1) {
|
|
2407
|
+
composedClasses.push(PointClass);
|
|
2408
|
+
wrap(PointClass.prototype, 'haloPath', wrapPointHaloPath);
|
|
2409
|
+
}
|
|
2410
|
+
if (composedClasses.indexOf(SeriesClass) === -1) {
|
|
2411
|
+
composedClasses.push(SeriesClass);
|
|
2412
|
+
addEvent(SeriesClass, 'destroy', onSeriesDestroy);
|
|
2413
|
+
addEvent(SeriesClass, 'hide', onSeriesHide);
|
|
2414
|
+
var seriesProto_1 = SeriesClass.prototype;
|
|
2415
|
+
if (wglMode) {
|
|
2416
|
+
seriesProto_1.renderCanvas = seriesRenderCanvas;
|
|
2417
|
+
}
|
|
2418
|
+
wrap(seriesProto_1, 'getExtremes', wrapSeriesGetExtremes);
|
|
2419
|
+
wrap(seriesProto_1, 'markerAttribs', wrapSeriesMarkerAttribs);
|
|
2420
|
+
wrap(seriesProto_1, 'processData', wrapSeriesProcessData);
|
|
2421
|
+
wrap(seriesProto_1, 'searchPoint', wrapSeriesSearchPoint);
|
|
2422
|
+
[
|
|
2423
|
+
'translate',
|
|
2424
|
+
'generatePoints',
|
|
2425
|
+
'drawTracker',
|
|
2426
|
+
'drawPoints',
|
|
2427
|
+
'render'
|
|
2428
|
+
].forEach(function (method) {
|
|
2429
|
+
return wrapSeriesFunctions(seriesProto_1, seriesTypes, method);
|
|
2430
|
+
});
|
|
2431
|
+
}
|
|
2432
|
+
if (composedClasses.indexOf(getOptions) === -1) {
|
|
2433
|
+
composedClasses.push(getOptions);
|
|
2434
|
+
var plotOptions_1 = getOptions().plotOptions;
|
|
2435
|
+
// Set default options
|
|
2436
|
+
Boostables.forEach(function (type) {
|
|
2437
|
+
var typePlotOptions = plotOptions_1[type];
|
|
2438
|
+
if (typePlotOptions) {
|
|
2439
|
+
typePlotOptions.boostThreshold = 5000;
|
|
2440
|
+
typePlotOptions.boostData = [];
|
|
2441
|
+
seriesTypes[type].prototype.fillOpacity = true;
|
|
2442
|
+
}
|
|
2443
|
+
});
|
|
2444
|
+
}
|
|
2445
|
+
if (wglMode) {
|
|
2446
|
+
var AreaSeries = seriesTypes.area,
|
|
2447
|
+
AreaSplineSeries = seriesTypes.areaspline,
|
|
2448
|
+
BubbleSeries = seriesTypes.bubble,
|
|
2449
|
+
ColumnSeries = seriesTypes.column,
|
|
2450
|
+
HeatmapSeries = seriesTypes.heatmap,
|
|
2451
|
+
ScatterSeries = seriesTypes.scatter,
|
|
2452
|
+
TreemapSeries = seriesTypes.treemap;
|
|
2453
|
+
if (AreaSeries &&
|
|
2454
|
+
composedClasses.indexOf(AreaSeries) === -1) {
|
|
2455
|
+
composedClasses.push(AreaSeries);
|
|
2456
|
+
extend(AreaSeries.prototype, {
|
|
2457
|
+
fill: true,
|
|
2458
|
+
fillOpacity: true,
|
|
2459
|
+
sampling: true
|
|
2460
|
+
});
|
|
2461
|
+
}
|
|
2462
|
+
if (AreaSplineSeries &&
|
|
2463
|
+
composedClasses.indexOf(AreaSplineSeries) === -1) {
|
|
2464
|
+
composedClasses.push(AreaSplineSeries);
|
|
2465
|
+
extend(AreaSplineSeries.prototype, {
|
|
2466
|
+
fill: true,
|
|
2467
|
+
fillOpacity: true,
|
|
2468
|
+
sampling: true
|
|
2469
|
+
});
|
|
2470
|
+
}
|
|
2471
|
+
if (BubbleSeries &&
|
|
2472
|
+
composedClasses.indexOf(BubbleSeries) === -1) {
|
|
2473
|
+
composedClasses.push(BubbleSeries);
|
|
2474
|
+
var bubbleProto_1 = BubbleSeries.prototype;
|
|
2475
|
+
// By default, the bubble series does not use the KD-tree, so force
|
|
2476
|
+
// it to.
|
|
2477
|
+
delete bubbleProto_1.buildKDTree;
|
|
2478
|
+
// seriesTypes.bubble.prototype.directTouch = false;
|
|
2479
|
+
// Needed for markers to work correctly
|
|
2480
|
+
wrap(bubbleProto_1, 'markerAttribs', function (proceed) {
|
|
2481
|
+
if (this.boosted) {
|
|
2482
|
+
return false;
|
|
2483
|
+
}
|
|
2484
|
+
return proceed.apply(this, [].slice.call(arguments, 1));
|
|
2485
|
+
});
|
|
2486
|
+
}
|
|
2487
|
+
if (ColumnSeries &&
|
|
2488
|
+
composedClasses.indexOf(ColumnSeries) === -1) {
|
|
2489
|
+
composedClasses.push(ColumnSeries);
|
|
2490
|
+
extend(ColumnSeries.prototype, {
|
|
2491
|
+
fill: true,
|
|
2492
|
+
sampling: true
|
|
2493
|
+
});
|
|
2494
|
+
}
|
|
2495
|
+
if (ScatterSeries &&
|
|
2496
|
+
composedClasses.indexOf(ScatterSeries) === -1) {
|
|
2497
|
+
composedClasses.push(ScatterSeries);
|
|
2498
|
+
ScatterSeries.prototype.fill = true;
|
|
2499
|
+
}
|
|
2500
|
+
// We need to handle heatmaps separatly, since we can't perform the
|
|
2501
|
+
// size/color calculations in the shader easily.
|
|
2502
|
+
// @todo This likely needs future optimization.
|
|
2503
|
+
[HeatmapSeries, TreemapSeries].forEach(function (SC) {
|
|
2504
|
+
if (SC && composedClasses.indexOf(SC) === -1) {
|
|
2505
|
+
composedClasses.push(SC);
|
|
2506
|
+
wrap(SC.prototype, 'drawPoints', wrapSeriesDrawPoints);
|
|
2507
|
+
}
|
|
2508
|
+
});
|
|
2509
|
+
}
|
|
2510
|
+
return SeriesClass;
|
|
2511
|
+
}
|
|
2512
|
+
/**
|
|
2513
|
+
* Create a canvas + context and attach it to the target
|
|
2514
|
+
*
|
|
2515
|
+
* @private
|
|
2516
|
+
* @function createAndAttachRenderer
|
|
2517
|
+
*
|
|
2518
|
+
* @param {Highcharts.Chart} chart
|
|
2519
|
+
* the chart
|
|
2520
|
+
*
|
|
2521
|
+
* @param {Highcharts.Series} series
|
|
2522
|
+
* the series
|
|
2523
|
+
*
|
|
2524
|
+
* @return {Highcharts.BoostGLRenderer}
|
|
2525
|
+
* the canvas renderer
|
|
2526
|
+
*/
|
|
2527
|
+
function createAndAttachRenderer(chart, series) {
|
|
2528
|
+
var ChartClass = chart.constructor,
|
|
2529
|
+
targetGroup = chart.seriesGroup || series.group,
|
|
2530
|
+
alpha = 1;
|
|
2531
|
+
var width = chart.chartWidth,
|
|
2532
|
+
height = chart.chartHeight,
|
|
2533
|
+
target = chart,
|
|
2534
|
+
foSupported = typeof SVGForeignObjectElement !== 'undefined';
|
|
2535
|
+
if (isChartSeriesBoosting(chart)) {
|
|
2536
|
+
target = chart;
|
|
2537
|
+
}
|
|
2538
|
+
else {
|
|
2539
|
+
target = series;
|
|
2540
|
+
}
|
|
2541
|
+
var boost = target.boost =
|
|
2542
|
+
target.boost ||
|
|
2543
|
+
{};
|
|
2544
|
+
// Support for foreignObject is flimsy as best.
|
|
2545
|
+
// IE does not support it, and Chrome has a bug which messes up
|
|
2546
|
+
// the canvas draw order.
|
|
2547
|
+
// As such, we force the Image fallback for now, but leaving the
|
|
2548
|
+
// actual Canvas path in-place in case this changes in the future.
|
|
2549
|
+
foSupported = false;
|
|
2550
|
+
if (!mainCanvas) {
|
|
2551
|
+
mainCanvas = doc.createElement('canvas');
|
|
2552
|
+
}
|
|
2553
|
+
if (!boost.target) {
|
|
2554
|
+
boost.canvas = mainCanvas;
|
|
2555
|
+
// Fall back to image tag if foreignObject isn't supported,
|
|
2556
|
+
// or if we're exporting.
|
|
2557
|
+
if (chart.renderer.forExport || !foSupported) {
|
|
2558
|
+
target.renderTarget = boost.target = chart.renderer.image('', 0, 0, width, height)
|
|
2559
|
+
.addClass('highcharts-boost-canvas')
|
|
2560
|
+
.add(targetGroup);
|
|
2561
|
+
boost.clear = function () {
|
|
2562
|
+
boost.target.attr({
|
|
2563
|
+
// Insert a blank pixel (#17182)
|
|
2564
|
+
/* eslint-disable-next-line max-len*/
|
|
2565
|
+
href: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII='
|
|
2566
|
+
});
|
|
2567
|
+
};
|
|
2568
|
+
boost.copy = function () {
|
|
2569
|
+
boost.resize();
|
|
2570
|
+
boost.target.attr({
|
|
2571
|
+
href: boost.canvas.toDataURL('image/png')
|
|
2572
|
+
});
|
|
2573
|
+
};
|
|
2574
|
+
}
|
|
2575
|
+
else {
|
|
2576
|
+
boost.targetFo = chart.renderer
|
|
2577
|
+
.createElement('foreignObject')
|
|
2578
|
+
.add(targetGroup);
|
|
2579
|
+
target.renderTarget = boost.target =
|
|
2580
|
+
doc.createElement('canvas');
|
|
2581
|
+
boost.targetCtx = boost.target.getContext('2d');
|
|
2582
|
+
boost.targetFo.element.appendChild(boost.target);
|
|
2583
|
+
boost.clear = function () {
|
|
2584
|
+
boost.target.width = boost.canvas.width;
|
|
2585
|
+
boost.target.height = boost.canvas.height;
|
|
2586
|
+
};
|
|
2587
|
+
boost.copy = function () {
|
|
2588
|
+
boost.target.width = boost.canvas.width;
|
|
2589
|
+
boost.target.height = boost.canvas.height;
|
|
2590
|
+
boost.targetCtx.drawImage(boost.canvas, 0, 0);
|
|
2591
|
+
};
|
|
2592
|
+
}
|
|
2593
|
+
boost.resize = function () {
|
|
2594
|
+
width = chart.chartWidth;
|
|
2595
|
+
height = chart.chartHeight;
|
|
2596
|
+
(boost.targetFo || boost.target)
|
|
2597
|
+
.attr({
|
|
2598
|
+
x: 0,
|
|
2599
|
+
y: 0,
|
|
2600
|
+
width: width,
|
|
2601
|
+
height: height
|
|
2602
|
+
})
|
|
2603
|
+
.css({
|
|
2604
|
+
pointerEvents: 'none',
|
|
2605
|
+
mixedBlendMode: 'normal',
|
|
2606
|
+
opacity: alpha
|
|
2607
|
+
});
|
|
2608
|
+
if (target instanceof ChartClass) {
|
|
2609
|
+
target.boost.markerGroup.translate(chart.plotLeft, chart.plotTop);
|
|
2610
|
+
}
|
|
2611
|
+
};
|
|
2612
|
+
boost.clipRect = chart.renderer.clipRect();
|
|
2613
|
+
(boost.targetFo || boost.target).clip(boost.clipRect);
|
|
2614
|
+
if (target instanceof ChartClass) {
|
|
2615
|
+
target.boost.markerGroup = target.renderer
|
|
2616
|
+
.g()
|
|
2617
|
+
.add(targetGroup)
|
|
2618
|
+
.translate(series.xAxis.pos, series.yAxis.pos);
|
|
2619
|
+
}
|
|
2620
|
+
}
|
|
2621
|
+
boost.canvas.width = width;
|
|
2622
|
+
boost.canvas.height = height;
|
|
2623
|
+
if (boost.clipRect) {
|
|
2624
|
+
boost.clipRect.attr(getBoostClipRect(chart, target));
|
|
2625
|
+
}
|
|
2626
|
+
boost.resize();
|
|
2627
|
+
boost.clear();
|
|
2628
|
+
if (!boost.wgl) {
|
|
2629
|
+
boost.wgl = new WGLRenderer(function (wgl) {
|
|
2630
|
+
if (wgl.settings.debug.timeBufferCopy) {
|
|
2631
|
+
console.time('buffer copy'); // eslint-disable-line no-console
|
|
2632
|
+
}
|
|
2633
|
+
boost.copy();
|
|
2634
|
+
if (wgl.settings.debug.timeBufferCopy) {
|
|
2635
|
+
console.timeEnd('buffer copy'); // eslint-disable-line no-console
|
|
2636
|
+
}
|
|
2637
|
+
});
|
|
2638
|
+
if (!boost.wgl.init(boost.canvas)) {
|
|
2639
|
+
// The OGL renderer couldn't be inited.
|
|
2640
|
+
// This likely means a shader error as we wouldn't get to this point
|
|
2641
|
+
// if there was no WebGL support.
|
|
2642
|
+
error('[highcharts boost] - unable to init WebGL renderer');
|
|
2643
|
+
}
|
|
2644
|
+
// target.ogl.clear();
|
|
2645
|
+
boost.wgl.setOptions(chart.options.boost || {});
|
|
2646
|
+
if (target instanceof ChartClass) {
|
|
2647
|
+
boost.wgl.allocateBuffer(chart);
|
|
2648
|
+
}
|
|
2649
|
+
}
|
|
2650
|
+
boost.wgl.setSize(width, height);
|
|
2651
|
+
return boost.wgl;
|
|
2652
|
+
}
|
|
2653
|
+
/**
|
|
2654
|
+
* If implemented in the core, parts of this can probably be
|
|
2655
|
+
* shared with other similar methods in Highcharts.
|
|
2656
|
+
* @private
|
|
2657
|
+
* @function Highcharts.Series#destroyGraphics
|
|
2658
|
+
*/
|
|
2659
|
+
function destroyGraphics(series) {
|
|
2660
|
+
var points = series.points;
|
|
2661
|
+
if (points) {
|
|
2662
|
+
var point = void 0,
|
|
2663
|
+
i = void 0;
|
|
2664
|
+
for (i = 0; i < points.length; i = i + 1) {
|
|
2665
|
+
point = points[i];
|
|
2666
|
+
if (point && point.destroyElements) {
|
|
2667
|
+
point.destroyElements(); // #7557
|
|
2668
|
+
}
|
|
2669
|
+
}
|
|
2670
|
+
}
|
|
2671
|
+
['graph', 'area', 'tracker'].forEach(function (prop) {
|
|
2672
|
+
var seriesProp = series[prop];
|
|
2673
|
+
if (seriesProp) {
|
|
2674
|
+
series[prop] = seriesProp.destroy();
|
|
2675
|
+
}
|
|
2676
|
+
});
|
|
2677
|
+
var zonesSeries = series;
|
|
2678
|
+
if (zonesSeries.getZonesGraphs) {
|
|
2679
|
+
var props = zonesSeries.getZonesGraphs([['graph', 'highcharts-graph']]);
|
|
2680
|
+
props.forEach(function (prop) {
|
|
2681
|
+
var zoneGraph = zonesSeries[prop[0]];
|
|
2682
|
+
if (zoneGraph) {
|
|
2683
|
+
zonesSeries[prop[0]] = zoneGraph.destroy();
|
|
2684
|
+
}
|
|
2685
|
+
});
|
|
2686
|
+
}
|
|
2687
|
+
}
|
|
2688
|
+
/**
|
|
2689
|
+
* An "async" foreach loop. Uses a setTimeout to keep the loop from blocking the
|
|
2690
|
+
* UI thread.
|
|
2691
|
+
*
|
|
2692
|
+
* @private
|
|
2693
|
+
* @param {Array<unknown>} arr
|
|
2694
|
+
* The array to loop through.
|
|
2695
|
+
* @param {Function} fn
|
|
2696
|
+
* The callback to call for each item.
|
|
2697
|
+
* @param {Function} finalFunc
|
|
2698
|
+
* The callback to call when done.
|
|
2699
|
+
* @param {number} [chunkSize]
|
|
2700
|
+
* The number of iterations per timeout.
|
|
2701
|
+
* @param {number} [i]
|
|
2702
|
+
* The current index.
|
|
2703
|
+
* @param {boolean} [noTimeout]
|
|
2704
|
+
* Set to true to skip timeouts.
|
|
2705
|
+
*/
|
|
2706
|
+
function eachAsync(arr, fn, finalFunc, chunkSize, i, noTimeout) {
|
|
2707
|
+
i = i || 0;
|
|
2708
|
+
chunkSize = chunkSize || CHUNK_SIZE;
|
|
2709
|
+
var threshold = i + chunkSize;
|
|
2710
|
+
var proceed = true;
|
|
2711
|
+
while (proceed && i < threshold && i < arr.length) {
|
|
2712
|
+
proceed = fn(arr[i], i);
|
|
2713
|
+
++i;
|
|
2714
|
+
}
|
|
2715
|
+
if (proceed) {
|
|
2716
|
+
if (i < arr.length) {
|
|
2717
|
+
if (noTimeout) {
|
|
2718
|
+
eachAsync(arr, fn, finalFunc, chunkSize, i, noTimeout);
|
|
2719
|
+
}
|
|
2720
|
+
else if (win.requestAnimationFrame) {
|
|
2721
|
+
// If available, do requestAnimationFrame - shaves off a few ms
|
|
2722
|
+
win.requestAnimationFrame(function () {
|
|
2723
|
+
eachAsync(arr, fn, finalFunc, chunkSize, i);
|
|
2724
|
+
});
|
|
2725
|
+
}
|
|
2726
|
+
else {
|
|
2727
|
+
setTimeout(eachAsync, 0, arr, fn, finalFunc, chunkSize, i);
|
|
2728
|
+
}
|
|
2729
|
+
}
|
|
2730
|
+
else if (finalFunc) {
|
|
2731
|
+
finalFunc();
|
|
2732
|
+
}
|
|
2733
|
+
}
|
|
2734
|
+
}
|
|
2735
|
+
/**
|
|
2736
|
+
* Enter boost mode and apply boost-specific properties.
|
|
2737
|
+
* @private
|
|
2738
|
+
* @function Highcharts.Series#enterBoost
|
|
2739
|
+
*/
|
|
2740
|
+
function enterBoost(series) {
|
|
2741
|
+
series.boost = series.boost || {
|
|
2742
|
+
// faster than a series bind:
|
|
2743
|
+
getPoint: (function (bp) { return getPoint(series, bp); })
|
|
2744
|
+
};
|
|
2745
|
+
var alteredByBoost = series.boost.altered = [];
|
|
2746
|
+
// Save the original values, including whether it was an own
|
|
2747
|
+
// property or inherited from the prototype.
|
|
2748
|
+
['allowDG', 'directTouch', 'stickyTracking'].forEach(function (prop) {
|
|
2749
|
+
alteredByBoost.push({
|
|
2750
|
+
prop: prop,
|
|
2751
|
+
val: series[prop],
|
|
2752
|
+
own: Object.hasOwnProperty.call(series, prop)
|
|
2753
|
+
});
|
|
2754
|
+
});
|
|
2755
|
+
series.allowDG = false;
|
|
2756
|
+
series.directTouch = false;
|
|
2757
|
+
series.stickyTracking = true;
|
|
2758
|
+
// Prevent animation when zooming in on boosted series(#13421).
|
|
2759
|
+
series.finishedAnimating = true;
|
|
2760
|
+
// Hide series label if any
|
|
2761
|
+
if (series.labelBySeries) {
|
|
2762
|
+
series.labelBySeries = series.labelBySeries.destroy();
|
|
2763
|
+
}
|
|
2764
|
+
}
|
|
2765
|
+
/**
|
|
2766
|
+
* Exit from boost mode and restore non-boost properties.
|
|
2767
|
+
* @private
|
|
2768
|
+
* @function Highcharts.Series#exitBoost
|
|
2769
|
+
*/
|
|
2770
|
+
function exitBoost(series) {
|
|
2771
|
+
var boost = series.boost;
|
|
2772
|
+
// Reset instance properties and/or delete instance properties and go back
|
|
2773
|
+
// to prototype
|
|
2774
|
+
if (boost) {
|
|
2775
|
+
(boost.altered || []).forEach(function (setting) {
|
|
2776
|
+
if (setting.own) {
|
|
2777
|
+
series[setting.prop] = setting.val;
|
|
2778
|
+
}
|
|
2779
|
+
else {
|
|
2780
|
+
// Revert to prototype
|
|
2781
|
+
delete series[setting.prop];
|
|
2782
|
+
}
|
|
2783
|
+
});
|
|
2784
|
+
// Clear previous run
|
|
2785
|
+
if (boost.clear) {
|
|
2786
|
+
boost.clear();
|
|
2787
|
+
}
|
|
2788
|
+
}
|
|
2789
|
+
}
|
|
2790
|
+
/**
|
|
2791
|
+
* @private
|
|
2792
|
+
* @function Highcharts.Series#hasExtremes
|
|
2793
|
+
*/
|
|
2794
|
+
function hasExtremes(series, checkX) {
|
|
2795
|
+
var options = series.options,
|
|
2796
|
+
data = options.data,
|
|
2797
|
+
xAxis = series.xAxis && series.xAxis.options,
|
|
2798
|
+
yAxis = series.yAxis && series.yAxis.options,
|
|
2799
|
+
colorAxis = series.colorAxis && series.colorAxis.options;
|
|
2800
|
+
return data.length > (options.boostThreshold || Number.MAX_VALUE) &&
|
|
2801
|
+
// Defined yAxis extremes
|
|
2802
|
+
isNumber(yAxis.min) &&
|
|
2803
|
+
isNumber(yAxis.max) &&
|
|
2804
|
+
// Defined (and required) xAxis extremes
|
|
2805
|
+
(!checkX ||
|
|
2806
|
+
(isNumber(xAxis.min) && isNumber(xAxis.max))) &&
|
|
2807
|
+
// Defined (e.g. heatmap) colorAxis extremes
|
|
2808
|
+
(!colorAxis ||
|
|
2809
|
+
(isNumber(colorAxis.min) && isNumber(colorAxis.max)));
|
|
2810
|
+
}
|
|
2811
|
+
/**
|
|
2812
|
+
* Extend series.destroy to also remove the fake k-d-tree points (#5137).
|
|
2813
|
+
* Normally this is handled by Series.destroy that calls Point.destroy,
|
|
2814
|
+
* but the fake search points are not registered like that.
|
|
2815
|
+
* @private
|
|
2816
|
+
*/
|
|
2817
|
+
function onSeriesDestroy() {
|
|
2818
|
+
var series = this,
|
|
2819
|
+
chart = series.chart;
|
|
2820
|
+
if (chart.boost &&
|
|
2821
|
+
chart.boost.markerGroup === series.markerGroup) {
|
|
2822
|
+
series.markerGroup = null;
|
|
2823
|
+
}
|
|
2824
|
+
if (chart.hoverPoints) {
|
|
2825
|
+
chart.hoverPoints = chart.hoverPoints.filter(function (point) {
|
|
2826
|
+
return point.series === series;
|
|
2827
|
+
});
|
|
2828
|
+
}
|
|
2829
|
+
if (chart.hoverPoint && chart.hoverPoint.series === series) {
|
|
2830
|
+
chart.hoverPoint = null;
|
|
2831
|
+
}
|
|
2832
|
+
}
|
|
2833
|
+
/**
|
|
2834
|
+
* @private
|
|
2835
|
+
*/
|
|
2836
|
+
function onSeriesHide() {
|
|
2837
|
+
var boost = this.boost;
|
|
2838
|
+
if (boost && boost.canvas && boost.target) {
|
|
2839
|
+
if (boost.wgl) {
|
|
2840
|
+
boost.wgl.clear();
|
|
2841
|
+
}
|
|
2842
|
+
if (boost.clear) {
|
|
2843
|
+
boost.clear();
|
|
2844
|
+
}
|
|
2845
|
+
}
|
|
2846
|
+
}
|
|
2847
|
+
/**
|
|
2848
|
+
* Performs the actual render if the renderer is
|
|
2849
|
+
* attached to the series.
|
|
2850
|
+
* @private
|
|
2851
|
+
*/
|
|
2852
|
+
function renderIfNotSeriesBoosting(series) {
|
|
2853
|
+
var boost = series.boost;
|
|
2854
|
+
if (boost &&
|
|
2855
|
+
boost.canvas &&
|
|
2856
|
+
boost.target &&
|
|
2857
|
+
boost.wgl &&
|
|
2858
|
+
!isChartSeriesBoosting(series.chart)) {
|
|
2859
|
+
boost.wgl.render(series.chart);
|
|
2860
|
+
}
|
|
2861
|
+
}
|
|
2862
|
+
/**
|
|
2863
|
+
* Return a full Point object based on the index.
|
|
2864
|
+
* The boost module uses stripped point objects for performance reasons.
|
|
2865
|
+
|
|
2866
|
+
* @private
|
|
2867
|
+
* @param {object|Highcharts.Point} boostPoint
|
|
2868
|
+
* A stripped-down point object
|
|
2869
|
+
* @return {Highcharts.Point}
|
|
2870
|
+
* A Point object as per https://api.highcharts.com/highcharts#Point
|
|
2871
|
+
*/
|
|
2872
|
+
function getPoint(series, boostPoint) {
|
|
2873
|
+
var seriesOptions = series.options,
|
|
2874
|
+
xAxis = series.xAxis,
|
|
2875
|
+
PointClass = series.pointClass;
|
|
2876
|
+
if (boostPoint instanceof PointClass) {
|
|
2877
|
+
return boostPoint;
|
|
2878
|
+
}
|
|
2879
|
+
var xData = (series.xData ||
|
|
2880
|
+
seriesOptions.xData ||
|
|
2881
|
+
series.processedXData ||
|
|
2882
|
+
false),
|
|
2883
|
+
point = (new PointClass()).init(series,
|
|
2884
|
+
series.options.data[boostPoint.i],
|
|
2885
|
+
xData ? xData[boostPoint.i] : void 0);
|
|
2886
|
+
point.category = pick(xAxis.categories ?
|
|
2887
|
+
xAxis.categories[point.x] :
|
|
2888
|
+
point.x, // @todo simplify
|
|
2889
|
+
point.x);
|
|
2890
|
+
point.dist = boostPoint.dist;
|
|
2891
|
+
point.distX = boostPoint.distX;
|
|
2892
|
+
point.plotX = boostPoint.plotX;
|
|
2893
|
+
point.plotY = boostPoint.plotY;
|
|
2894
|
+
point.index = boostPoint.i;
|
|
2895
|
+
point.isInside = series.isPointInside(point);
|
|
2896
|
+
return point;
|
|
2897
|
+
}
|
|
2898
|
+
/**
|
|
2899
|
+
* @private
|
|
2900
|
+
* @function Highcharts.Series#renderCanvas
|
|
2901
|
+
*/
|
|
2902
|
+
function seriesRenderCanvas() {
|
|
2903
|
+
var _this = this;
|
|
2904
|
+
var options = this.options || {}, chart = this.chart, xAxis = this.xAxis, yAxis = this.yAxis, xData = options.xData || this.processedXData, yData = options.yData || this.processedYData, rawData = options.data, xExtremes = xAxis.getExtremes(), xMin = xExtremes.min, xMax = xExtremes.max, yExtremes = yAxis.getExtremes(), yMin = yExtremes.min, yMax = yExtremes.max, pointTaken = {}, sampling = !!this.sampling, enableMouseTracking = options.enableMouseTracking !== false, threshold = options.threshold, isRange = this.pointArrayMap &&
|
|
2905
|
+
this.pointArrayMap.join(',') === 'low,high', isStacked = !!options.stacking, cropStart = this.cropStart || 0, requireSorting = this.requireSorting, useRaw = !xData, compareX = options.findNearestPointBy === 'x', xDataFull = (this.xData ||
|
|
2906
|
+
this.options.xData ||
|
|
2907
|
+
this.processedXData ||
|
|
2908
|
+
false);
|
|
2909
|
+
var renderer = false,
|
|
2910
|
+
lastClientX,
|
|
2911
|
+
yBottom = yAxis.getThreshold(threshold),
|
|
2912
|
+
minVal,
|
|
2913
|
+
maxVal,
|
|
2914
|
+
minI,
|
|
2915
|
+
maxI;
|
|
2916
|
+
// Get or create the renderer
|
|
2917
|
+
renderer = createAndAttachRenderer(chart, this);
|
|
2918
|
+
chart.boosted = true;
|
|
2919
|
+
if (!this.visible) {
|
|
2920
|
+
return;
|
|
2921
|
+
}
|
|
2922
|
+
// If we are zooming out from SVG mode, destroy the graphics
|
|
2923
|
+
if (this.points || this.graph) {
|
|
2924
|
+
destroyGraphics(this);
|
|
2925
|
+
}
|
|
2926
|
+
// If we're rendering per. series we should create the marker groups
|
|
2927
|
+
// as usual.
|
|
2928
|
+
if (!isChartSeriesBoosting(chart)) {
|
|
2929
|
+
// If all series were boosting, but are not anymore
|
|
2930
|
+
// restore private markerGroup
|
|
2931
|
+
if (chart.boost &&
|
|
2932
|
+
this.markerGroup === chart.boost.markerGroup) {
|
|
2933
|
+
this.markerGroup = void 0;
|
|
2934
|
+
}
|
|
2935
|
+
this.markerGroup = this.plotGroup('markerGroup', 'markers', true, 1, chart.seriesGroup);
|
|
2936
|
+
}
|
|
2937
|
+
else {
|
|
2938
|
+
// If series has a private markeGroup, remove that
|
|
2939
|
+
// and use common markerGroup
|
|
2940
|
+
if (this.markerGroup &&
|
|
2941
|
+
this.markerGroup !== chart.boost.markerGroup) {
|
|
2942
|
+
this.markerGroup.destroy();
|
|
2943
|
+
}
|
|
2944
|
+
// Use a single group for the markers
|
|
2945
|
+
this.markerGroup = chart.boost.markerGroup;
|
|
2946
|
+
// When switching from chart boosting mode, destroy redundant
|
|
2947
|
+
// series boosting targets
|
|
2948
|
+
if (this.boost && this.boost.target) {
|
|
2949
|
+
this.renderTarget = this.boost.target = this.boost.target.destroy();
|
|
2950
|
+
}
|
|
2951
|
+
}
|
|
2952
|
+
var points = this.points = [],
|
|
2953
|
+
addKDPoint = function (clientX,
|
|
2954
|
+
plotY,
|
|
2955
|
+
i) {
|
|
2956
|
+
// We need to do ceil on the clientX to make things
|
|
2957
|
+
// snap to pixel values. The renderer will frequently
|
|
2958
|
+
// draw stuff on "sub-pixels".
|
|
2959
|
+
clientX = Math.ceil(clientX);
|
|
2960
|
+
// Shaves off about 60ms compared to repeated concatenation
|
|
2961
|
+
index = compareX ? clientX : clientX + ',' + plotY;
|
|
2962
|
+
// The k-d tree requires series points.
|
|
2963
|
+
// Reduce the amount of points, since the time to build the
|
|
2964
|
+
// tree increases exponentially.
|
|
2965
|
+
if (enableMouseTracking && !pointTaken[index]) {
|
|
2966
|
+
pointTaken[index] = true;
|
|
2967
|
+
if (chart.inverted) {
|
|
2968
|
+
clientX = xAxis.len - clientX;
|
|
2969
|
+
plotY = yAxis.len - plotY;
|
|
2970
|
+
}
|
|
2971
|
+
points.push({
|
|
2972
|
+
x: xDataFull ? xDataFull[cropStart + i] : false,
|
|
2973
|
+
clientX: clientX,
|
|
2974
|
+
plotX: clientX,
|
|
2975
|
+
plotY: plotY,
|
|
2976
|
+
i: cropStart + i
|
|
2977
|
+
});
|
|
2978
|
+
}
|
|
2979
|
+
};
|
|
2980
|
+
// Do not start building while drawing
|
|
2981
|
+
this.buildKDTree = noop;
|
|
2982
|
+
if (renderer) {
|
|
2983
|
+
allocateIfNotSeriesBoosting(renderer, this);
|
|
2984
|
+
renderer.pushSeries(this);
|
|
2985
|
+
// Perform the actual renderer if we're on series level
|
|
2986
|
+
renderIfNotSeriesBoosting(this);
|
|
2987
|
+
}
|
|
2988
|
+
/**
|
|
2989
|
+
* This builds the KD-tree
|
|
2990
|
+
* @private
|
|
2991
|
+
*/
|
|
2992
|
+
function processPoint(d, i) {
|
|
2993
|
+
var chartDestroyed = typeof chart.index === 'undefined';
|
|
2994
|
+
var x,
|
|
2995
|
+
y,
|
|
2996
|
+
clientX,
|
|
2997
|
+
plotY,
|
|
2998
|
+
low = false,
|
|
2999
|
+
isYInside = true;
|
|
3000
|
+
if (typeof d === 'undefined') {
|
|
3001
|
+
return true;
|
|
3002
|
+
}
|
|
3003
|
+
if (!chartDestroyed) {
|
|
3004
|
+
if (useRaw) {
|
|
3005
|
+
x = d[0];
|
|
3006
|
+
y = d[1];
|
|
3007
|
+
}
|
|
3008
|
+
else {
|
|
3009
|
+
x = d;
|
|
3010
|
+
y = yData[i];
|
|
3011
|
+
}
|
|
3012
|
+
// Resolve low and high for range series
|
|
3013
|
+
if (isRange) {
|
|
3014
|
+
if (useRaw) {
|
|
3015
|
+
y = d.slice(1, 3);
|
|
3016
|
+
}
|
|
3017
|
+
low = y[0];
|
|
3018
|
+
y = y[1];
|
|
3019
|
+
}
|
|
3020
|
+
else if (isStacked) {
|
|
3021
|
+
x = d.x;
|
|
3022
|
+
y = d.stackY;
|
|
3023
|
+
low = y - d.y;
|
|
3024
|
+
}
|
|
3025
|
+
// Optimize for scatter zooming
|
|
3026
|
+
if (!requireSorting) {
|
|
3027
|
+
isYInside = (y || 0) >= yMin && y <= yMax;
|
|
3028
|
+
}
|
|
3029
|
+
if (y !== null && x >= xMin && x <= xMax && isYInside) {
|
|
3030
|
+
clientX = xAxis.toPixels(x, true);
|
|
3031
|
+
if (sampling) {
|
|
3032
|
+
if (typeof minI === 'undefined' ||
|
|
3033
|
+
clientX === lastClientX) {
|
|
3034
|
+
if (!isRange) {
|
|
3035
|
+
low = y;
|
|
3036
|
+
}
|
|
3037
|
+
if (typeof maxI === 'undefined' ||
|
|
3038
|
+
y > maxVal) {
|
|
3039
|
+
maxVal = y;
|
|
3040
|
+
maxI = i;
|
|
3041
|
+
}
|
|
3042
|
+
if (typeof minI === 'undefined' ||
|
|
3043
|
+
low < minVal) {
|
|
3044
|
+
minVal = low;
|
|
3045
|
+
minI = i;
|
|
3046
|
+
}
|
|
3047
|
+
}
|
|
3048
|
+
// Add points and reset
|
|
3049
|
+
if (!compareX || clientX !== lastClientX) {
|
|
3050
|
+
// maxI is number too:
|
|
3051
|
+
if (typeof minI !== 'undefined') {
|
|
3052
|
+
plotY =
|
|
3053
|
+
yAxis.toPixels(maxVal, true);
|
|
3054
|
+
yBottom =
|
|
3055
|
+
yAxis.toPixels(minVal, true);
|
|
3056
|
+
addKDPoint(clientX, plotY, maxI);
|
|
3057
|
+
if (yBottom !== plotY) {
|
|
3058
|
+
addKDPoint(clientX, yBottom, minI);
|
|
3059
|
+
}
|
|
3060
|
+
}
|
|
3061
|
+
minI = maxI = void 0;
|
|
3062
|
+
lastClientX = clientX;
|
|
3063
|
+
}
|
|
3064
|
+
}
|
|
3065
|
+
else {
|
|
3066
|
+
plotY = Math.ceil(yAxis.toPixels(y, true));
|
|
3067
|
+
addKDPoint(clientX, plotY, i);
|
|
3068
|
+
}
|
|
3069
|
+
}
|
|
3070
|
+
}
|
|
3071
|
+
return !chartDestroyed;
|
|
3072
|
+
}
|
|
3073
|
+
/**
|
|
3074
|
+
* @private
|
|
3075
|
+
*/
|
|
3076
|
+
var boostOptions = renderer.settings,
|
|
3077
|
+
doneProcessing = function () {
|
|
3078
|
+
fireEvent(_this, 'renderedCanvas');
|
|
3079
|
+
// Go back to prototype, ready to build
|
|
3080
|
+
delete _this.buildKDTree;
|
|
3081
|
+
_this.buildKDTree();
|
|
3082
|
+
if (boostOptions.debug.timeKDTree) {
|
|
3083
|
+
console.timeEnd('kd tree building'); // eslint-disable-line no-console
|
|
3084
|
+
}
|
|
3085
|
+
};
|
|
3086
|
+
// Loop over the points to build the k-d tree - skip this if
|
|
3087
|
+
// exporting
|
|
3088
|
+
if (!chart.renderer.forExport) {
|
|
3089
|
+
if (boostOptions.debug.timeKDTree) {
|
|
3090
|
+
console.time('kd tree building'); // eslint-disable-line no-console
|
|
3091
|
+
}
|
|
3092
|
+
eachAsync(isStacked ? this.data : (xData || rawData), processPoint, doneProcessing);
|
|
3093
|
+
}
|
|
3094
|
+
}
|
|
3095
|
+
/**
|
|
3096
|
+
* For inverted series, we need to swap X-Y values before running base
|
|
3097
|
+
* methods.
|
|
3098
|
+
* @private
|
|
3099
|
+
*/
|
|
3100
|
+
function wrapPointHaloPath(proceed) {
|
|
3101
|
+
var point = this,
|
|
3102
|
+
series = point.series,
|
|
3103
|
+
chart = series.chart,
|
|
3104
|
+
plotX = point.plotX || 0,
|
|
3105
|
+
plotY = point.plotY || 0,
|
|
3106
|
+
inverted = chart.inverted;
|
|
3107
|
+
if (series.boosted && inverted) {
|
|
3108
|
+
point.plotX = series.yAxis.len - plotY;
|
|
3109
|
+
point.plotY = series.xAxis.len - plotX;
|
|
3110
|
+
}
|
|
3111
|
+
var halo = proceed.apply(this,
|
|
3112
|
+
[].slice.call(arguments, 1));
|
|
3113
|
+
if (series.boosted && inverted) {
|
|
3114
|
+
point.plotX = plotX;
|
|
3115
|
+
point.plotY = plotY;
|
|
3116
|
+
}
|
|
3117
|
+
return halo;
|
|
3118
|
+
}
|
|
3119
|
+
/**
|
|
3120
|
+
* Used for treemap|heatmap.drawPoints
|
|
3121
|
+
* @private
|
|
3122
|
+
*/
|
|
3123
|
+
function wrapSeriesDrawPoints(proceed) {
|
|
3124
|
+
var enabled = true;
|
|
3125
|
+
if (this.chart.options && this.chart.options.boost) {
|
|
3126
|
+
enabled = typeof this.chart.options.boost.enabled === 'undefined' ?
|
|
3127
|
+
true :
|
|
3128
|
+
this.chart.options.boost.enabled;
|
|
3129
|
+
}
|
|
3130
|
+
if (!enabled || !this.boosted) {
|
|
3131
|
+
return proceed.call(this);
|
|
3132
|
+
}
|
|
3133
|
+
this.chart.boosted = true;
|
|
3134
|
+
// Make sure we have a valid OGL context
|
|
3135
|
+
var renderer = createAndAttachRenderer(this.chart,
|
|
3136
|
+
this);
|
|
3137
|
+
if (renderer) {
|
|
3138
|
+
allocateIfNotSeriesBoosting(renderer, this);
|
|
3139
|
+
renderer.pushSeries(this);
|
|
3140
|
+
}
|
|
3141
|
+
renderIfNotSeriesBoosting(this);
|
|
3142
|
+
}
|
|
3143
|
+
/**
|
|
3144
|
+
* Override a bunch of methods the same way. If the number of points is
|
|
3145
|
+
* below the threshold, run the original method. If not, check for a
|
|
3146
|
+
* canvas version or do nothing.
|
|
3147
|
+
*
|
|
3148
|
+
* Note that we're not overriding any of these for heatmaps.
|
|
3149
|
+
*/
|
|
3150
|
+
function wrapSeriesFunctions(seriesProto, seriesTypes, method) {
|
|
3151
|
+
/**
|
|
3152
|
+
* @private
|
|
3153
|
+
*/
|
|
3154
|
+
function branch(proceed) {
|
|
3155
|
+
var letItPass = this.options.stacking &&
|
|
3156
|
+
(method === 'translate' || method === 'generatePoints');
|
|
3157
|
+
if (!this.boosted ||
|
|
3158
|
+
letItPass ||
|
|
3159
|
+
!boostEnabled(this.chart) ||
|
|
3160
|
+
this.type === 'heatmap' ||
|
|
3161
|
+
this.type === 'treemap' ||
|
|
3162
|
+
!BoostableMap[this.type] ||
|
|
3163
|
+
this.options.boostThreshold === 0) {
|
|
3164
|
+
proceed.call(this);
|
|
3165
|
+
// Run canvas version of method, like renderCanvas(), if it exists
|
|
3166
|
+
}
|
|
3167
|
+
else if (method === 'render' && this.renderCanvas) {
|
|
3168
|
+
this.renderCanvas();
|
|
3169
|
+
}
|
|
3170
|
+
}
|
|
3171
|
+
wrap(seriesProto, method, branch);
|
|
3172
|
+
// Special case for some types, when translate method is already wrapped
|
|
3173
|
+
if (method === 'translate') {
|
|
3174
|
+
[
|
|
3175
|
+
'column',
|
|
3176
|
+
'arearange',
|
|
3177
|
+
'columnrange',
|
|
3178
|
+
'heatmap',
|
|
3179
|
+
'treemap'
|
|
3180
|
+
].forEach(function (type) {
|
|
3181
|
+
if (seriesTypes[type]) {
|
|
3182
|
+
wrap(seriesTypes[type].prototype, method, branch);
|
|
3183
|
+
}
|
|
3184
|
+
});
|
|
3185
|
+
}
|
|
3186
|
+
}
|
|
3187
|
+
/**
|
|
3188
|
+
* Do not compute extremes when min and max are set. If we use this in the
|
|
3189
|
+
* core, we can add the hook to hasExtremes to the methods directly.
|
|
3190
|
+
* @private
|
|
3191
|
+
*/
|
|
3192
|
+
function wrapSeriesGetExtremes(proceed) {
|
|
3193
|
+
if (this.boosted &&
|
|
3194
|
+
hasExtremes(this)) {
|
|
3195
|
+
return {};
|
|
3196
|
+
}
|
|
3197
|
+
return proceed.apply(this, [].slice.call(arguments, 1));
|
|
3198
|
+
}
|
|
3199
|
+
/**
|
|
3200
|
+
* @private
|
|
3201
|
+
*/
|
|
3202
|
+
function wrapSeriesMarkerAttribs(proceed, point) {
|
|
3203
|
+
var series = this,
|
|
3204
|
+
chart = series.chart,
|
|
3205
|
+
plotX = point.plotX || 0,
|
|
3206
|
+
plotY = point.plotY || 0,
|
|
3207
|
+
inverted = chart.inverted;
|
|
3208
|
+
if (series.boosted && inverted) {
|
|
3209
|
+
point.plotX = series.yAxis.len - plotY;
|
|
3210
|
+
point.plotY = series.xAxis.len - plotX;
|
|
3211
|
+
}
|
|
3212
|
+
var attribs = proceed.apply(this,
|
|
3213
|
+
[].slice.call(arguments, 1));
|
|
3214
|
+
if (series.boosted && inverted) {
|
|
3215
|
+
point.plotX = plotX;
|
|
3216
|
+
point.plotY = plotY;
|
|
3217
|
+
}
|
|
3218
|
+
return attribs;
|
|
3219
|
+
}
|
|
3220
|
+
/**
|
|
3221
|
+
* If the series is a heatmap or treemap, or if the series is not boosting
|
|
3222
|
+
* do the default behaviour. Otherwise, process if the series has no
|
|
3223
|
+
* extremes.
|
|
3224
|
+
* @private
|
|
3225
|
+
*/
|
|
3226
|
+
function wrapSeriesProcessData(proceed) {
|
|
3227
|
+
var _this = this;
|
|
3228
|
+
var dataToMeasure = this.options.data;
|
|
3229
|
+
/**
|
|
3230
|
+
* Used twice in this function, first on this.options.data, the second
|
|
3231
|
+
* time it runs the check again after processedXData is built.
|
|
3232
|
+
* If the data is going to be grouped, the series shouldn't be boosted.
|
|
3233
|
+
* @private
|
|
3234
|
+
*/
|
|
3235
|
+
var getSeriesBoosting = function (data) {
|
|
3236
|
+
var series = _this;
|
|
3237
|
+
// Check if will be grouped.
|
|
3238
|
+
if (series.forceCrop) {
|
|
3239
|
+
return false;
|
|
3240
|
+
}
|
|
3241
|
+
return (isChartSeriesBoosting(series.chart) ||
|
|
3242
|
+
((data ? data.length : 0) >=
|
|
3243
|
+
(series.options.boostThreshold || Number.MAX_VALUE)));
|
|
3244
|
+
};
|
|
3245
|
+
if (boostEnabled(this.chart) && BoostableMap[this.type]) {
|
|
3246
|
+
var series = this;
|
|
3247
|
+
// If there are no extremes given in the options, we also need to
|
|
3248
|
+
// process the data to read the data extremes. If this is a heatmap,
|
|
3249
|
+
// do default behaviour.
|
|
3250
|
+
if (
|
|
3251
|
+
// First pass with options.data:
|
|
3252
|
+
!getSeriesBoosting(dataToMeasure) ||
|
|
3253
|
+
series.type === 'heatmap' ||
|
|
3254
|
+
series.type === 'treemap' ||
|
|
3255
|
+
// processedYData for the stack (#7481):
|
|
3256
|
+
series.options.stacking ||
|
|
3257
|
+
!hasExtremes(series, true)) {
|
|
3258
|
+
proceed.apply(series, [].slice.call(arguments, 1));
|
|
3259
|
+
dataToMeasure = series.processedXData;
|
|
3260
|
+
}
|
|
3261
|
+
// Set the isBoosting flag, second pass with processedXData to
|
|
3262
|
+
// see if we have zoomed.
|
|
3263
|
+
series.boosted = getSeriesBoosting(dataToMeasure);
|
|
3264
|
+
// Enter or exit boost mode
|
|
3265
|
+
if (series.boosted) {
|
|
3266
|
+
// Force turbo-mode:
|
|
3267
|
+
var firstPoint = void 0;
|
|
3268
|
+
if (series.options.data &&
|
|
3269
|
+
series.options.data.length) {
|
|
3270
|
+
firstPoint = series.getFirstValidPoint(series.options.data);
|
|
3271
|
+
if (!isNumber(firstPoint) && !isArray(firstPoint)) {
|
|
3272
|
+
error(12, false, series.chart);
|
|
3273
|
+
}
|
|
3274
|
+
}
|
|
3275
|
+
enterBoost(series);
|
|
3276
|
+
}
|
|
3277
|
+
else {
|
|
3278
|
+
exitBoost(series);
|
|
3279
|
+
}
|
|
3280
|
+
// The series type is not boostable
|
|
3281
|
+
}
|
|
3282
|
+
else {
|
|
3283
|
+
proceed.apply(this, [].slice.call(arguments, 1));
|
|
3284
|
+
}
|
|
3285
|
+
}
|
|
3286
|
+
/**
|
|
3287
|
+
* Return a point instance from the k-d-tree
|
|
3288
|
+
* @private
|
|
3289
|
+
*/
|
|
3290
|
+
function wrapSeriesSearchPoint(proceed) {
|
|
3291
|
+
var result = proceed.apply(this,
|
|
3292
|
+
[].slice.call(arguments, 1));
|
|
3293
|
+
if (this.boost && result) {
|
|
3294
|
+
return this.boost.getPoint(result);
|
|
3295
|
+
}
|
|
3296
|
+
return result;
|
|
3297
|
+
}
|
|
3298
|
+
/* *
|
|
3299
|
+
*
|
|
3300
|
+
* Default Export
|
|
3301
|
+
*
|
|
3302
|
+
* */
|
|
3303
|
+
var BoostSeries = {
|
|
3304
|
+
compose: compose,
|
|
3305
|
+
destroyGraphics: destroyGraphics,
|
|
3306
|
+
getPoint: getPoint
|
|
3307
|
+
};
|
|
3308
|
+
|
|
3309
|
+
return BoostSeries;
|
|
3310
|
+
});
|
|
3311
|
+
_registerModule(_modules, 'Extensions/BoostCanvas.js', [_modules['Extensions/Boost/BoostChart.js'], _modules['Extensions/Boost/BoostSeries.js'], _modules['Core/Chart/Chart.js'], _modules['Core/Color/Color.js'], _modules['Core/Globals.js'], _modules['Core/Series/Series.js'], _modules['Core/Series/SeriesRegistry.js'], _modules['Core/Utilities.js']], function (BoostChart, BoostSeries, Chart, Color, H, Series, SeriesRegistry, U) {
|
|
42
3312
|
/* *
|
|
43
3313
|
*
|
|
44
3314
|
* License: www.highcharts.com/license
|
|
@@ -53,6 +3323,9 @@
|
|
|
53
3323
|
* !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
|
|
54
3324
|
*
|
|
55
3325
|
* */
|
|
3326
|
+
var getBoostClipRect = BoostChart.getBoostClipRect,
|
|
3327
|
+
isChartSeriesBoosting = BoostChart.isChartSeriesBoosting;
|
|
3328
|
+
var destroyGraphics = BoostSeries.destroyGraphics;
|
|
56
3329
|
var color = Color.parse;
|
|
57
3330
|
var doc = H.doc,
|
|
58
3331
|
noop = H.noop;
|
|
@@ -140,10 +3413,12 @@
|
|
|
140
3413
|
*/
|
|
141
3414
|
getContext: function () {
|
|
142
3415
|
var chart = this.chart,
|
|
143
|
-
|
|
3416
|
+
target = isChartSeriesBoosting(chart) ? chart : this,
|
|
3417
|
+
targetGroup = (target === chart ?
|
|
3418
|
+
chart.seriesGroup :
|
|
3419
|
+
chart.seriesGroup || this.group);
|
|
3420
|
+
var width = chart.chartWidth,
|
|
144
3421
|
height = chart.chartHeight,
|
|
145
|
-
targetGroup = chart.seriesGroup || this.group,
|
|
146
|
-
target = this,
|
|
147
3422
|
ctx,
|
|
148
3423
|
swapXY = function (proceed,
|
|
149
3424
|
x,
|
|
@@ -160,49 +3435,49 @@
|
|
|
160
3435
|
c,
|
|
161
3436
|
d);
|
|
162
3437
|
};
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
target
|
|
170
|
-
target.renderTarget = chart.renderer
|
|
3438
|
+
var boost = target.boost =
|
|
3439
|
+
target.boost ||
|
|
3440
|
+
{};
|
|
3441
|
+
ctx = boost.targetCtx;
|
|
3442
|
+
if (!boost.canvas) {
|
|
3443
|
+
boost.canvas = doc.createElement('canvas');
|
|
3444
|
+
boost.target = chart.renderer
|
|
171
3445
|
.image('', 0, 0, width, height)
|
|
172
3446
|
.addClass('highcharts-boost-canvas')
|
|
173
3447
|
.add(targetGroup);
|
|
174
|
-
|
|
3448
|
+
ctx = boost.targetCtx =
|
|
3449
|
+
boost.canvas.getContext('2d');
|
|
175
3450
|
if (chart.inverted) {
|
|
176
3451
|
['moveTo', 'lineTo', 'rect', 'arc'].forEach(function (fn) {
|
|
177
3452
|
wrap(ctx, fn, swapXY);
|
|
178
3453
|
});
|
|
179
3454
|
}
|
|
180
|
-
|
|
181
|
-
target.
|
|
182
|
-
href:
|
|
3455
|
+
boost.copy = function () {
|
|
3456
|
+
boost.target.attr({
|
|
3457
|
+
href: boost.canvas.toDataURL('image/png')
|
|
183
3458
|
});
|
|
184
3459
|
};
|
|
185
|
-
|
|
186
|
-
ctx.clearRect(0, 0,
|
|
187
|
-
if (target ===
|
|
188
|
-
target.
|
|
3460
|
+
boost.clear = function () {
|
|
3461
|
+
ctx.clearRect(0, 0, boost.canvas.width, boost.canvas.height);
|
|
3462
|
+
if (target === boost.target) {
|
|
3463
|
+
boost.target.attr({
|
|
189
3464
|
href: b64BlankPixel
|
|
190
3465
|
});
|
|
191
3466
|
}
|
|
192
3467
|
};
|
|
193
|
-
|
|
194
|
-
target.
|
|
3468
|
+
boost.clipRect = chart.renderer.clipRect();
|
|
3469
|
+
boost.target.clip(boost.clipRect);
|
|
195
3470
|
}
|
|
196
3471
|
else if (!(target instanceof Chart)) {
|
|
197
3472
|
// ctx.clearRect(0, 0, width, height);
|
|
198
3473
|
}
|
|
199
|
-
if (
|
|
200
|
-
|
|
3474
|
+
if (boost.canvas.width !== width) {
|
|
3475
|
+
boost.canvas.width = width;
|
|
201
3476
|
}
|
|
202
|
-
if (
|
|
203
|
-
|
|
3477
|
+
if (boost.canvas.height !== height) {
|
|
3478
|
+
boost.canvas.height = height;
|
|
204
3479
|
}
|
|
205
|
-
target.
|
|
3480
|
+
boost.target.attr({
|
|
206
3481
|
x: 0,
|
|
207
3482
|
y: 0,
|
|
208
3483
|
width: width,
|
|
@@ -210,7 +3485,9 @@
|
|
|
210
3485
|
style: 'pointer-events: none',
|
|
211
3486
|
href: b64BlankPixel
|
|
212
3487
|
});
|
|
213
|
-
|
|
3488
|
+
if (boost.clipRect) {
|
|
3489
|
+
boost.clipRect.attr(getBoostClipRect(chart, target));
|
|
3490
|
+
}
|
|
214
3491
|
return ctx;
|
|
215
3492
|
},
|
|
216
3493
|
/**
|
|
@@ -220,16 +3497,17 @@
|
|
|
220
3497
|
* @function Highcharts.Series#canvasToSVG
|
|
221
3498
|
*/
|
|
222
3499
|
canvasToSVG: function () {
|
|
223
|
-
if (!this.chart
|
|
224
|
-
if (this.
|
|
225
|
-
|
|
3500
|
+
if (!isChartSeriesBoosting(this.chart)) {
|
|
3501
|
+
if (this.boost && this.boost.copy) {
|
|
3502
|
+
this.boost.copy();
|
|
226
3503
|
}
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
if (this.boostClear) {
|
|
230
|
-
this.boostClear();
|
|
3504
|
+
else if (this.chart.boost && this.chart.boost.copy) {
|
|
3505
|
+
this.chart.boost.copy();
|
|
231
3506
|
}
|
|
232
3507
|
}
|
|
3508
|
+
else if (this.boost && this.boost.clear) {
|
|
3509
|
+
this.boost.clear();
|
|
3510
|
+
}
|
|
233
3511
|
},
|
|
234
3512
|
cvsLineTo: function (ctx, clientX, plotY) {
|
|
235
3513
|
ctx.lineTo(clientX, plotY);
|
|
@@ -338,13 +3616,13 @@
|
|
|
338
3616
|
i: cropStart + i
|
|
339
3617
|
});
|
|
340
3618
|
}
|
|
341
|
-
};
|
|
342
|
-
if (
|
|
343
|
-
|
|
3619
|
+
}, boost = this.boost || {};
|
|
3620
|
+
if (boost.target) {
|
|
3621
|
+
boost.target.attr({ href: b64BlankPixel });
|
|
344
3622
|
}
|
|
345
3623
|
// If we are zooming out from SVG mode, destroy the graphics
|
|
346
3624
|
if (this.points || this.graph) {
|
|
347
|
-
|
|
3625
|
+
destroyGraphics(this);
|
|
348
3626
|
}
|
|
349
3627
|
// The group
|
|
350
3628
|
series.plotGroup('group', 'series', series.visible ? 'visible' : 'hidden', options.zIndex, chart.seriesGroup);
|
|
@@ -356,8 +3634,8 @@
|
|
|
356
3634
|
points = this.points = [];
|
|
357
3635
|
ctx = this.getContext();
|
|
358
3636
|
series.buildKDTree = noop; // Do not start building while drawing
|
|
359
|
-
if (
|
|
360
|
-
|
|
3637
|
+
if (boost.clear) {
|
|
3638
|
+
boost.clear();
|
|
361
3639
|
}
|
|
362
3640
|
// if (this.canvas) {
|
|
363
3641
|
// ctx.clearRect(
|
|
@@ -495,8 +3773,13 @@
|
|
|
495
3773
|
}
|
|
496
3774
|
wasNull = isNull && !connectNulls;
|
|
497
3775
|
if (i % CHUNK_SIZE === 0) {
|
|
498
|
-
if (series.
|
|
499
|
-
|
|
3776
|
+
if (series.boost &&
|
|
3777
|
+
series.boost.copy) {
|
|
3778
|
+
series.boost.copy();
|
|
3779
|
+
}
|
|
3780
|
+
else if (series.chart.boost &&
|
|
3781
|
+
series.chart.boost.copy) {
|
|
3782
|
+
series.chart.boost.copy();
|
|
500
3783
|
}
|
|
501
3784
|
}
|
|
502
3785
|
}
|
|
@@ -579,19 +3862,20 @@
|
|
|
579
3862
|
* @private
|
|
580
3863
|
*/
|
|
581
3864
|
function canvasToSVG() {
|
|
582
|
-
if (chart.
|
|
583
|
-
chart.
|
|
3865
|
+
if (chart.boost && chart.boost.copy) {
|
|
3866
|
+
chart.boost.copy();
|
|
584
3867
|
}
|
|
585
3868
|
}
|
|
586
3869
|
/**
|
|
587
3870
|
* @private
|
|
588
3871
|
*/
|
|
589
3872
|
function clear() {
|
|
590
|
-
|
|
591
|
-
|
|
3873
|
+
var boost = this.boost || {};
|
|
3874
|
+
if (boost.target) {
|
|
3875
|
+
boost.target.attr({ href: b64BlankPixel });
|
|
592
3876
|
}
|
|
593
|
-
if (
|
|
594
|
-
|
|
3877
|
+
if (boost.canvas) {
|
|
3878
|
+
boost.canvas.getContext('2d').clearRect(0, 0, boost.canvas.width, boost.canvas.height);
|
|
595
3879
|
}
|
|
596
3880
|
}
|
|
597
3881
|
addEvent(chart, 'predraw', clear);
|