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
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import type {OutlierChartData} from "../observables/outliers";
|
|
2
|
+
import type {OutlierDatum, OutlierSeries} from "../series/outlierSeries";
|
|
3
|
+
import {emptySeries} from "../series/baseSeries";
|
|
4
|
+
import {BaseStreamingDataSource, type DataGenerator} from "./StreamingDataSource";
|
|
5
|
+
|
|
6
|
+
export interface OutlierDataSourceOptions<M extends readonly number[]> {
|
|
7
|
+
/**
|
|
8
|
+
* The initial series, owned (and mutated in place) by the source from here on
|
|
9
|
+
*/
|
|
10
|
+
initialData: Array<OutlierSeries<M>>
|
|
11
|
+
/**
|
|
12
|
+
* Creates the observable of chart data each time the source starts
|
|
13
|
+
*/
|
|
14
|
+
generator: DataGenerator<OutlierChartData<M>, OutlierSeries<M>>
|
|
15
|
+
/**
|
|
16
|
+
* Data older than this (ms), relative to the newest datum in the same chunk of new data, is
|
|
17
|
+
* dropped as new data arrives. Defaults to `Infinity` (never drop).
|
|
18
|
+
*/
|
|
19
|
+
dropDataAfter?: number
|
|
20
|
+
/**
|
|
21
|
+
* Called with each series' new data as it arrives
|
|
22
|
+
*/
|
|
23
|
+
onUpdateData?: (seriesName: string, data: Array<OutlierDatum<M>>) => void
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* A data source for outlier charts. Unlike time-series charts, series that aren't in the initial
|
|
28
|
+
* data are added as they first appear in the stream.
|
|
29
|
+
*/
|
|
30
|
+
export class OutlierDataSource<M extends readonly number[]>
|
|
31
|
+
extends BaseStreamingDataSource<OutlierChartData<M>, OutlierDatum<M>, OutlierSeries<M>> {
|
|
32
|
+
|
|
33
|
+
private dropDataAfter: number
|
|
34
|
+
private readonly onUpdateData: ((seriesName: string, data: Array<OutlierDatum<M>>) => void) | undefined
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Creates a outlier data source (stopped: call {@link start} to start it)
|
|
38
|
+
* @param options The initial data, the generator, and the data-retention settings
|
|
39
|
+
*/
|
|
40
|
+
constructor(options: OutlierDataSourceOptions<M>) {
|
|
41
|
+
super(options.initialData, options.generator)
|
|
42
|
+
this.dropDataAfter = options.dropDataAfter ?? Infinity
|
|
43
|
+
this.onUpdateData = options.onUpdateData
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Changes how long data is kept; takes effect as the next data arrives
|
|
48
|
+
* @param dropDataAfter Data older than this (ms) is dropped
|
|
49
|
+
*/
|
|
50
|
+
setDropDataAfter(dropDataAfter: number): void {
|
|
51
|
+
this.dropDataAfter = dropDataAfter
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* @return The latest time (the `datum.x` of the last datum) over all the series, or
|
|
56
|
+
* `-Infinity` when there is no data
|
|
57
|
+
*/
|
|
58
|
+
latestTime(): number {
|
|
59
|
+
return this.seriesList().reduce(
|
|
60
|
+
(tMax, series) => Math.max(tMax, series.last().map(datum => datum.datum.x).getOrElse(tMax)),
|
|
61
|
+
-Infinity
|
|
62
|
+
)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Adds each series' new points to it (adding the series itself the first time it appears),
|
|
67
|
+
* and drops the points that are older than `dropDataAfter` relative to the newest of the
|
|
68
|
+
* series' new points. Calls `onUpdateData` with each series' new points.
|
|
69
|
+
* @param data The chunk of chart data emitted by the generator
|
|
70
|
+
*/
|
|
71
|
+
protected ingest(data: OutlierChartData<M>): void {
|
|
72
|
+
data.newPoints.forEach((newData, name) => {
|
|
73
|
+
// register a series the first time it shows up in the stream
|
|
74
|
+
const series = this.seriesMap.get(name) || emptySeries<OutlierDatum<M>>(name) as OutlierSeries<M>
|
|
75
|
+
if (!this.seriesMap.has(name)) this.seriesMap.set(name, series)
|
|
76
|
+
|
|
77
|
+
if (this.onUpdateData) this.onUpdateData(name, newData)
|
|
78
|
+
|
|
79
|
+
series.data.push(...newData)
|
|
80
|
+
|
|
81
|
+
// drop data older than the max time-window, relative to this chunk's newest datum
|
|
82
|
+
const currentTime = Math.max(...newData.map(datum => datum.datum.x), -Infinity)
|
|
83
|
+
if (Number.isFinite(currentTime)) {
|
|
84
|
+
while (series.data.length > 0 && currentTime - series.data[0].datum.x > this.dropDataAfter) {
|
|
85
|
+
series.data.shift()
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
})
|
|
89
|
+
}
|
|
90
|
+
}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import type {Datum, TimeSeries} from "../series/timeSeries";
|
|
2
|
+
import type {TimeSeriesChartData} from "../series/timeSeriesChartData";
|
|
3
|
+
import {emptySeries} from "../series/baseSeries";
|
|
4
|
+
import {BaseStreamingDataSource, type DataGenerator} from "./StreamingDataSource";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Maps a series name to the "time group" whose clock governs it. Series in the same group share
|
|
8
|
+
* one current time (the max time over all of them), which is what `dropDataAfter` is measured
|
|
9
|
+
* against. Plots group series by their x-axis, so this is typically
|
|
10
|
+
* `name => axisAssignments.get(name)?.xAxis ?? defaultXAxisId`.
|
|
11
|
+
*/
|
|
12
|
+
export type TimeGroupFor = (seriesName: string) => string
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* The default time grouping: one group, holding all the series
|
|
16
|
+
*/
|
|
17
|
+
const SINGLE_TIME_GROUP: TimeGroupFor = () => ""
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Calculates the current time for each time group present in the chart data: the max over the
|
|
21
|
+
* group's series of each series' own max time (falling back to the chart-wide max time). Shared
|
|
22
|
+
* by the data source (for dropping old data) and the plots' view drivers (for advancing each
|
|
23
|
+
* x-axis), so both agree on what "now" is for each axis.
|
|
24
|
+
* @param data The chart data
|
|
25
|
+
* @param timeGroupFor Maps each series to its time group
|
|
26
|
+
* @return A map(group -> current_time)
|
|
27
|
+
*/
|
|
28
|
+
export function currentTimesByGroup(data: TimeSeriesChartData, timeGroupFor: TimeGroupFor): Map<string, number> {
|
|
29
|
+
const times = new Map<string, number>()
|
|
30
|
+
data.seriesNames.forEach(name => {
|
|
31
|
+
const group = timeGroupFor(name)
|
|
32
|
+
const seriesTime = data.maxTimes.get(name) || data.maxTime
|
|
33
|
+
times.set(group, Math.max(times.get(group) ?? -Infinity, seriesTime))
|
|
34
|
+
})
|
|
35
|
+
return times
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface TimeSeriesDataSourceOptions {
|
|
39
|
+
/**
|
|
40
|
+
* The initial series, owned (and mutated in place) by the source from here on
|
|
41
|
+
*/
|
|
42
|
+
initialData: Array<TimeSeries>
|
|
43
|
+
/**
|
|
44
|
+
* Creates the observable of chart data each time the source starts
|
|
45
|
+
*/
|
|
46
|
+
generator: DataGenerator<TimeSeriesChartData, TimeSeries>
|
|
47
|
+
/**
|
|
48
|
+
* Data older than this (ms), relative to its time group's current time, is dropped as new
|
|
49
|
+
* data arrives. Defaults to `Infinity` (never drop).
|
|
50
|
+
*/
|
|
51
|
+
dropDataAfter?: number
|
|
52
|
+
/**
|
|
53
|
+
* Assigns each series to a time group (see {@link TimeGroupFor}). Defaults to one group for
|
|
54
|
+
* all series.
|
|
55
|
+
*/
|
|
56
|
+
timeGroupFor?: TimeGroupFor
|
|
57
|
+
/**
|
|
58
|
+
* Called with each series' new data as it arrives
|
|
59
|
+
*/
|
|
60
|
+
onUpdateData?: (seriesName: string, data: Array<Datum>) => void
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* A data source for time-series charts (e.g. the scatter and raster plots)
|
|
65
|
+
*/
|
|
66
|
+
export class TimeSeriesDataSource extends BaseStreamingDataSource<TimeSeriesChartData, Datum, TimeSeries> {
|
|
67
|
+
private dropDataAfter: number
|
|
68
|
+
private readonly timeGroupFor: TimeGroupFor
|
|
69
|
+
private readonly onUpdateData: ((seriesName: string, data: Array<Datum>) => void) | undefined
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Creates a time-series data source (stopped: call {@link start} to start it)
|
|
73
|
+
* @param options The initial data, the generator, and the data-retention settings
|
|
74
|
+
*/
|
|
75
|
+
constructor(options: TimeSeriesDataSourceOptions) {
|
|
76
|
+
super(options.initialData, options.generator)
|
|
77
|
+
this.dropDataAfter = options.dropDataAfter ?? Infinity
|
|
78
|
+
this.timeGroupFor = options.timeGroupFor ?? SINGLE_TIME_GROUP
|
|
79
|
+
this.onUpdateData = options.onUpdateData
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Changes how long data is kept; takes effect as the next data arrives
|
|
84
|
+
* @param dropDataAfter Data older than this (ms) is dropped
|
|
85
|
+
*/
|
|
86
|
+
setDropDataAfter(dropDataAfter: number): void {
|
|
87
|
+
this.dropDataAfter = dropDataAfter
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* @return The latest time (the `x` of the last datum) over all the series, or
|
|
92
|
+
* `-Infinity` when there is no data
|
|
93
|
+
*/
|
|
94
|
+
latestTime(): number {
|
|
95
|
+
return this.seriesList().reduce(
|
|
96
|
+
(tMax, series) => Math.max(tMax, series.last().map(datum => datum.x).getOrElse(tMax)),
|
|
97
|
+
-Infinity
|
|
98
|
+
)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Adds each series' new points to it, and drops the points that are older than
|
|
103
|
+
* `dropDataAfter` relative to the current time of the series' time group (see
|
|
104
|
+
* `currentTimesByGroup`). New points for a series that isn't in the source are ignored
|
|
105
|
+
* (time-series charts have a fixed set of series). Calls `onUpdateData` with each series' new
|
|
106
|
+
* points.
|
|
107
|
+
* @param data The chunk of chart data emitted by the generator
|
|
108
|
+
*/
|
|
109
|
+
protected ingest(data: TimeSeriesChartData): void {
|
|
110
|
+
const groupTimes = currentTimesByGroup(data, this.timeGroupFor)
|
|
111
|
+
|
|
112
|
+
// add each new point to its corresponding series, the new points is a
|
|
113
|
+
// map(series_name -> new_point[])
|
|
114
|
+
data.newPoints.forEach((newData, name) => {
|
|
115
|
+
// note: as in the original subscription code, data for a series that isn't already in
|
|
116
|
+
// the source is accepted but not kept (time-series charts have a fixed set of series)
|
|
117
|
+
const series = this.seriesMap.get(name) || emptySeries<Datum>(name)
|
|
118
|
+
|
|
119
|
+
if (this.onUpdateData) this.onUpdateData(name, newData)
|
|
120
|
+
|
|
121
|
+
series.data.push(...newData)
|
|
122
|
+
|
|
123
|
+
// drop data that is older than the max time-window -- guarded on series.data.length so
|
|
124
|
+
// a sibling series in the same time group advancing the group's time past every point
|
|
125
|
+
// this series holds (e.g. this series stalls/updates slower) can't shift it down to
|
|
126
|
+
// empty and then throw on series.data[0].x
|
|
127
|
+
const currentTime = groupTimes.get(this.timeGroupFor(name)) || data.maxTime
|
|
128
|
+
while (series.data.length > 0 && currentTime - series.data[0].x > this.dropDataAfter) {
|
|
129
|
+
series.data.shift()
|
|
130
|
+
}
|
|
131
|
+
})
|
|
132
|
+
}
|
|
133
|
+
}
|
|
@@ -1,17 +1,57 @@
|
|
|
1
|
-
import {failureResult, Result, successResult} from "result-fn";
|
|
1
|
+
import {failureResult, type Result, successResult} from "result-fn";
|
|
2
|
+
import safeRegex from "safe-regex";
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
|
-
*
|
|
5
|
+
* Checks whether a regex is reasonably safe from catastrophic (exponential-time) backtracking --
|
|
6
|
+
* e.g. `/(a+)+$/`, the classic case that freezes on a long non-matching input. Every plot
|
|
7
|
+
* component tests a compiled `seriesFilter` regex against every series name on every redraw
|
|
8
|
+
* frame (not just once), so an unvetted pattern from a free-text filter field can hang the whole
|
|
9
|
+
* render loop, not just one call. Delegates to the `safe-regex` package, which walks the regex's
|
|
10
|
+
* actual parsed structure (via `regexp-tree`) rather than pattern-matching its source string, so
|
|
11
|
+
* it catches more than a hand-rolled "look for nested quantifiers" check would.
|
|
12
|
+
* @param pattern The regex (or its string source) to check
|
|
13
|
+
* @return `true` if the pattern is reasonably safe to run against arbitrary input; `false` if it
|
|
14
|
+
* risks catastrophic backtracking
|
|
15
|
+
*/
|
|
16
|
+
export function isSafeRegex(pattern: RegExp | string): boolean {
|
|
17
|
+
return safeRegex(pattern)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Wraps the creation of the regex in a try/catch and returns the regex, wrapped in a `Result`,
|
|
5
22
|
* when it is valid. This can be used, for example, in a text field where the user types a regex.
|
|
23
|
+
* Also rejects a pattern that compiles fine but risks catastrophic backtracking (see
|
|
24
|
+
* {@link isSafeRegex}) -- a syntax error and an exponential-time pattern are both "can't use this"
|
|
25
|
+
* outcomes from the caller's point of view, so both are reported the same way.
|
|
6
26
|
* @param regexString The string representation of the regex
|
|
7
|
-
* @return The regular expression (`RegExp`) wrapped in
|
|
8
|
-
* is
|
|
27
|
+
* @return The regular expression (`RegExp`) wrapped in a successful `Result`. If the regex is
|
|
28
|
+
* invalid, or is unsafe, then a failed `Result` holding a message that says why.
|
|
9
29
|
*/
|
|
10
30
|
export function regexFilter(regexString: string): Result<RegExp, string> {
|
|
11
31
|
try {
|
|
12
32
|
const regex = new RegExp(regexString)
|
|
33
|
+
if (!isSafeRegex(regex)) {
|
|
34
|
+
return failureResult(
|
|
35
|
+
`Refusing to use a regex that risks catastrophic backtracking; regex_expression: ${regexString}`
|
|
36
|
+
)
|
|
37
|
+
}
|
|
13
38
|
return successResult(regex)
|
|
14
39
|
} catch(error) {
|
|
15
|
-
return failureResult(
|
|
40
|
+
return failureResult(
|
|
41
|
+
`Unable to compile the regex expression; regex_expression: ${regexString}; error: ${error}`
|
|
42
|
+
)
|
|
16
43
|
}
|
|
17
44
|
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Builds a regex that matches `text` literally, for callers (e.g. a series-name filter input)
|
|
48
|
+
* who want to search for plain text without regex metacharacters (`.`, `*`, `+`, `(`, etc.) in it
|
|
49
|
+
* being given unintended regex semantics. Escapes those metacharacters before handing the result
|
|
50
|
+
* to {@link regexFilter}, so it shares the same `Result`-wrapped, never-throws contract.
|
|
51
|
+
* @param text The literal text to match
|
|
52
|
+
* @return The regular expression (`RegExp`) matching `text` literally, wrapped in a `Result` (see
|
|
53
|
+
* {@link regexFilter})
|
|
54
|
+
*/
|
|
55
|
+
export function literalFilter(text: string): Result<RegExp, string> {
|
|
56
|
+
return regexFilter(text.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'))
|
|
57
|
+
}
|
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
import {AxisInterval} from "../axes/AxisInterval";
|
|
2
|
+
import {type JSX, useCallback, useMemo, useRef, useState} from "react";
|
|
3
|
+
import {BaseAxisRange} from "../axes/BaseAxisRange";
|
|
4
|
+
import type {BaseAxis} from "../axes/axes";
|
|
5
|
+
import {usePlotDimensions} from "./usePlotDimensions";
|
|
6
|
+
import {AxesState} from "../axes/AxesState";
|
|
7
|
+
import type {AxesAssignment} from "../plots/plot";
|
|
8
|
+
import type {Dimensions} from "../styling/margins";
|
|
9
|
+
import {Optional} from "result-fn";
|
|
10
|
+
import {AxesContext, type UseAxesValues} from "./useAxes";
|
|
11
|
+
|
|
12
|
+
export type Props = {
|
|
13
|
+
/**
|
|
14
|
+
* Callback when axes bounds change.
|
|
15
|
+
* @param ranges The ranges (start, end) for each axis in the plot
|
|
16
|
+
*/
|
|
17
|
+
onUpdateAxesInterval?: (ranges: Map<string, AxisInterval>) => void
|
|
18
|
+
|
|
19
|
+
children: JSX.Element | Array<JSX.Element>
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* The React context provider for the {@link UseAxesValues}
|
|
23
|
+
* @param props The properties
|
|
24
|
+
* @return The children wrapped in this provider
|
|
25
|
+
* @template AR The type of the axis range (e.g. {@link ContinuousAxisRange} or {@link OrdinalAxisRange})
|
|
26
|
+
* @template A The axis type
|
|
27
|
+
*/
|
|
28
|
+
export default function AxesProvider<AR extends BaseAxisRange, A extends BaseAxis>(props: Props): JSX.Element {
|
|
29
|
+
const {onUpdateAxesInterval, children} = props
|
|
30
|
+
|
|
31
|
+
const plotDimensions = usePlotDimensions()
|
|
32
|
+
|
|
33
|
+
const [xAxesState, setXAxesState] = useState<AxesState<A>>(AxesState.empty<A>())
|
|
34
|
+
const [yAxesState, setYAxesState] = useState<AxesState<A>>(AxesState.empty<A>())
|
|
35
|
+
const axisAssignmentsRef = useRef<Map<string, AxesAssignment>>(new Map())
|
|
36
|
+
const axesBoundsUpdateHandlersRef = useRef<Map<string, (updates: Map<string, AR>, plotDim: Dimensions) => void>>(new Map())
|
|
37
|
+
const axesRangeRef = useRef<Map<string, AR>>(new Map())
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Retrieves the x-axis and y-axis assignments for the specified series. If the series does not
|
|
41
|
+
* have an assignment, then we assume it is using the default x- and y-axes.
|
|
42
|
+
* @param seriesName The name of the series for which to retrieve the axes assignments
|
|
43
|
+
* @return An {@link AxesAssignment} for the specified axes.
|
|
44
|
+
*/
|
|
45
|
+
const axisAssignmentsFor = useCallback(
|
|
46
|
+
(seriesName: string): AxesAssignment =>
|
|
47
|
+
axisAssignmentsRef.current.get(seriesName) || {
|
|
48
|
+
xAxis: xAxesState.axisDefaultId().getOrElse(""),
|
|
49
|
+
yAxis: yAxesState.axisDefaultId().getOrElse("")
|
|
50
|
+
},
|
|
51
|
+
[xAxesState, yAxesState]
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Called when the domain/range is updated on one or more of the chart's axes (generally x-axes). Stores
|
|
56
|
+
* the updated ranges, and in turn, dispatches the update to all the registered domain/range update
|
|
57
|
+
* handlers (e.g. the axes, which redraw themselves with their new domain).
|
|
58
|
+
* @param updates A map holding the axis ID to the updated axis time-range (i.e., map(axis_id, axis_time_range))
|
|
59
|
+
*/
|
|
60
|
+
const updateAxisRanges = useCallback(
|
|
61
|
+
(updates: Map<string, AR>): void => {
|
|
62
|
+
// update the current time-ranges reference
|
|
63
|
+
updates.forEach((range, id) => {
|
|
64
|
+
axesRangeRef.current.set(id, range)
|
|
65
|
+
})
|
|
66
|
+
// dispatch the updates to all the registered handlers
|
|
67
|
+
axesBoundsUpdateHandlersRef.current
|
|
68
|
+
.forEach((handler,) => handler(updates, plotDimensions.plotDimensions))
|
|
69
|
+
},
|
|
70
|
+
[plotDimensions.plotDimensions]
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Sets the axis ranges specified in the input map (without dispatching them to the update handlers)
|
|
75
|
+
* @param ranges The ranges to set
|
|
76
|
+
*/
|
|
77
|
+
const setAxesRanges = useCallback(
|
|
78
|
+
(ranges: Map<string, AR>): void => {
|
|
79
|
+
ranges.forEach((range, id) => {
|
|
80
|
+
axesRangeRef.current.set(id, range)
|
|
81
|
+
})
|
|
82
|
+
},
|
|
83
|
+
[]
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Sets the axis range for the specified axis ID (without dispatching it to the update handlers)
|
|
88
|
+
* @param axisId The axis ID
|
|
89
|
+
* @param range The range to set
|
|
90
|
+
*/
|
|
91
|
+
const setAxisRangeFor = useCallback(
|
|
92
|
+
(axisId: string, range: AR): void => {
|
|
93
|
+
axesRangeRef.current.set(axisId, range)
|
|
94
|
+
},
|
|
95
|
+
[]
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Sets the axis bounds (the current range) for the specified axis ID. Note that this does not
|
|
100
|
+
* change the original axis interval, doesn't dispatch the change to the update handlers, and
|
|
101
|
+
* does nothing when the axis has no range yet.
|
|
102
|
+
* @param axisId The axis ID
|
|
103
|
+
* @param interval The interval
|
|
104
|
+
*/
|
|
105
|
+
const setAxisIntervalFor = useCallback(
|
|
106
|
+
(axisId: string, interval: AxisInterval): void => {
|
|
107
|
+
Optional.ofNullable(axesRangeRef.current.get(axisId))
|
|
108
|
+
.map(range => range.update(interval.start, interval.end) as AR)
|
|
109
|
+
.ifPresent(updatedRange => axesRangeRef.current.set(axisId, updatedRange))
|
|
110
|
+
},
|
|
111
|
+
[]
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Sets the original axis interval for the axis range (does nothing when the axis has no range yet)
|
|
116
|
+
* @param axisId The axis ID
|
|
117
|
+
* @param interval The interval to which to set the origin interval
|
|
118
|
+
*/
|
|
119
|
+
const setOriginalAxisIntervalFor = useCallback(
|
|
120
|
+
(axisId: string, interval: AxisInterval): void => {
|
|
121
|
+
Optional.ofNullable(axesRangeRef.current.get(axisId))
|
|
122
|
+
.map(range => range.updateOriginal(interval.start, interval.end) as AR)
|
|
123
|
+
.ifPresent(updatedRange => axesRangeRef.current.set(axisId, updatedRange))
|
|
124
|
+
},
|
|
125
|
+
[]
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Re-applies the specified axis' stored range: dispatches it, unchanged, to the update handlers
|
|
130
|
+
* (so that the axis redraws with it). Note that this does *not* restore the axis' original
|
|
131
|
+
* range. Does nothing when the axis has no range.
|
|
132
|
+
* @param axisId The ID of the axis
|
|
133
|
+
*/
|
|
134
|
+
const resetAxisIntervalFor = useCallback(
|
|
135
|
+
(axisId: string): void => {
|
|
136
|
+
Optional
|
|
137
|
+
.ofNullable(axesRangeRef.current.get(axisId))
|
|
138
|
+
.map(range => new Map<string, AR>([[axisId, range]]))
|
|
139
|
+
.ifPresent(updates => updateAxisRanges(updates))
|
|
140
|
+
},
|
|
141
|
+
[updateAxisRanges]
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Sets the ranges of the axes in the specified map, and dispatches them to the update handlers
|
|
146
|
+
* (the same as {@link updateAxisRanges}). Axes that aren't in the map are left as they are, so
|
|
147
|
+
* the default (empty) map changes nothing.
|
|
148
|
+
* @param [axesRanges=new Map()] An optional map holds bounds for specified axes. The map
|
|
149
|
+
* associates an axis ID with the new bounds.
|
|
150
|
+
*/
|
|
151
|
+
const resetAxesRanges = useCallback(
|
|
152
|
+
(axesRanges: Map<string, AR> = new Map()): void => {
|
|
153
|
+
updateAxisRanges(axesRanges)
|
|
154
|
+
},
|
|
155
|
+
[updateAxisRanges]
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Adds a handler to deal with updates to the bounds of the axes
|
|
160
|
+
* @param handlerId the unique ID of the handler
|
|
161
|
+
* @param handler The handler function that accepts a map of updates and a plot dimension
|
|
162
|
+
* @return A map with all the handlers
|
|
163
|
+
* @throws Error when a handler with the same ID is already registered
|
|
164
|
+
*/
|
|
165
|
+
const addAxesRangesUpdateHandler = useCallback(
|
|
166
|
+
(
|
|
167
|
+
handlerId: string,
|
|
168
|
+
handler: (updates: Map<string, AR>, plotDim: Dimensions) => void
|
|
169
|
+
): Map<string, (updates: Map<string, AR>, plotDim: Dimensions) => void> => {
|
|
170
|
+
if (axesBoundsUpdateHandlersRef.current.has(handlerId)) {
|
|
171
|
+
throw new Error(
|
|
172
|
+
`Handler with ID already exists, please remove it before adding it; ` +
|
|
173
|
+
`handler_id: ${handlerId}; ` +
|
|
174
|
+
`existing_handler_ids: [${Array.from(axesBoundsUpdateHandlersRef.current.keys()).join(", ")}]`
|
|
175
|
+
)
|
|
176
|
+
}
|
|
177
|
+
return axesBoundsUpdateHandlersRef.current.set(handlerId, handler)
|
|
178
|
+
},
|
|
179
|
+
[]
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Removes the axis-update handler with the specified ID
|
|
184
|
+
* @param handlerId The ID of the handler to remove
|
|
185
|
+
* @return `true` when the handler was registered (and has been removed); `false` otherwise
|
|
186
|
+
*/
|
|
187
|
+
const removeAxesRangesUpdateHandler = useCallback(
|
|
188
|
+
(handlerId: string): boolean => axesBoundsUpdateHandlersRef.current.delete(handlerId),
|
|
189
|
+
[]
|
|
190
|
+
)
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Adds an x-axis to the x-axes state (a new state object, so dependents re-render)
|
|
194
|
+
* @param axis The axis to add
|
|
195
|
+
* @param id The ID of the axis to add
|
|
196
|
+
* @param [range] The initial axis range (when given, it's stored as the axis' range)
|
|
197
|
+
*/
|
|
198
|
+
const addXAxis = useCallback(
|
|
199
|
+
(axis: A, id: string, range?: AR): void => {
|
|
200
|
+
setXAxesState(xAxesState.addAxis(axis, id))
|
|
201
|
+
if (range !== undefined) {
|
|
202
|
+
axesRangeRef.current.set(id, range)
|
|
203
|
+
}
|
|
204
|
+
},
|
|
205
|
+
[xAxesState]
|
|
206
|
+
)
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Adds a y-axis to the y-axes state (a new state object, so dependents re-render)
|
|
210
|
+
* @param axis The axis to add
|
|
211
|
+
* @param id The ID of the axis to add
|
|
212
|
+
* @param [range] The initial axis range (when given, it's stored as the axis' range)
|
|
213
|
+
*/
|
|
214
|
+
const addYAxis = useCallback(
|
|
215
|
+
(axis: A, id: string, range?: AR): void => {
|
|
216
|
+
setYAxesState(yAxesState.addAxis(axis, id))
|
|
217
|
+
if (range !== undefined) {
|
|
218
|
+
axesRangeRef.current.set(id, range)
|
|
219
|
+
}
|
|
220
|
+
},
|
|
221
|
+
[yAxesState]
|
|
222
|
+
)
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Sets the axes assigned to each series (replacing any earlier assignments)
|
|
226
|
+
* @param assignments The assignment of the series to their axes
|
|
227
|
+
*/
|
|
228
|
+
const setAxisAssignments = useCallback(
|
|
229
|
+
(assignments: Map<string, AxesAssignment>): void => {
|
|
230
|
+
axisAssignmentsRef.current = assignments
|
|
231
|
+
},
|
|
232
|
+
[]
|
|
233
|
+
)
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* @return A copy of the map of the axes' current ranges, by axis ID
|
|
237
|
+
*/
|
|
238
|
+
const axesRanges = useCallback(
|
|
239
|
+
(): Map<string, AR> => new Map<string, AR>(axesRangeRef.current),
|
|
240
|
+
[]
|
|
241
|
+
)
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Retrieves the current axis range for the specified axis ID
|
|
245
|
+
* @param axisId The ID of the axis
|
|
246
|
+
* @return The axis' range, or an empty `Optional` when the axis has no range
|
|
247
|
+
*/
|
|
248
|
+
const axisRangeFor = useCallback(
|
|
249
|
+
(axisId: string) => Optional.ofNullable(axesRangeRef.current.get(axisId)),
|
|
250
|
+
[]
|
|
251
|
+
)
|
|
252
|
+
|
|
253
|
+
// the context's `value` prop is typed as `unknown` (see `AxesContext` in `useAxes.tsx`), so
|
|
254
|
+
// the object literal needs its own explicit type here to give the handler functions below
|
|
255
|
+
// their parameter types -- otherwise they'd fall back to implicit `any`.
|
|
256
|
+
//
|
|
257
|
+
// Memoized so consumers relying on this context value's identity (e.g. a `useMemo`/effect
|
|
258
|
+
// keyed on it) don't re-run on essentially every render of anything above this provider --
|
|
259
|
+
// previously a fresh object literal every render, with every method inside it also a fresh
|
|
260
|
+
// closure. This is the same class of bug already documented/worked around in ScatterPlot.tsx/
|
|
261
|
+
// RasterPlot.tsx/OutlierPlot.tsx (their own comments on `axesRanges` never being memoized
|
|
262
|
+
// here) -- those workarounds (refs populated imperatively instead of `useMemo([axesRanges])`)
|
|
263
|
+
// are left in place; they're redundant once this is memoized, but harmless, and removing them
|
|
264
|
+
// isn't part of this change.
|
|
265
|
+
const value: UseAxesValues<AR, A> = useMemo(
|
|
266
|
+
() => ({
|
|
267
|
+
xAxesState,
|
|
268
|
+
yAxesState,
|
|
269
|
+
addXAxis,
|
|
270
|
+
addYAxis,
|
|
271
|
+
setAxisAssignments,
|
|
272
|
+
axisAssignmentsFor,
|
|
273
|
+
updateAxisRanges,
|
|
274
|
+
axesRanges,
|
|
275
|
+
axisRangeFor,
|
|
276
|
+
setAxesRanges,
|
|
277
|
+
setAxisRangeFor,
|
|
278
|
+
setAxisIntervalFor,
|
|
279
|
+
setOriginalAxisIntervalFor,
|
|
280
|
+
resetAxesRanges,
|
|
281
|
+
resetAxisIntervalFor,
|
|
282
|
+
onUpdateAxesInterval,
|
|
283
|
+
addAxesRangesUpdateHandler,
|
|
284
|
+
removeAxesRangesUpdateHandler,
|
|
285
|
+
}),
|
|
286
|
+
[
|
|
287
|
+
xAxesState, yAxesState,
|
|
288
|
+
addXAxis, addYAxis,
|
|
289
|
+
setAxisAssignments, axisAssignmentsFor,
|
|
290
|
+
updateAxisRanges, axesRanges, axisRangeFor,
|
|
291
|
+
setAxesRanges, setAxisRangeFor, setAxisIntervalFor, setOriginalAxisIntervalFor,
|
|
292
|
+
resetAxesRanges, resetAxisIntervalFor,
|
|
293
|
+
onUpdateAxesInterval,
|
|
294
|
+
addAxesRangesUpdateHandler, removeAxesRangesUpdateHandler,
|
|
295
|
+
]
|
|
296
|
+
)
|
|
297
|
+
|
|
298
|
+
return <AxesContext.Provider value={value}>
|
|
299
|
+
{children}
|
|
300
|
+
</AxesContext.Provider>
|
|
301
|
+
}
|