stream-charts 1.2.1 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +809 -1022
- package/changes.md +36 -0
- package/dist/app/charts/Chart.d.ts +35 -139
- package/dist/app/charts/Chart.d.ts.map +1 -0
- package/dist/app/charts/Chart.js +74 -65
- package/dist/app/charts/Chart.js.map +1 -1
- package/dist/app/charts/axes/AxesState.d.ts +26 -18
- package/dist/app/charts/axes/AxesState.d.ts.map +1 -0
- package/dist/app/charts/axes/AxesState.js +26 -24
- package/dist/app/charts/axes/AxesState.js.map +1 -1
- package/dist/app/charts/axes/AxisInterval.d.ts +44 -26
- package/dist/app/charts/axes/AxisInterval.d.ts.map +1 -0
- package/dist/app/charts/axes/AxisInterval.js +48 -29
- package/dist/app/charts/axes/AxisInterval.js.map +1 -1
- package/dist/app/charts/axes/BaseAxisRange.d.ts +46 -22
- package/dist/app/charts/axes/BaseAxisRange.d.ts.map +1 -0
- package/dist/app/charts/axes/BaseAxisRange.js +17 -12
- package/dist/app/charts/axes/BaseAxisRange.js.map +1 -1
- package/dist/app/charts/axes/ContinuousAxis.d.ts +47 -6
- package/dist/app/charts/axes/ContinuousAxis.d.ts.map +1 -0
- package/dist/app/charts/axes/ContinuousAxis.js +160 -27
- package/dist/app/charts/axes/ContinuousAxis.js.map +1 -1
- package/dist/app/charts/axes/ContinuousAxisRange.d.ts +29 -10
- package/dist/app/charts/axes/ContinuousAxisRange.d.ts.map +1 -0
- package/dist/app/charts/axes/ContinuousAxisRange.js +29 -11
- package/dist/app/charts/axes/ContinuousAxisRange.js.map +1 -1
- package/dist/app/charts/axes/EmptyAxis.d.ts +5 -2
- package/dist/app/charts/axes/EmptyAxis.d.ts.map +1 -0
- package/dist/app/charts/axes/EmptyAxis.js +30 -9
- package/dist/app/charts/axes/EmptyAxis.js.map +1 -1
- package/dist/app/charts/axes/OrdinalAxis.d.ts +5 -3
- package/dist/app/charts/axes/OrdinalAxis.d.ts.map +1 -0
- package/dist/app/charts/axes/OrdinalAxis.js +39 -16
- package/dist/app/charts/axes/OrdinalAxis.js.map +1 -1
- package/dist/app/charts/axes/OrdinalAxisRange.d.ts +76 -13
- package/dist/app/charts/axes/OrdinalAxisRange.d.ts.map +1 -0
- package/dist/app/charts/axes/OrdinalAxisRange.js +95 -16
- package/dist/app/charts/axes/OrdinalAxisRange.js.map +1 -1
- package/dist/app/charts/axes/autoScale.d.ts +111 -0
- package/dist/app/charts/axes/autoScale.d.ts.map +1 -0
- package/dist/app/charts/axes/autoScale.js +188 -0
- package/dist/app/charts/axes/autoScale.js.map +1 -0
- package/dist/app/charts/axes/axes.d.ts +273 -150
- package/dist/app/charts/axes/axes.d.ts.map +1 -0
- package/dist/app/charts/axes/axes.js +808 -583
- package/dist/app/charts/axes/axes.js.map +1 -1
- package/dist/app/charts/d3types.d.ts +40 -11
- package/dist/app/charts/d3types.d.ts.map +1 -0
- package/dist/app/charts/d3types.js +3 -0
- package/dist/app/charts/d3types.js.map +1 -1
- package/dist/app/charts/datasources/StreamingDataSource.d.ts +149 -0
- package/dist/app/charts/datasources/StreamingDataSource.d.ts.map +1 -0
- package/dist/app/charts/datasources/StreamingDataSource.js +110 -0
- package/dist/app/charts/datasources/StreamingDataSource.js.map +1 -0
- package/dist/app/charts/datasources/iteratesDataSource.d.ts +73 -0
- package/dist/app/charts/datasources/iteratesDataSource.d.ts.map +1 -0
- package/dist/app/charts/datasources/iteratesDataSource.js +87 -0
- package/dist/app/charts/datasources/iteratesDataSource.js.map +1 -0
- package/dist/app/charts/datasources/ordinalDataSource.d.ts +75 -0
- package/dist/app/charts/datasources/ordinalDataSource.d.ts.map +1 -0
- package/dist/app/charts/datasources/ordinalDataSource.js +135 -0
- package/dist/app/charts/datasources/ordinalDataSource.js.map +1 -0
- package/dist/app/charts/datasources/outlierDataSource.d.ts +53 -0
- package/dist/app/charts/datasources/outlierDataSource.d.ts.map +1 -0
- package/dist/app/charts/datasources/outlierDataSource.js +57 -0
- package/dist/app/charts/datasources/outlierDataSource.js.map +1 -0
- package/dist/app/charts/datasources/timeSeriesDataSource.d.ts +77 -0
- package/dist/app/charts/datasources/timeSeriesDataSource.d.ts.map +1 -0
- package/dist/app/charts/datasources/timeSeriesDataSource.js +85 -0
- package/dist/app/charts/datasources/timeSeriesDataSource.js.map +1 -0
- package/dist/app/charts/filters/regexFilter.d.ts +31 -4
- package/dist/app/charts/filters/regexFilter.d.ts.map +1 -0
- package/dist/app/charts/filters/regexFilter.js +38 -4
- package/dist/app/charts/filters/regexFilter.js.map +1 -1
- package/dist/app/charts/hooks/AxesProvider.d.ts +21 -0
- package/dist/app/charts/hooks/AxesProvider.d.ts.map +1 -0
- package/dist/app/charts/hooks/AxesProvider.js +213 -0
- package/dist/app/charts/hooks/AxesProvider.js.map +1 -0
- package/dist/app/charts/hooks/CanvasSurfaceProvider.d.ts +25 -0
- package/dist/app/charts/hooks/CanvasSurfaceProvider.d.ts.map +1 -0
- package/dist/app/charts/hooks/CanvasSurfaceProvider.js +76 -0
- package/dist/app/charts/hooks/CanvasSurfaceProvider.js.map +1 -0
- package/dist/app/charts/hooks/ChartProvider.d.ts +40 -0
- package/dist/app/charts/hooks/ChartProvider.d.ts.map +1 -0
- package/dist/app/charts/hooks/ChartProvider.js +33 -0
- package/dist/app/charts/hooks/ChartProvider.js.map +1 -0
- package/dist/app/charts/hooks/InteractionProvider.d.ts +23 -0
- package/dist/app/charts/hooks/InteractionProvider.d.ts.map +1 -0
- package/dist/app/charts/hooks/InteractionProvider.js +60 -0
- package/dist/app/charts/hooks/InteractionProvider.js.map +1 -0
- package/dist/app/charts/hooks/PlotDimensionsProvider.d.ts +16 -0
- package/dist/app/charts/hooks/PlotDimensionsProvider.d.ts.map +1 -0
- package/dist/app/charts/hooks/PlotDimensionsProvider.js +76 -0
- package/dist/app/charts/hooks/PlotDimensionsProvider.js.map +1 -0
- package/dist/app/charts/hooks/defaultAxesValues.d.ts +11 -0
- package/dist/app/charts/hooks/defaultAxesValues.d.ts.map +1 -0
- package/dist/app/charts/hooks/defaultAxesValues.js +36 -0
- package/dist/app/charts/hooks/defaultAxesValues.js.map +1 -0
- package/dist/app/charts/hooks/defaultMouseValues.d.ts +9 -0
- package/dist/app/charts/hooks/defaultMouseValues.d.ts.map +1 -0
- package/dist/app/charts/hooks/defaultMouseValues.js +23 -0
- package/dist/app/charts/hooks/defaultMouseValues.js.map +1 -0
- package/dist/app/charts/hooks/defaultPlotDimensions.d.ts +13 -0
- package/dist/app/charts/hooks/defaultPlotDimensions.d.ts.map +1 -0
- package/dist/app/charts/hooks/defaultPlotDimensions.js +23 -0
- package/dist/app/charts/hooks/defaultPlotDimensions.js.map +1 -0
- package/dist/app/charts/hooks/defaultTooltipValues.d.ts +9 -0
- package/dist/app/charts/hooks/defaultTooltipValues.d.ts.map +1 -0
- package/dist/app/charts/hooks/defaultTooltipValues.js +21 -0
- package/dist/app/charts/hooks/defaultTooltipValues.js.map +1 -0
- package/dist/app/charts/hooks/defaultUseChartValues.d.ts +14 -0
- package/dist/app/charts/hooks/defaultUseChartValues.d.ts.map +1 -0
- package/dist/app/charts/hooks/defaultUseChartValues.js +30 -0
- package/dist/app/charts/hooks/defaultUseChartValues.js.map +1 -0
- package/dist/app/charts/hooks/useAxes.d.ts +49 -36
- package/dist/app/charts/hooks/useAxes.d.ts.map +1 -0
- package/dist/app/charts/hooks/useAxes.js +16 -176
- package/dist/app/charts/hooks/useAxes.js.map +1 -1
- package/dist/app/charts/hooks/useCanvasSurface.d.ts +25 -0
- package/dist/app/charts/hooks/useCanvasSurface.d.ts.map +1 -0
- package/dist/app/charts/hooks/useCanvasSurface.js +18 -0
- package/dist/app/charts/hooks/useCanvasSurface.js.map +1 -0
- package/dist/app/charts/hooks/useChart.d.ts +30 -44
- package/dist/app/charts/hooks/useChart.d.ts.map +1 -0
- package/dist/app/charts/hooks/useChart.js +26 -48
- package/dist/app/charts/hooks/useChart.js.map +1 -1
- package/dist/app/charts/hooks/useDataSource.d.ts +68 -0
- package/dist/app/charts/hooks/useDataSource.d.ts.map +1 -0
- package/dist/app/charts/hooks/useDataSource.js +63 -0
- package/dist/app/charts/hooks/useDataSource.js.map +1 -0
- package/dist/app/charts/hooks/useHoveredSeries.d.ts +25 -0
- package/dist/app/charts/hooks/useHoveredSeries.d.ts.map +1 -0
- package/dist/app/charts/hooks/useHoveredSeries.js +15 -0
- package/dist/app/charts/hooks/useHoveredSeries.js.map +1 -0
- package/dist/app/charts/hooks/useMouse.d.ts +46 -22
- package/dist/app/charts/hooks/useMouse.d.ts.map +1 -0
- package/dist/app/charts/hooks/useMouse.js +12 -56
- package/dist/app/charts/hooks/useMouse.js.map +1 -1
- package/dist/app/charts/hooks/usePlotDimensions.d.ts +25 -13
- package/dist/app/charts/hooks/usePlotDimensions.d.ts.map +1 -0
- package/dist/app/charts/hooks/usePlotDimensions.js +6 -62
- package/dist/app/charts/hooks/usePlotDimensions.js.map +1 -1
- package/dist/app/charts/hooks/useTooltip.d.ts +24 -26
- package/dist/app/charts/hooks/useTooltip.d.ts.map +1 -0
- package/dist/app/charts/hooks/useTooltip.js +12 -42
- package/dist/app/charts/hooks/useTooltip.js.map +1 -1
- package/dist/app/charts/index.d.ts +66 -0
- package/dist/app/charts/index.d.ts.map +1 -0
- package/dist/app/charts/index.js +87 -0
- package/dist/app/charts/index.js.map +1 -0
- package/dist/app/charts/legends/Legend.d.ts +33 -12
- package/dist/app/charts/legends/Legend.d.ts.map +1 -0
- package/dist/app/charts/legends/Legend.js +138 -379
- package/dist/app/charts/legends/Legend.js.map +1 -1
- package/dist/app/charts/legends/constants.d.ts +19 -0
- package/dist/app/charts/legends/constants.d.ts.map +1 -0
- package/dist/app/charts/legends/constants.js +34 -0
- package/dist/app/charts/legends/constants.js.map +1 -0
- package/dist/app/charts/observables/ChartData.d.ts +1 -0
- package/dist/app/charts/observables/ChartData.d.ts.map +1 -0
- package/dist/app/charts/observables/iterates.d.ts +13 -7
- package/dist/app/charts/observables/iterates.d.ts.map +1 -0
- package/dist/app/charts/observables/iterates.js +42 -9
- package/dist/app/charts/observables/iterates.js.map +1 -1
- package/dist/app/charts/observables/ordinals.d.ts +70 -12
- package/dist/app/charts/observables/ordinals.d.ts.map +1 -0
- package/dist/app/charts/observables/ordinals.js +127 -48
- package/dist/app/charts/observables/ordinals.js.map +1 -1
- package/dist/app/charts/observables/outliers.d.ts +18 -0
- package/dist/app/charts/observables/outliers.d.ts.map +1 -0
- package/dist/app/charts/observables/outliers.js +2 -0
- package/dist/app/charts/observables/outliers.js.map +1 -0
- package/dist/app/charts/plots/BarPlot.d.ts +87 -13
- package/dist/app/charts/plots/BarPlot.d.ts.map +1 -0
- package/dist/app/charts/plots/BarPlot.js +603 -356
- package/dist/app/charts/plots/BarPlot.js.map +1 -1
- package/dist/app/charts/plots/OutlierPlot.d.ts +123 -0
- package/dist/app/charts/plots/OutlierPlot.d.ts.map +1 -0
- package/dist/app/charts/plots/OutlierPlot.js +430 -0
- package/dist/app/charts/plots/OutlierPlot.js.map +1 -0
- package/dist/app/charts/plots/PoincarePlot.d.ts +92 -14
- package/dist/app/charts/plots/PoincarePlot.d.ts.map +1 -0
- package/dist/app/charts/plots/PoincarePlot.js +523 -364
- package/dist/app/charts/plots/PoincarePlot.js.map +1 -1
- package/dist/app/charts/plots/RasterPlot.d.ts +31 -10
- package/dist/app/charts/plots/RasterPlot.d.ts.map +1 -0
- package/dist/app/charts/plots/RasterPlot.js +198 -306
- package/dist/app/charts/plots/RasterPlot.js.map +1 -1
- package/dist/app/charts/plots/ScatterPlot.d.ts +77 -21
- package/dist/app/charts/plots/ScatterPlot.d.ts.map +1 -0
- package/dist/app/charts/plots/ScatterPlot.js +359 -302
- package/dist/app/charts/plots/ScatterPlot.js.map +1 -1
- package/dist/app/charts/plots/autoScaleYAxes.d.ts +43 -0
- package/dist/app/charts/plots/autoScaleYAxes.d.ts.map +1 -0
- package/dist/app/charts/plots/autoScaleYAxes.js +71 -0
- package/dist/app/charts/plots/autoScaleYAxes.js.map +1 -0
- package/dist/app/charts/plots/colorizedLine.d.ts +61 -0
- package/dist/app/charts/plots/colorizedLine.d.ts.map +1 -0
- package/dist/app/charts/plots/colorizedLine.js +157 -0
- package/dist/app/charts/plots/colorizedLine.js.map +1 -0
- package/dist/app/charts/plots/constants.d.ts +7 -0
- package/dist/app/charts/plots/constants.d.ts.map +1 -0
- package/dist/app/charts/plots/constants.js +11 -0
- package/dist/app/charts/plots/constants.js.map +1 -0
- package/dist/app/charts/plots/hitTesting.d.ts +88 -0
- package/dist/app/charts/plots/hitTesting.d.ts.map +1 -0
- package/dist/app/charts/plots/hitTesting.js +136 -0
- package/dist/app/charts/plots/hitTesting.js.map +1 -0
- package/dist/app/charts/plots/plot.d.ts +52 -16
- package/dist/app/charts/plots/plot.d.ts.map +1 -0
- package/dist/app/charts/plots/plot.js +108 -35
- package/dist/app/charts/plots/plot.js.map +1 -1
- package/dist/app/charts/plots/useCanvasZoomPan.d.ts +119 -0
- package/dist/app/charts/plots/useCanvasZoomPan.d.ts.map +1 -0
- package/dist/app/charts/plots/useCanvasZoomPan.js +113 -0
- package/dist/app/charts/plots/useCanvasZoomPan.js.map +1 -0
- package/dist/app/charts/plots/useStreamingTimeAxes.d.ts +103 -0
- package/dist/app/charts/plots/useStreamingTimeAxes.d.ts.map +1 -0
- package/dist/app/charts/plots/useStreamingTimeAxes.js +257 -0
- package/dist/app/charts/plots/useStreamingTimeAxes.js.map +1 -0
- package/dist/app/charts/series/baseSeries.d.ts +60 -8
- package/dist/app/charts/series/baseSeries.d.ts.map +1 -0
- package/dist/app/charts/series/baseSeries.js +53 -8
- package/dist/app/charts/series/baseSeries.js.map +1 -1
- package/dist/app/charts/series/iterateSeries.d.ts +9 -8
- package/dist/app/charts/series/iterateSeries.d.ts.map +1 -0
- package/dist/app/charts/series/iterateSeries.js +7 -7
- package/dist/app/charts/series/iterateSeries.js.map +1 -1
- package/dist/app/charts/series/ordinalSeries.d.ts +27 -13
- package/dist/app/charts/series/ordinalSeries.d.ts.map +1 -0
- package/dist/app/charts/series/ordinalSeries.js +29 -15
- package/dist/app/charts/series/ordinalSeries.js.map +1 -1
- package/dist/app/charts/series/outlierSeries.d.ts +142 -0
- package/dist/app/charts/series/outlierSeries.d.ts.map +1 -0
- package/dist/app/charts/series/outlierSeries.js +82 -0
- package/dist/app/charts/series/outlierSeries.js.map +1 -0
- package/dist/app/charts/series/timeSeries.d.ts +13 -9
- package/dist/app/charts/series/timeSeries.d.ts.map +1 -0
- package/dist/app/charts/series/timeSeries.js +6 -3
- package/dist/app/charts/series/timeSeries.js.map +1 -1
- package/dist/app/charts/series/timeSeriesChartData.d.ts +18 -10
- package/dist/app/charts/series/timeSeriesChartData.d.ts.map +1 -0
- package/dist/app/charts/series/timeSeriesChartData.js +28 -14
- package/dist/app/charts/series/timeSeriesChartData.js.map +1 -1
- package/dist/app/charts/styling/barPlotStyle.d.ts +46 -2
- package/dist/app/charts/styling/barPlotStyle.d.ts.map +1 -0
- package/dist/app/charts/styling/barPlotStyle.js +37 -3
- package/dist/app/charts/styling/barPlotStyle.js.map +1 -1
- package/dist/app/charts/styling/canvasStyle.d.ts +53 -0
- package/dist/app/charts/styling/canvasStyle.d.ts.map +1 -0
- package/dist/app/charts/styling/canvasStyle.js +71 -0
- package/dist/app/charts/styling/canvasStyle.js.map +1 -0
- package/dist/app/charts/styling/margins.d.ts +21 -2
- package/dist/app/charts/styling/margins.d.ts.map +1 -0
- package/dist/app/charts/styling/margins.js +25 -4
- package/dist/app/charts/styling/margins.js.map +1 -1
- package/dist/app/charts/styling/svgStyle.d.ts +10 -56
- package/dist/app/charts/styling/svgStyle.d.ts.map +1 -0
- package/dist/app/charts/styling/svgStyle.js +3 -78
- package/dist/app/charts/styling/svgStyle.js.map +1 -1
- package/dist/app/charts/subscriptions/viewDrivers.d.ts +124 -0
- package/dist/app/charts/subscriptions/viewDrivers.d.ts.map +1 -0
- package/dist/app/charts/subscriptions/viewDrivers.js +338 -0
- package/dist/app/charts/subscriptions/viewDrivers.js.map +1 -0
- package/dist/app/charts/tooltips/BarPlotTooltipContent.d.ts +12 -78
- package/dist/app/charts/tooltips/BarPlotTooltipContent.d.ts.map +1 -0
- package/dist/app/charts/tooltips/BarPlotTooltipContent.js +65 -257
- package/dist/app/charts/tooltips/BarPlotTooltipContent.js.map +1 -1
- package/dist/app/charts/tooltips/DefaultOutlierTooltipContent.d.ts +9 -0
- package/dist/app/charts/tooltips/DefaultOutlierTooltipContent.d.ts.map +1 -0
- package/dist/app/charts/tooltips/DefaultOutlierTooltipContent.js +16 -0
- package/dist/app/charts/tooltips/DefaultOutlierTooltipContent.js.map +1 -0
- package/dist/app/charts/tooltips/OutlierPlotTooltipContent.d.ts +30 -0
- package/dist/app/charts/tooltips/OutlierPlotTooltipContent.d.ts.map +1 -0
- package/dist/app/charts/tooltips/OutlierPlotTooltipContent.js +26 -0
- package/dist/app/charts/tooltips/OutlierPlotTooltipContent.js.map +1 -0
- package/dist/app/charts/tooltips/PoincarePlotTooltipContent.d.ts +22 -72
- package/dist/app/charts/tooltips/PoincarePlotTooltipContent.d.ts.map +1 -0
- package/dist/app/charts/tooltips/PoincarePlotTooltipContent.js +104 -171
- package/dist/app/charts/tooltips/PoincarePlotTooltipContent.js.map +1 -1
- package/dist/app/charts/tooltips/RasterPlotTooltipContent.d.ts +32 -8
- package/dist/app/charts/tooltips/RasterPlotTooltipContent.d.ts.map +1 -0
- package/dist/app/charts/tooltips/RasterPlotTooltipContent.js +62 -115
- package/dist/app/charts/tooltips/RasterPlotTooltipContent.js.map +1 -1
- package/dist/app/charts/tooltips/ScatterPlotTooltipContent.d.ts +39 -12
- package/dist/app/charts/tooltips/ScatterPlotTooltipContent.d.ts.map +1 -0
- package/dist/app/charts/tooltips/ScatterPlotTooltipContent.js +162 -134
- package/dist/app/charts/tooltips/ScatterPlotTooltipContent.js.map +1 -1
- package/dist/app/charts/tooltips/Tooltip.d.ts +27 -32
- package/dist/app/charts/tooltips/Tooltip.d.ts.map +1 -0
- package/dist/app/charts/tooltips/Tooltip.js +37 -81
- package/dist/app/charts/tooltips/Tooltip.js.map +1 -1
- package/dist/app/charts/tooltips/TooltipContent.d.ts +81 -0
- package/dist/app/charts/tooltips/TooltipContent.d.ts.map +1 -0
- package/dist/app/charts/tooltips/TooltipContent.js +99 -0
- package/dist/app/charts/tooltips/TooltipContent.js.map +1 -0
- package/dist/app/charts/tooltips/tooltipUtils.d.ts +186 -36
- package/dist/app/charts/tooltips/tooltipUtils.d.ts.map +1 -0
- package/dist/app/charts/tooltips/tooltipUtils.js +277 -48
- package/dist/app/charts/tooltips/tooltipUtils.js.map +1 -1
- package/dist/app/charts/tooltips/useOutlierTooltip.d.ts +59 -0
- package/dist/app/charts/tooltips/useOutlierTooltip.d.ts.map +1 -0
- package/dist/app/charts/tooltips/useOutlierTooltip.js +16 -0
- package/dist/app/charts/tooltips/useOutlierTooltip.js.map +1 -0
- package/dist/app/charts/tooltips/useTooltipPlacement.d.ts +51 -0
- package/dist/app/charts/tooltips/useTooltipPlacement.d.ts.map +1 -0
- package/dist/app/charts/tooltips/useTooltipPlacement.js +52 -0
- package/dist/app/charts/tooltips/useTooltipPlacement.js.map +1 -0
- package/dist/app/charts/tooltips/useTooltipStyle.d.ts +11 -0
- package/dist/app/charts/tooltips/useTooltipStyle.d.ts.map +1 -0
- package/dist/app/charts/tooltips/useTooltipStyle.js +14 -0
- package/dist/app/charts/tooltips/useTooltipStyle.js.map +1 -0
- package/dist/app/charts/trackers/Tracker.d.ts +22 -6
- package/dist/app/charts/trackers/Tracker.d.ts.map +1 -0
- package/dist/app/charts/trackers/Tracker.js +36 -22
- package/dist/app/charts/trackers/Tracker.js.map +1 -1
- package/dist/app/charts/trackers/trackerUtils.d.ts +40 -18
- package/dist/app/charts/trackers/trackerUtils.d.ts.map +1 -0
- package/dist/app/charts/trackers/trackerUtils.js +213 -300
- package/dist/app/charts/trackers/trackerUtils.js.map +1 -1
- package/dist/app/charts/utils.d.ts +72 -33
- package/dist/app/charts/utils.d.ts.map +1 -0
- package/dist/app/charts/utils.js +87 -42
- package/dist/app/charts/utils.js.map +1 -1
- package/dist/index.d.ts +2 -45
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -72
- package/dist/index.js.map +1 -1
- package/package.json +87 -46
- package/src/app/charts/Chart.tsx +132 -168
- package/src/app/charts/axes/AxesState.ts +27 -29
- package/src/app/charts/axes/AxisInterval.ts +57 -32
- package/src/app/charts/axes/BaseAxisRange.ts +47 -27
- package/src/app/charts/axes/ContinuousAxis.tsx +235 -39
- package/src/app/charts/axes/ContinuousAxisRange.ts +29 -11
- package/src/app/charts/axes/EmptyAxis.tsx +52 -17
- package/src/app/charts/axes/OrdinalAxis.tsx +54 -28
- package/src/app/charts/axes/OrdinalAxisRange.ts +96 -16
- package/src/app/charts/axes/autoScale.ts +244 -0
- package/src/app/charts/axes/axes.ts +954 -735
- package/src/app/charts/d3types.ts +42 -13
- package/src/app/charts/datasources/StreamingDataSource.ts +214 -0
- package/src/app/charts/datasources/iteratesDataSource.ts +122 -0
- package/src/app/charts/datasources/ordinalDataSource.ts +205 -0
- package/src/app/charts/datasources/outlierDataSource.ts +90 -0
- package/src/app/charts/datasources/timeSeriesDataSource.ts +133 -0
- package/src/app/charts/filters/regexFilter.ts +45 -5
- package/src/app/charts/hooks/AxesProvider.tsx +301 -0
- package/src/app/charts/hooks/CanvasSurfaceProvider.tsx +117 -0
- package/src/app/charts/hooks/ChartProvider.tsx +79 -0
- package/src/app/charts/hooks/InteractionProvider.tsx +88 -0
- package/src/app/charts/hooks/PlotDimensionsProvider.tsx +109 -0
- package/src/app/charts/hooks/defaultAxesValues.ts +40 -0
- package/src/app/charts/hooks/defaultMouseValues.ts +24 -0
- package/src/app/charts/hooks/defaultPlotDimensions.ts +27 -0
- package/src/app/charts/hooks/defaultTooltipValues.tsx +23 -0
- package/src/app/charts/hooks/defaultUseChartValues.tsx +36 -0
- package/src/app/charts/hooks/useAxes.tsx +60 -228
- package/src/app/charts/hooks/useCanvasSurface.tsx +35 -0
- package/src/app/charts/hooks/useChart.tsx +47 -106
- package/src/app/charts/hooks/useDataSource.tsx +106 -0
- package/src/app/charts/hooks/useHoveredSeries.tsx +33 -0
- package/src/app/charts/hooks/useMouse.tsx +58 -82
- package/src/app/charts/hooks/usePlotDimensions.tsx +25 -89
- package/src/app/charts/hooks/useTooltip.tsx +32 -63
- package/src/app/charts/index.ts +213 -0
- package/src/app/charts/legends/Legend.tsx +198 -479
- package/src/app/charts/legends/constants.ts +37 -0
- package/src/app/charts/observables/iterates.ts +32 -12
- package/src/app/charts/observables/ordinals.ts +141 -67
- package/src/app/charts/observables/outliers.ts +20 -0
- package/src/app/charts/plots/BarPlot.tsx +784 -666
- package/src/app/charts/plots/OutlierPlot.tsx +685 -0
- package/src/app/charts/plots/PoincarePlot.tsx +707 -489
- package/src/app/charts/plots/RasterPlot.tsx +253 -445
- package/src/app/charts/plots/ScatterPlot.tsx +480 -463
- package/src/app/charts/plots/autoScaleYAxes.ts +102 -0
- package/src/app/charts/plots/colorizedLine.ts +185 -0
- package/src/app/charts/plots/constants.ts +16 -0
- package/src/app/charts/plots/hitTesting.ts +198 -0
- package/src/app/charts/plots/plot.ts +138 -44
- package/src/app/charts/plots/useCanvasZoomPan.ts +240 -0
- package/src/app/charts/plots/useStreamingTimeAxes.ts +384 -0
- package/src/app/charts/series/baseSeries.ts +81 -14
- package/src/app/charts/series/iterateSeries.ts +8 -8
- package/src/app/charts/series/ordinalSeries.ts +35 -20
- package/src/app/charts/series/outlierSeries.ts +188 -0
- package/src/app/charts/series/timeSeries.ts +14 -12
- package/src/app/charts/series/timeSeriesChartData.ts +31 -17
- package/src/app/charts/styling/barPlotStyle.ts +48 -5
- package/src/app/charts/styling/canvasStyle.ts +86 -0
- package/src/app/charts/styling/margins.ts +28 -4
- package/src/app/charts/styling/svgStyle.ts +10 -91
- package/src/app/charts/subscriptions/viewDrivers.ts +447 -0
- package/src/app/charts/tooltips/BarPlotTooltipContent.tsx +156 -380
- package/src/app/charts/tooltips/DefaultOutlierTooltipContent.tsx +40 -0
- package/src/app/charts/tooltips/OutlierPlotTooltipContent.tsx +67 -0
- package/src/app/charts/tooltips/PoincarePlotTooltipContent.tsx +229 -292
- package/src/app/charts/tooltips/RasterPlotTooltipContent.tsx +164 -217
- package/src/app/charts/tooltips/ScatterPlotTooltipContent.tsx +373 -236
- package/src/app/charts/tooltips/Tooltip.tsx +58 -124
- package/src/app/charts/tooltips/TooltipContent.tsx +177 -0
- package/src/app/charts/tooltips/tooltipUtils.ts +359 -61
- package/src/app/charts/tooltips/useOutlierTooltip.tsx +68 -0
- package/src/app/charts/tooltips/useTooltipPlacement.ts +86 -0
- package/src/app/charts/tooltips/useTooltipStyle.ts +15 -0
- package/src/app/charts/trackers/Tracker.tsx +68 -33
- package/src/app/charts/trackers/trackerUtils.ts +263 -376
- package/src/app/charts/utils.ts +90 -48
- package/src/index.ts +2 -322
- package/dist/app/charts/axes/AxesState.test.d.ts +0 -1
- package/dist/app/charts/axes/AxesState.test.js +0 -30
- package/dist/app/charts/axes/AxesState.test.js.map +0 -1
- package/dist/app/charts/axes/AxisInterval.test.d.ts +0 -1
- package/dist/app/charts/axes/AxisInterval.test.js +0 -120
- package/dist/app/charts/axes/AxisInterval.test.js.map +0 -1
- package/dist/app/charts/axes/ContinuousAxisRange.test.d.ts +0 -1
- package/dist/app/charts/axes/ContinuousAxisRange.test.js +0 -47
- package/dist/app/charts/axes/ContinuousAxisRange.test.js.map +0 -1
- package/dist/app/charts/axes/OrdinalAxisRange.test.d.ts +0 -1
- package/dist/app/charts/axes/OrdinalAxisRange.test.js +0 -48
- package/dist/app/charts/axes/OrdinalAxisRange.test.js.map +0 -1
- package/dist/app/charts/filters/regexFilter.test.d.ts +0 -1
- package/dist/app/charts/filters/regexFilter.test.js +0 -11
- package/dist/app/charts/filters/regexFilter.test.js.map +0 -1
- package/dist/app/charts/hooks/useDataObservable.d.ts +0 -72
- package/dist/app/charts/hooks/useDataObservable.js +0 -74
- package/dist/app/charts/hooks/useDataObservable.js.map +0 -1
- package/dist/app/charts/hooks/useInitialData.d.ts +0 -36
- package/dist/app/charts/hooks/useInitialData.js +0 -28
- package/dist/app/charts/hooks/useInitialData.js.map +0 -1
- package/dist/app/charts/observables/iterates.test.d.ts +0 -1
- package/dist/app/charts/observables/iterates.test.js +0 -180
- package/dist/app/charts/observables/iterates.test.js.map +0 -1
- package/dist/app/charts/observables/ordinals.test.d.ts +0 -1
- package/dist/app/charts/observables/ordinals.test.js +0 -102
- package/dist/app/charts/observables/ordinals.test.js.map +0 -1
- package/dist/app/charts/series/datumSeries.test.d.ts +0 -1
- package/dist/app/charts/series/datumSeries.test.js +0 -50
- package/dist/app/charts/series/datumSeries.test.js.map +0 -1
- package/dist/app/charts/styling/margins.test.d.ts +0 -1
- package/dist/app/charts/styling/margins.test.js +0 -19
- package/dist/app/charts/styling/margins.test.js.map +0 -1
- package/dist/app/charts/subscriptions/subscription.test.d.ts +0 -1
- package/dist/app/charts/subscriptions/subscription.test.js +0 -395
- package/dist/app/charts/subscriptions/subscription.test.js.map +0 -1
- package/dist/app/charts/subscriptions/subscriptions.d.ts +0 -100
- package/dist/app/charts/subscriptions/subscriptions.js +0 -449
- package/dist/app/charts/subscriptions/subscriptions.js.map +0 -1
- package/src/app/charts/axes/AxesState.test.ts +0 -34
- package/src/app/charts/axes/AxisInterval.test.ts +0 -143
- package/src/app/charts/axes/ContinuousAxisRange.test.ts +0 -55
- package/src/app/charts/axes/OrdinalAxisRange.test.ts +0 -55
- package/src/app/charts/filters/regexFilter.test.ts +0 -13
- package/src/app/charts/hooks/useDataObservable.tsx +0 -170
- package/src/app/charts/hooks/useInitialData.tsx +0 -64
- package/src/app/charts/observables/iterates.test.ts +0 -201
- package/src/app/charts/observables/ordinals.test.ts +0 -135
- package/src/app/charts/series/datumSeries.test.ts +0 -60
- package/src/app/charts/styling/margins.test.ts +0 -22
- package/src/app/charts/subscriptions/subscription.test.ts +0 -499
- package/src/app/charts/subscriptions/subscriptions.ts +0 -635
|
@@ -8,18 +8,24 @@ export interface Margin {
|
|
|
8
8
|
left: number
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
+
/**
|
|
12
|
+
* @return Margins of 0 on every side
|
|
13
|
+
*/
|
|
11
14
|
export function noMargins(): Margin {
|
|
12
15
|
return {top: 0, bottom: 0, left: 0, right: 0}
|
|
13
16
|
}
|
|
14
17
|
|
|
18
|
+
/**
|
|
19
|
+
* A width and height (in pixels)
|
|
20
|
+
*/
|
|
15
21
|
export interface Dimensions {
|
|
16
22
|
readonly width: number
|
|
17
23
|
readonly height: number
|
|
18
24
|
}
|
|
19
25
|
|
|
20
26
|
/**
|
|
21
|
-
*
|
|
22
|
-
*
|
|
27
|
+
* Calculates the dimensions of the actual plot from the container's width and height, and the
|
|
28
|
+
* plot's margins, by subtracting the margins (never less than 0).
|
|
23
29
|
* @param containerWidth The overall width of the container (plot and margins)
|
|
24
30
|
* @param containerHeight The overall height of the container (plot and margins)
|
|
25
31
|
* @param plotMargins The margins around the plot (top, bottom, left, right)
|
|
@@ -28,9 +34,15 @@ export interface Dimensions {
|
|
|
28
34
|
* @see containerDimensionsFrom
|
|
29
35
|
*/
|
|
30
36
|
export function plotDimensionsFrom(containerWidth: number, containerHeight: number, plotMargins: Margin): Dimensions {
|
|
37
|
+
// floor at zero -- margins larger than the container would otherwise produce negative
|
|
38
|
+
// width/height, which propagates into D3 scale ranges, tracker/tooltip clamping math, and
|
|
39
|
+
// canvas draw coordinates as silent garbage. Mirrors the same Math.max(0, ...) convention
|
|
40
|
+
// already used defensively at some (but not all) points of use, e.g. plot.ts's
|
|
41
|
+
// resizeCanvasTo/clipToArea -- clamping here makes Dimensions a non-negative invariant for
|
|
42
|
+
// every downstream consumer instead of relying on each one to remember to clamp itself.
|
|
31
43
|
return {
|
|
32
|
-
width: containerWidth - plotMargins.left - plotMargins.right,
|
|
33
|
-
height: containerHeight - plotMargins.top - plotMargins.bottom
|
|
44
|
+
width: Math.max(0, containerWidth - plotMargins.left - plotMargins.right),
|
|
45
|
+
height: Math.max(0, containerHeight - plotMargins.top - plotMargins.bottom)
|
|
34
46
|
}
|
|
35
47
|
}
|
|
36
48
|
|
|
@@ -49,10 +61,22 @@ export function containerDimensionsFrom(plotDimensions: Dimensions, plotMargin:
|
|
|
49
61
|
}
|
|
50
62
|
}
|
|
51
63
|
|
|
64
|
+
/**
|
|
65
|
+
* Whether two dimensions have the same width and height
|
|
66
|
+
* @param dimension1 The first dimensions
|
|
67
|
+
* @param dimension2 The second dimensions
|
|
68
|
+
* @return `true` when the widths and heights are equal; `false` otherwise
|
|
69
|
+
*/
|
|
52
70
|
export function dimensionsEqual(dimension1: Dimensions, dimension2: Dimensions) {
|
|
53
71
|
return dimension1.height === dimension2.height && dimension1.width === dimension2.width
|
|
54
72
|
}
|
|
55
73
|
|
|
74
|
+
/**
|
|
75
|
+
* Whether two dimensions differ in width or height (the negation of {@link dimensionsEqual})
|
|
76
|
+
* @param dimension1 The first dimensions
|
|
77
|
+
* @param dimension2 The second dimensions
|
|
78
|
+
* @return `true` when the widths or heights differ; `false` otherwise
|
|
79
|
+
*/
|
|
56
80
|
export function dimensionsNotEqual(dimension1: Dimensions, dimension2: Dimensions) {
|
|
57
81
|
return !dimensionsEqual(dimension1, dimension2)
|
|
58
82
|
}
|
|
@@ -1,118 +1,37 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
/**
|
|
2
|
+
* CSS style properties for the chart's container element (the canvas -- named for the SVG
|
|
3
|
+
* element it used to be)
|
|
4
|
+
*/
|
|
4
5
|
export interface SvgStyle {
|
|
5
6
|
height?: string | number;
|
|
6
7
|
width?: string | number;
|
|
7
8
|
outline?: string;
|
|
8
9
|
|
|
9
|
-
[propName: string]:
|
|
10
|
+
[propName: string]: string | number | undefined;
|
|
10
11
|
}
|
|
11
12
|
|
|
13
|
+
/**
|
|
14
|
+
* The default container style: full width, anchored at the top left
|
|
15
|
+
*/
|
|
12
16
|
export const initialSvgStyle: SvgStyle = {
|
|
13
17
|
width: '100%',
|
|
14
|
-
// display: "inline-block",
|
|
15
|
-
// position: "floating",
|
|
16
18
|
top: 0,
|
|
17
19
|
left: 0
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Grabs the client-width of the svg element, or 1 if the svg element hasn't yet
|
|
22
|
-
* been initialized. The client-width is a read-only property returns the width of
|
|
23
|
-
* the html element, including horizontal padding and borders, as an integer. The reason
|
|
24
|
-
* that we return 1 when the svg element hasn't yet been initialized, is so that the
|
|
25
|
-
* aspect (width / height) is 1.
|
|
26
|
-
* @param {SVGElement | null} svg The svg element
|
|
27
|
-
* @return {number} The client width of the svg
|
|
28
|
-
*/
|
|
29
|
-
export function grabWidth(svg: SVGElement | null): number {
|
|
30
|
-
return svg !== null ? svg.clientWidth : 1;
|
|
31
20
|
}
|
|
32
21
|
|
|
33
22
|
/**
|
|
34
|
-
*
|
|
35
|
-
* been initialized. The client-height is a read-only property returns the height of
|
|
36
|
-
* the html element, including vertical padding and borders, as an integer. The reason
|
|
37
|
-
* that we return 1 when the svg element hasn't yet been initialized, is so that the
|
|
38
|
-
* aspect (width / height) is 1.
|
|
39
|
-
* @param {SVGElement | null} svg The svg element
|
|
40
|
-
* @return {number} The client height of the svg
|
|
23
|
+
* The style of a stroke (used by the bar plot's styles)
|
|
41
24
|
*/
|
|
42
|
-
export function grabHeight(svg: SVGElement | null): number {
|
|
43
|
-
return svg !== null ? svg.clientHeight : 1;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
export const STROKE_COLOR: string = "stroke"
|
|
48
|
-
export const STROKE_WIDTH: string = "stroke-width"
|
|
49
|
-
export const STROKE_OPACITY: string = "stroke-opacity"
|
|
50
|
-
|
|
51
25
|
export interface SvgStrokeStyle {
|
|
52
26
|
readonly color: string
|
|
53
27
|
readonly width: number
|
|
54
28
|
readonly opacity: number
|
|
55
29
|
}
|
|
56
30
|
|
|
57
|
-
export function updateSvgStrokeColor(current: SvgStrokeStyle, color: string) {
|
|
58
|
-
return {...current, color};
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
export function updateSvgStrokeWidth(current: SvgStrokeStyle, width: number) {
|
|
62
|
-
return {...current, width};
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
export function updateSvgStrokeOpacity(current: SvgStrokeStyle, opacity: number) {
|
|
66
|
-
return {...current, opacity};
|
|
67
|
-
}
|
|
68
|
-
|
|
69
31
|
/**
|
|
70
|
-
*
|
|
71
|
-
* @param style
|
|
72
|
-
* @param selection
|
|
73
|
-
* @template E The SVG element (e.g. SVGRectElement, SVGLineElement, etc)
|
|
74
|
-
* @template D The datum type
|
|
75
|
-
* @template The SVG G element
|
|
32
|
+
* The style of a fill (used by the bar plot's styles)
|
|
76
33
|
*/
|
|
77
|
-
export function applyStrokeStylesTo<E extends BaseType, D, G extends BaseType = SVGGElement>(
|
|
78
|
-
selection: d3.Selection<E, D, G, any>,
|
|
79
|
-
style: Partial<SvgStrokeStyle>
|
|
80
|
-
): d3.Selection<E, D, G, any> {
|
|
81
|
-
if (style.color !== undefined) selection.style(STROKE_COLOR, style.color)
|
|
82
|
-
if (style.width !== undefined) selection.style(STROKE_WIDTH, style.width)
|
|
83
|
-
if (style.opacity !== undefined) selection.style(STROKE_OPACITY, style.opacity)
|
|
84
|
-
return selection
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
const FILL_COLOR: string = "fill"
|
|
88
|
-
const FILL_OPACITY: string = "fill-opacity"
|
|
89
|
-
|
|
90
34
|
export interface SvgFillStyle {
|
|
91
35
|
readonly color: string
|
|
92
36
|
readonly opacity: number
|
|
93
37
|
}
|
|
94
|
-
|
|
95
|
-
export function updateSvgFillColor(current: SvgFillStyle, color: string): SvgFillStyle {
|
|
96
|
-
return {...current, color}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
export function updateSvgFillOpacity(current: SvgFillStyle, opacity: number): SvgFillStyle {
|
|
100
|
-
return {...current, opacity}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
*
|
|
105
|
-
* @param style
|
|
106
|
-
* @param selection
|
|
107
|
-
* @template E The SVG element (e.g. SVGRectElement, SVGLineElement, etc)
|
|
108
|
-
* @template D The datum type
|
|
109
|
-
* @template The SVG G element
|
|
110
|
-
*/
|
|
111
|
-
export function applyFillStylesTo<E extends BaseType, D, G extends BaseType = SVGGElement>(
|
|
112
|
-
selection: d3.Selection<E, D, G, any>,
|
|
113
|
-
style: Partial<SvgFillStyle>
|
|
114
|
-
): d3.Selection<E, D, G, any> {
|
|
115
|
-
if (style.color !== undefined) selection.style(FILL_COLOR, style.color)
|
|
116
|
-
if (style.opacity !== undefined) selection.style(FILL_OPACITY, style.opacity)
|
|
117
|
-
return selection
|
|
118
|
-
}
|
|
@@ -0,0 +1,447 @@
|
|
|
1
|
+
import {interval, type Observable, type OperatorFunction, Subscription} from "rxjs";
|
|
2
|
+
import {bufferCount, bufferTime, map, mergeAll, mergeWith} from "rxjs/operators";
|
|
3
|
+
import {continuousAxisRanges, type ContinuousNumericAxis} from "../axes/axes";
|
|
4
|
+
import {AxesState} from "../axes/AxesState";
|
|
5
|
+
import {ContinuousAxisRange} from "../axes/ContinuousAxisRange";
|
|
6
|
+
import type {AxesAssignment} from "../plots/plot";
|
|
7
|
+
import type {ChartData} from "../observables/ChartData";
|
|
8
|
+
import type {TimeSeriesChartData} from "../series/timeSeriesChartData";
|
|
9
|
+
import type {OutlierChartData} from "../observables/outliers";
|
|
10
|
+
import type {OrdinalChartData} from "../observables/ordinals";
|
|
11
|
+
import type {IterateChartData} from "../observables/iterates";
|
|
12
|
+
import type {StreamingDataSource} from "../datasources/StreamingDataSource";
|
|
13
|
+
import {currentTimesByGroup, type TimeGroupFor} from "../datasources/timeSeriesDataSource";
|
|
14
|
+
import {iteratesCurrentTime} from "../datasources/iteratesDataSource";
|
|
15
|
+
|
|
16
|
+
/*
|
|
17
|
+
* View drivers: the *view* half of a streaming plot.
|
|
18
|
+
*
|
|
19
|
+
* A {@link StreamingDataSource} (owned by the application) ingests the stream and keeps the series.
|
|
20
|
+
* A view driver (owned by one mounted plot) listens to the source's `chartDataUpdatesObservable` and keeps that plot's
|
|
21
|
+
* view in step with the data -- advancing the visible time-window (auto-scroll, cadence) and asking
|
|
22
|
+
* the plot to redraw. A plot creates its driver when it mounts and *always* unsubscribes it when it
|
|
23
|
+
* unmounts. Nothing here ever outlives the plot that created it, and nothing here ever mutates the
|
|
24
|
+
* series, so there is never a reason to keep a driver alive across a remount, adopt one, or defer
|
|
25
|
+
* its teardown.
|
|
26
|
+
*
|
|
27
|
+
* (Before v2, a plot's single subscription did both the ingestion and the view work, which tied
|
|
28
|
+
* the data's lifetime to the plot's -- see the data sources for the ingestion half.)
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* The behavior of the time window when data is added to the chart: `SCROLL` slides the window
|
|
33
|
+
* forward (keeping its width) as new data passes its end; `SQUEEZE` keeps the window's start
|
|
34
|
+
* pinned and widens it instead.
|
|
35
|
+
* Note: a const object rather than an enum, to support `erasableSyntaxOnly`
|
|
36
|
+
*/
|
|
37
|
+
export const TimeWindowBehavior = {
|
|
38
|
+
SCROLL: "SCROLL",
|
|
39
|
+
SQUEEZE: "SQUEEZE"
|
|
40
|
+
} as const
|
|
41
|
+
|
|
42
|
+
export type TimeWindowBehavior = (typeof TimeWindowBehavior)[keyof typeof TimeWindowBehavior];
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* The part of a data source a view driver needs
|
|
46
|
+
*/
|
|
47
|
+
export type ViewDriverSource<CD extends ChartData> = Pick<StreamingDataSource<CD, unknown>, 'chartDataUpdatesObservable' | 'latestTime'>
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Batches the source's updates for rendering. When the source's own emission period is known,
|
|
51
|
+
* batches by a fixed count (`windowingTime / dataUpdatePeriod`) rather than by wall-clock time:
|
|
52
|
+
* `bufferTime` and the source's own timer are two independent clocks, so ordinary timer jitter can
|
|
53
|
+
* shift a tick across a buffer boundary, making the number of ticks per flush vary and the
|
|
54
|
+
* auto-scroll uneven. Counting emissions directly is immune to that jitter.
|
|
55
|
+
* @param windowingTime The time (ms) over which to batch updates
|
|
56
|
+
* @param dataUpdatePeriod The period (ms) at which the source emits, when known
|
|
57
|
+
* @return The batching operator
|
|
58
|
+
*/
|
|
59
|
+
function renderBatching<CD>(windowingTime: number, dataUpdatePeriod?: number): OperatorFunction<CD, Array<CD>> {
|
|
60
|
+
return dataUpdatePeriod !== undefined && dataUpdatePeriod > 0 ?
|
|
61
|
+
bufferCount<CD>(Math.max(1, Math.round(windowingTime / dataUpdatePeriod))) :
|
|
62
|
+
bufferTime<CD>(windowingTime)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Advances the visible window for the specified axis (in place, within `timesWindows`) so its
|
|
67
|
+
* right edge sits at `targetTime`, preserving the window's current width (but never starting
|
|
68
|
+
* before 0, in which case the window stays at [0, width] until the time passes its width) -- but only once
|
|
69
|
+
* `targetTime` actually exceeds the window's current right edge. This gate is what lets a user
|
|
70
|
+
* pan/zoom the window ahead of the current time and watch the data catch up to it before scrolling
|
|
71
|
+
* resumes. Leaves `.original` untouched (zoom math is incremental, so it doesn't depend on it).
|
|
72
|
+
* @param timesWindows A `map(axis_id -> range)` updated in place
|
|
73
|
+
* @param axisId The axis to advance
|
|
74
|
+
* @param targetTime The time the axis's right edge should advance to
|
|
75
|
+
*/
|
|
76
|
+
function advanceAxisRangeInMapTo(timesWindows: Map<string, ContinuousAxisRange>, axisId: string, targetTime: number): void {
|
|
77
|
+
const range = timesWindows.get(axisId)
|
|
78
|
+
if (range === undefined) return
|
|
79
|
+
const [startTime, endTime] = range.current.asTuple()
|
|
80
|
+
if (endTime < targetTime) {
|
|
81
|
+
const timeWindow = endTime - startTime
|
|
82
|
+
timesWindows.set(axisId, range.update(Math.max(0, targetTime - timeWindow), Math.max(targetTime, timeWindow)))
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Advances a range to a target time when new data arrives: SCROLL slides the window (width
|
|
88
|
+
* preserved); SQUEEZE pins the window's start at `initialStart` so the window widens instead.
|
|
89
|
+
* @param range The range to advance
|
|
90
|
+
* @param targetTime The time the range's right edge should advance to
|
|
91
|
+
* @param timeWindowBehavior Whether to scroll or squeeze
|
|
92
|
+
* @param initialStart The pinned start time for SQUEEZE mode (ignored for SCROLL)
|
|
93
|
+
* @return The advanced range, with `.original` unchanged
|
|
94
|
+
*/
|
|
95
|
+
function scrollOrSqueezeRangeTo(
|
|
96
|
+
range: ContinuousAxisRange,
|
|
97
|
+
targetTime: number,
|
|
98
|
+
timeWindowBehavior: TimeWindowBehavior,
|
|
99
|
+
initialStart?: number,
|
|
100
|
+
): ContinuousAxisRange {
|
|
101
|
+
const [startTime, endTime] = range.current.asTuple()
|
|
102
|
+
const timeWindow = endTime - startTime
|
|
103
|
+
const newStart = timeWindowBehavior === TimeWindowBehavior.SQUEEZE && initialStart !== undefined ?
|
|
104
|
+
initialStart :
|
|
105
|
+
Math.max(0, targetTime - timeWindow)
|
|
106
|
+
return range.update(newStart, Math.max(targetTime, timeWindow))
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* @param axisAssignments The assignment of the series to their x- and y-axes
|
|
111
|
+
* @param xAxesState The current state of the x-axes (for the default x-axis)
|
|
112
|
+
* @return A {@link TimeGroupFor} that groups series by their assigned x-axis (or the default x-axis)
|
|
113
|
+
*/
|
|
114
|
+
function xAxisGroupFor(axisAssignments: Map<string, AxesAssignment>, xAxesState: AxesState<ContinuousNumericAxis>): TimeGroupFor {
|
|
115
|
+
return name => axisAssignments.get(name)?.xAxis || xAxesState.axisDefaultId().getOrElse("")
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Re-syncs every x-axis to the data's ground-truth time whenever the page becomes visible again.
|
|
120
|
+
* Browsers pause `requestAnimationFrame` and throttle timers for hidden pages (including a macOS
|
|
121
|
+
* Spaces switch), and the cadence and data timers don't resume in lockstep, so without this an
|
|
122
|
+
* axis can lag behind until whichever clock fell behind organically catches up.
|
|
123
|
+
* @param dataSource The data source (for the data's ground-truth time)
|
|
124
|
+
* @param xAxesState The current state of the x-axes
|
|
125
|
+
* @param timesWindows A `map(axis_id -> range)` of the x-axes' windows, updated in place
|
|
126
|
+
* @param setCurrentTime Records the current time for an axis
|
|
127
|
+
* @param updateTimingAndPlot Redraws the plot for the (advanced) time-windows
|
|
128
|
+
* @return The teardown for the listener, to add to the driver's subscription
|
|
129
|
+
*/
|
|
130
|
+
function resyncOnVisible(
|
|
131
|
+
dataSource: ViewDriverSource<ChartData>,
|
|
132
|
+
xAxesState: AxesState<ContinuousNumericAxis>,
|
|
133
|
+
timesWindows: Map<string, ContinuousAxisRange>,
|
|
134
|
+
setCurrentTime: (axisId: string, end: number) => void,
|
|
135
|
+
updateTimingAndPlot: (ranges: Map<string, ContinuousAxisRange>) => void,
|
|
136
|
+
): () => void {
|
|
137
|
+
if (typeof document === 'undefined') return () => {
|
|
138
|
+
}
|
|
139
|
+
const resyncAxesOnVisible = (): void => {
|
|
140
|
+
if (document.visibilityState !== 'visible') return
|
|
141
|
+
const groundTruthTime = dataSource.latestTime()
|
|
142
|
+
if (!isFinite(groundTruthTime)) return
|
|
143
|
+
xAxesState.axisIds().forEach(axisId => {
|
|
144
|
+
advanceAxisRangeInMapTo(timesWindows, axisId, groundTruthTime)
|
|
145
|
+
setCurrentTime(axisId, groundTruthTime)
|
|
146
|
+
})
|
|
147
|
+
updateTimingAndPlot(timesWindows)
|
|
148
|
+
}
|
|
149
|
+
document.addEventListener('visibilitychange', resyncAxesOnVisible)
|
|
150
|
+
return () => document.removeEventListener('visibilitychange', resyncAxesOnVisible)
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Marks a cadence tick in a view driver's stream of updates (rather than disguising the tick as an
|
|
155
|
+
* empty chunk of chart data)
|
|
156
|
+
*/
|
|
157
|
+
const CADENCE_TICK = Symbol('cadence-tick')
|
|
158
|
+
type CadenceTick = typeof CADENCE_TICK
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* The cadence ticks merged, unbuffered, with the batched data updates. Cadence ticks must not go
|
|
162
|
+
* through the render batching, or each batch would deliver its cadence ticks in one burst,
|
|
163
|
+
* collapsing the smooth per-tick scroll down to the batch rate. (The ticks carry no time: the
|
|
164
|
+
* driver projects the stream time from its own wall-clock anchor, so throttled ticks don't make it
|
|
165
|
+
* fall permanently behind.)
|
|
166
|
+
* @param updates$ The data source's updates
|
|
167
|
+
* @param windowingTime The time (ms) over which the data updates are batched
|
|
168
|
+
* @param cadencePeriod The time (ms) between cadence ticks
|
|
169
|
+
* @return The data updates (each batch flattened back into single updates), merged with the
|
|
170
|
+
* cadence ticks
|
|
171
|
+
*/
|
|
172
|
+
function withCadence<CD>(updates$: Observable<CD>, windowingTime: number, cadencePeriod: number): Observable<CD | CadenceTick> {
|
|
173
|
+
const cadence = interval(cadencePeriod).pipe(map((): CadenceTick => CADENCE_TICK))
|
|
174
|
+
return updates$.pipe(
|
|
175
|
+
bufferTime<CD>(windowingTime),
|
|
176
|
+
mergeAll(),
|
|
177
|
+
mergeWith(cadence) as OperatorFunction<CD, CD | CadenceTick>
|
|
178
|
+
)
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Tracks the best-known stream time and when it was measured, so a cadence tick can project the
|
|
183
|
+
* current stream time as `knownTime + (now - measuredAt)`. Seeded from the data source -- which
|
|
184
|
+
* kept ingesting while the plot was unmounted, so this is the true current time even right after
|
|
185
|
+
* a remount -- and corrected forward whenever real data overtakes the projection (but never
|
|
186
|
+
* backward, which would make cadence stutter by the data's processing latency on every tick).
|
|
187
|
+
* @param seedTime The best-known stream time to start from (`-Infinity` when there's no data yet)
|
|
188
|
+
* @return The anchor: `now()` projects the current stream time, `isKnown()` says whether there's a
|
|
189
|
+
* stream time to project from, and `correctTo(time)` moves the anchor forward to a later real time
|
|
190
|
+
*/
|
|
191
|
+
function cadenceAnchor(seedTime: number) {
|
|
192
|
+
let knownTime = seedTime
|
|
193
|
+
let measuredAt = performance.now()
|
|
194
|
+
const now = (): number => knownTime + (performance.now() - measuredAt)
|
|
195
|
+
return {
|
|
196
|
+
now,
|
|
197
|
+
isKnown: (): boolean => isFinite(knownTime),
|
|
198
|
+
correctTo: (realTime: number): void => {
|
|
199
|
+
if (realTime > now()) {
|
|
200
|
+
knownTime = realTime
|
|
201
|
+
measuredAt = performance.now()
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Gives the current time ("now") of each x-axis that a chunk of chart data has new points for
|
|
209
|
+
* @template CD The type of the chart data
|
|
210
|
+
*/
|
|
211
|
+
export type AxisTimesFor<CD> = (data: CD) => Map<string, number>
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* The x-axes' times for time-series chart data: each axis's time is the latest time of the
|
|
215
|
+
* series assigned to it (see {@link currentTimesByGroup}), falling back to the chunk's latest time
|
|
216
|
+
* @param axisAssignments The assignment of the series to their x- and y-axes
|
|
217
|
+
* @param xAxesState The current state of the x-axes (for the default x-axis)
|
|
218
|
+
* @return The x-axes' times for a chunk of chart data
|
|
219
|
+
*/
|
|
220
|
+
export function timeSeriesAxisTimes(
|
|
221
|
+
axisAssignments: Map<string, AxesAssignment>,
|
|
222
|
+
xAxesState: AxesState<ContinuousNumericAxis>,
|
|
223
|
+
): AxisTimesFor<TimeSeriesChartData> {
|
|
224
|
+
const groupFor = xAxisGroupFor(axisAssignments, xAxesState)
|
|
225
|
+
return data => {
|
|
226
|
+
const groupTimes = currentTimesByGroup(data, groupFor)
|
|
227
|
+
const times = new Map<string, number>()
|
|
228
|
+
data.newPoints.forEach((_, name) => {
|
|
229
|
+
const axisId = groupFor(name)
|
|
230
|
+
times.set(axisId, groupTimes.get(axisId) || data.maxTime)
|
|
231
|
+
})
|
|
232
|
+
return times
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* The x-axes' times for outlier chart data: each axis's time is the time of the newest datum, of
|
|
238
|
+
* the series assigned to it, in the chunk
|
|
239
|
+
* @param axisAssignments The assignment of the series to their x- and y-axes
|
|
240
|
+
* @param xAxesState The current state of the x-axes (for the default x-axis)
|
|
241
|
+
* @return The x-axes' times for a chunk of chart data
|
|
242
|
+
* @template M The type of the outlier series' measures
|
|
243
|
+
*/
|
|
244
|
+
export function outlierAxisTimes<M extends readonly number[]>(
|
|
245
|
+
axisAssignments: Map<string, AxesAssignment>,
|
|
246
|
+
xAxesState: AxesState<ContinuousNumericAxis>,
|
|
247
|
+
): AxisTimesFor<OutlierChartData<M>> {
|
|
248
|
+
const groupFor = xAxisGroupFor(axisAssignments, xAxesState)
|
|
249
|
+
return data => {
|
|
250
|
+
const times = new Map<string, number>()
|
|
251
|
+
data.newPoints.forEach((newData, name) => {
|
|
252
|
+
const axisId = groupFor(name)
|
|
253
|
+
let time = times.get(axisId) ?? -Infinity
|
|
254
|
+
for (const datum of newData) time = Math.max(time, datum.datum.x)
|
|
255
|
+
if (Number.isFinite(time)) times.set(axisId, time)
|
|
256
|
+
})
|
|
257
|
+
return times
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* The options of a time-axis view driver (see {@link timeAxisViewDriverFor})
|
|
263
|
+
*/
|
|
264
|
+
export interface TimeAxisViewDriverOptions {
|
|
265
|
+
/**
|
|
266
|
+
* The time (ms) over which updates are batched before redrawing
|
|
267
|
+
*/
|
|
268
|
+
windowingTime: number
|
|
269
|
+
/**
|
|
270
|
+
* The period (ms) at which the source emits, when known (see {@link renderBatching}); not
|
|
271
|
+
* used with cadence
|
|
272
|
+
*/
|
|
273
|
+
dataUpdatePeriod?: number
|
|
274
|
+
/**
|
|
275
|
+
* The time (ms) between cadence ticks, which advance the axes smoothly between data arrivals.
|
|
276
|
+
* Without one, the axes only advance as data arrives.
|
|
277
|
+
*/
|
|
278
|
+
cadencePeriod?: number
|
|
279
|
+
/**
|
|
280
|
+
* Whether the time axes scroll or squeeze as data passes their ends (without cadence).
|
|
281
|
+
* Defaults to SCROLL.
|
|
282
|
+
*/
|
|
283
|
+
timeWindowBehavior?: TimeWindowBehavior
|
|
284
|
+
/**
|
|
285
|
+
* The pinned start time for each axis, for SQUEEZE
|
|
286
|
+
*/
|
|
287
|
+
initialTimes?: Map<string, number>
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/**
|
|
291
|
+
* The view driver for a plot whose x-axes are time (the scatter, raster, and outlier plots): it
|
|
292
|
+
* advances each x-axis's window as the data's time passes its end, records each axis's current
|
|
293
|
+
* time, and asks the plot to redraw.
|
|
294
|
+
*
|
|
295
|
+
* Without cadence, each axis's window advances (SCROLL or SQUEEZE) as new data passes its end.
|
|
296
|
+
* With cadence, cadence ticks advance every axis's window smoothly between data arrivals, to the
|
|
297
|
+
* stream time projected from a wall-clock anchor; real data (treated as ground truth) re-syncs the
|
|
298
|
+
* axes, and corrects the anchor when cadence has fallen behind. The driver also catches the axes up
|
|
299
|
+
* to the data source's latest time when it starts (e.g. after a remount), and whenever the page
|
|
300
|
+
* becomes visible again.
|
|
301
|
+
* @param dataSource The data source whose updates drive the view
|
|
302
|
+
* @param xAxesState The current state of the x-axes
|
|
303
|
+
* @param axisTimesFor Gives the current time of each x-axis that a chunk of data has new points for
|
|
304
|
+
* (e.g. {@link timeSeriesAxisTimes} or {@link outlierAxisTimes})
|
|
305
|
+
* @param updateTimingAndPlot Redraws the plot for the (advanced) time-windows
|
|
306
|
+
* @param setCurrentTime Records the current time for an axis
|
|
307
|
+
* @param options The batching, cadence, and time-window behavior
|
|
308
|
+
* @return The driver's subscription, to unsubscribe when the plot unmounts
|
|
309
|
+
* @template CD The type of the chart data
|
|
310
|
+
*/
|
|
311
|
+
export function timeAxisViewDriverFor<CD extends ChartData>(
|
|
312
|
+
dataSource: ViewDriverSource<CD>,
|
|
313
|
+
xAxesState: AxesState<ContinuousNumericAxis>,
|
|
314
|
+
axisTimesFor: AxisTimesFor<CD>,
|
|
315
|
+
updateTimingAndPlot: (ranges: Map<string, ContinuousAxisRange>) => void,
|
|
316
|
+
setCurrentTime: (axisId: string, end: number) => void,
|
|
317
|
+
options: TimeAxisViewDriverOptions,
|
|
318
|
+
): Subscription {
|
|
319
|
+
const {
|
|
320
|
+
windowingTime,
|
|
321
|
+
dataUpdatePeriod,
|
|
322
|
+
cadencePeriod,
|
|
323
|
+
timeWindowBehavior = TimeWindowBehavior.SCROLL,
|
|
324
|
+
initialTimes = new Map<string, number>(),
|
|
325
|
+
} = options
|
|
326
|
+
|
|
327
|
+
// built ONCE, here, and advanced in place on every update: the plot hands this same map
|
|
328
|
+
// back to its pan/zoom handlers (via `updateTimingAndPlot`), so their mutations land here too
|
|
329
|
+
// rather than being discarded by a rebuild
|
|
330
|
+
const timesWindows = continuousAxisRanges(xAxesState.axes)
|
|
331
|
+
|
|
332
|
+
if (cadencePeriod === undefined) {
|
|
333
|
+
return dataSource.chartDataUpdatesObservable
|
|
334
|
+
.pipe(renderBatching<CD>(windowingTime, dataUpdatePeriod))
|
|
335
|
+
.subscribe(dataList => dataList.forEach(data => {
|
|
336
|
+
axisTimesFor(data).forEach((currentAxisTime, axisId) => {
|
|
337
|
+
// record the axis' "now" on every update -- not only once the window starts
|
|
338
|
+
// scrolling -- since the plot's zoom pivots on it while streaming: before the
|
|
339
|
+
// data reaches the window's end, there would otherwise be no "now" to pivot on,
|
|
340
|
+
// and the zoom would pivot on the window's right edge, possibly leaving the
|
|
341
|
+
// data off-screen
|
|
342
|
+
setCurrentTime(axisId, currentAxisTime)
|
|
343
|
+
const range = timesWindows.get(axisId)
|
|
344
|
+
if (range !== undefined && range.current.end < currentAxisTime) {
|
|
345
|
+
timesWindows.set(axisId, scrollOrSqueezeRangeTo(range, currentAxisTime, timeWindowBehavior, initialTimes.get(axisId)))
|
|
346
|
+
}
|
|
347
|
+
})
|
|
348
|
+
updateTimingAndPlot(timesWindows)
|
|
349
|
+
}))
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
const anchor = cadenceAnchor(dataSource.latestTime())
|
|
353
|
+
const catchUp = (): void => {
|
|
354
|
+
if (!anchor.isKnown()) return
|
|
355
|
+
xAxesState.axisIds().forEach(axisId => advanceAxisRangeInMapTo(timesWindows, axisId, anchor.now()))
|
|
356
|
+
updateTimingAndPlot(timesWindows)
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
// catch the axes up to the current stream time right away, rather than leaving them where they
|
|
360
|
+
// were restored to until the first tick arrives (which, right after a remount, can take a
|
|
361
|
+
// noticeable while and would show up as "pause, then jump")
|
|
362
|
+
catchUp()
|
|
363
|
+
|
|
364
|
+
const subscription = withCadence(dataSource.chartDataUpdatesObservable, windowingTime, cadencePeriod)
|
|
365
|
+
.subscribe(update => {
|
|
366
|
+
if (update === CADENCE_TICK) {
|
|
367
|
+
// a cadence tick: advance every axis to the projected stream time
|
|
368
|
+
const cadenceTime = anchor.now()
|
|
369
|
+
xAxesState.axisIds().forEach(axisId => {
|
|
370
|
+
advanceAxisRangeInMapTo(timesWindows, axisId, cadenceTime)
|
|
371
|
+
setCurrentTime(axisId, cadenceTime)
|
|
372
|
+
})
|
|
373
|
+
} else {
|
|
374
|
+
// real data: re-sync each axis to the data's own time, and correct the cadence
|
|
375
|
+
// anchor if the data has overtaken it
|
|
376
|
+
axisTimesFor(update).forEach((currentAxisTime, axisId) => {
|
|
377
|
+
advanceAxisRangeInMapTo(timesWindows, axisId, currentAxisTime)
|
|
378
|
+
anchor.correctTo(currentAxisTime)
|
|
379
|
+
})
|
|
380
|
+
}
|
|
381
|
+
updateTimingAndPlot(timesWindows)
|
|
382
|
+
})
|
|
383
|
+
|
|
384
|
+
subscription.add(resyncOnVisible(dataSource, xAxesState, timesWindows, setCurrentTime, updateTimingAndPlot))
|
|
385
|
+
|
|
386
|
+
// one more catch-up on the next paint frame, narrowing the gap until the first real tick
|
|
387
|
+
// (whose scheduling can lag right after a route change, while React commits the new tree)
|
|
388
|
+
const catchUpFrame = requestAnimationFrame(catchUp)
|
|
389
|
+
subscription.add(() => cancelAnimationFrame(catchUpFrame))
|
|
390
|
+
|
|
391
|
+
return subscription
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
/**
|
|
395
|
+
* The view driver for an ordinal (bar) plot: reports the chart-wide current time and asks the
|
|
396
|
+
* plot to redraw as new data arrives. (The stats are kept by the data source.) Unlike the
|
|
397
|
+
* time-series drivers, it has no axis ranges to advance: an ordinal plot's axes don't scroll as
|
|
398
|
+
* data arrives, so its axes' ranges change only through the plot's own zoom, pan, and resize.
|
|
399
|
+
* @param dataSource The data source whose updates drive the view
|
|
400
|
+
* @param windowingTime The time (ms) over which updates are batched before redrawing
|
|
401
|
+
* @param updateTimingAndPlot Redraws the plot (and reports the chart time)
|
|
402
|
+
* @param setCurrentTime Records the chart-wide current time
|
|
403
|
+
* @param dataUpdatePeriod The period (ms) at which the source emits, when known (see {@link renderBatching})
|
|
404
|
+
* @return The driver's subscription, to unsubscribe when the plot unmounts
|
|
405
|
+
*/
|
|
406
|
+
export function ordinalViewDriverFor(
|
|
407
|
+
dataSource: ViewDriverSource<OrdinalChartData>,
|
|
408
|
+
windowingTime: number,
|
|
409
|
+
updateTimingAndPlot: () => void,
|
|
410
|
+
setCurrentTime: (currentTime: number) => void,
|
|
411
|
+
dataUpdatePeriod?: number,
|
|
412
|
+
): Subscription {
|
|
413
|
+
return dataSource.chartDataUpdatesObservable
|
|
414
|
+
.pipe(renderBatching<OrdinalChartData>(windowingTime, dataUpdatePeriod))
|
|
415
|
+
.subscribe(dataList => dataList.forEach(data => {
|
|
416
|
+
if (data.newPoints.size > 0) setCurrentTime(data.stats.maxDatum.time.time || NaN)
|
|
417
|
+
updateTimingAndPlot()
|
|
418
|
+
}))
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
/**
|
|
422
|
+
* The view driver for an iterates (Poincaré) plot: reports the current time and asks the plot to
|
|
423
|
+
* redraw as new data arrives (once the plot has both an x-axis and a y-axis).
|
|
424
|
+
* @param dataSource The data source whose updates drive the view
|
|
425
|
+
* @param windowingTime The time (ms) over which updates are batched before redrawing
|
|
426
|
+
* @param xAxesState The current state of the x-axes
|
|
427
|
+
* @param yAxesState The current state of the y-axes
|
|
428
|
+
* @param updateRangesAndPlot Updates the axes' ranges, and redraws the plot
|
|
429
|
+
* @param updateCurrentTime Records the current time (see {@link iteratesCurrentTime})
|
|
430
|
+
* @return The driver's subscription, to unsubscribe when the plot unmounts
|
|
431
|
+
*/
|
|
432
|
+
export function iteratesViewDriverFor(
|
|
433
|
+
dataSource: ViewDriverSource<IterateChartData>,
|
|
434
|
+
windowingTime: number,
|
|
435
|
+
xAxesState: AxesState<ContinuousNumericAxis>,
|
|
436
|
+
yAxesState: AxesState<ContinuousNumericAxis>,
|
|
437
|
+
updateRangesAndPlot: () => void,
|
|
438
|
+
updateCurrentTime: (time: number) => void,
|
|
439
|
+
): Subscription {
|
|
440
|
+
return dataSource.chartDataUpdatesObservable
|
|
441
|
+
.pipe(bufferTime<IterateChartData>(windowingTime))
|
|
442
|
+
.subscribe(dataList => dataList.forEach(data => {
|
|
443
|
+
if (data.newPoints.size > 0) updateCurrentTime(iteratesCurrentTime(data))
|
|
444
|
+
// (the original only redrew once both a default x-axis and a default y-axis existed)
|
|
445
|
+
if (xAxesState.axes.size > 0 && yAxesState.axes.size > 0) updateRangesAndPlot()
|
|
446
|
+
}))
|
|
447
|
+
}
|