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,8 +1,9 @@
|
|
|
1
|
-
import {Series} from "../plots/plot";
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
1
|
+
import type {Series} from "../plots/plot";
|
|
2
|
+
import type {Dimensions, Margin} from "../styling/margins";
|
|
3
|
+
import type {OrdinalStringAxis} from "../axes/axes";
|
|
4
|
+
import type {ScaleContinuousNumeric} from "d3";
|
|
5
|
+
import type {Datum} from "../series/timeSeries";
|
|
6
|
+
import {firstIndexAtOrAfter} from "../utils";
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* Properties for rendering the tooltip. This is the style for the container
|
|
@@ -48,6 +49,9 @@ export interface TooltipStyle {
|
|
|
48
49
|
paddingBottom: number;
|
|
49
50
|
}
|
|
50
51
|
|
|
52
|
+
/**
|
|
53
|
+
* The default tooltip style
|
|
54
|
+
*/
|
|
51
55
|
export const defaultTooltipStyle: TooltipStyle = {
|
|
52
56
|
visible: false,
|
|
53
57
|
|
|
@@ -72,91 +76,76 @@ export const defaultTooltipStyle: TooltipStyle = {
|
|
|
72
76
|
paddingBottom: 10,
|
|
73
77
|
};
|
|
74
78
|
|
|
75
|
-
export interface TooltipDimensions {
|
|
76
|
-
x: number,
|
|
77
|
-
y: number,
|
|
78
|
-
contentWidth: number,
|
|
79
|
-
contentHeight: number
|
|
80
|
-
}
|
|
81
|
-
|
|
82
79
|
/**
|
|
83
|
-
*
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Calculates the x-coordinate of the upper left-hand side of the tooltip rectangle (obviously without
|
|
91
|
-
* "rounded corners"). Adjusts the x-coordinate so that tooltip is visible on the edges of the plot.
|
|
92
|
-
* @param x The current x-coordinate of the mouse
|
|
93
|
-
* @param textWidth The width of the tooltip text
|
|
80
|
+
* Calculates the x-coordinate of the left side of the tooltip. The tooltip goes to the right of the
|
|
81
|
+
* mouse, unless it would run past the right edge of the plot, in which case it goes to the left of
|
|
82
|
+
* the mouse (and never past the left edge of the chart).
|
|
83
|
+
* @param x The x-coordinate of the mouse, relative to the chart
|
|
84
|
+
* @param width The tooltip's (rendered) width, including its padding and border
|
|
94
85
|
* @param plotDimensions The dimensions of the plot
|
|
95
|
-
* @param tooltipStyle The tooltip style information
|
|
86
|
+
* @param tooltipStyle The tooltip style information (its left padding is used as the gap between
|
|
87
|
+
* the mouse and the tooltip)
|
|
96
88
|
* @param margin The plot margin
|
|
97
|
-
* @return The x-coordinate of the
|
|
89
|
+
* @return The x-coordinate of the tooltip's left side, relative to the chart
|
|
98
90
|
*/
|
|
99
|
-
export function tooltipX(x: number,
|
|
100
|
-
|
|
101
|
-
|
|
91
|
+
export function tooltipX(x: number, width: number, plotDimensions: Dimensions, tooltipStyle: TooltipStyle, margin: Margin): number {
|
|
92
|
+
const gap = tooltipStyle.paddingLeft
|
|
93
|
+
if (x + gap + width <= margin.left + plotDimensions.width) {
|
|
94
|
+
return x + gap
|
|
102
95
|
}
|
|
103
|
-
return x
|
|
96
|
+
return Math.max(0, x - gap - width)
|
|
104
97
|
}
|
|
105
98
|
|
|
106
99
|
/**
|
|
107
|
-
* Calculates the y-coordinate of the
|
|
108
|
-
*
|
|
109
|
-
*
|
|
110
|
-
* @param
|
|
100
|
+
* Calculates the y-coordinate of the top of the tooltip. The tooltip goes below the mouse, unless it
|
|
101
|
+
* would run past the bottom of the plot, in which case it's moved up so that its bottom lines up
|
|
102
|
+
* with the plot's bottom (and never past the top edge of the chart).
|
|
103
|
+
* @param y The y-coordinate of the mouse, relative to the chart
|
|
104
|
+
* @param height The tooltip's (rendered) height, including its padding and border
|
|
111
105
|
* @param plotDimensions The dimensions of the plot
|
|
112
|
-
* @param tooltipStyle The tooltip style information
|
|
106
|
+
* @param tooltipStyle The tooltip style information (its top padding is used as the gap between
|
|
107
|
+
* the mouse and the tooltip)
|
|
113
108
|
* @param margin The plot margin
|
|
114
|
-
* @return The y-coordinate of the
|
|
109
|
+
* @return The y-coordinate of the tooltip's top, relative to the chart
|
|
115
110
|
*/
|
|
116
|
-
export function tooltipY(y: number,
|
|
117
|
-
|
|
118
|
-
|
|
111
|
+
export function tooltipY(y: number, height: number, plotDimensions: Dimensions, tooltipStyle: TooltipStyle, margin: Margin): number {
|
|
112
|
+
const gap = tooltipStyle.paddingTop
|
|
113
|
+
if (y + gap + height <= margin.top + plotDimensions.height) {
|
|
114
|
+
return y + gap
|
|
119
115
|
}
|
|
120
|
-
return
|
|
116
|
+
return Math.max(0, margin.top + plotDimensions.height - height)
|
|
121
117
|
}
|
|
122
118
|
|
|
123
119
|
/**
|
|
124
|
-
* Calculates the y-coordinate
|
|
125
|
-
*
|
|
126
|
-
* @param seriesName The name of the series
|
|
127
|
-
* @param
|
|
120
|
+
* Calculates the y-coordinate of the top of a tooltip for a category (e.g. a raster plot's row):
|
|
121
|
+
* the tooltip is centered on the category, but kept within the plot's top and bottom edges.
|
|
122
|
+
* @param seriesName The name of the series (the category)
|
|
123
|
+
* @param height The tooltip's (rendered) height, including its padding and border
|
|
128
124
|
* @param axis The category axis for determining the y-value of the tooltip
|
|
129
|
-
* @param tooltipStyle The tooltip style
|
|
130
125
|
* @param margin The plot margin
|
|
131
126
|
* @param categoryHeight The height (in pixels) of the category
|
|
132
127
|
* @param plotDimensions The dimensions of the plot
|
|
133
|
-
* @return The y-coordinate of the
|
|
128
|
+
* @return The y-coordinate of the tooltip's top, relative to the chart
|
|
134
129
|
*/
|
|
135
130
|
export function categoryTooltipY(
|
|
136
131
|
seriesName: string,
|
|
137
|
-
|
|
132
|
+
height: number,
|
|
138
133
|
axis: OrdinalStringAxis,
|
|
139
|
-
tooltipStyle: TooltipStyle,
|
|
140
134
|
margin: Margin,
|
|
141
135
|
categoryHeight: number,
|
|
142
136
|
plotDimensions: Dimensions
|
|
143
137
|
): number {
|
|
144
|
-
const
|
|
145
|
-
const
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
}
|
|
149
|
-
if (y > plotDimensions.height + margin.top - halfHeight) {
|
|
150
|
-
return plotDimensions.height + margin.top - textHeight
|
|
151
|
-
}
|
|
152
|
-
return y + margin.top - halfHeight + categoryHeight / 2
|
|
138
|
+
const categoryCenter = margin.top + (axis.scale(seriesName) || 0) + categoryHeight / 2
|
|
139
|
+
const top = categoryCenter - height / 2
|
|
140
|
+
const lowest = margin.top + plotDimensions.height - height
|
|
141
|
+
return Math.max(margin.top, Math.min(top, lowest))
|
|
153
142
|
}
|
|
154
143
|
|
|
155
144
|
/**
|
|
156
145
|
* Returns the index of the data point whose time is the upper boundary on the specified
|
|
157
|
-
* time. If the specified time is larger than any time in the specified data,
|
|
146
|
+
* time. If the specified time is larger than any time in the specified data, then returns
|
|
158
147
|
* the length of the data array. If the specified time is smaller than all the values in
|
|
159
|
-
* the specified array, then returns
|
|
148
|
+
* the specified array, then returns 0. The data must not be empty.
|
|
160
149
|
* @param data The array of points from which to select the
|
|
161
150
|
* boundary.
|
|
162
151
|
* @param value The time for which to find the bounding points
|
|
@@ -185,11 +174,17 @@ function boundingPointsIndex<D>(data: Series<D>, value: number, xFrom: (value: D
|
|
|
185
174
|
* @param xFrom A function that extracts the x-value from the datum
|
|
186
175
|
* @param emptyDatum A function that returns an empty datum
|
|
187
176
|
* @template D The type of the datum in the data-series
|
|
188
|
-
* @return
|
|
189
|
-
* the
|
|
190
|
-
*
|
|
177
|
+
* @return The point that comes just before the mouse and just after the mouse. If the mouse is
|
|
178
|
+
* after the last point, then the "after" point is the empty datum. If the mouse is before the
|
|
179
|
+
* first point, then the "before" point is the empty datum. (Both are, for an empty series.)
|
|
191
180
|
*/
|
|
192
181
|
export function boundingPoints<D>(data: Series<D>, value: number, xFrom: (value: D) => number, emptyDatum: () => D): [D, D] {
|
|
182
|
+
// an empty series has no bounding points at all -- guard here (not just inside
|
|
183
|
+
// boundingPointsIndex) since this function's own upperIndex<=0/>=data.length fallbacks below
|
|
184
|
+
// also read data[0]/data[data.length-1], which are just as undefined on an empty array
|
|
185
|
+
if (data.length === 0) {
|
|
186
|
+
return [emptyDatum(), emptyDatum()]
|
|
187
|
+
}
|
|
193
188
|
const upperIndex = boundingPointsIndex<D>(data, value, xFrom)
|
|
194
189
|
if (upperIndex <= 0) {
|
|
195
190
|
return [emptyDatum(), data[0]]
|
|
@@ -200,6 +195,19 @@ export function boundingPoints<D>(data: Series<D>, value: number, xFrom: (value:
|
|
|
200
195
|
return [data[upperIndex - 1], data[upperIndex]]
|
|
201
196
|
}
|
|
202
197
|
|
|
198
|
+
/**
|
|
199
|
+
* Finds the first point whose x-value is within the tolerance of the specified value, along with
|
|
200
|
+
* the points before and after it
|
|
201
|
+
* @param data The series' data
|
|
202
|
+
* @param value The x-value to look for
|
|
203
|
+
* @param tolerance How far (in the x-value's units) a point's x-value may be from the value
|
|
204
|
+
* @param xFrom A function that extracts the x-value from the datum
|
|
205
|
+
* @param emptyDatum A function that returns an empty datum (for a point that doesn't exist)
|
|
206
|
+
* @return The point before, the point, the point after, and the point's index (-1 when no point
|
|
207
|
+
* is within the tolerance, in which case the point and the point before are empty, and the point
|
|
208
|
+
* after is the series' first point)
|
|
209
|
+
* @template D The type of the datum in the data-series
|
|
210
|
+
*/
|
|
203
211
|
export function findPointAndNeighbors<D>(
|
|
204
212
|
data: Series<D>,
|
|
205
213
|
value: number,
|
|
@@ -214,3 +222,293 @@ export function findPointAndNeighbors<D>(
|
|
|
214
222
|
const upper = (index < data.length - 1) ? data[index+1] : emptyDatum()
|
|
215
223
|
return [lower, point, upper, index]
|
|
216
224
|
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* The points of a scatter series that a tooltip shows (and the plot highlights), depending on
|
|
228
|
+
* where the mouse is over the series:
|
|
229
|
+
* - directly over a data point: that `point`, along with the points `before` and `after` it
|
|
230
|
+
* - over a line segment between two points: the points `before` and `after` the mouse
|
|
231
|
+
*
|
|
232
|
+
* `before` and `after` are undefined when there's no such point (e.g. before the first point).
|
|
233
|
+
*/
|
|
234
|
+
export type ScatterTooltipPoints =
|
|
235
|
+
| { kind: 'point', before?: Datum, point: Datum, after?: Datum }
|
|
236
|
+
| { kind: 'segment', before?: Datum, after?: Datum }
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* The scatter plot's tooltip metadata: the points the tooltip shows
|
|
240
|
+
*/
|
|
241
|
+
export interface ScatterTooltipMetadata {
|
|
242
|
+
points: ScatterTooltipPoints
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Determines which of a scatter series' points a tooltip shows, from where the mouse is: when the
|
|
247
|
+
* mouse is over a data point, that point (and its neighbors); otherwise the points on either side
|
|
248
|
+
* of the mouse (the segment it's over).
|
|
249
|
+
*
|
|
250
|
+
* The mouse is over a point when it's within `pointRadius` pixels of it -- or, when the point's
|
|
251
|
+
* nearest neighbor is closer than three times that, within a third of the way to that neighbor.
|
|
252
|
+
* Otherwise, with dense data (points a few pixels apart), the mouse would almost always be within
|
|
253
|
+
* the radius of some point, and the segments between them could hardly be hovered at all.
|
|
254
|
+
* @param data The series' data, ordered by x
|
|
255
|
+
* @param mouse The mouse's coordinates, within the plot area (i.e. in the axes' ranges)
|
|
256
|
+
* @param xScale The series' x-axis scale
|
|
257
|
+
* @param yScale The series' y-axis scale
|
|
258
|
+
* @param pointRadius How close (in pixels) the mouse must be to a data point to be over it
|
|
259
|
+
* @return The points the tooltip shows
|
|
260
|
+
*/
|
|
261
|
+
export function scatterTooltipPoints(
|
|
262
|
+
data: { length: number, [index: number]: Datum },
|
|
263
|
+
mouse: [x: number, y: number],
|
|
264
|
+
xScale: ScaleContinuousNumeric<number, number>,
|
|
265
|
+
yScale: ScaleContinuousNumeric<number, number>,
|
|
266
|
+
pointRadius: number
|
|
267
|
+
): ScatterTooltipPoints {
|
|
268
|
+
const [mouseX, mouseY] = mouse
|
|
269
|
+
const pointAt = (index: number): Datum | undefined => index >= 0 && index < data.length ? data[index] : undefined
|
|
270
|
+
// the first point at, or after, the mouse's x-value
|
|
271
|
+
const index = firstIndexAtOrAfter(data, xScale.invert(mouseX), datum => datum.x)
|
|
272
|
+
|
|
273
|
+
// the on-screen distance between two points
|
|
274
|
+
const distanceBetween = (a: Datum, b: Datum): number => Math.hypot(xScale(a.x) - xScale(b.x), yScale(a.y) - yScale(b.y))
|
|
275
|
+
// how close the mouse must be to the point (see above)
|
|
276
|
+
const radiusFor = (candidate: number): number => {
|
|
277
|
+
const neighborDistances = [pointAt(candidate - 1), pointAt(candidate + 1)]
|
|
278
|
+
.filter((neighbor): neighbor is Datum => neighbor !== undefined)
|
|
279
|
+
.map(neighbor => distanceBetween(data[candidate], neighbor))
|
|
280
|
+
return Math.min(pointRadius, ...neighborDistances.map(distance => distance / 3))
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
// the nearest point (on screen) that the mouse is over, among those around the mouse's x-value
|
|
284
|
+
let nearest: number | undefined = undefined
|
|
285
|
+
let nearestDistance = Infinity
|
|
286
|
+
for (let candidate = index - 2; candidate <= index + 1; candidate++) {
|
|
287
|
+
const datum = pointAt(candidate)
|
|
288
|
+
if (datum === undefined) continue
|
|
289
|
+
const distance = Math.hypot(xScale(datum.x) - mouseX, yScale(datum.y) - mouseY)
|
|
290
|
+
if (distance <= radiusFor(candidate) && distance < nearestDistance) {
|
|
291
|
+
nearestDistance = distance
|
|
292
|
+
nearest = candidate
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
if (nearest !== undefined) {
|
|
297
|
+
return {kind: 'point', before: pointAt(nearest - 1), point: data[nearest], after: pointAt(nearest + 1)}
|
|
298
|
+
}
|
|
299
|
+
return {kind: 'segment', before: pointAt(index - 1), after: pointAt(index)}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* The points a scatter tooltip shows, as a list (e.g. for highlighting them)
|
|
304
|
+
* @param points The points the tooltip shows
|
|
305
|
+
* @return The points, in order
|
|
306
|
+
*/
|
|
307
|
+
export function scatterTooltipPointList(points: ScatterTooltipPoints): Array<Datum> {
|
|
308
|
+
const list = points.kind === 'point' ?
|
|
309
|
+
[points.before, points.point, points.after] :
|
|
310
|
+
[points.before, points.after]
|
|
311
|
+
return list.filter((datum): datum is Datum => datum !== undefined)
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* A sparkline: a small line chart of a series' values over time (e.g. for a tooltip), as an SVG
|
|
316
|
+
* path, and where its last point is
|
|
317
|
+
*/
|
|
318
|
+
export interface Sparkline {
|
|
319
|
+
// the SVG path of the line, within the sparkline's width and height
|
|
320
|
+
path: string
|
|
321
|
+
// where the line ends (the latest value)
|
|
322
|
+
end: [x: number, y: number]
|
|
323
|
+
// where the marked point is (see `sparklineFor`'s `markedTime`), when one was asked for, and found
|
|
324
|
+
mark?: [x: number, y: number]
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
/**
|
|
328
|
+
* Creates a sparkline of the specified (time-ordered) values: time runs left to right across the
|
|
329
|
+
* width, and the values are scaled to fill the height (the highest at the top). Values that
|
|
330
|
+
* aren't finite are skipped.
|
|
331
|
+
*
|
|
332
|
+
* A long series is reduced to (at most) four points per pixel column -- the column's first,
|
|
333
|
+
* lowest, highest, and last values, in the order they occurred -- so that the path stays small,
|
|
334
|
+
* while still tracing the line's true shape, spikes included.
|
|
335
|
+
* @param data The values, ordered by time
|
|
336
|
+
* @param width The sparkline's width (in pixels)
|
|
337
|
+
* @param height The sparkline's height (in pixels)
|
|
338
|
+
* @param padding The space (in pixels) to leave around the line, within the width and height
|
|
339
|
+
* @param valueRange The (fixed) range of values the height spans (values outside it are drawn at
|
|
340
|
+
* its edge) -- by default, the range of the values themselves
|
|
341
|
+
* @param markedTime The time of a point to mark (e.g. the hovered point), whose position is
|
|
342
|
+
* returned as the sparkline's `mark` -- by default, none
|
|
343
|
+
* @return The sparkline, or `undefined` when there are fewer than two values to draw
|
|
344
|
+
*/
|
|
345
|
+
export function sparklineFor(
|
|
346
|
+
data: { length: number, [index: number]: { time: number, value: number } },
|
|
347
|
+
width: number,
|
|
348
|
+
height: number,
|
|
349
|
+
padding: number = 2,
|
|
350
|
+
valueRange?: [min: number, max: number],
|
|
351
|
+
markedTime?: number
|
|
352
|
+
): Sparkline | undefined {
|
|
353
|
+
const points: Array<{ time: number, value: number }> = []
|
|
354
|
+
for (let i = 0; i < data.length; i++) {
|
|
355
|
+
if (Number.isFinite(data[i].time) && Number.isFinite(data[i].value)) points.push(data[i])
|
|
356
|
+
}
|
|
357
|
+
if (points.length < 2) return undefined
|
|
358
|
+
|
|
359
|
+
const startTime = points[0].time
|
|
360
|
+
const timeSpan = points[points.length - 1].time - startTime
|
|
361
|
+
let minValue = Infinity
|
|
362
|
+
let maxValue = -Infinity
|
|
363
|
+
if (valueRange !== undefined) {
|
|
364
|
+
[minValue, maxValue] = valueRange
|
|
365
|
+
} else {
|
|
366
|
+
points.forEach(({value}) => {
|
|
367
|
+
minValue = Math.min(minValue, value)
|
|
368
|
+
maxValue = Math.max(maxValue, value)
|
|
369
|
+
})
|
|
370
|
+
}
|
|
371
|
+
const innerWidth = width - 2 * padding
|
|
372
|
+
const innerHeight = height - 2 * padding
|
|
373
|
+
const xOf = (time: number) => padding + (timeSpan > 0 ? (time - startTime) / timeSpan * innerWidth : innerWidth / 2)
|
|
374
|
+
// (a flat line sits in the middle)
|
|
375
|
+
const yOf = (value: number) => padding + (maxValue > minValue ?
|
|
376
|
+
(maxValue - Math.min(maxValue, Math.max(minValue, value))) / (maxValue - minValue) * innerHeight :
|
|
377
|
+
innerHeight / 2)
|
|
378
|
+
|
|
379
|
+
// each pixel column's first, lowest, highest, and last values, in the order they occurred
|
|
380
|
+
const reduced: Array<{ time: number, value: number }> = []
|
|
381
|
+
let column: Array<{ index: number, point: { time: number, value: number } }> = []
|
|
382
|
+
let columnX = Math.floor(xOf(points[0].time))
|
|
383
|
+
const flushColumn = () => {
|
|
384
|
+
if (column.length === 0) return
|
|
385
|
+
const lowest = column.reduce((low, entry) => entry.point.value < low.point.value ? entry : low)
|
|
386
|
+
const highest = column.reduce((high, entry) => entry.point.value > high.point.value ? entry : high)
|
|
387
|
+
const kept = new Map([column[0], lowest, highest, column[column.length - 1]].map(entry => [entry.index, entry.point]))
|
|
388
|
+
Array.from(kept.entries()).sort(([a], [b]) => a - b).forEach(([, point]) => reduced.push(point))
|
|
389
|
+
column = []
|
|
390
|
+
}
|
|
391
|
+
points.forEach((point, index) => {
|
|
392
|
+
const x = Math.floor(xOf(point.time))
|
|
393
|
+
if (x !== columnX) {
|
|
394
|
+
flushColumn()
|
|
395
|
+
columnX = x
|
|
396
|
+
}
|
|
397
|
+
column.push({index, point})
|
|
398
|
+
})
|
|
399
|
+
flushColumn()
|
|
400
|
+
|
|
401
|
+
const coordinates = reduced.map(({time, value}) => [xOf(time), yOf(value)] as [number, number])
|
|
402
|
+
const round = (value: number) => Math.round(value * 100) / 100
|
|
403
|
+
const marked = markedTime === undefined ? undefined : points.find(point => point.time === markedTime)
|
|
404
|
+
return {
|
|
405
|
+
path: coordinates.map(([x, y], index) => `${index === 0 ? 'M' : 'L'}${round(x)},${round(y)}`).join(' '),
|
|
406
|
+
end: coordinates[coordinates.length - 1],
|
|
407
|
+
...(marked !== undefined ? {mark: [xOf(marked.time), yOf(marked.value)] as [number, number]} : {}),
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
/**
|
|
412
|
+
* The raster plot's tooltip metadata: all of the hovered series' spikes that the chart holds (the
|
|
413
|
+
* tooltip data's `series` holds just the hovered spike)
|
|
414
|
+
*/
|
|
415
|
+
export interface RasterTooltipMetadata {
|
|
416
|
+
spikes: Series<Datum>
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
/**
|
|
420
|
+
* Statistics of a series' (time, value) points -- e.g. a raster chart's spikes, or a scatter
|
|
421
|
+
* chart's points -- over the window of data that the chart holds. Those that need at least two
|
|
422
|
+
* points are undefined when there's only one.
|
|
423
|
+
*/
|
|
424
|
+
export interface SeriesStatistics {
|
|
425
|
+
// the number of points
|
|
426
|
+
count: number
|
|
427
|
+
// the mean of the points' values
|
|
428
|
+
meanValue: number | undefined
|
|
429
|
+
// the (sample) standard deviation of the points' values
|
|
430
|
+
valueStandardDeviation: number | undefined
|
|
431
|
+
// the mean time between consecutive points
|
|
432
|
+
meanInterval: number | undefined
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
/**
|
|
436
|
+
* Calculates the statistics of a series' (time, value) points: their count, the mean and the
|
|
437
|
+
* (sample) standard deviation of their values, and the mean time between consecutive points.
|
|
438
|
+
* Points whose value or time isn't finite are skipped.
|
|
439
|
+
* @param spikes The points (e.g. spikes), ordered by time
|
|
440
|
+
* @return The statistics
|
|
441
|
+
*/
|
|
442
|
+
export function seriesStatistics(spikes: { length: number, [index: number]: Datum }): SeriesStatistics {
|
|
443
|
+
const valid: Array<Datum> = []
|
|
444
|
+
for (let i = 0; i < spikes.length; i++) {
|
|
445
|
+
if (Number.isFinite(spikes[i].x) && Number.isFinite(spikes[i].y)) valid.push(spikes[i])
|
|
446
|
+
}
|
|
447
|
+
const count = valid.length
|
|
448
|
+
if (count === 0) return {count, meanValue: undefined, valueStandardDeviation: undefined, meanInterval: undefined}
|
|
449
|
+
|
|
450
|
+
const meanValue = valid.reduce((sum, spike) => sum + spike.y, 0) / count
|
|
451
|
+
if (count < 2) return {count, meanValue, valueStandardDeviation: undefined, meanInterval: undefined}
|
|
452
|
+
|
|
453
|
+
const sumOfSquares = valid.reduce((sum, spike) => sum + (spike.y - meanValue) ** 2, 0)
|
|
454
|
+
return {
|
|
455
|
+
count,
|
|
456
|
+
meanValue,
|
|
457
|
+
valueStandardDeviation: Math.sqrt(sumOfSquares / (count - 1)),
|
|
458
|
+
// the intervals between consecutive spikes sum to the span from the first to the last
|
|
459
|
+
meanInterval: (valid[count - 1].x - valid[0].x) / (count - 1),
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
/**
|
|
464
|
+
* Formats a value, or shows a dash when there isn't one (e.g. the standard deviation of a single
|
|
465
|
+
* point)
|
|
466
|
+
* @param value The value, if there is one
|
|
467
|
+
* @param formatter Formats the value
|
|
468
|
+
* @return The formatted value, or a dash
|
|
469
|
+
*/
|
|
470
|
+
export function valueOrMissing(value: number | undefined, formatter: (value: number) => string): string {
|
|
471
|
+
return value === undefined ? '–' : formatter(value)
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
// the largest lag (in points) for which the autocorrelation is calculated by default
|
|
475
|
+
const MAX_AUTOCORRELATION_LAG = 50
|
|
476
|
+
|
|
477
|
+
/**
|
|
478
|
+
* Calculates the (sample) autocorrelation of a series' values, by lag: for each lag `k` (in
|
|
479
|
+
* points, not time -- a series' points needn't be evenly spaced in time), the correlation between
|
|
480
|
+
* the values and the values `k` points later,
|
|
481
|
+
* <p>`r[k] = sum[t](x[t] - mean) * (x[t+k] - mean) / sum[t](x[t] - mean)^2`</p>
|
|
482
|
+
* so `r[0]` is 1, and the values are between -1 and 1. Points whose value or time isn't finite are
|
|
483
|
+
* skipped.
|
|
484
|
+
* @param points The series' points, ordered by time
|
|
485
|
+
* @param maxLag The largest lag -- by default, a quarter of the number of points (the usual rule
|
|
486
|
+
* of thumb, since the estimates for larger lags rest on too few pairs of points), but no more than 50
|
|
487
|
+
* @return The autocorrelation for each lag, from 0 to the largest lag, or `undefined` when there
|
|
488
|
+
* are fewer than four points (so no lag beyond 0), or the values don't vary
|
|
489
|
+
*/
|
|
490
|
+
export function autocorrelation(
|
|
491
|
+
points: { length: number, [index: number]: Datum },
|
|
492
|
+
maxLag?: number
|
|
493
|
+
): Array<number> | undefined {
|
|
494
|
+
const values: Array<number> = []
|
|
495
|
+
for (let i = 0; i < points.length; i++) {
|
|
496
|
+
if (Number.isFinite(points[i].x) && Number.isFinite(points[i].y)) values.push(points[i].y)
|
|
497
|
+
}
|
|
498
|
+
const count = values.length
|
|
499
|
+
const largestLag = Math.min(count - 1, maxLag ?? Math.min(MAX_AUTOCORRELATION_LAG, Math.floor(count / 4)))
|
|
500
|
+
if (largestLag < 1) return undefined
|
|
501
|
+
|
|
502
|
+
const mean = values.reduce((sum, value) => sum + value, 0) / count
|
|
503
|
+
const deviations = values.map(value => value - mean)
|
|
504
|
+
const variance = deviations.reduce((sum, deviation) => sum + deviation * deviation, 0)
|
|
505
|
+
if (variance === 0) return undefined
|
|
506
|
+
|
|
507
|
+
const correlations: Array<number> = []
|
|
508
|
+
for (let lag = 0; lag <= largestLag; lag++) {
|
|
509
|
+
let sum = 0
|
|
510
|
+
for (let t = 0; t + lag < count; t++) sum += deviations[t] * deviations[t + lag]
|
|
511
|
+
correlations.push(sum / variance)
|
|
512
|
+
}
|
|
513
|
+
return correlations
|
|
514
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import {type JSX, createContext, useContext} from "react"
|
|
2
|
+
import type {OutlierBandTooltipMetadata} from "../plots/OutlierPlot"
|
|
3
|
+
import type {TooltipStyle} from "./tooltipUtils"
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* What the outlier tooltip shows: the name of the series, and the band (and, for an outlier, the
|
|
7
|
+
* datum) under the mouse
|
|
8
|
+
*/
|
|
9
|
+
export type OutlierTooltipData<M extends readonly number[] = readonly number[]> =
|
|
10
|
+
{seriesName: string} & OutlierBandTooltipMetadata<M>
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* The (optional) formatters for the outlier tooltip's content
|
|
14
|
+
*/
|
|
15
|
+
export type OutlierTooltipContentFormatters = {
|
|
16
|
+
/**
|
|
17
|
+
* Formatter for the datum
|
|
18
|
+
* @param x X-coordinate of the datum
|
|
19
|
+
* @param y Y-coordinate of the datum
|
|
20
|
+
* @return a human-readable description of the datum
|
|
21
|
+
*/
|
|
22
|
+
datumFormatter?: (x: number, y: number) => string | JSX.Element
|
|
23
|
+
/**
|
|
24
|
+
* Formatter for the band (it's handed the band's measures, not its bounds)
|
|
25
|
+
* @param lower The measure of the band's inner edge (the measure of the next tighter band, or
|
|
26
|
+
* 0 for the tightest band)
|
|
27
|
+
* @param upper The measure of the band's outer edge (the hovered band's own measure)
|
|
28
|
+
* @return a human-readable description of the band
|
|
29
|
+
*/
|
|
30
|
+
bandFormatter?: (lower: number, upper: number) => string | JSX.Element
|
|
31
|
+
/**
|
|
32
|
+
* Formatter for the description of the band's measure: the probabilities of a point being in,
|
|
33
|
+
* and outside, the band
|
|
34
|
+
* @param innerProb Probability of points being within this band
|
|
35
|
+
* @param outerProb Probability of points being outside this band
|
|
36
|
+
* @return a human-readable description of the band: text, JSX, or an array of lines (shown
|
|
37
|
+
* one per line)
|
|
38
|
+
*/
|
|
39
|
+
measureFormatter?: (innerProb: number, outerProb: number) => string | JSX.Element | Array<string>
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* The outlier tooltip's context: what it shows, its style, and its formatters (the
|
|
44
|
+
* `measureFormatter`'s lines, when it returns an array of them, already laid out one per line)
|
|
45
|
+
*/
|
|
46
|
+
export type OutlierTooltipContextValue = {
|
|
47
|
+
tooltipContent: OutlierTooltipData
|
|
48
|
+
tooltipStyle: TooltipStyle
|
|
49
|
+
datumFormatter: (x: number, y: number) => string | JSX.Element
|
|
50
|
+
bandFormatter: (lower: number, upper: number) => string | JSX.Element
|
|
51
|
+
measureFormatter: (innerProb: number, outerProb: number) => string | JSX.Element
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export const UseOutlierTooltip = createContext<OutlierTooltipContextValue | null>(null)
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Hook for consuming the outlier tooltip context inside a child of
|
|
58
|
+
* {@link OutlierPlotTooltipContent} (for writing your own content for the outlier tooltip)
|
|
59
|
+
* @return What the tooltip shows, its style, and its formatters
|
|
60
|
+
* @throws Error when used outside an `<OutlierPlotTooltipContent>`
|
|
61
|
+
*/
|
|
62
|
+
export function useOutlierTooltip(): OutlierTooltipContextValue {
|
|
63
|
+
const context = useContext(UseOutlierTooltip)
|
|
64
|
+
if (context === null) {
|
|
65
|
+
throw new Error('useOutlierTooltip must be used inside OutlierPlotTooltipContent')
|
|
66
|
+
}
|
|
67
|
+
return context
|
|
68
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import {type RefObject, useLayoutEffect} from "react";
|
|
2
|
+
import type {Dimensions, Margin} from "../styling/margins";
|
|
3
|
+
import {type TooltipStyle, tooltipX, tooltipY} from "./tooltipUtils";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Where a tooltip is anchored: the mouse, when the tooltip's content was captured
|
|
7
|
+
*/
|
|
8
|
+
export type TooltipAnchor = {
|
|
9
|
+
/**
|
|
10
|
+
* The mouse's coordinates, relative to the chart (its canvas)
|
|
11
|
+
*/
|
|
12
|
+
mouse: [x: number, y: number]
|
|
13
|
+
/**
|
|
14
|
+
* The chart's (canvas') position in the viewport, when the content was captured
|
|
15
|
+
*/
|
|
16
|
+
canvasLeft: number
|
|
17
|
+
canvasTop: number
|
|
18
|
+
/**
|
|
19
|
+
* Optional: the y-coordinate (relative to the chart) of the tooltip's top, given its rendered
|
|
20
|
+
* height, for a tooltip that isn't placed below the mouse (e.g. one centered on a raster
|
|
21
|
+
* plot's category). Defaults to `tooltipY`.
|
|
22
|
+
*/
|
|
23
|
+
topFor?: (height: number) => number
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Positions a tooltip (a `position: fixed` element, e.g. a tooltip content's portal) next to the
|
|
28
|
+
* mouse, based on its *rendered* size: after each render, measures the tooltip and sets its
|
|
29
|
+
* `left` and `top` directly, before the browser paints (so the tooltip never shows in the wrong
|
|
30
|
+
* place). The tooltip goes to the right of the mouse, or to the left when it would run past the
|
|
31
|
+
* plot's right edge (see `tooltipX` and `tooltipY`).
|
|
32
|
+
*
|
|
33
|
+
* A tooltip's size depends on its content, so it can only be known once the content has been
|
|
34
|
+
* rendered -- positioning it from an estimate of its size put a narrower-than-estimated tooltip
|
|
35
|
+
* far from the mouse when it flipped to the mouse's left.
|
|
36
|
+
* @param tooltipRef The tooltip's element
|
|
37
|
+
* @param anchor Where the tooltip is anchored (the mouse), or `null` when no tooltip is shown
|
|
38
|
+
* @param plotDimensions The dimensions of the plot
|
|
39
|
+
* @param margin The plot margin
|
|
40
|
+
* @param tooltipStyle The tooltip's style
|
|
41
|
+
*/
|
|
42
|
+
export function useTooltipPlacement(
|
|
43
|
+
tooltipRef: RefObject<HTMLElement | null>,
|
|
44
|
+
anchor: TooltipAnchor | null,
|
|
45
|
+
plotDimensions: Dimensions,
|
|
46
|
+
margin: Margin,
|
|
47
|
+
tooltipStyle: TooltipStyle,
|
|
48
|
+
): void {
|
|
49
|
+
useLayoutEffect(
|
|
50
|
+
() => {
|
|
51
|
+
const tooltip = tooltipRef.current
|
|
52
|
+
if (tooltip === null || anchor === null) return
|
|
53
|
+
// measured at the viewport's top-left corner, where nothing limits its width: a
|
|
54
|
+
// `position: fixed` element near the viewport's right edge only gets the width left to
|
|
55
|
+
// the edge, so its content could wrap, and it would measure narrower than it really is
|
|
56
|
+
tooltip.style.left = '0px'
|
|
57
|
+
tooltip.style.top = '0px'
|
|
58
|
+
const {width, height} = tooltip.getBoundingClientRect()
|
|
59
|
+
const [x, y] = anchor.mouse
|
|
60
|
+
const left = tooltipX(x, width, plotDimensions, tooltipStyle, margin)
|
|
61
|
+
const top = anchor.topFor !== undefined ?
|
|
62
|
+
anchor.topFor(height) :
|
|
63
|
+
tooltipY(y, height, plotDimensions, tooltipStyle, margin)
|
|
64
|
+
tooltip.style.left = `${anchor.canvasLeft + left}px`
|
|
65
|
+
tooltip.style.top = `${anchor.canvasTop + top}px`
|
|
66
|
+
}
|
|
67
|
+
)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Creates a tooltip's anchor: the mouse, relative to the chart, and the chart's position in the
|
|
72
|
+
* viewport
|
|
73
|
+
* @param mouseCoords The mouse's coordinates, relative to the chart (its canvas)
|
|
74
|
+
* @param canvas The chart's canvas
|
|
75
|
+
* @param topFor Optional: the y-coordinate of the tooltip's top for its rendered height (see
|
|
76
|
+
* {@link TooltipAnchor.topFor})
|
|
77
|
+
* @return The anchor
|
|
78
|
+
*/
|
|
79
|
+
export function tooltipAnchorFor(
|
|
80
|
+
mouseCoords: [x: number, y: number],
|
|
81
|
+
canvas: HTMLCanvasElement,
|
|
82
|
+
topFor?: (height: number) => number
|
|
83
|
+
): TooltipAnchor {
|
|
84
|
+
const canvasRect = canvas.getBoundingClientRect()
|
|
85
|
+
return {mouse: mouseCoords, canvasLeft: canvasRect.left, canvasTop: canvasRect.top, topFor}
|
|
86
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import {createContext, useContext} from "react";
|
|
2
|
+
import {defaultTooltipStyle, type TooltipStyle} from "./tooltipUtils";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* The style of the enclosing {@link Tooltip} (its `style`, over the default tooltip style)
|
|
6
|
+
*/
|
|
7
|
+
export const TooltipStyleContext = createContext<TooltipStyle>(defaultTooltipStyle)
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @return The style of the enclosing {@link Tooltip}: its `style` property over the default tooltip
|
|
11
|
+
* style (or just the default style, outside a tooltip)
|
|
12
|
+
*/
|
|
13
|
+
export function useTooltipStyle(): TooltipStyle {
|
|
14
|
+
return useContext(TooltipStyleContext)
|
|
15
|
+
}
|