stream-charts 1.0.0 → 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 +758 -345
- package/changes.md +10 -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} +17 -11
- package/dist/src/app/charts/{tooltipUtils.js → tooltips/tooltipUtils.js} +52 -25
- 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,379 @@
|
|
|
1
|
+
import { useCallback, useEffect, useMemo, useRef } from 'react';
|
|
2
|
+
import { useChart } from "../hooks/useChart";
|
|
3
|
+
import * as d3 from "d3";
|
|
4
|
+
import { setClipPathG } from "./plot";
|
|
5
|
+
import { axesForSeriesGen, continuousAxisIntervals, continuousAxisRanges, continuousAxisZoomHandler, defaultLineStyle, panHandler } from "../axes/axes";
|
|
6
|
+
import { noop } from "../utils";
|
|
7
|
+
import { subscriptionTimeSeriesFor, subscriptionTimeSeriesWithCadenceFor, TimeWindowBehavior } from "../subscriptions/subscriptions";
|
|
8
|
+
import { useDataObservable } from "../hooks/useDataObservable";
|
|
9
|
+
import { usePlotDimensions } from "../hooks/usePlotDimensions";
|
|
10
|
+
import { useInitialData } from "../hooks/useInitialData";
|
|
11
|
+
import { Optional } from "result-fn";
|
|
12
|
+
import { ContinuousAxisRange } from "../axes/ContinuousAxisRange";
|
|
13
|
+
/**
|
|
14
|
+
* Renders a streaming scatter plot for the series in the initial data and those sourced by the
|
|
15
|
+
* observable specified as a property in the {@link Chart}. This component uses the {@link useChart}
|
|
16
|
+
* hook, and therefore must be a child of the {@link Chart} in order to be plugged in to the
|
|
17
|
+
* chart ecosystem (axes, tracker, tooltip).
|
|
18
|
+
*
|
|
19
|
+
* @param props The properties associated with the scatter plot
|
|
20
|
+
* @constructor
|
|
21
|
+
* @example
|
|
22
|
+
<ScatterPlot
|
|
23
|
+
interpolation={interpolation}
|
|
24
|
+
axisAssignments={new Map([
|
|
25
|
+
['test2', assignAxes("x-axis-2", "y-axis-2")],
|
|
26
|
+
])}
|
|
27
|
+
dropDataAfter={10000}
|
|
28
|
+
panEnabled={true}
|
|
29
|
+
zoomEnabled={true}
|
|
30
|
+
zoomKeyModifiersRequired={true}
|
|
31
|
+
/>
|
|
32
|
+
*/
|
|
33
|
+
export function ScatterPlot(props) {
|
|
34
|
+
const { chartId, container, mainG, axes, color, seriesStyles, seriesFilter, mouse } = useChart();
|
|
35
|
+
const { initialData } = useInitialData();
|
|
36
|
+
const { xAxesState, yAxesState, setAxisIntervalFor, updateAxisRanges = noop, onUpdateAxesInterval, axesRanges, } = axes;
|
|
37
|
+
const { mouseOverHandlerFor, mouseLeaveHandlerFor } = mouse;
|
|
38
|
+
const { plotDimensions, margin } = usePlotDimensions();
|
|
39
|
+
const { seriesObservable, windowingTime = 100, shouldSubscribe, onSubscribe = noop, onUpdateData, } = useDataObservable();
|
|
40
|
+
const { axisAssignments = new Map(), interpolation = d3.curveLinear, dropDataAfter = Infinity, panEnabled = false, zoomEnabled = false, zoomKeyModifiersRequired = true, withCadenceOf, timeWindowBehavior = TimeWindowBehavior.SCROLL, } = props;
|
|
41
|
+
const initialTimes = useMemo(() => {
|
|
42
|
+
return new Map(Array.from(axesRanges().entries())
|
|
43
|
+
.map(([axisId, range]) => ([axisId, range.original.start])));
|
|
44
|
+
}, [axesRanges]);
|
|
45
|
+
// why do "dataRef" and "seriesRef" both hold on to the same underlying data? for performance.
|
|
46
|
+
//
|
|
47
|
+
// the "dataRef" and "seriesRef" both point to the same underlying data, a collection
|
|
48
|
+
// of series. The series in "dataRef" are bound to the DOM elements through d3. The "seriesRef" series
|
|
49
|
+
// are the ones that are updated as new data is streamed in.
|
|
50
|
+
//
|
|
51
|
+
// the "dataRef" object holds on to a copy of the initial data (which is an array of
|
|
52
|
+
// time-series, e.i. an array of BaseSeries<OrdinalDatum> objects). The slice just creates a copy of
|
|
53
|
+
// the array, but the references to the BaseSeries objects are the same and still point to the same
|
|
54
|
+
// data as the "initialData" array.
|
|
55
|
+
//
|
|
56
|
+
// the "seriesRef" object is a reference to a map (series_name -> BaseSeries<OrdinalDatum>) which is
|
|
57
|
+
// used to update the data in the series. When new data enters, it is appended to one or more series.
|
|
58
|
+
//
|
|
59
|
+
// the series in the "dataRef" object are the ones bound to the DOM elements in d3, and so as these
|
|
60
|
+
// are updated, d3 will update the DOM elements (the elements in this plot).
|
|
61
|
+
const dataRef = useRef(initialData.slice());
|
|
62
|
+
const seriesRef = useRef(new Map(initialData.map(series => [series.name, series])));
|
|
63
|
+
// map(axis_id -> current_time) -- maps the axis ID to the current time for that axis
|
|
64
|
+
const currentTimeRef = useRef(new Map());
|
|
65
|
+
const subscriptionRef = useRef(undefined);
|
|
66
|
+
const isSubscriptionClosed = () => subscriptionRef.current === undefined || subscriptionRef.current.closed;
|
|
67
|
+
const allowTooltip = useRef(isSubscriptionClosed());
|
|
68
|
+
useEffect(() => {
|
|
69
|
+
currentTimeRef.current = new Map(Array.from(xAxesState.axes.keys()).map(id => [id, 0]));
|
|
70
|
+
}, [xAxesState]);
|
|
71
|
+
// calculates the distinct series IDs that cover all the series in the plot
|
|
72
|
+
const axesForSeries = useMemo(() => axesForSeriesGen(initialData, axisAssignments, xAxesState), [initialData, axisAssignments, xAxesState]);
|
|
73
|
+
// updates the timing using the onUpdateTime and updatePlot references. This and the references
|
|
74
|
+
// defined above allow the axes' times to be updated properly by avoid stale reference to these
|
|
75
|
+
// functions.
|
|
76
|
+
const updateTimingAndPlot = useCallback((ranges) => {
|
|
77
|
+
if (mainG !== null) {
|
|
78
|
+
onUpdateTimeRef.current(ranges);
|
|
79
|
+
updatePlotRef.current(ranges, mainG);
|
|
80
|
+
if (onUpdateAxesInterval) {
|
|
81
|
+
setTimeout(() => {
|
|
82
|
+
const times = new Map();
|
|
83
|
+
ranges.forEach((range, name) => times.set(name, range.current));
|
|
84
|
+
onUpdateAxesInterval(times);
|
|
85
|
+
}, 0);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}, [mainG, onUpdateAxesInterval]);
|
|
89
|
+
// todo find better way
|
|
90
|
+
// when the initial data changes, then reset the plot. note that the initial data doesn't change
|
|
91
|
+
// during the normal course of updates from the observable, only when the plot is restarted.
|
|
92
|
+
useEffect(() => {
|
|
93
|
+
dataRef.current = initialData.slice();
|
|
94
|
+
seriesRef.current = new Map(initialData.map(series => [series.name, series]));
|
|
95
|
+
currentTimeRef.current = new Map(Array.from(xAxesState.axes.keys()).map(id => [id, 0]));
|
|
96
|
+
updateTimingAndPlot(new Map(Array.from(continuousAxisRanges(xAxesState.axes).entries())
|
|
97
|
+
.map(([id, range]) => {
|
|
98
|
+
// grab the current range, then calculate the minimum time from the initial data, and
|
|
99
|
+
// set that as the start, and then add the range to it for the end time
|
|
100
|
+
const [start, end] = range.original.asTuple();
|
|
101
|
+
const minTime = initialData
|
|
102
|
+
.filter(srs => { var _a; return ((_a = axisAssignments.get(srs.name)) === null || _a === void 0 ? void 0 : _a.xAxis) === id; })
|
|
103
|
+
.reduce((tMin, series) => Math.min(tMin, !series.isEmpty() ? series.data[0].time : tMin), Infinity);
|
|
104
|
+
const startTime = minTime === Infinity ? 0 : minTime;
|
|
105
|
+
return [id, ContinuousAxisRange.from(startTime, startTime + end - start)];
|
|
106
|
+
})));
|
|
107
|
+
},
|
|
108
|
+
// ** not happy about this **
|
|
109
|
+
// only want this effect to run when the initial data is changed, which mean all the
|
|
110
|
+
// other dependencies are recalculated anyway.
|
|
111
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
112
|
+
[initialData]);
|
|
113
|
+
/**
|
|
114
|
+
* Adjusts the time-range and updates the plot when the plot is dragged to the left or right
|
|
115
|
+
* @param deltaX The amount that the plot is dragged
|
|
116
|
+
* @param plotDimensions The dimensions of the plot
|
|
117
|
+
* @param ranges A map holding the axis ID and its associated time range
|
|
118
|
+
*/
|
|
119
|
+
const onPan = useCallback((x, plotDimensions, ranges) => panHandler(axesForSeries, margin, setAxisIntervalFor, xAxesState)(x, plotDimensions, ranges), [axesForSeries, margin, setAxisIntervalFor, xAxesState]);
|
|
120
|
+
/**
|
|
121
|
+
* Called when the user uses the scroll wheel (or scroll gesture) to zoom in or out. Zooms in/out
|
|
122
|
+
* at the location of the mouse when the scroll wheel or gesture was applied.
|
|
123
|
+
* @param transform The d3 zoom transformation information
|
|
124
|
+
* @param x The x-position of the mouse when the scroll wheel or gesture is used
|
|
125
|
+
* @param plotDimensions The dimensions of the plot
|
|
126
|
+
* @param series An array of series names
|
|
127
|
+
* @param ranges A map holding the axis ID and its associated time-range
|
|
128
|
+
*/
|
|
129
|
+
const onZoom = useCallback((transform, x, plotDimensions, ranges) => continuousAxisZoomHandler(axesForSeries, margin, setAxisIntervalFor, xAxesState)(transform, x, plotDimensions, ranges), [axesForSeries, margin, setAxisIntervalFor, xAxesState]);
|
|
130
|
+
const updatePlot = useCallback(
|
|
131
|
+
/**
|
|
132
|
+
* Updates the plot data for the specified time-range, which may have changed due to zoom or pan
|
|
133
|
+
* @param timeRanges The current time range
|
|
134
|
+
* @param mainGElem The main <g> element selection for that holds the plot
|
|
135
|
+
*/
|
|
136
|
+
(timeRanges, mainGElem) => {
|
|
137
|
+
if (container) {
|
|
138
|
+
// select the svg element bind the data to them
|
|
139
|
+
const svg = d3.select(container);
|
|
140
|
+
// create a map associating series-names to their time-series.
|
|
141
|
+
//
|
|
142
|
+
// performance-related confusion: wondering where the dataRef is updated? well it isn't
|
|
143
|
+
// directly. The dataRef holds on to an array of references to the Series. And so does the
|
|
144
|
+
// seriesRef, though is uses a map(series_name -> series). The seriesRef is use to append
|
|
145
|
+
// data to the underlying Series, and the dataRef is used so that we can just use
|
|
146
|
+
// dataRef.current and don't have to do Array.from(seriesRef.current.values()) which
|
|
147
|
+
// creates a temporary array
|
|
148
|
+
const boundedSeries = new Map(dataRef.current.map(series => [
|
|
149
|
+
series.name,
|
|
150
|
+
series.data
|
|
151
|
+
]));
|
|
152
|
+
// set up panning
|
|
153
|
+
if (panEnabled) {
|
|
154
|
+
const drag = d3.drag()
|
|
155
|
+
.on("start", () => {
|
|
156
|
+
d3.select(container).style("cursor", "move");
|
|
157
|
+
// during panning, we need to disable viewing the tooltip to prevent
|
|
158
|
+
// tooltips from rendering but not getting removed
|
|
159
|
+
allowTooltip.current = false;
|
|
160
|
+
})
|
|
161
|
+
.on("drag", (event) => {
|
|
162
|
+
onPan(event.dx, plotDimensions,
|
|
163
|
+
// Array.from(boundedSeries.keys()),
|
|
164
|
+
timeRanges);
|
|
165
|
+
updatePlotRef.current(timeRanges, mainGElem);
|
|
166
|
+
})
|
|
167
|
+
.on("end", () => {
|
|
168
|
+
d3.select(container).style("cursor", "auto");
|
|
169
|
+
// during panning, we disabled viewing the tooltip to prevent
|
|
170
|
+
// tooltips from rendering but not getting removed, now that panning
|
|
171
|
+
// is over, allow tooltips to render again
|
|
172
|
+
allowTooltip.current = isSubscriptionClosed();
|
|
173
|
+
});
|
|
174
|
+
svg.call(drag);
|
|
175
|
+
}
|
|
176
|
+
// set up for zooming
|
|
177
|
+
if (zoomEnabled) {
|
|
178
|
+
const zoom = d3.zoom()
|
|
179
|
+
.filter(event => !zoomKeyModifiersRequired || event.shiftKey || event.ctrlKey)
|
|
180
|
+
.scaleExtent([0, 10])
|
|
181
|
+
.translateExtent([[margin.left, margin.top], [plotDimensions.width, plotDimensions.height]])
|
|
182
|
+
.on("zoom", event => {
|
|
183
|
+
onZoom(event.transform, event.sourceEvent.offsetX - margin.left, plotDimensions, timeRanges);
|
|
184
|
+
updatePlotRef.current(timeRanges, mainGElem);
|
|
185
|
+
});
|
|
186
|
+
svg.call(zoom);
|
|
187
|
+
}
|
|
188
|
+
// define the clip-path so that the series lines don't go beyond the plot area
|
|
189
|
+
const clipPathId = setClipPathG(chartId, mainGElem, plotDimensions);
|
|
190
|
+
boundedSeries.forEach((data, name) => {
|
|
191
|
+
// grab the x and y axes assigned to the series, and if either or both
|
|
192
|
+
// axes aren't found, then give up and return
|
|
193
|
+
const [xAxisLinear, yAxisLinear] = axesFor(name, axisAssignments, axisId => xAxesState.axisFor(axisId).getOrUndefined(), axisId => yAxesState.axisFor(axisId).getOrUndefined());
|
|
194
|
+
if (xAxisLinear === undefined || yAxisLinear === undefined)
|
|
195
|
+
return;
|
|
196
|
+
// grab the style for the series
|
|
197
|
+
const { color, lineWidth } = seriesStyles.get(name) || Object.assign(Object.assign({}, defaultLineStyle()), { highlightColor: defaultLineStyle().color });
|
|
198
|
+
// only show the data for which the filter matches
|
|
199
|
+
const plotData = (name.match(seriesFilter)) ? data : [];
|
|
200
|
+
// create the time-series paths
|
|
201
|
+
mainGElem
|
|
202
|
+
.selectAll(`#${name}-${chartId}-scatter`)
|
|
203
|
+
.data([[], plotData], () => `${name}`)
|
|
204
|
+
.join(enter => enter
|
|
205
|
+
.append("path")
|
|
206
|
+
.attr("class", 'time-series-lines')
|
|
207
|
+
.attr("id", `${name}-${chartId}-scatter`)
|
|
208
|
+
.attr("d", d3.line()
|
|
209
|
+
.x((d) => xAxisLinear.scale(d.time) || 0)
|
|
210
|
+
.y((d) => yAxisLinear.scale(d.value) || 0)
|
|
211
|
+
.curve(interpolation))
|
|
212
|
+
.attr("fill", "none")
|
|
213
|
+
.attr("stroke", color)
|
|
214
|
+
.attr("stroke-width", lineWidth)
|
|
215
|
+
.attr('transform', `translate(${margin.left}, ${margin.top})`)
|
|
216
|
+
.attr("clip-path", `url(#${clipPathId})`)
|
|
217
|
+
.on("mouseover", (event, datumArray) =>
|
|
218
|
+
// recall that this handler is passed down via the "useChart" hook
|
|
219
|
+
handleMouseOverSeries(container, xAxisLinear, name, datumArray, event, margin, seriesStyles, allowTooltip.current, mouseOverHandlerFor(`tooltip-${chartId}`)))
|
|
220
|
+
.on("mouseleave", event => handleMouseLeaveSeries(name, event.currentTarget, seriesStyles, mouseLeaveHandlerFor(`tooltip-${chartId}`))), update => update, exit => exit.remove());
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
}, [
|
|
224
|
+
container, panEnabled, zoomEnabled, chartId, plotDimensions, margin, onPan,
|
|
225
|
+
zoomKeyModifiersRequired, onZoom, axisAssignments,
|
|
226
|
+
xAxesState, yAxesState,
|
|
227
|
+
seriesStyles, seriesFilter, interpolation,
|
|
228
|
+
mouseOverHandlerFor, mouseLeaveHandlerFor
|
|
229
|
+
]);
|
|
230
|
+
// need to keep the function references for use by the subscription, which forms a closure
|
|
231
|
+
// on them. without the references, the closures become stale, and resizing during streaming
|
|
232
|
+
// doesn't work properly
|
|
233
|
+
const updatePlotRef = useRef(noop);
|
|
234
|
+
useEffect(() => {
|
|
235
|
+
updatePlotRef.current = updatePlot;
|
|
236
|
+
}, [updatePlot]);
|
|
237
|
+
const onUpdateTimeRef = useRef(updateAxisRanges);
|
|
238
|
+
useEffect(() => {
|
|
239
|
+
onUpdateTimeRef.current = updateAxisRanges;
|
|
240
|
+
}, [updateAxisRanges]);
|
|
241
|
+
// memoized function for subscribing to the chart-data observable
|
|
242
|
+
const subscribe = useCallback(() => {
|
|
243
|
+
if (seriesObservable === undefined || mainG === null)
|
|
244
|
+
return undefined;
|
|
245
|
+
if (withCadenceOf !== undefined) {
|
|
246
|
+
return subscriptionTimeSeriesWithCadenceFor(seriesObservable, onSubscribe, windowingTime, axisAssignments, xAxesState, onUpdateData, dropDataAfter, updateTimingAndPlot,
|
|
247
|
+
// as new data flows into the subscription, the subscription
|
|
248
|
+
// updates this map directly (for performance)
|
|
249
|
+
seriesRef.current, (axisId, end) => currentTimeRef.current.set(axisId, end), withCadenceOf);
|
|
250
|
+
}
|
|
251
|
+
return subscriptionTimeSeriesFor(seriesObservable, onSubscribe, windowingTime, axisAssignments, xAxesState, onUpdateData, dropDataAfter, updateTimingAndPlot,
|
|
252
|
+
// as new data flows into the subscription, the subscription
|
|
253
|
+
// updates this map directly (for performance)
|
|
254
|
+
seriesRef.current, (axisId, end) => currentTimeRef.current.set(axisId, end), timeWindowBehavior, initialTimes);
|
|
255
|
+
}, [
|
|
256
|
+
axisAssignments, dropDataAfter, mainG,
|
|
257
|
+
onSubscribe, onUpdateData,
|
|
258
|
+
seriesObservable, updateTimingAndPlot, windowingTime, xAxesState,
|
|
259
|
+
withCadenceOf,
|
|
260
|
+
initialTimes, timeWindowBehavior
|
|
261
|
+
]);
|
|
262
|
+
const timeRangesRef = useRef(new Map());
|
|
263
|
+
useEffect(() => {
|
|
264
|
+
if (container && mainG) {
|
|
265
|
+
// so this gets a bit complicated. the time-ranges need to be updated whenever the time-ranges
|
|
266
|
+
// change. for example, as data is streamed in, the times change, and then we need to update the
|
|
267
|
+
// time-range. however, we want to keep the time-ranges to reflect their original scale so that
|
|
268
|
+
// we can zoom properly (so the updates can't fuck with the scale). At the same time, when the
|
|
269
|
+
// interpolation changes, then the update plot changes, and the time-ranges must maintain their
|
|
270
|
+
// original scale as well.
|
|
271
|
+
if (timeRangesRef.current.size === 0) {
|
|
272
|
+
// when no time-ranges have yet been created, then create them and hold on to a mutable
|
|
273
|
+
// reference to them
|
|
274
|
+
timeRangesRef.current = continuousAxisRanges(xAxesState.axes);
|
|
275
|
+
}
|
|
276
|
+
else {
|
|
277
|
+
// when the time-ranges already exist, then we want to update the time-ranges for each
|
|
278
|
+
// existing time-range in a way that maintains the original scale.
|
|
279
|
+
const intervals = continuousAxisIntervals(xAxesState.axes);
|
|
280
|
+
timeRangesRef.current
|
|
281
|
+
.forEach((range, id, rangesMap) => {
|
|
282
|
+
const [start, end] = Optional.ofNullable(intervals.get(id))
|
|
283
|
+
.map(interval => interval.asTuple())
|
|
284
|
+
.getOrThrow(() => new Error(`Unable to retrieve interval for axis; axis_id: ${id}`));
|
|
285
|
+
// .getOrElse([NaN, NaN])
|
|
286
|
+
if (!isNaN(start) && !isNaN(end)) {
|
|
287
|
+
// update the reference map with the new (start, end) portion of the range,
|
|
288
|
+
// while keeping the original scale intact
|
|
289
|
+
rangesMap.set(id, range.update(start, end));
|
|
290
|
+
}
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
updatePlot(timeRangesRef.current, mainG);
|
|
294
|
+
}
|
|
295
|
+
}, [chartId, color, container, mainG, plotDimensions, updatePlot, xAxesState]);
|
|
296
|
+
// subscribe/unsubscribe to the observable chart data. when the `shouldSubscribe`
|
|
297
|
+
// is changed to `true` and we haven't subscribed yet, then subscribe. when the
|
|
298
|
+
// `shouldSubscribe` is `false` and we had subscribed, then unsubscribe. otherwise,
|
|
299
|
+
// do nothing.
|
|
300
|
+
useEffect(() => {
|
|
301
|
+
var _a;
|
|
302
|
+
if (shouldSubscribe && subscriptionRef.current === undefined) {
|
|
303
|
+
subscriptionRef.current = subscribe();
|
|
304
|
+
allowTooltip.current = false;
|
|
305
|
+
}
|
|
306
|
+
else if (!shouldSubscribe && subscriptionRef.current !== undefined) {
|
|
307
|
+
(_a = subscriptionRef.current) === null || _a === void 0 ? void 0 : _a.unsubscribe();
|
|
308
|
+
subscriptionRef.current = undefined;
|
|
309
|
+
allowTooltip.current = true;
|
|
310
|
+
}
|
|
311
|
+
}, [shouldSubscribe, subscribe]);
|
|
312
|
+
return null;
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* Attempts to locate the x- and y-axes for the specified series. If no axis is found for the
|
|
316
|
+
* series name, then uses the default returned by the useChart() hook
|
|
317
|
+
* @param seriesName Name of the series for which to retrieve the axis
|
|
318
|
+
* @param axisAssignments A map holding the series name and the associated x- and y-axes assigned
|
|
319
|
+
* to that series. Note that the series in the axis-assignment map is merely a subset of the set
|
|
320
|
+
* of series names.
|
|
321
|
+
* @param xAxisFor The function that accepts an axis ID and returns the corresponding x-axis
|
|
322
|
+
* @param yAxisFor The function that accepts an axis ID and returns the corresponding y-axis
|
|
323
|
+
*/
|
|
324
|
+
function axesFor(seriesName, axisAssignments, xAxisFor, yAxisFor) {
|
|
325
|
+
const axes = axisAssignments.get(seriesName);
|
|
326
|
+
const xAxis = xAxisFor((axes === null || axes === void 0 ? void 0 : axes.xAxis) || "");
|
|
327
|
+
const xAxisLinear = xAxis;
|
|
328
|
+
const yAxis = yAxisFor((axes === null || axes === void 0 ? void 0 : axes.yAxis) || "");
|
|
329
|
+
const yAxisLinear = yAxis;
|
|
330
|
+
if (xAxis && !xAxisLinear) {
|
|
331
|
+
throw Error("Scatter plot requires that x-axis be of type LinearAxis");
|
|
332
|
+
}
|
|
333
|
+
if (yAxis && !yAxisLinear) {
|
|
334
|
+
throw Error("Scatter plot requires that y-axis be of type LinearAxis");
|
|
335
|
+
}
|
|
336
|
+
return [xAxisLinear, yAxisLinear];
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* Renders a tooltip showing the neuron, spike time, and the spike strength when the mouse hovers over a spike.
|
|
340
|
+
* @param container The chart container
|
|
341
|
+
* @param xAxis The x-axis
|
|
342
|
+
* @param seriesName The name of the series (i.e. the neuron ID)
|
|
343
|
+
* @param series The time series
|
|
344
|
+
* @param event The mouse-over series event
|
|
345
|
+
* @param margin The plot margin
|
|
346
|
+
* @param seriesStyles The series style information (needed for (un)highlighting)
|
|
347
|
+
* @param allowTooltip When set to `false` won't show tooltip, even if it is visible (used by pan)
|
|
348
|
+
* @param mouseOverHandlerFor The handler for the mouse over (registered by the <Tooltip/>)
|
|
349
|
+
*/
|
|
350
|
+
function handleMouseOverSeries(container, xAxis, seriesName, series, event, margin, seriesStyles, allowTooltip, mouseOverHandlerFor) {
|
|
351
|
+
// grab the time needed for the tooltip ID
|
|
352
|
+
const [x, y] = d3.pointer(event, container);
|
|
353
|
+
const time = Math.round(xAxis.scale.invert(x - margin.left));
|
|
354
|
+
const { highlightColor, highlightWidth } = seriesStyles.get(seriesName) || defaultLineStyle();
|
|
355
|
+
// Use d3 to select element, change color and size
|
|
356
|
+
d3.select(event.currentTarget)
|
|
357
|
+
.attr('stroke', highlightColor)
|
|
358
|
+
.attr('stroke-width', highlightWidth);
|
|
359
|
+
if (mouseOverHandlerFor && allowTooltip) {
|
|
360
|
+
mouseOverHandlerFor(seriesName, time, { series, metadata: {} }, [x, y]);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
/**
|
|
364
|
+
* Unselects the time series and calls the mouse-leave-series handler registered for this series.
|
|
365
|
+
* @param seriesName The name of the series (i.e. the neuron ID)
|
|
366
|
+
* @param segment The SVG line element representing the spike, over which the mouse is hovering.
|
|
367
|
+
* @param seriesStyles The styles for the series (for (un)highlighting)
|
|
368
|
+
* @param mouseLeaverHandlerFor Registered handler for the series when the mouse leaves
|
|
369
|
+
*/
|
|
370
|
+
function handleMouseLeaveSeries(seriesName, segment, seriesStyles, mouseLeaverHandlerFor) {
|
|
371
|
+
const { color, lineWidth } = seriesStyles.get(seriesName) || defaultLineStyle();
|
|
372
|
+
d3.select(segment)
|
|
373
|
+
.attr('stroke', color)
|
|
374
|
+
.attr('stroke-width', lineWidth);
|
|
375
|
+
if (mouseLeaverHandlerFor) {
|
|
376
|
+
mouseLeaverHandlerFor(seriesName);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
//# sourceMappingURL=ScatterPlot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ScatterPlot.js","sourceRoot":"","sources":["../../../../../src/app/charts/plots/ScatterPlot.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { Dimensions
|
|
2
|
-
import { GSelection
|
|
3
|
-
export
|
|
4
|
-
export declare type TimeSeries = Array<[number, number]>;
|
|
1
|
+
import { Dimensions } from "../styling/margins";
|
|
2
|
+
import { GSelection } from "../d3types";
|
|
3
|
+
export type Series<D> = Array<D>;
|
|
5
4
|
/**
|
|
6
5
|
* Creates the main SVG for holding the plot.
|
|
7
6
|
* @param chartId A unique value identifying the chart.
|
|
@@ -13,18 +12,17 @@ export declare function createPlotContainer(chartId: number, container: SVGSVGEl
|
|
|
13
12
|
/**
|
|
14
13
|
* Adds a clip area for the chart to the specified SVG element. The clip-area is given
|
|
15
14
|
* an `id` of `clip-series-<chart_id>`, which because the chart ID should be unique, makes
|
|
16
|
-
* this unique as well
|
|
17
|
-
* @param chartId The ID of the chart to which the clip area is to be added
|
|
18
|
-
* @param
|
|
19
|
-
* @param plotDimensions The dimensions of the plot
|
|
20
|
-
* @
|
|
21
|
-
* @return The ID of the clip-path
|
|
15
|
+
* this unique as well.
|
|
16
|
+
* @param chartId The ID of the chart to which the clip area is to be added.
|
|
17
|
+
* @param plotGroup The SVG group element to which the clip area is to be added.
|
|
18
|
+
* @param plotDimensions The dimensions of the plot.
|
|
19
|
+
* @return The ID of the clip-path.
|
|
22
20
|
*/
|
|
23
|
-
export declare function
|
|
21
|
+
export declare function setClipPathG(chartId: number, plotGroup: GSelection, plotDimensions: Dimensions): string;
|
|
24
22
|
/**
|
|
25
|
-
* Represents the assignment of an x-axis and y-axis to a series.
|
|
26
|
-
*
|
|
27
|
-
*
|
|
23
|
+
* Represents the assignment of an x-axis and y-axis to a series. Plots (see, for example,
|
|
24
|
+
* {@link ScatterPlot} and {@link RasterPlot}) use this interface to manage the assignment
|
|
25
|
+
* of axes to series
|
|
28
26
|
*/
|
|
29
27
|
export interface AxesAssignment {
|
|
30
28
|
xAxis: string;
|
|
@@ -7,35 +7,37 @@ import * as d3 from "d3";
|
|
|
7
7
|
* @param color The SVG `color` attribute used for the axis
|
|
8
8
|
*/
|
|
9
9
|
export function createPlotContainer(chartId, container, plotDimensions, color) {
|
|
10
|
-
|
|
10
|
+
const { width, height } = plotDimensions;
|
|
11
11
|
return d3.select(container)
|
|
12
|
-
.attr('width', width)
|
|
13
|
-
.attr('height', height)
|
|
12
|
+
.attr('width', Math.max(0, width))
|
|
13
|
+
.attr('height', Math.max(0, height))
|
|
14
14
|
.attr('color', color)
|
|
15
15
|
.append('g')
|
|
16
|
-
.attr('id',
|
|
16
|
+
.attr('id', `main-container-${chartId}`);
|
|
17
17
|
}
|
|
18
18
|
/**
|
|
19
19
|
* Adds a clip area for the chart to the specified SVG element. The clip-area is given
|
|
20
20
|
* an `id` of `clip-series-<chart_id>`, which because the chart ID should be unique, makes
|
|
21
|
-
* this unique as well
|
|
22
|
-
* @param chartId The ID of the chart to which the clip area is to be added
|
|
23
|
-
* @param
|
|
24
|
-
* @param plotDimensions The dimensions of the plot
|
|
25
|
-
* @
|
|
26
|
-
* @return The ID of the clip-path
|
|
21
|
+
* this unique as well.
|
|
22
|
+
* @param chartId The ID of the chart to which the clip area is to be added.
|
|
23
|
+
* @param plotGroup The SVG group element to which the clip area is to be added.
|
|
24
|
+
* @param plotDimensions The dimensions of the plot.
|
|
25
|
+
* @return The ID of the clip-path.
|
|
27
26
|
*/
|
|
28
|
-
export function
|
|
29
|
-
|
|
27
|
+
export function setClipPathG(chartId, plotGroup, plotDimensions) {
|
|
28
|
+
const clipPathId = `chart-clip-path-${chartId}`;
|
|
30
29
|
// remove the old clipping region and add a new one with the updated plot dimensions
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
plotGroup.select(`#${clipPathId}-defs`).remove();
|
|
31
|
+
plotGroup
|
|
33
32
|
.append('defs')
|
|
33
|
+
.attr('id', `${clipPathId}-defs`)
|
|
34
34
|
.append("clipPath")
|
|
35
35
|
.attr("id", clipPathId)
|
|
36
36
|
.append("rect")
|
|
37
|
-
.attr("
|
|
38
|
-
.attr("
|
|
37
|
+
.attr("x", 0)
|
|
38
|
+
.attr("y", 0)
|
|
39
|
+
.attr("width", Math.max(0, plotDimensions.width))
|
|
40
|
+
.attr("height", Math.max(0, plotDimensions.height));
|
|
39
41
|
return clipPathId;
|
|
40
42
|
}
|
|
41
43
|
/**
|
|
@@ -44,5 +46,5 @@ export function setClipPath(chartId, svg, plotDimensions, margin) {
|
|
|
44
46
|
* @param yAxis The ID of the y-axis
|
|
45
47
|
* @return An {@link AxesAssignment}
|
|
46
48
|
*/
|
|
47
|
-
export
|
|
49
|
+
export const assignAxes = (xAxis, yAxis) => ({ xAxis, yAxis });
|
|
48
50
|
//# sourceMappingURL=plot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plot.js","sourceRoot":"","sources":["../../../../../src/app/charts/plots/plot.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AAKzB;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CAC/B,OAAe,EACf,SAAwB,EACxB,cAA0B,EAC1B,KAAa;IAEb,MAAM,EAAC,KAAK,EAAE,MAAM,EAAC,GAAG,cAAc,CAAA;IACtC,OAAO,EAAE,CAAC,MAAM,CAAqB,SAAS,CAAC;SAC1C,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;SACjC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;SACnC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC;SACpB,MAAM,CAAc,GAAG,CAAC;SACxB,IAAI,CAAC,IAAI,EAAE,kBAAkB,OAAO,EAAE,CAAC,CAAA;AAChD,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,YAAY,CAAC,OAAe,EAAE,SAAqB,EAAE,cAA0B;IAC3F,MAAM,UAAU,GAAG,mBAAmB,OAAO,EAAE,CAAA;IAE/C,oFAAoF;IACpF,SAAS,CAAC,MAAM,CAAC,IAAI,UAAU,OAAO,CAAC,CAAC,MAAM,EAAE,CAAC;IACjD,SAAS;SACJ,MAAM,CAAC,MAAM,CAAC;SACV,IAAI,CAAC,IAAI,EAAE,GAAG,UAAU,OAAO,CAAC;SACpC,MAAM,CAAC,UAAU,CAAC;SACd,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC;SAC1B,MAAM,CAAC,MAAM,CAAC;SACV,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;SACZ,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;SACZ,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,cAAc,CAAC,KAAK,CAAC,CAAC;SAChD,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC,CAAA;IAE3D,OAAO,UAAU,CAAA;AACrB,CAAC;AAYD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,KAAa,EAAE,KAAa,EAAkB,EAAE,CAAC,CAAC,EAAC,KAAK,EAAE,KAAK,EAAC,CAAC,CAAA"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { Result } from "result-fn";
|
|
2
|
+
/**
|
|
3
|
+
* A spike series holding an array of spike (time, value) datum, the name and supplemental information
|
|
4
|
+
* needed by the `RasterChart`
|
|
5
|
+
*/
|
|
6
|
+
export interface BaseSeries<D> {
|
|
7
|
+
readonly name: string;
|
|
8
|
+
data: Array<D>;
|
|
9
|
+
readonly last: () => Result<D, string>;
|
|
10
|
+
readonly length: () => number;
|
|
11
|
+
readonly isEmpty: () => boolean;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Creates a series from the name and the optional array of `Datum`.
|
|
15
|
+
* @param name The name of the series (i.e. neuron)
|
|
16
|
+
* @param data The array of datum, which could be `(t, f(t))`, or `(f[n](x), f[n+1](x))`
|
|
17
|
+
* @return A {@link BaseSeries} for object that can be used by in {@link Chart}s
|
|
18
|
+
* @see seriesFromTuples
|
|
19
|
+
* @see emptySeries
|
|
20
|
+
*/
|
|
21
|
+
export declare function seriesFrom<D>(name: string, data?: Array<D>): BaseSeries<D>;
|
|
22
|
+
/**
|
|
23
|
+
* Returns an empty series with the specified name
|
|
24
|
+
* @param name The name of the series
|
|
25
|
+
* @return The empty series
|
|
26
|
+
* @see seriesFrom
|
|
27
|
+
* @see seriesFromTuples
|
|
28
|
+
*/
|
|
29
|
+
export declare const emptySeries: <D>(name: string) => BaseSeries<D>;
|
|
30
|
+
/**
|
|
31
|
+
* Creates an array of empty series, one for each specified name
|
|
32
|
+
* @param names The names for each of the empty series
|
|
33
|
+
* @return An array of empty series with the specified names
|
|
34
|
+
* @see emptySeries
|
|
35
|
+
* @see seriesFrom
|
|
36
|
+
* @see seriesFromTuples
|
|
37
|
+
*/
|
|
38
|
+
export declare const emptySeriesFor: <D>(names: Array<string>) => Array<BaseSeries<D>>;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { failureResult, successResult } from "result-fn";
|
|
2
|
+
/**
|
|
3
|
+
* Creates a series from the name and the optional array of `Datum`.
|
|
4
|
+
* @param name The name of the series (i.e. neuron)
|
|
5
|
+
* @param data The array of datum, which could be `(t, f(t))`, or `(f[n](x), f[n+1](x))`
|
|
6
|
+
* @return A {@link BaseSeries} for object that can be used by in {@link Chart}s
|
|
7
|
+
* @see seriesFromTuples
|
|
8
|
+
* @see emptySeries
|
|
9
|
+
*/
|
|
10
|
+
export function seriesFrom(name, data = []) {
|
|
11
|
+
return {
|
|
12
|
+
name: name,
|
|
13
|
+
data: data,
|
|
14
|
+
last: () => data ? (data.length > 0 ? successResult(data[data.length - 1]) : failureResult("Data is empty")) : failureResult("Data is not defined"),
|
|
15
|
+
length: () => data ? data.length : 0,
|
|
16
|
+
isEmpty: () => data ? data.length === 0 : true
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Returns an empty series with the specified name
|
|
21
|
+
* @param name The name of the series
|
|
22
|
+
* @return The empty series
|
|
23
|
+
* @see seriesFrom
|
|
24
|
+
* @see seriesFromTuples
|
|
25
|
+
*/
|
|
26
|
+
export const emptySeries = (name) => seriesFrom(name);
|
|
27
|
+
/**
|
|
28
|
+
* Creates an array of empty series, one for each specified name
|
|
29
|
+
* @param names The names for each of the empty series
|
|
30
|
+
* @return An array of empty series with the specified names
|
|
31
|
+
* @see emptySeries
|
|
32
|
+
* @see seriesFrom
|
|
33
|
+
* @see seriesFromTuples
|
|
34
|
+
*/
|
|
35
|
+
export const emptySeriesFor = (names) => names.map(name => seriesFrom(name));
|
|
36
|
+
//# sourceMappingURL=baseSeries.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"baseSeries.js","sourceRoot":"","sources":["../../../../../src/app/charts/series/baseSeries.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,aAAa,EAAU,aAAa,EAAC,MAAM,WAAW,CAAC;AAc/D;;;;;;;GAOG;AACH,MAAM,UAAU,UAAU,CAAI,IAAY,EAAE,OAAiB,EAAE;IAC3D,OAAO;QACH,IAAI,EAAE,IAAI;QACV,IAAI,EAAE,IAAI;QACV,IAAI,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,aAAa,CAAY,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAY,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAY,qBAAqB,CAAC;QACpL,MAAM,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACpC,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI;KACjD,CAAA;AACL,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAI,IAAY,EAAiB,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;AAEhF;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAI,KAAoB,EAAwB,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|