stream-charts 1.2.0 → 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 +40 -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
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
AxesFont,
|
|
2
|
+
type AxesFont,
|
|
4
3
|
AxisLocation,
|
|
5
|
-
AxisTickStyle,
|
|
6
|
-
defaultAxesFont,
|
|
4
|
+
type AxisTickStyle, defaultAxesFont,
|
|
7
5
|
defaultAxisTickStyle,
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
addOrdinalStringAxis,
|
|
7
|
+
removeOrdinalXAxis,
|
|
8
|
+
removeOrdinalYAxis,
|
|
9
|
+
type OrdinalStringAxis,
|
|
10
|
+
type SeriesStyle
|
|
10
11
|
} from "./axes"
|
|
11
|
-
import
|
|
12
|
-
import {
|
|
13
|
-
import {useChart} from "../hooks/useChart";
|
|
12
|
+
import type {ScaleBand} from "d3";
|
|
13
|
+
import {type NoTooltipMetadata, useChart} from "../hooks/useChart";
|
|
14
14
|
import {useEffect, useRef} from "react";
|
|
15
|
-
import {Dimensions} from "../styling/margins";
|
|
15
|
+
import type {Dimensions} from "../styling/margins";
|
|
16
16
|
import {usePlotDimensions} from "../hooks/usePlotDimensions";
|
|
17
17
|
import {OrdinalAxisRange} from "./OrdinalAxisRange";
|
|
18
|
-
import {Datum} from "../series/timeSeries";
|
|
18
|
+
import type {Datum} from "../series/timeSeries";
|
|
19
19
|
import {AxisInterval} from "./AxisInterval";
|
|
20
20
|
|
|
21
21
|
export interface Props {
|
|
@@ -56,17 +56,18 @@ export interface Props {
|
|
|
56
56
|
* Category axis that represents the x-axis when its location is either on the bottom or the top.
|
|
57
57
|
* When the axis location is left or right, then the category axis represents the y-axis. The category
|
|
58
58
|
* axis requires a set of categories that will form the axis. Generally, these categories should
|
|
59
|
-
* be the name of the series used to represent each category.
|
|
59
|
+
* be the name of the series used to represent each category. This component returns null, meaning
|
|
60
|
+
* React won't render it because we are drawing directly onto the chart's shared canvas.
|
|
60
61
|
* @param props The properties for the component
|
|
61
62
|
* @return null
|
|
62
63
|
*/
|
|
63
64
|
export function OrdinalAxis(props: Props): null {
|
|
64
65
|
const {
|
|
65
66
|
chartId,
|
|
66
|
-
|
|
67
|
+
canvasContext,
|
|
67
68
|
axes,
|
|
68
69
|
color,
|
|
69
|
-
} = useChart<Datum,
|
|
70
|
+
} = useChart<Datum, SeriesStyle, NoTooltipMetadata, OrdinalAxisRange, OrdinalStringAxis>()
|
|
70
71
|
|
|
71
72
|
const {
|
|
72
73
|
xAxesState,
|
|
@@ -103,18 +104,16 @@ export function OrdinalAxis(props: Props): null {
|
|
|
103
104
|
// handles plot size changes by updating the range of the axis and the original range of the axis
|
|
104
105
|
useEffect(
|
|
105
106
|
() => {
|
|
106
|
-
if (
|
|
107
|
-
const svg = d3.select<SVGSVGElement, any>(container)
|
|
107
|
+
if (canvasContext) {
|
|
108
108
|
const font: AxesFont = {...defaultAxesFont(), color, ...props.font}
|
|
109
109
|
const axisTickStyle = {...defaultAxisTickStyle(), ...props.axisTickStyle}
|
|
110
110
|
|
|
111
|
-
|
|
112
111
|
// lambda that gets called when the axes need to be updated
|
|
113
112
|
const handleRangeUpdates = (updates: Map<string, OrdinalAxisRange>, plotDim: Dimensions): void => {
|
|
114
113
|
if (rangeUpdateHandlerIdRef.current && axis) {
|
|
115
114
|
const range = updates.get(axisId)
|
|
116
115
|
if (range) {
|
|
117
|
-
axis.update(range.current, range.original, plotDim, margin)
|
|
116
|
+
axis.update(categories, range.current, range.original, plotDim, margin)
|
|
118
117
|
}
|
|
119
118
|
}
|
|
120
119
|
}
|
|
@@ -126,13 +125,13 @@ export function OrdinalAxis(props: Props): null {
|
|
|
126
125
|
case AxisLocation.Top:
|
|
127
126
|
case AxisLocation.Bottom: {
|
|
128
127
|
const xAxis = addOrdinalStringAxis(
|
|
129
|
-
|
|
128
|
+
canvasContext, axisId, location, categories,
|
|
130
129
|
label, font, axisTickStyle, plotDimensions, margin,
|
|
131
130
|
setAxisIntervalFor, setOriginalAxisIntervalFor
|
|
132
131
|
)
|
|
133
132
|
|
|
134
133
|
// add the x-axis to the chart context
|
|
135
|
-
const [start, end] = AxisInterval.as(xAxis.scale.range()).asTuple()
|
|
134
|
+
const [start, end] = AxisInterval.as(xAxis.scale.range() as [number, number]).asTuple()
|
|
136
135
|
addXAxis(xAxis, axisId, OrdinalAxisRange.from(start, end))
|
|
137
136
|
|
|
138
137
|
// add an update handler
|
|
@@ -144,12 +143,12 @@ export function OrdinalAxis(props: Props): null {
|
|
|
144
143
|
case AxisLocation.Left:
|
|
145
144
|
case AxisLocation.Right: {
|
|
146
145
|
const yAxis = addOrdinalStringAxis(
|
|
147
|
-
|
|
146
|
+
canvasContext, axisId, location, categories,
|
|
148
147
|
label, font, axisTickStyle, plotDimensions, margin,
|
|
149
148
|
setAxisIntervalFor, setOriginalAxisIntervalFor
|
|
150
149
|
)
|
|
151
150
|
// add the y-axis to the chart context
|
|
152
|
-
const [start, end] = AxisInterval.as(yAxis.scale.range()).asTuple()
|
|
151
|
+
const [start, end] = AxisInterval.as(yAxis.scale.range() as [number, number]).asTuple()
|
|
153
152
|
addYAxis(yAxis, axisId, OrdinalAxisRange.from(start, end))
|
|
154
153
|
// add an update handler
|
|
155
154
|
rangeUpdateHandlerIdRef.current = `y-axis-${chartId}-${axisId}-${location.valueOf()}`
|
|
@@ -161,15 +160,20 @@ export function OrdinalAxis(props: Props): null {
|
|
|
161
160
|
.map(range => ([range.current, range.original]))
|
|
162
161
|
.getOrElse([AxisInterval.empty(), AxisInterval.empty()])
|
|
163
162
|
if (range && originalRange) {
|
|
164
|
-
axis.update(range, originalRange, plotDimensions, margin)
|
|
163
|
+
axis.update(categories, range, originalRange, plotDimensions, margin)
|
|
165
164
|
}
|
|
166
165
|
|
|
167
|
-
|
|
166
|
+
// keep the axis *label's* color in sync with the chart's color (e.g. on theme
|
|
167
|
+
// change), without recreating the axis or touching its domain. Note: tick label
|
|
168
|
+
// color is intentionally NOT touched here -- it stays fixed at whatever
|
|
169
|
+
// axisTickStyle.font was at creation, matching the original SVG version, which
|
|
170
|
+
// only ever updated the label's `fill`, not the ticks'.
|
|
171
|
+
axis.updateFont(font)
|
|
168
172
|
}
|
|
169
173
|
}
|
|
170
174
|
},
|
|
171
175
|
[
|
|
172
|
-
|
|
176
|
+
canvasContext,
|
|
173
177
|
axis,
|
|
174
178
|
addXAxis, addYAxis,
|
|
175
179
|
addAxesRangesUpdateHandler,
|
|
@@ -193,7 +197,10 @@ export function OrdinalAxis(props: Props): null {
|
|
|
193
197
|
const {current, original} = OrdinalAxisRange
|
|
194
198
|
.from(start, end, 0, oldDimension.width)
|
|
195
199
|
.zoom(oldDimension.width, newDimension.width)
|
|
196
|
-
|
|
200
|
+
// a resize never changes the set of categories -- read the axis's own
|
|
201
|
+
// current domain rather than `categories` from props, since `categories`
|
|
202
|
+
// isn't in this effect's dependency array and so may be stale here
|
|
203
|
+
axis.update(axis.scale.domain(), current, original, plotDimensions, margin)
|
|
197
204
|
}
|
|
198
205
|
if (location === AxisLocation.Left || location === AxisLocation.Right) {
|
|
199
206
|
const [start, end] = axisRangeFor(axisId)
|
|
@@ -202,7 +209,7 @@ export function OrdinalAxis(props: Props): null {
|
|
|
202
209
|
const {current, original} = OrdinalAxisRange
|
|
203
210
|
.from(start, end, 0, oldDimension.height)
|
|
204
211
|
.zoom(oldDimension.height, newDimension.height)
|
|
205
|
-
axis.update(current, original, plotDimensions, margin)
|
|
212
|
+
axis.update(axis.scale.domain(), current, original, plotDimensions, margin)
|
|
206
213
|
}
|
|
207
214
|
}
|
|
208
215
|
})
|
|
@@ -229,6 +236,25 @@ export function OrdinalAxis(props: Props): null {
|
|
|
229
236
|
[removeAxesRangesUpdateHandler]
|
|
230
237
|
)
|
|
231
238
|
|
|
239
|
+
// unregister the axis' draw function when the axis unmounts
|
|
240
|
+
useEffect(
|
|
241
|
+
() => {
|
|
242
|
+
return () => {
|
|
243
|
+
if (canvasContext) {
|
|
244
|
+
switch (location) {
|
|
245
|
+
case AxisLocation.Top:
|
|
246
|
+
case AxisLocation.Bottom:
|
|
247
|
+
removeOrdinalXAxis(canvasContext, axisId)
|
|
248
|
+
break
|
|
249
|
+
case AxisLocation.Left:
|
|
250
|
+
case AxisLocation.Right:
|
|
251
|
+
removeOrdinalYAxis(canvasContext, axisId)
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
},
|
|
256
|
+
[canvasContext, axisId, location]
|
|
257
|
+
)
|
|
258
|
+
|
|
232
259
|
return null
|
|
233
260
|
}
|
|
234
|
-
|
|
@@ -6,6 +6,13 @@ import {BaseAxisRange} from "./BaseAxisRange";
|
|
|
6
6
|
*/
|
|
7
7
|
export class OrdinalAxisRange extends BaseAxisRange {
|
|
8
8
|
|
|
9
|
+
/**
|
|
10
|
+
* Use {@link OrdinalAxisRange.from} to create an instance
|
|
11
|
+
* @param start The start of the axis-range
|
|
12
|
+
* @param end The end of the axis-range
|
|
13
|
+
* @param [originalStart=start] The original start of the axis-range
|
|
14
|
+
* @param [originalEnd=end] The original end of the axis-range
|
|
15
|
+
*/
|
|
9
16
|
private constructor(start: number, end: number, originalStart: number = start, originalEnd: number = end) {
|
|
10
17
|
super(start, end, originalStart, originalEnd)
|
|
11
18
|
}
|
|
@@ -18,36 +25,100 @@ export class OrdinalAxisRange extends BaseAxisRange {
|
|
|
18
25
|
* Defaults to the start value if not specified.)
|
|
19
26
|
* @param [originalEnd=end] The optional original end of the axis-range (e.g. before any zooming or panning.
|
|
20
27
|
* Defaults to the end value if not specified.)
|
|
21
|
-
* @return A new
|
|
28
|
+
* @return A new ordinal-axis range instance.
|
|
22
29
|
*/
|
|
23
30
|
static from(start: number, end: number, originalStart: number = start, originalEnd: number = end): OrdinalAxisRange {
|
|
24
31
|
return new OrdinalAxisRange(start, end, originalStart, originalEnd)
|
|
25
32
|
}
|
|
26
33
|
|
|
27
34
|
/**
|
|
28
|
-
* Scales the axis-range by the specified scale factor
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
35
|
+
* Scales the axis-range by the specified *cumulative* scale factor (d3-zoom's own
|
|
36
|
+
* `event.transform.k`, taken as-is -- NOT converted to an incremental, relative-to-the-
|
|
37
|
+
* previous-event factor), pivoting on `value`.
|
|
38
|
+
*
|
|
39
|
+
* Two cases, because neither a purely incremental nor a purely cumulative-from-`.original`
|
|
40
|
+
* formula is correct on its own for a bounded ordinal domain:
|
|
41
|
+
*
|
|
42
|
+
* - `factor === 1` (fully zoomed out): returns `.original` directly, bypassing the pivot math
|
|
43
|
+
* entirely. An ordinal axis's domain (the fixed set of categories) is bounded, so "zoomed all
|
|
44
|
+
* the way back out" has exactly one correct answer -- `.current` must equal `.original`
|
|
45
|
+
* *exactly*, regardless of how many different pivots were used to get there. d3-zoom's own
|
|
46
|
+
* `.scaleExtent` clamps `k` to *exactly* 1 at the zoom floor (not just asymptotically close),
|
|
47
|
+
* so this equality check reliably detects that boundary.
|
|
48
|
+
* - Otherwise: scales from `.current` using the *incremental* step implied by the cumulative
|
|
49
|
+
* factor (`factor` divided by the range's own current/original width ratio) -- the same
|
|
50
|
+
* pivot-preserving composition `ContinuousAxisRange` uses (see `BaseAxisRange.scaledRange`).
|
|
51
|
+
* This composes correctly across any sequence of differing pivots without jumping.
|
|
52
|
+
*
|
|
53
|
+
* Why not just always scale from `.original` by the cumulative factor (a prior version of this
|
|
54
|
+
* method did exactly that)? Composing pivot-preserving zooms at *different* pivots is not
|
|
55
|
+
* itself position-preserving -- zooming in at one spot and back out at another nets a
|
|
56
|
+
* translation, same as any pinch-zoom or map UI, verified live: zoom in at pivot A to k=5, then
|
|
57
|
+
* zoom out at a different pivot B to k=1, lands `.current` at `[400, 1400]` instead of
|
|
58
|
+
* `[0, 1000]` even under the mathematically-correct incremental composition. Scaling
|
|
59
|
+
* `.original` directly by the raw cumulative factor "fixes" that only by recomputing the
|
|
60
|
+
* *entire* zoom from scratch at the current pivot on every single event -- which is correct
|
|
61
|
+
* only when the pivot never changes since the last identity reset, and otherwise discards all
|
|
62
|
+
* zoom history, producing a visible jump the moment the pivot changes at any *non-identity* zoom
|
|
63
|
+
* level (confirmed live: continuing to zoom in from k=5 at pivot A to k=6 at a different pivot B
|
|
64
|
+
* jumped from the correct, continuous `[-1600, 4400]` to `[-4000, 2000]`). The `factor === 1`
|
|
65
|
+
* special case gets the position-preserving guarantee only where it's actually needed -- the
|
|
66
|
+
* one canonical "fully zoomed out" state -- without sacrificing composability everywhere else.
|
|
67
|
+
* A continuous/scrolling axis (`ContinuousAxisRange`) never needs the equivalent of this special
|
|
68
|
+
* case, since it has no fixed domain edge for translational drift to visibly clip against.
|
|
69
|
+
* @param factor The cumulative scale factor (`event.transform.k`, unmodified)
|
|
32
70
|
* @param value The value from which to scale the interval
|
|
33
|
-
* @return
|
|
71
|
+
* @return The new range, as a plain {start, end} pair
|
|
72
|
+
*/
|
|
73
|
+
private scaledCumulative(factor: number, value: number): {start: number, end: number} {
|
|
74
|
+
// when the factor is 1 or the original measure is 0, return the original range
|
|
75
|
+
if (factor === 1 || this.original.measure() === 0) {
|
|
76
|
+
return {start: this.original.start, end: this.original.end}
|
|
77
|
+
}
|
|
78
|
+
const scaleFactor = this.current.measure() / this.original.measure()
|
|
79
|
+
const incrementalFactor = factor / scaleFactor
|
|
80
|
+
const dtStart = value - this.current.start
|
|
81
|
+
const dtEnd = this.current.end - value
|
|
82
|
+
return {start: value - dtStart * incrementalFactor, end: value + dtEnd * incrementalFactor}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Scales the axis-range by the specified *cumulative* scale factor (see
|
|
87
|
+
* `scaledCumulative` for why this must be cumulative, not incremental) from the
|
|
88
|
+
* specified value. The equations are written so that the zooming (scaling) occurs at the
|
|
89
|
+
* specified value, and expands/contracts equally from that value. This operation does not
|
|
90
|
+
* modify the original range.
|
|
91
|
+
* @param factor The cumulative scale factor
|
|
92
|
+
* @param value The value from which to scale the interval
|
|
93
|
+
* @return A new ordinal-axis range with updated values
|
|
34
94
|
*/
|
|
35
95
|
scale(factor: number, value: number): OrdinalAxisRange {
|
|
36
|
-
const scaledInterval = this.
|
|
96
|
+
const scaledInterval = this.scaledCumulative(factor, value)
|
|
37
97
|
return new OrdinalAxisRange(scaledInterval.start, scaledInterval.end, this.original.start, this.original.end)
|
|
38
98
|
}
|
|
39
99
|
|
|
40
100
|
/**
|
|
41
|
-
* Scales the axis-range by the specified scale factor
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
101
|
+
* Scales the axis-range by the specified *cumulative* scale factor (see
|
|
102
|
+
* `scaledCumulative` for why this must be cumulative, not incremental) from the
|
|
103
|
+
* specified value, while keeping the range within the constraints (start, end). The equations
|
|
104
|
+
* are written so that the zooming (scaling) occurs at the specified value, and
|
|
105
|
+
* expands/contracts equally from that value.
|
|
106
|
+
*
|
|
107
|
+
* Widens the scaled result to *cover* `constraint` (never narrower than it) -- `constraint`
|
|
108
|
+
* is the domain that must be fully visible once zoomed all the way out, and widening rather
|
|
109
|
+
* than clamping is exactly what fixes the pivot-drift bug described on
|
|
110
|
+
* `scaledCumulative` (zooming in at one pivot and back out at another must never leave
|
|
111
|
+
* part of the domain clipped). This is the opposite direction from
|
|
112
|
+
* {@link ContinuousAxisRange.constrainedScale}, which *clamps* its result inside `constraint`
|
|
113
|
+
* instead -- see that method's doc comment for why a continuous axis needs the opposite
|
|
114
|
+
* behavior. Do not "fix" this difference without reading both.
|
|
115
|
+
* @param factor The cumulative scale factor
|
|
45
116
|
* @param value The value from which to scale the interval
|
|
46
117
|
* @param constraint The minimum and maximum values that range bounds can be
|
|
47
|
-
* @return A new
|
|
118
|
+
* @return A new ordinal-axis range with updated values
|
|
48
119
|
*/
|
|
49
120
|
constrainedScale(factor: number, value: number, constraint: [min: number, max: number]): OrdinalAxisRange {
|
|
50
|
-
const scaledInterval = this.
|
|
121
|
+
const scaledInterval = this.scaledCumulative(factor, value)
|
|
51
122
|
const [min, max] = constraint
|
|
52
123
|
return new OrdinalAxisRange(
|
|
53
124
|
Math.min(min, scaledInterval.start),
|
|
@@ -57,14 +128,16 @@ export class OrdinalAxisRange extends BaseAxisRange {
|
|
|
57
128
|
)
|
|
58
129
|
}
|
|
59
130
|
/**
|
|
60
|
-
* Translates the axis-range by the specified amount
|
|
131
|
+
* Translates the axis-range by the specified amount, unless that would take it outside the
|
|
132
|
+
* constraint interval (when both ends of the constraint are infinite, there's no constraint)
|
|
61
133
|
* @param amount The amount by which to translate the axis-range
|
|
62
134
|
* @param [constraint=[-Infinity, Infinity]] Optional constraint interval in which the axis range must be within
|
|
63
|
-
* @return An updated {@link OrdinalAxisRange} that has been translated by the specified amount
|
|
135
|
+
* @return An updated {@link OrdinalAxisRange} that has been translated by the specified amount (or an
|
|
136
|
+
* unchanged copy, when the translation would leave the constraint interval)
|
|
64
137
|
*/
|
|
65
138
|
translate(amount: number, constraint: [start: number, end: number] = [-Infinity, Infinity]): OrdinalAxisRange {
|
|
66
139
|
const [cs, ce] = constraint
|
|
67
|
-
// when
|
|
140
|
+
// when both of the constraints are infinite, or the pan keeps the new axis range
|
|
68
141
|
// within the origin axis range (i.e. zoomed in and the panned), then allow the pan,
|
|
69
142
|
// otherwise don't update
|
|
70
143
|
if ((!isFinite(cs) && !isFinite(ce)) || (this.current.start + amount >= cs && this.current.end + amount <= ce)) {
|
|
@@ -83,6 +156,13 @@ export class OrdinalAxisRange extends BaseAxisRange {
|
|
|
83
156
|
* the dimensions.
|
|
84
157
|
*/
|
|
85
158
|
zoom(beforeDimension: number, afterDimension: number): OrdinalAxisRange {
|
|
159
|
+
// a zero `beforeDimension` (e.g. a chart mounted inside a collapsed/hidden container that
|
|
160
|
+
// later becomes visible) would otherwise divide by zero below, producing a NaN/Infinity
|
|
161
|
+
// range that corrupts this axis until remount. There's no proportional "before" range to
|
|
162
|
+
// scale from in that case, so just take the new dimension as the fresh, un-zoomed range.
|
|
163
|
+
if (beforeDimension === 0) {
|
|
164
|
+
return new OrdinalAxisRange(0, afterDimension, 0, afterDimension)
|
|
165
|
+
}
|
|
86
166
|
const [start, end] = this.current.asTuple()
|
|
87
167
|
const delta = (end - start ) * (afterDimension - beforeDimension) / beforeDimension
|
|
88
168
|
const lowerBound = start / (end - start) * delta + start
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
import type {ScaleContinuousNumeric} from "d3";
|
|
2
|
+
import {firstIndexAtOrAfter} from "../utils";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* The auto-scaling settings of a (y-) axis whose domain grows to fit the data plotted against it
|
|
6
|
+
* (see `ContinuousAxis`'s `autoScale`, `autoScaleMin`, `autoScaleMax`, and `autoScalePadding` props)
|
|
7
|
+
*/
|
|
8
|
+
export type AutoScale = {
|
|
9
|
+
/**
|
|
10
|
+
* Where the axis' domain starts out: its `domain` prop, clamped to the limits. It's what the
|
|
11
|
+
* domain is restored to when its plot's data is replaced (e.g. on a reset).
|
|
12
|
+
*/
|
|
13
|
+
domain: [min: number, max: number]
|
|
14
|
+
/**
|
|
15
|
+
* The smallest value the axis' domain may reach
|
|
16
|
+
*/
|
|
17
|
+
min: number
|
|
18
|
+
/**
|
|
19
|
+
* The largest value the axis' domain may reach
|
|
20
|
+
*/
|
|
21
|
+
max: number
|
|
22
|
+
/**
|
|
23
|
+
* The fraction of the axis' length left beyond the data's extreme on a side that grows (so
|
|
24
|
+
* the extreme point isn't drawn right on the edge), from 0 to 0.45
|
|
25
|
+
*/
|
|
26
|
+
padding: number
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Clamps a domain to the auto-scaling limits, so that an auto-scaling axis never starts out past
|
|
31
|
+
* them. (When the domain lies entirely beyond a limit, it collapses onto that limit.)
|
|
32
|
+
* @param domain The domain
|
|
33
|
+
* @param min The smallest value the domain may reach
|
|
34
|
+
* @param max The largest value the domain may reach
|
|
35
|
+
* @return The domain, clamped to the limits
|
|
36
|
+
*/
|
|
37
|
+
export function clampedDomain(
|
|
38
|
+
domain: [min: number, max: number],
|
|
39
|
+
min: number,
|
|
40
|
+
max: number
|
|
41
|
+
): [min: number, max: number] {
|
|
42
|
+
const clamp = (value: number) => Math.min(max, Math.max(min, value))
|
|
43
|
+
return [clamp(domain[0]), clamp(domain[1])]
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Whether two auto-scaling settings are the same (`undefined` means "not auto-scaling")
|
|
48
|
+
* @param a The first settings
|
|
49
|
+
* @param b The second settings
|
|
50
|
+
* @return `true` when they're the same; `false` otherwise
|
|
51
|
+
*/
|
|
52
|
+
export function sameAutoScale(a: AutoScale | undefined, b: AutoScale | undefined): boolean {
|
|
53
|
+
if (a === undefined || b === undefined) return a === b
|
|
54
|
+
return a.domain[0] === b.domain[0] && a.domain[1] === b.domain[1] &&
|
|
55
|
+
a.min === b.min && a.max === b.max && a.padding === b.padding
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Grows an axis' domain to include the specified extent of the data, with the padding beyond it,
|
|
60
|
+
* without going past the auto-scaling limits. A side grows when the data reaches into its padding
|
|
61
|
+
* (not only when the data goes past the edge), so that the data always has the padding's room to
|
|
62
|
+
* spare (until a limit is reached), and it grows so that the data's extreme sits exactly the
|
|
63
|
+
* padding from the edge. The domain only ever grows: an extent that's within the domain, and
|
|
64
|
+
* clear of its padding, leaves the domain as it is.
|
|
65
|
+
*
|
|
66
|
+
* The padding is applied in the scale's own space (e.g. logarithmically, for a log scale), as a
|
|
67
|
+
* fraction of the axis' length.
|
|
68
|
+
* @param domain The axis' current domain
|
|
69
|
+
* @param extent The [min, max] of the data plotted against the axis, or `undefined` when there's
|
|
70
|
+
* no data
|
|
71
|
+
* @param autoScale The auto-scaling settings (the limits, and the padding)
|
|
72
|
+
* @param scale The axis' scale (only its kind matters: linear, log, ...)
|
|
73
|
+
* @return The grown domain (or the current domain, when there's nothing to grow for)
|
|
74
|
+
*/
|
|
75
|
+
export function grownDomain(
|
|
76
|
+
domain: [min: number, max: number],
|
|
77
|
+
extent: [min: number, max: number] | undefined,
|
|
78
|
+
autoScale: Pick<AutoScale, 'min' | 'max' | 'padding'>,
|
|
79
|
+
scale: ScaleContinuousNumeric<number, number>
|
|
80
|
+
): [min: number, max: number] {
|
|
81
|
+
if (extent === undefined) return domain
|
|
82
|
+
const [domainMin, domainMax] = domain
|
|
83
|
+
const padding = Math.min(0.45, Math.max(0, autoScale.padding))
|
|
84
|
+
|
|
85
|
+
// a side grows when the data reaches into its padding (or past its edge). Where the data sits
|
|
86
|
+
// within the current domain is measured in the scale's own space, with a little tolerance, so
|
|
87
|
+
// that an extreme that sits exactly the padding from the edge (as growing leaves it) doesn't
|
|
88
|
+
// grow the domain again by rounding errors on every frame.
|
|
89
|
+
const tolerance = 1e-9
|
|
90
|
+
const current = scale.copy().domain([domainMin, domainMax]).range([0, 1])
|
|
91
|
+
const growsDown = extent[0] < domainMin || current(extent[0]) < padding - tolerance
|
|
92
|
+
const growsUp = extent[1] > domainMax || current(extent[1]) > 1 - padding + tolerance
|
|
93
|
+
if (!growsDown && !growsUp) return domain
|
|
94
|
+
|
|
95
|
+
let min = growsDown ? extent[0] : domainMin
|
|
96
|
+
let max = growsUp ? extent[1] : domainMax
|
|
97
|
+
if (padding > 0 && min < max) {
|
|
98
|
+
// the normalized scale over the grown domain, extended on each growing side so that the
|
|
99
|
+
// extreme sits `padding` of the (extended) axis' length from that edge: with n growing
|
|
100
|
+
// sides, each extension e satisfies e / (1 + n e) = padding
|
|
101
|
+
const normalized = scale.copy().domain([min, max]).range([0, 1])
|
|
102
|
+
const growingSides = (growsDown ? 1 : 0) + (growsUp ? 1 : 0)
|
|
103
|
+
const extension = padding / (1 - growingSides * padding)
|
|
104
|
+
if (growsDown) min = normalized.invert(-extension)
|
|
105
|
+
if (growsUp) max = normalized.invert(1 + extension)
|
|
106
|
+
}
|
|
107
|
+
// (never past the limits -- and never shrinking a side, should the domain already be past one)
|
|
108
|
+
return [
|
|
109
|
+
growsDown ? Math.min(domainMin, Math.max(autoScale.min, min)) : domainMin,
|
|
110
|
+
growsUp ? Math.max(domainMax, Math.min(autoScale.max, max)) : domainMax,
|
|
111
|
+
]
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Extends an extent to include the specified value
|
|
116
|
+
* @param extent The extent so far, or `undefined` when there's none yet
|
|
117
|
+
* @param value The value to include
|
|
118
|
+
* @return The extent, including the value
|
|
119
|
+
*/
|
|
120
|
+
export function extentWith(
|
|
121
|
+
extent: [min: number, max: number] | undefined,
|
|
122
|
+
value: number
|
|
123
|
+
): [min: number, max: number] {
|
|
124
|
+
if (extent === undefined) return [value, value]
|
|
125
|
+
return [Math.min(extent[0], value), Math.max(extent[1], value)]
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Calculates the extent (the [min, max]) of the specified values, skipping those the y-scale
|
|
130
|
+
* can't show (e.g. values <= 0 on a log scale, or NaN)
|
|
131
|
+
* @param values The values
|
|
132
|
+
* @param yScale The y-axis' scale
|
|
133
|
+
* @return The extent of the values, or `undefined` when there are none (that can be shown)
|
|
134
|
+
*/
|
|
135
|
+
export function extentOf(
|
|
136
|
+
values: Iterable<number>,
|
|
137
|
+
yScale: ScaleContinuousNumeric<number, number>
|
|
138
|
+
): [min: number, max: number] | undefined {
|
|
139
|
+
let extent: [min: number, max: number] | undefined = undefined
|
|
140
|
+
for (const value of values) {
|
|
141
|
+
if (Number.isFinite(yScale(value))) extent = extentWith(extent, value)
|
|
142
|
+
}
|
|
143
|
+
return extent
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Calculates the extent (the [min, max] of the y-values) of a series' data that's visible within
|
|
148
|
+
* the x-axis' window: the values of the points within the window, and -- when the series is drawn
|
|
149
|
+
* with lines -- the lines' heights where they cross the window's left and right edges (a line from
|
|
150
|
+
* a point just off screen can reach higher, or lower, within the window than any point that's on
|
|
151
|
+
* screen). Values the y-scale can't show (e.g. values <= 0 on a log scale) are skipped.
|
|
152
|
+
*
|
|
153
|
+
* A point can have several values, each drawn as its own line across the points (e.g. an outlier
|
|
154
|
+
* series' value, and its bands' lower and upper bounds), so the crossings are calculated for each.
|
|
155
|
+
* They're calculated in the y-scale's own space (as the lines are drawn), so they're exact for
|
|
156
|
+
* straight lines, on any kind of scale.
|
|
157
|
+
* @param data The series' data, ordered by x
|
|
158
|
+
* @param window The x-axis' [start, end]
|
|
159
|
+
* @param yScale The y-axis' scale
|
|
160
|
+
* @param withLines Whether the series is drawn with lines (rather than just points)
|
|
161
|
+
* @param xOf The point's x-value (defaults to its `x`)
|
|
162
|
+
* @param valuesOf The point's y-values, each drawn as its own line (defaults to its `y`)
|
|
163
|
+
* @return The extent of the visible data, or `undefined` when nothing is visible
|
|
164
|
+
* @template P The type of the data's points
|
|
165
|
+
*/
|
|
166
|
+
export function visibleExtent<P>(
|
|
167
|
+
data: { length: number, [index: number]: P },
|
|
168
|
+
window: [start: number, end: number],
|
|
169
|
+
yScale: ScaleContinuousNumeric<number, number>,
|
|
170
|
+
withLines: boolean,
|
|
171
|
+
xOf: (point: P) => number = point => (point as { x: number }).x,
|
|
172
|
+
valuesOf: (point: P) => Array<number> = point => [(point as { y: number }).y],
|
|
173
|
+
): [min: number, max: number] | undefined {
|
|
174
|
+
const [start, end] = window
|
|
175
|
+
const showable = (value: number) => Number.isFinite(yScale(value))
|
|
176
|
+
// includes the heights where the lines between the two points cross x
|
|
177
|
+
const withCrossings = (
|
|
178
|
+
extent: [min: number, max: number] | undefined,
|
|
179
|
+
from: P,
|
|
180
|
+
to: P,
|
|
181
|
+
x: number
|
|
182
|
+
): [min: number, max: number] | undefined => {
|
|
183
|
+
const fromValues = valuesOf(from)
|
|
184
|
+
const toValues = valuesOf(to)
|
|
185
|
+
const fraction = xOf(to) === xOf(from) ? 1 : (x - xOf(from)) / (xOf(to) - xOf(from))
|
|
186
|
+
fromValues.forEach((fromValue, index) => {
|
|
187
|
+
const toValue = toValues[index]
|
|
188
|
+
if (toValue === undefined || !showable(fromValue) || !showable(toValue)) return
|
|
189
|
+
const fromY = yScale(fromValue)
|
|
190
|
+
extent = extentWith(extent, yScale.invert(fromY + (yScale(toValue) - fromY) * fraction))
|
|
191
|
+
})
|
|
192
|
+
return extent
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
let extent: [min: number, max: number] | undefined = undefined
|
|
196
|
+
let index = firstIndexAtOrAfter(data, start, xOf)
|
|
197
|
+
|
|
198
|
+
// the lines entering through the window's left edge
|
|
199
|
+
if (withLines && index > 0 && index < data.length && xOf(data[index]) <= end) {
|
|
200
|
+
extent = withCrossings(extent, data[index - 1], data[index], start)
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// the points within the window
|
|
204
|
+
for (; index < data.length && xOf(data[index]) <= end; index++) {
|
|
205
|
+
valuesOf(data[index]).forEach(value => {
|
|
206
|
+
if (showable(value)) extent = extentWith(extent, value)
|
|
207
|
+
})
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// the lines leaving through the window's right edge (or, when no point is within the window,
|
|
211
|
+
// passing straight across it)
|
|
212
|
+
if (withLines && index > 0 && index < data.length && xOf(data[index - 1]) < end) {
|
|
213
|
+
extent = withCrossings(extent, data[index - 1], data[index], end)
|
|
214
|
+
if (xOf(data[index - 1]) < start) extent = withCrossings(extent, data[index - 1], data[index], start)
|
|
215
|
+
}
|
|
216
|
+
return extent
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// the warnings already issued (each is only issued once)
|
|
220
|
+
const issuedWarnings = new Set<string>()
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Issues a warning to the console, once (e.g. about auto-scaling settings that are ignored)
|
|
224
|
+
* @param message The warning
|
|
225
|
+
*/
|
|
226
|
+
export function warnOnce(message: string): void {
|
|
227
|
+
if (issuedWarnings.has(message)) return
|
|
228
|
+
issuedWarnings.add(message)
|
|
229
|
+
console.warn(message)
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Warns (once per axis) about the auto-scaling y-axes of a plot that doesn't support auto-scaling,
|
|
234
|
+
* whose `autoScale` setting is therefore ignored
|
|
235
|
+
* @param plotName The name of the plot (e.g. "BarPlot")
|
|
236
|
+
* @param yAxes The plot's y-axes, by their IDs
|
|
237
|
+
*/
|
|
238
|
+
export function warnAboutIgnoredAutoScale(plotName: string, yAxes: Map<string, object>): void {
|
|
239
|
+
yAxes.forEach((axis, axisId) => {
|
|
240
|
+
if ((axis as { autoScale?: AutoScale }).autoScale !== undefined) {
|
|
241
|
+
warnOnce(`The ${plotName} doesn't support auto-scaling y-axes, so the "autoScale" setting of y-axis "${axisId}" is ignored`)
|
|
242
|
+
}
|
|
243
|
+
})
|
|
244
|
+
}
|