stream-charts 1.0.1 → 1.1.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/README.md +756 -343
- package/changes.md +7 -0
- package/dist/src/app/charts/Chart.d.ts +116 -87
- package/dist/src/app/charts/Chart.js +96 -101
- package/dist/src/app/charts/Chart.js.map +1 -1
- package/dist/src/app/charts/axes/AxesState.d.ts +64 -0
- package/dist/src/app/charts/axes/AxesState.js +97 -0
- package/dist/src/app/charts/axes/AxesState.js.map +1 -0
- package/dist/src/app/charts/axes/AxesState.test.js +30 -0
- package/dist/src/app/charts/axes/AxesState.test.js.map +1 -0
- package/dist/src/app/charts/axes/AxisInterval.d.ts +92 -0
- package/dist/src/app/charts/axes/AxisInterval.js +126 -0
- package/dist/src/app/charts/axes/AxisInterval.js.map +1 -0
- package/dist/src/app/charts/axes/AxisInterval.test.js +120 -0
- package/dist/src/app/charts/axes/AxisInterval.test.js.map +1 -0
- package/dist/src/app/charts/axes/BaseAxisRange.d.ts +83 -0
- package/dist/src/app/charts/axes/BaseAxisRange.js +58 -0
- package/dist/src/app/charts/axes/BaseAxisRange.js.map +1 -0
- package/dist/src/app/charts/axes/ContinuousAxis.d.ts +22 -0
- package/dist/src/app/charts/axes/ContinuousAxis.js +96 -0
- package/dist/src/app/charts/axes/ContinuousAxis.js.map +1 -0
- package/dist/src/app/charts/axes/ContinuousAxisRange.d.ts +59 -0
- package/dist/src/app/charts/axes/ContinuousAxisRange.js +84 -0
- package/dist/src/app/charts/axes/ContinuousAxisRange.js.map +1 -0
- package/dist/src/app/charts/axes/ContinuousAxisRange.test.js +47 -0
- package/dist/src/app/charts/axes/ContinuousAxisRange.test.js.map +1 -0
- package/dist/src/app/charts/axes/OrdinalAxis.d.ts +23 -0
- package/dist/src/app/charts/axes/OrdinalAxis.js +124 -0
- package/dist/src/app/charts/axes/OrdinalAxis.js.map +1 -0
- package/dist/src/app/charts/axes/OrdinalAxisRange.d.ts +69 -0
- package/dist/src/app/charts/axes/OrdinalAxisRange.js +100 -0
- package/dist/src/app/charts/axes/OrdinalAxisRange.js.map +1 -0
- package/dist/src/app/charts/axes/OrdinalAxisRange.test.js +48 -0
- package/dist/src/app/charts/axes/OrdinalAxisRange.test.js.map +1 -0
- package/dist/src/app/charts/axes/axes.d.ts +391 -0
- package/dist/src/app/charts/axes/axes.js +1046 -0
- package/dist/src/app/charts/axes/axes.js.map +1 -0
- package/dist/src/app/charts/d3types.d.ts +10 -10
- package/dist/src/app/charts/filters/regexFilter.d.ts +9 -0
- package/dist/src/app/charts/filters/regexFilter.js +18 -0
- package/dist/src/app/charts/filters/regexFilter.js.map +1 -0
- package/dist/src/app/charts/filters/regexFilter.test.d.ts +1 -0
- package/dist/src/app/charts/filters/regexFilter.test.js +11 -0
- package/dist/src/app/charts/filters/regexFilter.test.js.map +1 -0
- package/dist/src/app/charts/hooks/useAxes.d.ts +144 -0
- package/dist/src/app/charts/hooks/useAxes.js +187 -0
- package/dist/src/app/charts/hooks/useAxes.js.map +1 -0
- package/dist/src/app/charts/hooks/useChart.d.ts +30 -201
- package/dist/src/app/charts/hooks/useChart.js +33 -134
- package/dist/src/app/charts/hooks/useChart.js.map +1 -1
- package/dist/src/app/charts/hooks/useDataObservable.d.ts +74 -0
- package/dist/src/app/charts/hooks/useDataObservable.js +76 -0
- package/dist/src/app/charts/hooks/useDataObservable.js.map +1 -0
- package/dist/src/app/charts/hooks/useInitialData.d.ts +38 -0
- package/dist/src/app/charts/hooks/useInitialData.js +29 -0
- package/dist/src/app/charts/hooks/useInitialData.js.map +1 -0
- package/dist/src/app/charts/hooks/useMouse.d.ts +53 -0
- package/dist/src/app/charts/hooks/useMouse.js +65 -0
- package/dist/src/app/charts/hooks/useMouse.js.map +1 -0
- package/dist/src/app/charts/hooks/usePlotDimensions.d.ts +34 -0
- package/dist/src/app/charts/hooks/usePlotDimensions.js +73 -0
- package/dist/src/app/charts/hooks/usePlotDimensions.js.map +1 -0
- package/dist/src/app/charts/hooks/useTooltip.d.ts +64 -0
- package/dist/src/app/charts/hooks/useTooltip.js +52 -0
- package/dist/src/app/charts/hooks/useTooltip.js.map +1 -0
- package/dist/src/app/charts/observables/ChartData.d.ts +23 -0
- package/dist/src/app/charts/observables/ChartData.js +20 -0
- package/dist/src/app/charts/observables/ChartData.js.map +1 -0
- package/dist/src/app/charts/observables/iterates.d.ts +52 -0
- package/dist/src/app/charts/observables/iterates.js +121 -0
- package/dist/src/app/charts/observables/iterates.js.map +1 -0
- package/dist/src/app/charts/observables/iterates.test.d.ts +1 -0
- package/dist/src/app/charts/observables/iterates.test.js +180 -0
- package/dist/src/app/charts/observables/iterates.test.js.map +1 -0
- package/dist/src/app/charts/observables/ordinals.d.ts +75 -0
- package/dist/src/app/charts/observables/ordinals.js +141 -0
- package/dist/src/app/charts/observables/ordinals.js.map +1 -0
- package/dist/src/app/charts/observables/ordinals.test.d.ts +1 -0
- package/dist/src/app/charts/observables/ordinals.test.js +102 -0
- package/dist/src/app/charts/observables/ordinals.test.js.map +1 -0
- package/dist/src/app/charts/plots/BarPlot.d.ts +81 -0
- package/dist/src/app/charts/plots/BarPlot.js +557 -0
- package/dist/src/app/charts/plots/BarPlot.js.map +1 -0
- package/dist/src/app/charts/plots/PoincarePlot.d.ts +78 -0
- package/dist/src/app/charts/plots/PoincarePlot.js +504 -0
- package/dist/src/app/charts/plots/PoincarePlot.js.map +1 -0
- package/dist/src/app/charts/{RasterPlot.d.ts → plots/RasterPlot.d.ts} +1 -1
- package/dist/src/app/charts/{RasterPlot.js → plots/RasterPlot.js} +152 -133
- package/dist/src/app/charts/plots/RasterPlot.js.map +1 -0
- package/dist/src/app/charts/{ScatterPlot.d.ts → plots/ScatterPlot.d.ts} +10 -8
- package/dist/src/app/charts/plots/ScatterPlot.js +379 -0
- package/dist/src/app/charts/plots/ScatterPlot.js.map +1 -0
- package/dist/src/app/charts/{plot.d.ts → plots/plot.d.ts} +12 -14
- package/dist/src/app/charts/{plot.js → plots/plot.js} +19 -17
- package/dist/src/app/charts/plots/plot.js.map +1 -0
- package/dist/src/app/charts/series/baseSeries.d.ts +38 -0
- package/dist/src/app/charts/series/baseSeries.js +36 -0
- package/dist/src/app/charts/series/baseSeries.js.map +1 -0
- package/dist/src/app/charts/series/datumSeries.test.d.ts +1 -0
- package/dist/src/app/charts/series/datumSeries.test.js +50 -0
- package/dist/src/app/charts/series/datumSeries.test.js.map +1 -0
- package/dist/src/app/charts/series/iterateSeries.d.ts +42 -0
- package/dist/src/app/charts/series/iterateSeries.js +34 -0
- package/dist/src/app/charts/series/iterateSeries.js.map +1 -0
- package/dist/src/app/charts/series/ordinalSeries.d.ts +54 -0
- package/dist/src/app/charts/series/ordinalSeries.js +98 -0
- package/dist/src/app/charts/series/ordinalSeries.js.map +1 -0
- package/dist/src/app/charts/series/timeSeries.d.ts +30 -0
- package/dist/src/app/charts/series/timeSeries.js +19 -0
- package/dist/src/app/charts/series/timeSeries.js.map +1 -0
- package/dist/src/app/charts/{chartData.d.ts → series/timeSeriesChartData.d.ts} +11 -6
- package/dist/src/app/charts/series/timeSeriesChartData.js +32 -0
- package/dist/src/app/charts/series/timeSeriesChartData.js.map +1 -0
- package/dist/src/app/charts/styling/barPlotStyle.d.ts +41 -0
- package/dist/src/app/charts/styling/barPlotStyle.js +84 -0
- package/dist/src/app/charts/styling/barPlotStyle.js.map +1 -0
- package/dist/src/app/charts/{margins.d.ts → styling/margins.d.ts} +7 -5
- package/dist/src/app/charts/{margins.js → styling/margins.js} +19 -9
- package/dist/src/app/charts/styling/margins.js.map +1 -0
- package/dist/src/app/charts/styling/margins.test.d.ts +1 -0
- package/dist/src/app/charts/styling/margins.test.js +19 -0
- package/dist/src/app/charts/styling/margins.test.js.map +1 -0
- package/dist/src/app/charts/styling/svgStyle.d.ts +76 -0
- package/dist/src/app/charts/styling/svgStyle.js +84 -0
- package/dist/src/app/charts/styling/svgStyle.js.map +1 -0
- package/dist/src/app/charts/subscriptions/subscription.test.d.ts +1 -0
- package/dist/src/app/charts/subscriptions/subscription.test.js +395 -0
- package/dist/src/app/charts/subscriptions/subscription.test.js.map +1 -0
- package/dist/src/app/charts/subscriptions/subscriptions.d.ts +100 -0
- package/dist/src/app/charts/subscriptions/subscriptions.js +449 -0
- package/dist/src/app/charts/subscriptions/subscriptions.js.map +1 -0
- package/dist/src/app/charts/tooltips/BarPlotTooltipContent.d.ts +90 -0
- package/dist/src/app/charts/tooltips/BarPlotTooltipContent.js +302 -0
- package/dist/src/app/charts/tooltips/BarPlotTooltipContent.js.map +1 -0
- package/dist/src/app/charts/tooltips/PoincarePlotTooltipContent.d.ts +100 -0
- package/dist/src/app/charts/tooltips/PoincarePlotTooltipContent.js +190 -0
- package/dist/src/app/charts/tooltips/PoincarePlotTooltipContent.js.map +1 -0
- package/dist/src/app/charts/{RasterPlotTooltipContent.js → tooltips/RasterPlotTooltipContent.js} +40 -44
- package/dist/src/app/charts/tooltips/RasterPlotTooltipContent.js.map +1 -0
- package/dist/src/app/charts/tooltips/ScatterPlotTooltipContent.js +154 -0
- package/dist/src/app/charts/tooltips/ScatterPlotTooltipContent.js.map +1 -0
- package/dist/src/app/charts/{Tooltip.d.ts → tooltips/Tooltip.d.ts} +4 -2
- package/dist/src/app/charts/{Tooltip.js → tooltips/Tooltip.js} +23 -28
- package/dist/src/app/charts/tooltips/Tooltip.js.map +1 -0
- package/dist/src/app/charts/{tooltipUtils.d.ts → tooltips/tooltipUtils.d.ts} +11 -6
- package/dist/src/app/charts/{tooltipUtils.js → tooltips/tooltipUtils.js} +33 -17
- package/dist/src/app/charts/tooltips/tooltipUtils.js.map +1 -0
- package/dist/src/app/charts/{Tracker.d.ts → trackers/Tracker.d.ts} +6 -5
- package/dist/src/app/charts/trackers/Tracker.js +60 -0
- package/dist/src/app/charts/trackers/Tracker.js.map +1 -0
- package/dist/src/app/charts/{trackerUtils.d.ts → trackers/trackerUtils.d.ts} +13 -8
- package/dist/src/app/charts/trackers/trackerUtils.js +359 -0
- package/dist/src/app/charts/trackers/trackerUtils.js.map +1 -0
- package/dist/src/app/charts/utils.d.ts +22 -32
- package/dist/src/app/charts/utils.js +36 -37
- package/dist/src/app/charts/utils.js.map +1 -1
- package/dist/src/index.d.ts +48 -15
- package/dist/src/index.js +71 -15
- package/dist/src/index.js.map +1 -1
- package/package.json +30 -20
- package/src/app/charts/Chart.tsx +334 -0
- package/src/app/charts/axes/AxesState.test.ts +34 -0
- package/src/app/charts/axes/AxesState.ts +112 -0
- package/src/app/charts/axes/AxisInterval.test.ts +143 -0
- package/src/app/charts/axes/AxisInterval.ts +139 -0
- package/src/app/charts/axes/BaseAxisRange.ts +113 -0
- package/src/app/charts/axes/ContinuousAxis.tsx +192 -0
- package/src/app/charts/axes/ContinuousAxisRange.test.ts +55 -0
- package/src/app/charts/axes/ContinuousAxisRange.ts +96 -0
- package/src/app/charts/axes/OrdinalAxis.tsx +223 -0
- package/src/app/charts/axes/OrdinalAxisRange.test.ts +55 -0
- package/src/app/charts/axes/OrdinalAxisRange.ts +112 -0
- package/src/app/charts/axes/axes.ts +1569 -0
- package/src/app/charts/d3types.ts +16 -0
- package/src/app/charts/filters/regexFilter.test.ts +13 -0
- package/src/app/charts/filters/regexFilter.ts +17 -0
- package/src/app/charts/hooks/useAxes.tsx +341 -0
- package/src/app/charts/hooks/useChart.tsx +159 -0
- package/src/app/charts/hooks/useDataObservable.tsx +175 -0
- package/src/app/charts/hooks/useInitialData.tsx +65 -0
- package/src/app/charts/hooks/useMouse.tsx +125 -0
- package/src/app/charts/hooks/usePlotDimensions.tsx +120 -0
- package/src/app/charts/hooks/useTooltip.tsx +112 -0
- package/src/app/charts/observables/ChartData.ts +31 -0
- package/src/app/charts/observables/iterates.test.ts +201 -0
- package/src/app/charts/observables/iterates.ts +203 -0
- package/src/app/charts/observables/ordinals.test.ts +135 -0
- package/src/app/charts/observables/ordinals.ts +248 -0
- package/src/app/charts/plots/BarPlot.tsx +1088 -0
- package/src/app/charts/plots/PoincarePlot.tsx +832 -0
- package/src/app/charts/plots/RasterPlot.tsx +676 -0
- package/src/app/charts/plots/ScatterPlot.tsx +653 -0
- package/src/app/charts/plots/plot.ts +75 -0
- package/src/app/charts/series/baseSeries.ts +52 -0
- package/src/app/charts/series/datumSeries.test.ts +60 -0
- package/src/app/charts/series/iterateSeries.ts +56 -0
- package/src/app/charts/series/ordinalSeries.ts +164 -0
- package/src/app/charts/series/timeSeries.ts +40 -0
- package/src/app/charts/series/timeSeriesChartData.ts +68 -0
- package/src/app/charts/styling/barPlotStyle.ts +126 -0
- package/src/app/charts/styling/margins.test.ts +22 -0
- package/src/app/charts/styling/margins.ts +58 -0
- package/src/app/charts/styling/svgStyle.ts +118 -0
- package/src/app/charts/subscriptions/subscription.test.ts +499 -0
- package/src/app/charts/subscriptions/subscriptions.ts +635 -0
- package/src/app/charts/tooltips/BarPlotTooltipContent.tsx +440 -0
- package/src/app/charts/tooltips/PoincarePlotTooltipContent.tsx +352 -0
- package/src/app/charts/tooltips/RasterPlotTooltipContent.tsx +274 -0
- package/src/app/charts/tooltips/ScatterPlotTooltipContent.tsx +319 -0
- package/src/app/charts/tooltips/Tooltip.tsx +148 -0
- package/src/app/charts/tooltips/tooltipUtils.ts +216 -0
- package/src/app/charts/trackers/Tracker.tsx +129 -0
- package/src/app/charts/trackers/trackerUtils.ts +494 -0
- package/src/app/charts/utils.ts +109 -0
- package/dist/src/app/charts/CategoryAxis.d.ts +0 -20
- package/dist/src/app/charts/CategoryAxis.js +0 -112
- package/dist/src/app/charts/CategoryAxis.js.map +0 -1
- package/dist/src/app/charts/ContinuousAxis.d.ts +0 -16
- package/dist/src/app/charts/ContinuousAxis.js +0 -186
- package/dist/src/app/charts/ContinuousAxis.js.map +0 -1
- package/dist/src/app/charts/RasterPlot.js.map +0 -1
- package/dist/src/app/charts/RasterPlotTooltipContent.js.map +0 -1
- package/dist/src/app/charts/ScatterPlot.js +0 -351
- package/dist/src/app/charts/ScatterPlot.js.map +0 -1
- package/dist/src/app/charts/ScatterPlotTooltipContent.js +0 -163
- package/dist/src/app/charts/ScatterPlotTooltipContent.js.map +0 -1
- package/dist/src/app/charts/Tooltip.js.map +0 -1
- package/dist/src/app/charts/Tracker.js +0 -65
- package/dist/src/app/charts/Tracker.js.map +0 -1
- package/dist/src/app/charts/axes.d.ts +0 -132
- package/dist/src/app/charts/axes.js +0 -265
- package/dist/src/app/charts/axes.js.map +0 -1
- package/dist/src/app/charts/chartData.js +0 -32
- package/dist/src/app/charts/chartData.js.map +0 -1
- package/dist/src/app/charts/continuousAxisRangeFor.d.ts +0 -20
- package/dist/src/app/charts/continuousAxisRangeFor.js +0 -68
- package/dist/src/app/charts/continuousAxisRangeFor.js.map +0 -1
- package/dist/src/app/charts/datumSeries.d.ts +0 -59
- package/dist/src/app/charts/datumSeries.js +0 -55
- package/dist/src/app/charts/datumSeries.js.map +0 -1
- package/dist/src/app/charts/datumSeries.test.js +0 -50
- package/dist/src/app/charts/datumSeries.test.js.map +0 -1
- package/dist/src/app/charts/hooks/AxesState.d.ts +0 -37
- package/dist/src/app/charts/hooks/AxesState.js +0 -44
- package/dist/src/app/charts/hooks/AxesState.js.map +0 -1
- package/dist/src/app/charts/margins.js.map +0 -1
- package/dist/src/app/charts/margins.test.js +0 -14
- package/dist/src/app/charts/margins.test.js.map +0 -1
- package/dist/src/app/charts/plot.js.map +0 -1
- package/dist/src/app/charts/regexFilter.d.ts +0 -9
- package/dist/src/app/charts/regexFilter.js +0 -17
- package/dist/src/app/charts/regexFilter.js.map +0 -1
- package/dist/src/app/charts/regexFilter.test.js +0 -11
- package/dist/src/app/charts/regexFilter.test.js.map +0 -1
- package/dist/src/app/charts/subscriptions.d.ts +0 -43
- package/dist/src/app/charts/subscriptions.js +0 -213
- package/dist/src/app/charts/subscriptions.js.map +0 -1
- package/dist/src/app/charts/svgStyle.d.ts +0 -27
- package/dist/src/app/charts/svgStyle.js +0 -32
- package/dist/src/app/charts/svgStyle.js.map +0 -1
- package/dist/src/app/charts/timeRange.test.js +0 -54
- package/dist/src/app/charts/timeRange.test.js.map +0 -1
- package/dist/src/app/charts/tooltipUtils.js.map +0 -1
- package/dist/src/app/charts/trackerUtils.js +0 -130
- package/dist/src/app/charts/trackerUtils.js.map +0 -1
- /package/dist/src/app/charts/{datumSeries.test.d.ts → axes/AxesState.test.d.ts} +0 -0
- /package/dist/src/app/charts/{margins.test.d.ts → axes/AxisInterval.test.d.ts} +0 -0
- /package/dist/src/app/charts/{regexFilter.test.d.ts → axes/ContinuousAxisRange.test.d.ts} +0 -0
- /package/dist/src/app/charts/{timeRange.test.d.ts → axes/OrdinalAxisRange.test.d.ts} +0 -0
- /package/dist/src/app/charts/{RasterPlotTooltipContent.d.ts → tooltips/RasterPlotTooltipContent.d.ts} +0 -0
- /package/dist/src/app/charts/{ScatterPlotTooltipContent.d.ts → tooltips/ScatterPlotTooltipContent.d.ts} +0 -0
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import {createContext, JSX, useContext} from "react";
|
|
2
|
+
import {concat, from, Observable, Subscription} from "rxjs";
|
|
3
|
+
import {ChartData} from "../observables/ChartData";
|
|
4
|
+
import {useInitialData} from "./useInitialData";
|
|
5
|
+
import {BaseSeries} from "../series/baseSeries";
|
|
6
|
+
// import {noop} from "../utils";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* No operation function for use when a default function is needed
|
|
10
|
+
*/
|
|
11
|
+
const noop = () => {
|
|
12
|
+
/* empty on purpose */
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// type SeriesObservable = Observable<TimeSeriesChartData> | Observable<IterateChartData>
|
|
16
|
+
// type Data = Array<Datum> | Array<IterateDatum>
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* The values exposed through the {@link useDataObservable} react hook
|
|
20
|
+
*/
|
|
21
|
+
interface UseObservableValues<CD extends ChartData, D> {
|
|
22
|
+
/**
|
|
23
|
+
* An observable source for chart data
|
|
24
|
+
*/
|
|
25
|
+
// seriesObservable?: SeriesObservable
|
|
26
|
+
seriesObservable?: Observable<CD>
|
|
27
|
+
/**
|
|
28
|
+
* When `true` the chart will subscribe to the observable, or if already subscribed, will remain
|
|
29
|
+
* subscribed. When `false` the chart will unsubscribe to the observable if subscribed, or will
|
|
30
|
+
* remain unsubscribed if not already subscribed.
|
|
31
|
+
*/
|
|
32
|
+
shouldSubscribe?: boolean
|
|
33
|
+
/**
|
|
34
|
+
* The windowing time for aggregating chart-data events. Defines the update rate of the chart.
|
|
35
|
+
* For example if chart-data events occur every 1 ms, and the windowing time is set to 10 ms,
|
|
36
|
+
* then events will be aggregated for 10 ms, and then the chart will be updated. In this example,
|
|
37
|
+
* the chart would be updated only once per 10 ms.
|
|
38
|
+
*/
|
|
39
|
+
windowingTime?: number
|
|
40
|
+
|
|
41
|
+
/*
|
|
42
|
+
| USER CALLBACK FUNCTIONS
|
|
43
|
+
*/
|
|
44
|
+
/**
|
|
45
|
+
* Callback function that is called when the chart subscribes to the observable
|
|
46
|
+
* @param subscription The subscription resulting form the subscribe action
|
|
47
|
+
*/
|
|
48
|
+
onSubscribe: (subscription: Subscription) => void
|
|
49
|
+
/**
|
|
50
|
+
* Callback function that is called when new data arrives to the chart.
|
|
51
|
+
* @param seriesName The name of the series for which new data arrived
|
|
52
|
+
* @param data The new data that arrived in the windowing tine
|
|
53
|
+
* @see UseChartValues.windowingTime
|
|
54
|
+
*/
|
|
55
|
+
onUpdateData?: (seriesName: string, data: Array<D>) => void
|
|
56
|
+
/**
|
|
57
|
+
* todo
|
|
58
|
+
* @param time
|
|
59
|
+
*/
|
|
60
|
+
onUpdateChartTime?: (time: number) => void
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const defaultObservableValues: UseObservableValues<any, any> = {
|
|
64
|
+
windowingTime: NaN,
|
|
65
|
+
shouldSubscribe: false,
|
|
66
|
+
|
|
67
|
+
// user callbacks
|
|
68
|
+
onSubscribe: noop,
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const DataObservableContext = createContext<UseObservableValues<any, any>>(defaultObservableValues)
|
|
72
|
+
|
|
73
|
+
interface Props<CD extends ChartData, D> {
|
|
74
|
+
// live data
|
|
75
|
+
seriesObservable?: Observable<CD>
|
|
76
|
+
windowingTime?: number
|
|
77
|
+
shouldSubscribe?: boolean
|
|
78
|
+
|
|
79
|
+
/*
|
|
80
|
+
| USER CALLBACK FUNCTIONS
|
|
81
|
+
*/
|
|
82
|
+
/**
|
|
83
|
+
* Callback function that is called when the chart subscribes to the observable
|
|
84
|
+
* @param subscription The subscription resulting form the subscribe action
|
|
85
|
+
*/
|
|
86
|
+
onSubscribe?: (subscription: Subscription) => void
|
|
87
|
+
/**
|
|
88
|
+
* Callback function that is called when new data arrives to the chart.
|
|
89
|
+
* @param seriesName The name of the series for which new data arrived
|
|
90
|
+
* @param data The new data that arrived in the windowing tine
|
|
91
|
+
* @see UseChartValues.windowingTime
|
|
92
|
+
*/
|
|
93
|
+
onUpdateData?: (seriesName: string, data: Array<D>) => void
|
|
94
|
+
onUpdateChartTime?: (time: number) => void
|
|
95
|
+
|
|
96
|
+
children: JSX.Element | Array<JSX.Element>
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* The react context provider for the {@link UseObservableValues}
|
|
101
|
+
* @param props The properties
|
|
102
|
+
* @return The children wrapped in this provider
|
|
103
|
+
* @constructor
|
|
104
|
+
*/
|
|
105
|
+
export default function DataObservableProvider<CD extends ChartData, D>(props: Props<CD, D>): JSX.Element {
|
|
106
|
+
|
|
107
|
+
const {
|
|
108
|
+
seriesObservable,
|
|
109
|
+
windowingTime = defaultObservableValues.windowingTime || 100,
|
|
110
|
+
shouldSubscribe,
|
|
111
|
+
|
|
112
|
+
onSubscribe = noop,
|
|
113
|
+
onUpdateData = noop,
|
|
114
|
+
onUpdateChartTime = noop,
|
|
115
|
+
} = props
|
|
116
|
+
|
|
117
|
+
// when initial data is provided, and importantly, when a function is provided that converts
|
|
118
|
+
// the initial data into an object of type ChartData, and when there is a defined series
|
|
119
|
+
// observable, then the initial data is prepended to the data observable.
|
|
120
|
+
const {initialData, asChartData} = useInitialData<CD, D>()
|
|
121
|
+
const observable = dataObservable<CD, D>(seriesObservable, initialData, asChartData)
|
|
122
|
+
|
|
123
|
+
return <DataObservableContext.Provider
|
|
124
|
+
value={{
|
|
125
|
+
seriesObservable: observable,
|
|
126
|
+
windowingTime,
|
|
127
|
+
shouldSubscribe,
|
|
128
|
+
|
|
129
|
+
onSubscribe,
|
|
130
|
+
onUpdateData,
|
|
131
|
+
onUpdateChartTime,
|
|
132
|
+
}}
|
|
133
|
+
>
|
|
134
|
+
{props.children}
|
|
135
|
+
</DataObservableContext.Provider>
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* When initial data is provided, and importantly, when a function is provided that converts
|
|
140
|
+
* the initial data into an object of type ChartData, and when there is a defined series
|
|
141
|
+
* observable, then the initial data is prepended to the data observable. When only initial data
|
|
142
|
+
* is provided and a conversion function, then a creates an observable from the initial data.
|
|
143
|
+
* And, when only a defined series observable is specified, then that is used (this is the default,
|
|
144
|
+
* and backward compatible behavior).
|
|
145
|
+
* @param seriesObservable An optional series observable
|
|
146
|
+
* @param initialData An array of initial data series
|
|
147
|
+
* @param asChartData A function that converts the initial data series into chart data
|
|
148
|
+
* @return An {@link Observable} of {@link ChartData}, or an `undefined`
|
|
149
|
+
*/
|
|
150
|
+
function dataObservable<CD extends ChartData, D>(
|
|
151
|
+
seriesObservable?: Observable<CD>,
|
|
152
|
+
initialData?: Array<BaseSeries<D>>,
|
|
153
|
+
asChartData?: (seriesList: Array<BaseSeries<D>>) => CD
|
|
154
|
+
): Observable<CD> | undefined {
|
|
155
|
+
if (seriesObservable !== undefined && initialData !== undefined && initialData.length > 0 && asChartData !== undefined) {
|
|
156
|
+
return concat(from([asChartData(initialData)]), seriesObservable)
|
|
157
|
+
} else if (initialData !== undefined && initialData.length > 0 && asChartData !== undefined) {
|
|
158
|
+
return from([asChartData(initialData)])
|
|
159
|
+
} else {
|
|
160
|
+
return seriesObservable
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* React hook that sets up the React context for the chart values.
|
|
166
|
+
* @return The {@link UseObservableValues} held in the React context.
|
|
167
|
+
*/
|
|
168
|
+
export function useDataObservable<CD extends ChartData, D>(): UseObservableValues<CD, D> {
|
|
169
|
+
const context = useContext<UseObservableValues<CD, D>>(DataObservableContext)
|
|
170
|
+
const {onSubscribe} = context
|
|
171
|
+
if (onSubscribe === undefined) {
|
|
172
|
+
throw new Error("useDataObservable can only be used when the parent is a <DataObservableProvider/>")
|
|
173
|
+
}
|
|
174
|
+
return context
|
|
175
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import {createContext, JSX, useContext} from "react";
|
|
2
|
+
import {BaseSeries} from "../series/baseSeries";
|
|
3
|
+
import {ChartData} from "../observables/ChartData";
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* The values exposed through the {@link useInitialData} react hook
|
|
8
|
+
*/
|
|
9
|
+
type UseInitialDataValues<CD extends ChartData, D> = {
|
|
10
|
+
/**
|
|
11
|
+
* An array of series representing the initial data for the chart (i.e. static data
|
|
12
|
+
* before streaming starts) where D is a datum, whose type must be the same as that
|
|
13
|
+
* used for the Observable on the chart data
|
|
14
|
+
*/
|
|
15
|
+
initialData: Array<BaseSeries<D>>
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Function that takes an array of series (which has elements of type D) and converts
|
|
19
|
+
* it into a chart data type, CD
|
|
20
|
+
* @param seriesList
|
|
21
|
+
*/
|
|
22
|
+
asChartData?: (seriesList: Array<BaseSeries<D>>) => CD
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const defaultInitialDataValues: UseInitialDataValues<any, any> = {
|
|
26
|
+
initialData: new Array<BaseSeries<any>>()
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const InitialDataContext = createContext<UseInitialDataValues<any, any>>(defaultInitialDataValues)
|
|
30
|
+
|
|
31
|
+
interface Props<CD extends ChartData, D> {
|
|
32
|
+
initialData: Array<BaseSeries<D>>
|
|
33
|
+
asChartData?: (seriesList: Array<BaseSeries<D>>) => CD
|
|
34
|
+
children: JSX.Element | Array<JSX.Element>
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* The React context provider for the {@link UseInitialDataValues}
|
|
39
|
+
* @param props The properties
|
|
40
|
+
* @return The children wrapped in this provider
|
|
41
|
+
* @constructor
|
|
42
|
+
*/
|
|
43
|
+
export default function InitialDataProvider<CD extends ChartData, D>(props: Props<CD, D>): JSX.Element {
|
|
44
|
+
const {
|
|
45
|
+
initialData,
|
|
46
|
+
asChartData
|
|
47
|
+
} = props
|
|
48
|
+
|
|
49
|
+
return <InitialDataContext.Provider value={{initialData, asChartData}}>
|
|
50
|
+
{props.children}
|
|
51
|
+
</InitialDataContext.Provider>
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* React hook that sets up the React context for the initial data values.
|
|
56
|
+
* @return The {@link UseInitialDataValues} held in the React context.
|
|
57
|
+
*/
|
|
58
|
+
export function useInitialData<CD extends ChartData, D>(): UseInitialDataValues<CD, D> {
|
|
59
|
+
const context = useContext<UseInitialDataValues<CD, D>>(InitialDataContext)
|
|
60
|
+
const {initialData} = context
|
|
61
|
+
if (initialData === undefined) {
|
|
62
|
+
throw new Error("useInitialData can only be used when the parent is a <InitialDataProvider/>")
|
|
63
|
+
}
|
|
64
|
+
return context
|
|
65
|
+
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import {createContext, JSX, useContext, useRef} from "react";
|
|
2
|
+
import {TooltipData} from "./useTooltip";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* No operation function for use when a default function is needed
|
|
6
|
+
*/
|
|
7
|
+
const noop = () => {
|
|
8
|
+
/* empty on purpose */
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export type UseMouseValues<D, TM> = {
|
|
12
|
+
/**
|
|
13
|
+
* Adds a mouse-over-series handler with the specified ID and handler function
|
|
14
|
+
* @param handlerId The handler ID
|
|
15
|
+
* @param handler The handler function called when a mouse-over-series event occurs.
|
|
16
|
+
* The handler function is handed the series name, the time (x-value), the actual
|
|
17
|
+
* series, and the mouse coordinates over which the mouse has moved over.
|
|
18
|
+
* @return The handler ID.
|
|
19
|
+
*/
|
|
20
|
+
registerMouseOverHandler: (
|
|
21
|
+
handlerId: string,
|
|
22
|
+
handler: (seriesName: string, time: number, tooltipData: TooltipData<D, TM>, mouseCoords: [x: number, y: number]) => void
|
|
23
|
+
) => string
|
|
24
|
+
/**
|
|
25
|
+
* Removes the mouse-over-series handler with the specified ID
|
|
26
|
+
* @param handlerId The ID of the handler to remove
|
|
27
|
+
*/
|
|
28
|
+
unregisterMouseOverHandler: (handlerId: string) => void
|
|
29
|
+
/**
|
|
30
|
+
* Attempts to retrieve the mouse-over-series handler for the specified ID
|
|
31
|
+
* @param handlerId The ID of the handler
|
|
32
|
+
* @return The mouse-over-series handler for the ID, or `undefined` if not found
|
|
33
|
+
*/
|
|
34
|
+
mouseOverHandlerFor: (handlerId: string, providerId?: string) =>
|
|
35
|
+
((seriesName: string, time: number, tooltipData: TooltipData<D, TM>, mouseCoords: [x: number, y: number], providerId?: string) => void) | undefined
|
|
36
|
+
/**
|
|
37
|
+
* Adds a mouse-leave-series handler with the specified ID and handler function
|
|
38
|
+
* @param handlerId The handler ID
|
|
39
|
+
* @param handler The handler function called when a mouse-leave-series event occurs
|
|
40
|
+
* @return The handler ID
|
|
41
|
+
*/
|
|
42
|
+
registerMouseLeaveHandler: (handlerId: string, handler: (seriesName: string) => void) => string
|
|
43
|
+
/**
|
|
44
|
+
* Removes the mouse-leave-series handler with the specified ID
|
|
45
|
+
* @param handlerId The ID of the handler to remove
|
|
46
|
+
*/
|
|
47
|
+
unregisterMouseLeaveHandler: (handlerId: string) => void
|
|
48
|
+
/**
|
|
49
|
+
* Attempts to retrieve the mouse-leave-series handler for the specified ID
|
|
50
|
+
* @param handlerId The ID of the handler
|
|
51
|
+
* @return The mouse-leave-series handler for the ID, or `undefined` if not found
|
|
52
|
+
*/
|
|
53
|
+
mouseLeaveHandlerFor: (handlerId: string, providerId?: string) => ((seriesName: string, providerId?: string) => void) | undefined
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export const defaultMouseValues = (): UseMouseValues<any, any> => ({
|
|
57
|
+
registerMouseOverHandler: () => '',
|
|
58
|
+
unregisterMouseOverHandler: noop,
|
|
59
|
+
mouseOverHandlerFor: () => undefined,
|
|
60
|
+
registerMouseLeaveHandler: () => '',
|
|
61
|
+
unregisterMouseLeaveHandler: noop,
|
|
62
|
+
mouseLeaveHandlerFor: () => undefined,
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
const MouseContext = createContext<UseMouseValues<any, any>>(defaultMouseValues())
|
|
66
|
+
|
|
67
|
+
type Props = {
|
|
68
|
+
children: JSX.Element | Array<JSX.Element>
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export default function MouseProvider<D, TM>(props: Props): JSX.Element {
|
|
72
|
+
const {children} = props
|
|
73
|
+
|
|
74
|
+
const mouseOverHandlersRef = useRef<Map<string, (seriesName: string, time: number, tooltipData: TooltipData<D, TM>, mouseCoords: [x: number, y: number], providerId?: string) => void>>(new Map())
|
|
75
|
+
const mouseLeaveHandlersRef = useRef<Map<string, (seriesName: string, providerId?: string) => void>>(new Map())
|
|
76
|
+
|
|
77
|
+
return <MouseContext.Provider
|
|
78
|
+
value={{
|
|
79
|
+
registerMouseOverHandler: (handlerId, handler) => {
|
|
80
|
+
mouseOverHandlersRef.current.set(handlerId, handler)
|
|
81
|
+
return handlerId
|
|
82
|
+
},
|
|
83
|
+
unregisterMouseOverHandler: handlerId => mouseOverHandlersRef.current.delete(handlerId),
|
|
84
|
+
mouseOverHandlerFor: (handlerId, providerId) => {
|
|
85
|
+
const handlerHoc = mouseOverHandlersRef.current.get(handlerId)
|
|
86
|
+
if (handlerHoc !== undefined) {
|
|
87
|
+
return (seriesName: string, time: number, tooltipData: TooltipData<D, TM>, mouseCoords: [x: number, y: number])=> {
|
|
88
|
+
handlerHoc(seriesName, time, tooltipData, mouseCoords, providerId)
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return undefined
|
|
92
|
+
},
|
|
93
|
+
|
|
94
|
+
registerMouseLeaveHandler: (handlerId, handler) => {
|
|
95
|
+
mouseLeaveHandlersRef.current.set(handlerId, handler)
|
|
96
|
+
return handlerId
|
|
97
|
+
},
|
|
98
|
+
unregisterMouseLeaveHandler: handlerId => mouseLeaveHandlersRef.current.delete(handlerId),
|
|
99
|
+
mouseLeaveHandlerFor: (handlerId, providerId) => {
|
|
100
|
+
const handlerHoc = mouseLeaveHandlersRef.current.get(handlerId)
|
|
101
|
+
if (handlerHoc !== undefined) {
|
|
102
|
+
return (seriesName: string)=> {
|
|
103
|
+
handlerHoc(seriesName, providerId)
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return undefined
|
|
107
|
+
},
|
|
108
|
+
}}
|
|
109
|
+
>
|
|
110
|
+
{children}
|
|
111
|
+
</MouseContext.Provider>
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* React hook that sets up the React context for the mouse values.
|
|
116
|
+
* @return The {@link UseMouseValues} held in the React context.
|
|
117
|
+
*/
|
|
118
|
+
export function useMouse<D, TM>(): UseMouseValues<D, TM> {
|
|
119
|
+
const context = useContext<UseMouseValues<D, TM>>(MouseContext)
|
|
120
|
+
const {mouseOverHandlerFor} = context
|
|
121
|
+
if (mouseOverHandlerFor === undefined || mouseOverHandlerFor === null) {
|
|
122
|
+
throw new Error("useMouse can only be used when the parent is a <MouseProvider/>")
|
|
123
|
+
}
|
|
124
|
+
return context
|
|
125
|
+
}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import {Dimensions, dimensionsNotEqual, Margin, plotDimensionsFrom} from "../styling/margins";
|
|
2
|
+
import {createContext, JSX, useContext, useEffect, useRef, useState} from "react";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* No operation function for use when a default function is needed
|
|
6
|
+
*/
|
|
7
|
+
const noop = () => {
|
|
8
|
+
/* empty on purpose */
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const defaultMargin: Margin = {top: 30, right: 20, bottom: 30, left: 50}
|
|
12
|
+
|
|
13
|
+
export type PlotDimensionChangeHandler = (previousDimensions: Dimensions, newDimensions: Dimensions) => void
|
|
14
|
+
|
|
15
|
+
export type UsePlotDimensionsValues = {
|
|
16
|
+
/**
|
|
17
|
+
* The width and height (in pixels) of this chart
|
|
18
|
+
*/
|
|
19
|
+
plotDimensions: Dimensions
|
|
20
|
+
/**
|
|
21
|
+
* The plot margins for the border of main G
|
|
22
|
+
*/
|
|
23
|
+
margin: Margin
|
|
24
|
+
/**
|
|
25
|
+
* Update the plot dimensions (for example, on a window resize)
|
|
26
|
+
* @param dimensions the new dimensions of the plot
|
|
27
|
+
*/
|
|
28
|
+
updateDimensions: (dimensions: Dimensions) => void
|
|
29
|
+
registerPlotDimensionChangeHandler: (handler: PlotDimensionChangeHandler) => string
|
|
30
|
+
unregisterPlotDimensionChangeHandler: (handlerId: string) => void
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export const defaultPlotDimensions = (): UsePlotDimensionsValues => ({
|
|
34
|
+
plotDimensions: {width: 0, height: 0},
|
|
35
|
+
margin: defaultMargin,
|
|
36
|
+
updateDimensions: noop,
|
|
37
|
+
registerPlotDimensionChangeHandler: () => "",
|
|
38
|
+
unregisterPlotDimensionChangeHandler: noop
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
const PlotDimensionsContext = createContext<UsePlotDimensionsValues>(defaultPlotDimensions())
|
|
42
|
+
|
|
43
|
+
type Props = {
|
|
44
|
+
containerDimensions: Dimensions
|
|
45
|
+
margin: Margin
|
|
46
|
+
children: JSX.Element | Array<JSX.Element>
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export default function PlotDimensionsProvider(props: Props): JSX.Element {
|
|
50
|
+
const {
|
|
51
|
+
containerDimensions,
|
|
52
|
+
margin,
|
|
53
|
+
children
|
|
54
|
+
} = props
|
|
55
|
+
|
|
56
|
+
const [dimensions, setDimensions] = useState<Dimensions>(defaultPlotDimensions().plotDimensions)
|
|
57
|
+
const plotDimensionChangeHandersRef = useRef<Map<string, PlotDimensionChangeHandler>>(new Map())
|
|
58
|
+
|
|
59
|
+
// update the plot dimensions when the container size or margin change
|
|
60
|
+
useEffect(
|
|
61
|
+
() => {
|
|
62
|
+
const newDimensions = plotDimensionsFrom(containerDimensions.width, containerDimensions.height, margin)
|
|
63
|
+
setDimensions(prevDimensions => {
|
|
64
|
+
if (dimensionsNotEqual(prevDimensions, newDimensions)) {
|
|
65
|
+
for(const handler of plotDimensionChangeHandersRef.current.values()) {
|
|
66
|
+
handler(prevDimensions, newDimensions)
|
|
67
|
+
}
|
|
68
|
+
return newDimensions
|
|
69
|
+
}
|
|
70
|
+
return prevDimensions
|
|
71
|
+
})
|
|
72
|
+
},
|
|
73
|
+
[containerDimensions, margin]
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
function updateDimensions(newDimensions: Dimensions) {
|
|
77
|
+
setDimensions(prevState => {
|
|
78
|
+
for(const handler of plotDimensionChangeHandersRef.current.values()) {
|
|
79
|
+
handler(prevState, newDimensions)
|
|
80
|
+
}
|
|
81
|
+
return newDimensions
|
|
82
|
+
})
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function registerPlotDimensionChangeHandler(handler: PlotDimensionChangeHandler) {
|
|
86
|
+
const handlerId = crypto.randomUUID()
|
|
87
|
+
plotDimensionChangeHandersRef.current.set(handlerId, handler)
|
|
88
|
+
return handlerId
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function unregisterPlotDimensionChangeHandler(handlerId: string): boolean {
|
|
92
|
+
return plotDimensionChangeHandersRef.current.delete(handlerId)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return <PlotDimensionsContext.Provider
|
|
96
|
+
value={{
|
|
97
|
+
plotDimensions: dimensions,
|
|
98
|
+
margin,
|
|
99
|
+
updateDimensions,
|
|
100
|
+
// updateDimensions: dimensions => setDimensions(dimensions),
|
|
101
|
+
registerPlotDimensionChangeHandler,
|
|
102
|
+
unregisterPlotDimensionChangeHandler
|
|
103
|
+
}}
|
|
104
|
+
>
|
|
105
|
+
{children}
|
|
106
|
+
</PlotDimensionsContext.Provider>
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* React hook that sets up the React context for the plot-dimension values.
|
|
111
|
+
* @return The {@link UsePlotDimensionsValues} held in the React context.
|
|
112
|
+
*/
|
|
113
|
+
export function usePlotDimensions(): UsePlotDimensionsValues {
|
|
114
|
+
const context = useContext<UsePlotDimensionsValues>(PlotDimensionsContext)
|
|
115
|
+
const {plotDimensions} = context
|
|
116
|
+
if (plotDimensions === undefined || plotDimensions === null) {
|
|
117
|
+
throw new Error("usePlotDimensions can only be used when the parent is a <PlotDimensionsProvider/>")
|
|
118
|
+
}
|
|
119
|
+
return context
|
|
120
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import {Series} from "../plots/plot";
|
|
2
|
+
import {TooltipDimensions} from "../tooltips/tooltipUtils";
|
|
3
|
+
import {createContext, JSX, useContext, useRef} from "react";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* No operation function for use when a default function is needed
|
|
7
|
+
*/
|
|
8
|
+
const noop = () => {
|
|
9
|
+
/* empty on purpose */
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Base interface for tooltip data that is passed through to the tooltip content provider
|
|
14
|
+
*/
|
|
15
|
+
export interface TooltipData<D, M> {
|
|
16
|
+
series: Series<D>
|
|
17
|
+
metadata: M
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* A higher-order function that returns a function that provides the tooltip content or
|
|
22
|
+
* `undefined` if no tooltip content is available.
|
|
23
|
+
* @return The tooltip content, or `undefined` if no tooltip content is available.
|
|
24
|
+
* @param seriesName The name of the series for which the tooltip content is being provided
|
|
25
|
+
* @param time The time (x-value) for which the tooltip content is being provided
|
|
26
|
+
* @param tooltipData The tooltip data
|
|
27
|
+
* @param mouseCoords The mouse coordinates over which the mouse is hovering
|
|
28
|
+
* @param providerId An optional ID of the tooltip content provider.
|
|
29
|
+
*/
|
|
30
|
+
type TooltipContentProvider<D, M> =
|
|
31
|
+
(seriesName: string, time: number, tooltipData: TooltipData<D, M>, mouseCoords: [x: number, y: number], providerId?: string) => TooltipDimensions
|
|
32
|
+
// type TooltipContentProvider<D, M> =
|
|
33
|
+
// (seriesName: string, time: number, tooltipData: TooltipData<D, M>, mouseCoords: [x: number, y: number]) => TooltipDimensions
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* The functions and values exposed through the {@link useTooltip} react hook
|
|
37
|
+
*/
|
|
38
|
+
export type UseTooltipValues<D, M> = {
|
|
39
|
+
/**
|
|
40
|
+
* Registers the provider of the tooltip content (generally the plot will register this).
|
|
41
|
+
* When this function is called again, overwrites the previously registered provider with the
|
|
42
|
+
* one specified. This function can be called repeatedly.
|
|
43
|
+
* @param provider The function that provides the content when called.
|
|
44
|
+
*/
|
|
45
|
+
registerTooltipContentProvider: (provider: TooltipContentProvider<D, M>) => void
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* @return The registered function that provides the tooltip content. If no function has been
|
|
49
|
+
* registered, then returns `undefined`.
|
|
50
|
+
*/
|
|
51
|
+
tooltipContentProvider: () => (TooltipContentProvider<D, M> | undefined)
|
|
52
|
+
|
|
53
|
+
setVisibilityState: (visible: boolean) => void
|
|
54
|
+
visibilityState: boolean
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* The default values for the {@link UseTooltipValues}
|
|
59
|
+
*/
|
|
60
|
+
export const defaultTooltipValues = (): UseTooltipValues<any, any> => ({
|
|
61
|
+
registerTooltipContentProvider: noop,
|
|
62
|
+
tooltipContentProvider: () => undefined,
|
|
63
|
+
setVisibilityState: noop,
|
|
64
|
+
visibilityState: false,
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
const TooltipContext = createContext<UseTooltipValues<any, any>>(defaultTooltipValues())
|
|
68
|
+
|
|
69
|
+
type Props = {
|
|
70
|
+
children: JSX.Element | Array<JSX.Element>
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* The tooltip context provider allows registering and retrieving tooltip content providers. When
|
|
75
|
+
* a tooltip content provider is registered with a provider ID, then it must be retrieved with that
|
|
76
|
+
* same provider ID. This allows a chart to have multiple tooltip content providers, depending on
|
|
77
|
+
* the context or types of objects being moused over. When a tooltip content provider is registered
|
|
78
|
+
* without a provider ID, then the default provider ID is used.
|
|
79
|
+
* @param props The properties holding the children
|
|
80
|
+
* @constructor
|
|
81
|
+
* @return A JSX element containing the children
|
|
82
|
+
*/
|
|
83
|
+
export default function TooltipProvider<D, M>(props: Props): JSX.Element {
|
|
84
|
+
const {children} = props
|
|
85
|
+
|
|
86
|
+
const tooltipContentProviderRef = useRef<TooltipContentProvider<D, M>>(undefined)
|
|
87
|
+
const visibilityStateRef = useRef<boolean>(false)
|
|
88
|
+
|
|
89
|
+
return <TooltipContext.Provider
|
|
90
|
+
value={{
|
|
91
|
+
registerTooltipContentProvider: provider => tooltipContentProviderRef.current = provider,
|
|
92
|
+
tooltipContentProvider: () => tooltipContentProviderRef.current,
|
|
93
|
+
setVisibilityState: (visible: boolean) => visibilityStateRef.current = visible,
|
|
94
|
+
visibilityState: visibilityStateRef.current
|
|
95
|
+
}}
|
|
96
|
+
>
|
|
97
|
+
{children}
|
|
98
|
+
</TooltipContext.Provider>
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* React hook that sets up the React context for the mouse values.
|
|
103
|
+
* @return The {@link UseTooltipValues} held in the React context.
|
|
104
|
+
*/
|
|
105
|
+
export function useTooltip<D, M>(): UseTooltipValues<D, M> {
|
|
106
|
+
const context = useContext<UseTooltipValues<D, M>>(TooltipContext)
|
|
107
|
+
const {registerTooltipContentProvider} = context
|
|
108
|
+
if (registerTooltipContentProvider === undefined || registerTooltipContentProvider === null) {
|
|
109
|
+
throw new Error("useTooltip can only be used when the parent is a <TooltipProvider/>")
|
|
110
|
+
}
|
|
111
|
+
return context
|
|
112
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Intended base interface for chart data. All chart data need to hold
|
|
3
|
+
* a {@link Set} of series names.
|
|
4
|
+
* @see TimeSeriesChartData
|
|
5
|
+
* @see IterateChartData
|
|
6
|
+
* @see OrdinalChartData
|
|
7
|
+
*/
|
|
8
|
+
export interface ChartData {
|
|
9
|
+
seriesNames: Set<string>
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @return A default {@link ChartData} object with an empty set of series
|
|
14
|
+
* names
|
|
15
|
+
*/
|
|
16
|
+
export function defaultChartData(): ChartData {
|
|
17
|
+
return {
|
|
18
|
+
seriesNames: new Set<string>()
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Creates and returns a deep copy of the {@link ChartData}
|
|
24
|
+
* @param data The chart data to copy
|
|
25
|
+
* @return A deep copy of the chart data
|
|
26
|
+
*/
|
|
27
|
+
export function copyChartData(data: ChartData) {
|
|
28
|
+
return {
|
|
29
|
+
seriesNames: new Set(data.seriesNames.values()),
|
|
30
|
+
}
|
|
31
|
+
}
|