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,75 @@
|
|
|
1
|
+
import {Dimensions} from "../styling/margins";
|
|
2
|
+
import * as d3 from "d3";
|
|
3
|
+
import {GSelection} from "../d3types";
|
|
4
|
+
|
|
5
|
+
export type Series<D> = Array<D>
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Creates the main SVG for holding the plot.
|
|
9
|
+
* @param chartId A unique value identifying the chart.
|
|
10
|
+
* @param container The SVG element interface
|
|
11
|
+
* @param plotDimensions The dimensions of the plot
|
|
12
|
+
* @param color The SVG `color` attribute used for the axis
|
|
13
|
+
*/
|
|
14
|
+
export function createPlotContainer(
|
|
15
|
+
chartId: number,
|
|
16
|
+
container: SVGSVGElement,
|
|
17
|
+
plotDimensions: Dimensions,
|
|
18
|
+
color: string
|
|
19
|
+
): GSelection {
|
|
20
|
+
const {width, height} = plotDimensions
|
|
21
|
+
return d3.select<SVGSVGElement, any>(container)
|
|
22
|
+
.attr('width', Math.max(0, width))
|
|
23
|
+
.attr('height', Math.max(0, height))
|
|
24
|
+
.attr('color', color)
|
|
25
|
+
.append<SVGGElement>('g')
|
|
26
|
+
.attr('id', `main-container-${chartId}`)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Adds a clip area for the chart to the specified SVG element. The clip-area is given
|
|
31
|
+
* an `id` of `clip-series-<chart_id>`, which because the chart ID should be unique, makes
|
|
32
|
+
* this unique as well.
|
|
33
|
+
* @param chartId The ID of the chart to which the clip area is to be added.
|
|
34
|
+
* @param plotGroup The SVG group element to which the clip area is to be added.
|
|
35
|
+
* @param plotDimensions The dimensions of the plot.
|
|
36
|
+
* @return The ID of the clip-path.
|
|
37
|
+
*/
|
|
38
|
+
export function setClipPathG(chartId: number, plotGroup: GSelection, plotDimensions: Dimensions): string {
|
|
39
|
+
const clipPathId = `chart-clip-path-${chartId}`
|
|
40
|
+
|
|
41
|
+
// remove the old clipping region and add a new one with the updated plot dimensions
|
|
42
|
+
plotGroup.select(`#${clipPathId}-defs`).remove();
|
|
43
|
+
plotGroup
|
|
44
|
+
.append('defs')
|
|
45
|
+
.attr('id', `${clipPathId}-defs`)
|
|
46
|
+
.append("clipPath")
|
|
47
|
+
.attr("id", clipPathId)
|
|
48
|
+
.append("rect")
|
|
49
|
+
.attr("x", 0)
|
|
50
|
+
.attr("y", 0)
|
|
51
|
+
.attr("width", Math.max(0, plotDimensions.width))
|
|
52
|
+
.attr("height", Math.max(0, plotDimensions.height))
|
|
53
|
+
|
|
54
|
+
return clipPathId
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Represents the assignment of an x-axis and y-axis to a series. Plots (see, for example,
|
|
59
|
+
* {@link ScatterPlot} and {@link RasterPlot}) use this interface to manage the assignment
|
|
60
|
+
* of axes to series
|
|
61
|
+
*/
|
|
62
|
+
export interface AxesAssignment {
|
|
63
|
+
xAxis: string
|
|
64
|
+
yAxis: string
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Factory function for the assignment of axes to series
|
|
69
|
+
* @param xAxis The ID of the x-axis
|
|
70
|
+
* @param yAxis The ID of the y-axis
|
|
71
|
+
* @return An {@link AxesAssignment}
|
|
72
|
+
*/
|
|
73
|
+
export const assignAxes = (xAxis: string, yAxis: string): AxesAssignment => ({xAxis, yAxis})
|
|
74
|
+
|
|
75
|
+
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import {failureResult, Result, successResult} from "result-fn";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* A spike series holding an array of spike (time, value) datum, the name and supplemental information
|
|
5
|
+
* needed by the `RasterChart`
|
|
6
|
+
*/
|
|
7
|
+
export interface BaseSeries<D> {
|
|
8
|
+
readonly name: string;
|
|
9
|
+
data: Array<D>;
|
|
10
|
+
readonly last: () => Result<D, string>;
|
|
11
|
+
readonly length: () => number;
|
|
12
|
+
readonly isEmpty: () => boolean;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Creates a series from the name and the optional array of `Datum`.
|
|
17
|
+
* @param name The name of the series (i.e. neuron)
|
|
18
|
+
* @param data The array of datum, which could be `(t, f(t))`, or `(f[n](x), f[n+1](x))`
|
|
19
|
+
* @return A {@link BaseSeries} for object that can be used by in {@link Chart}s
|
|
20
|
+
* @see seriesFromTuples
|
|
21
|
+
* @see emptySeries
|
|
22
|
+
*/
|
|
23
|
+
export function seriesFrom<D>(name: string, data: Array<D> = []): BaseSeries<D> {
|
|
24
|
+
return {
|
|
25
|
+
name: name,
|
|
26
|
+
data: data,
|
|
27
|
+
last: () => data ? (data.length > 0 ? successResult<D, string>(data[data.length - 1]) : failureResult<D, string>("Data is empty")) : failureResult<D, string>("Data is not defined"),
|
|
28
|
+
length: () => data ? data.length : 0,
|
|
29
|
+
isEmpty: () => data ? data.length === 0 : true
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Returns an empty series with the specified name
|
|
35
|
+
* @param name The name of the series
|
|
36
|
+
* @return The empty series
|
|
37
|
+
* @see seriesFrom
|
|
38
|
+
* @see seriesFromTuples
|
|
39
|
+
*/
|
|
40
|
+
export const emptySeries = <D>(name: string): BaseSeries<D> => seriesFrom(name);
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Creates an array of empty series, one for each specified name
|
|
44
|
+
* @param names The names for each of the empty series
|
|
45
|
+
* @return An array of empty series with the specified names
|
|
46
|
+
* @see emptySeries
|
|
47
|
+
* @see seriesFrom
|
|
48
|
+
* @see seriesFromTuples
|
|
49
|
+
*/
|
|
50
|
+
export const emptySeriesFor = <D>(names: Array<string>): Array<BaseSeries<D>> => names.map(name => seriesFrom(name))
|
|
51
|
+
|
|
52
|
+
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import {emptySeries, seriesFrom} from "./baseSeries";
|
|
2
|
+
|
|
3
|
+
describe('should be able to create an empty series', () => {
|
|
4
|
+
test('an empty series should be empty', () => {
|
|
5
|
+
expect(emptySeries('test1').isEmpty());
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
test('an empty series should not have a last element', () => {
|
|
9
|
+
expect(emptySeries('test1').last().failed);
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
test('an empty series should have 0 length', () => {
|
|
13
|
+
expect(emptySeries('test1').length()).toBe(0);
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
test('an empty series should not have any data', () => {
|
|
17
|
+
expect(emptySeries('test1').data.length).toBe(0);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
test('an empty series should have the specified name', () => {
|
|
21
|
+
expect(emptySeries('test1').name).toBe('test1');
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
describe('should be able to create a series from data', () => {
|
|
26
|
+
const data = [
|
|
27
|
+
{time: 1, value: 10},
|
|
28
|
+
{time: 2, value: 20},
|
|
29
|
+
{time: 3, value: 30},
|
|
30
|
+
{time: 4, value: 40},
|
|
31
|
+
{time: 5, value: 50},
|
|
32
|
+
{time: 6, value: 60},
|
|
33
|
+
{time: 7, value: 70},
|
|
34
|
+
{time: 8, value: 80},
|
|
35
|
+
{time: 9, value: 90},
|
|
36
|
+
{time: 10, value: 100},
|
|
37
|
+
];
|
|
38
|
+
const series = seriesFrom('test2', data);
|
|
39
|
+
|
|
40
|
+
test('series should not be empty', () => {
|
|
41
|
+
expect(!series.isEmpty())
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
test('series name should be test2', () => {
|
|
45
|
+
expect(series.name).toEqual('test2')
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
test('series should have 10 points', () => {
|
|
49
|
+
expect(series.length()).toBe(10);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
test('last value in series should be (10, 100)', () => {
|
|
53
|
+
const lastElement = series.last().getOrElse({time: NaN, value: NaN});
|
|
54
|
+
expect(lastElement).toEqual({time: 10, value: 100});
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
test('series data should equal original data', () => {
|
|
58
|
+
expect(series.data).toEqual(data);
|
|
59
|
+
});
|
|
60
|
+
});
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import {BaseSeries, seriesFrom} from "./baseSeries";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* An immutable datum object that holds the iterate `(f[n](x), f[n+1](x))` with an
|
|
5
|
+
* informational time
|
|
6
|
+
*/
|
|
7
|
+
export interface IterateDatum {
|
|
8
|
+
readonly time: number;
|
|
9
|
+
readonly iterateN: number;
|
|
10
|
+
readonly iterateN_1: number
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Creates an empty iterate datum
|
|
15
|
+
*/
|
|
16
|
+
export const emptyIterateDatum: IterateDatum = {time: NaN, iterateN: NaN, iterateN_1: NaN}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Creates an iterate datum
|
|
20
|
+
* @param time The informational time
|
|
21
|
+
* @param iterateN The n-th iterate (i.e. `f[n](x)`)
|
|
22
|
+
* @param iterateN_1 The (n+1)-th iterate (i.e. `f[n+1](x)`)
|
|
23
|
+
* @return An iterate datum
|
|
24
|
+
*/
|
|
25
|
+
export const iterateDatumOf = (time: number, iterateN: number, iterateN_1: number): IterateDatum => ({
|
|
26
|
+
time,
|
|
27
|
+
iterateN,
|
|
28
|
+
iterateN_1
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Returns whether the iterate datum is considered empty. An iterate datum is considered
|
|
33
|
+
* empty when the time, `f[n](x)`, `f[n+1](x)` values are all `NaN`
|
|
34
|
+
* @param datum The iterate datum to test
|
|
35
|
+
* @return `true` if the iterate datum is empty; `false` otherwise
|
|
36
|
+
*/
|
|
37
|
+
export const nonEmptyIterateDatum = (datum: IterateDatum): boolean =>
|
|
38
|
+
!isNaN(datum.time) && !isNaN(datum.iterateN) && !isNaN(datum.iterateN_1)
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* A series of iterate (i.e. `(f[n](x), f[n+1](x))` pairs)
|
|
42
|
+
*/
|
|
43
|
+
export type IterateSeries = BaseSeries<IterateDatum>
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Creates a series from the name and the optional array of (x, y) pairs (tuples)
|
|
47
|
+
* @param name The name of the series
|
|
48
|
+
* @param data The optional array of (x, y) pairs (tuples)
|
|
49
|
+
* @return A `Series` for object that can be used by the `PoincarePlot`
|
|
50
|
+
* @see seriesFrom
|
|
51
|
+
* @see emptySeries
|
|
52
|
+
*/
|
|
53
|
+
export const iterateSeriesFromTuples = (name: string, data: Array<[number, number, number]> = []): IterateSeries =>
|
|
54
|
+
seriesFrom(name, data.map(([t, fn, fn_1]) => iterateDatumOf(t, fn, fn_1)))
|
|
55
|
+
|
|
56
|
+
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import {BaseSeries, seriesFrom} from "./baseSeries";
|
|
2
|
+
import {
|
|
3
|
+
initialMaxTimeDatum,
|
|
4
|
+
initialMaxValueDatum, initialMinTimeDatum,
|
|
5
|
+
initialMinValueDatum,
|
|
6
|
+
OrdinalChartData,
|
|
7
|
+
OrdinalStats,
|
|
8
|
+
OrdinalValueStats
|
|
9
|
+
} from "../observables/ordinals";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* An immutable datum object for series with a category and value.
|
|
13
|
+
* This could be a series of (ordinal, value) where the category runs
|
|
14
|
+
* along the x-axis. Or, it could be a series of (value, ordinal) where
|
|
15
|
+
* the categories run along the y-axis.
|
|
16
|
+
*/
|
|
17
|
+
export interface OrdinalDatum {
|
|
18
|
+
readonly time: number
|
|
19
|
+
readonly ordinal: string
|
|
20
|
+
readonly value: number
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Creates an empty ordinal datum
|
|
26
|
+
*/
|
|
27
|
+
export const emptyOrdinalDatum: OrdinalDatum = {
|
|
28
|
+
time: NaN,
|
|
29
|
+
ordinal: "",
|
|
30
|
+
value: NaN,
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export const copyOrdinalDatum = (datum: OrdinalDatum): OrdinalDatum => ({
|
|
34
|
+
time: datum.time,
|
|
35
|
+
ordinal: datum.ordinal,
|
|
36
|
+
value: datum.value,
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Creates an iterate datum
|
|
41
|
+
* @param time The datum time, which is mostly informational
|
|
42
|
+
* @param ordinal The category name or identifier
|
|
43
|
+
* @param value The value
|
|
44
|
+
* @return An iterate datum
|
|
45
|
+
*/
|
|
46
|
+
export const ordinalDatumOf = (time: number, ordinal: string, value: number): OrdinalDatum => ({
|
|
47
|
+
time,
|
|
48
|
+
ordinal,
|
|
49
|
+
value,
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Returns whether the ordinal datum is empty. An ordinal datum is considered empty
|
|
55
|
+
* when the time is NaN, the ordinal is blank (empty or only whitespace), and the value
|
|
56
|
+
* is NaN.
|
|
57
|
+
* @param datum The iterate datum to test
|
|
58
|
+
* @return `true` if the iterate datum is empty; `false` otherwise
|
|
59
|
+
*/
|
|
60
|
+
export const nonEmptyOrdinalDatum = (datum: OrdinalDatum): boolean =>
|
|
61
|
+
!isNaN(datum.time) && datum.ordinal.replace(/\s/g, "").length > 0 && !isNaN(datum.value)
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* A series of ordinal datum
|
|
65
|
+
*/
|
|
66
|
+
export type OrdinalSeries = BaseSeries<OrdinalDatum>
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Creates a series from the name and the optional array of (time, ordinal, value) tuples
|
|
70
|
+
* @param name The name of the series
|
|
71
|
+
* @param data The optional array of (time, ordinal, value) tuples
|
|
72
|
+
* @return An {@link OrdinalSeries} for charts where one axis is the category, and the other a value
|
|
73
|
+
* @see seriesFrom
|
|
74
|
+
* @see emptySeries
|
|
75
|
+
*/
|
|
76
|
+
export function ordinateSeriesFromTuples(
|
|
77
|
+
name: string,
|
|
78
|
+
data: Array<[time: number, ordinal: string, value: number]> = []
|
|
79
|
+
): OrdinalSeries {
|
|
80
|
+
return seriesFrom(
|
|
81
|
+
name,
|
|
82
|
+
data.map(([t, ordinal, value]) => ordinalDatumOf(t, ordinal, value))
|
|
83
|
+
)
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Creates an empty chart data object with all the values set to 0
|
|
88
|
+
* @param seriesList The list of series names (identifiers) to update
|
|
89
|
+
* @return An empty chart data object
|
|
90
|
+
*/
|
|
91
|
+
export function initialOrdinalChartData(seriesList: Array<OrdinalSeries>): OrdinalChartData {
|
|
92
|
+
return {
|
|
93
|
+
seriesNames: new Set(seriesList.map(series => series.name)),
|
|
94
|
+
stats: calculateOrdinalStats(seriesList),
|
|
95
|
+
newPoints: new Map<string, Array<OrdinalDatum>>(seriesList.map(series => [
|
|
96
|
+
series.name,
|
|
97
|
+
series.data.map(datum => ({
|
|
98
|
+
time: datum.time,
|
|
99
|
+
ordinal: datum.ordinal,
|
|
100
|
+
value: datum.value,
|
|
101
|
+
}))
|
|
102
|
+
]))
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export function calculateOrdinalStats(seriesList: Array<OrdinalSeries>): OrdinalStats {
|
|
107
|
+
const ordinalValueStats = new Map<string, OrdinalValueStats>(seriesList.map(
|
|
108
|
+
(series: OrdinalSeries) => {
|
|
109
|
+
const seriesMin = series.data.reduce(
|
|
110
|
+
(min, datum) => datum.value < min.value ? datum : min,
|
|
111
|
+
initialMinValueDatum()
|
|
112
|
+
)
|
|
113
|
+
const seriesMax = series.data.reduce(
|
|
114
|
+
(max, datum) => datum.value > max.value ? datum : max,
|
|
115
|
+
initialMaxValueDatum()
|
|
116
|
+
)
|
|
117
|
+
const seriesSum = series.data.reduce((sum, datum) => sum + datum.value, 0)
|
|
118
|
+
const seriesSumSquared = series.data.reduce((sumSquared, datum) => sumSquared + datum.value * datum.value, 0)
|
|
119
|
+
const seriesMean = series.data.length > 0 ? seriesSum / series.data.length : NaN
|
|
120
|
+
return [series.name, {
|
|
121
|
+
max: seriesMax,
|
|
122
|
+
min: seriesMin,
|
|
123
|
+
count: series.data.length,
|
|
124
|
+
sum: seriesSum,
|
|
125
|
+
sumSquared: seriesSumSquared,
|
|
126
|
+
mean: seriesMean,
|
|
127
|
+
}]
|
|
128
|
+
}
|
|
129
|
+
))
|
|
130
|
+
const minValueDatum: OrdinalDatum = Array.from(ordinalValueStats.values()).reduce(
|
|
131
|
+
(min: OrdinalDatum, value: OrdinalValueStats) => value.min.value < min.value ? value.min : min,
|
|
132
|
+
initialMinValueDatum()
|
|
133
|
+
)
|
|
134
|
+
const maxValueDatum: OrdinalDatum = Array.from(ordinalValueStats.values()).reduce(
|
|
135
|
+
(max: OrdinalDatum, value: OrdinalValueStats) => value.max.value > max.value ? value.max : max,
|
|
136
|
+
initialMaxValueDatum()
|
|
137
|
+
)
|
|
138
|
+
const minTimeDatum: OrdinalDatum = seriesList.reduce(
|
|
139
|
+
(globalMin: OrdinalDatum, series: OrdinalSeries) => {
|
|
140
|
+
const seriesMin = series.data.reduce(
|
|
141
|
+
(min, datum) => datum.value < min.value ? datum : min,
|
|
142
|
+
globalMin
|
|
143
|
+
)
|
|
144
|
+
return seriesMin.value < globalMin.value ? seriesMin : globalMin
|
|
145
|
+
},
|
|
146
|
+
initialMinTimeDatum()
|
|
147
|
+
)
|
|
148
|
+
const maxTimeDatum: OrdinalDatum = seriesList.reduce(
|
|
149
|
+
(globalMax: OrdinalDatum, series: OrdinalSeries) => {
|
|
150
|
+
const seriesMax = series.data.reduce(
|
|
151
|
+
(max, datum) => datum.value > max.value ? datum : max,
|
|
152
|
+
globalMax
|
|
153
|
+
)
|
|
154
|
+
return seriesMax.value > globalMax.value ? seriesMax : globalMax
|
|
155
|
+
},
|
|
156
|
+
initialMaxTimeDatum()
|
|
157
|
+
)
|
|
158
|
+
return {
|
|
159
|
+
maxDatum: {time: maxTimeDatum, value: maxValueDatum},
|
|
160
|
+
minDatum: {time: minTimeDatum, value: minValueDatum},
|
|
161
|
+
valueStatsForSeries: ordinalValueStats
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import {BaseSeries, seriesFrom} from "./baseSeries";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* An immutable datum object that holds the spike (time, value) representing a neuron spike
|
|
5
|
+
*/
|
|
6
|
+
export interface Datum {
|
|
7
|
+
readonly time: number;
|
|
8
|
+
readonly value: number;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Creates a datum from a (time, value) pair
|
|
13
|
+
* @param time The time
|
|
14
|
+
* @param value The value
|
|
15
|
+
* @return A {@link Datum} instance with the specified (time, value)
|
|
16
|
+
*/
|
|
17
|
+
export const datumOf = (time: number, value: number): Datum => ({time, value})
|
|
18
|
+
|
|
19
|
+
export const emptyDatum = (): Datum => ({time: NaN, value: NaN})
|
|
20
|
+
|
|
21
|
+
export type TimeSeries = BaseSeries<Datum>
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Creates a series from the name and the optional array of (x, y) pairs (tuples)
|
|
26
|
+
* @param name The name of the series
|
|
27
|
+
* @param data The optional array of (x, y) pairs (tuples)
|
|
28
|
+
* @return A `Series` for object that can be used by the `RasterChart`
|
|
29
|
+
* @see seriesFrom
|
|
30
|
+
* @see emptySeries
|
|
31
|
+
*/
|
|
32
|
+
export const timeSeriesFromTuples = (name: string, data: Array<[number, number]> = []): TimeSeries =>
|
|
33
|
+
seriesFrom(name, data.map(([t, y]) => datumOf(t, y)))
|
|
34
|
+
|
|
35
|
+
export interface PixelDatum extends Datum {
|
|
36
|
+
x: number;
|
|
37
|
+
y: number;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import {Datum, TimeSeries} from "./timeSeries";
|
|
2
|
+
import {ChartData, defaultChartData} from "../observables/ChartData";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* The spike-chart data produced by the rxjs observable that is pushed to a streaming chart
|
|
6
|
+
*/
|
|
7
|
+
export interface TimeSeriesChartData extends ChartData {
|
|
8
|
+
/**
|
|
9
|
+
* The max (latest) time for the data in the newPoints map
|
|
10
|
+
*/
|
|
11
|
+
maxTime: number
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Holds the association of the series name to the current max time for that series
|
|
15
|
+
*/
|
|
16
|
+
maxTimes: Map<string, number>
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Map holding the name of the series (the time-series identifier) and the associated
|
|
20
|
+
* data points for that time-series (`map(series_name -> array(datum))`)
|
|
21
|
+
*/
|
|
22
|
+
newPoints: Map<string, Array<Datum>>
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* The current time (for example, when used with cadence)
|
|
26
|
+
*/
|
|
27
|
+
currentTime?: number
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Creates an empty chart data object with all the values set to 0
|
|
32
|
+
* @param {Array<string>} series The list of series names (identifiers) to update
|
|
33
|
+
* @return {TimeSeriesChartData} An empty chart data object
|
|
34
|
+
*/
|
|
35
|
+
export function emptyTimeSeriesChartData(series: Array<string>): TimeSeriesChartData {
|
|
36
|
+
return {
|
|
37
|
+
...defaultChartData(),
|
|
38
|
+
maxTime: 0,
|
|
39
|
+
maxTimes: new Map(series.map(name => [name, 0])),
|
|
40
|
+
newPoints: new Map<string, Array<Datum>>(series.map(name => [name, [{time: 0, value: 0}]]))
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Creates an empty chart data object with all the values set to 0
|
|
46
|
+
* @param seriesList The list of series names (identifiers) to update
|
|
47
|
+
* @param [currentTime=0] The current time
|
|
48
|
+
* @return An empty chart data object
|
|
49
|
+
*/
|
|
50
|
+
export function initialTimeSeriesChartData(seriesList: Array<TimeSeries>, currentTime: number = 0): TimeSeriesChartData {
|
|
51
|
+
const maxTime = seriesList.reduce(
|
|
52
|
+
(tMax, series) => Math.max(tMax, series.last().map(datum => datum.time).getOrElse(-Infinity)),
|
|
53
|
+
-Infinity
|
|
54
|
+
)
|
|
55
|
+
return {
|
|
56
|
+
seriesNames: new Set(seriesList.map(series => series.name)),
|
|
57
|
+
maxTime,
|
|
58
|
+
maxTimes: new Map(seriesList.map(series => [series.name, series.last().map(datum => datum.time).getOrElse(0)])),
|
|
59
|
+
newPoints: new Map<string, Array<Datum>>(seriesList.map(series => [
|
|
60
|
+
series.name,
|
|
61
|
+
[{
|
|
62
|
+
time: series.last().map(datum => datum.time).getOrElse(0),
|
|
63
|
+
value: series.last().map(datum => datum.value).getOrElse(0)
|
|
64
|
+
}]
|
|
65
|
+
])),
|
|
66
|
+
currentTime: currentTime
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import {SeriesStyle} from "../axes/axes";
|
|
2
|
+
import {SvgFillStyle, SvgStrokeStyle} from "./svgStyle";
|
|
3
|
+
import * as d3 from "d3";
|
|
4
|
+
|
|
5
|
+
export interface BarSeriesStyle extends SeriesStyle {
|
|
6
|
+
/**
|
|
7
|
+
* The bar style for the lifetime min/max range bar. The style is for the width, fill,
|
|
8
|
+
* and stroke.
|
|
9
|
+
*/
|
|
10
|
+
minMaxBar: BarStyle
|
|
11
|
+
/**
|
|
12
|
+
* The bar style for the windowed min/max range bar. The style is for the width, fill,
|
|
13
|
+
* and stroke.
|
|
14
|
+
*/
|
|
15
|
+
windowedMinMaxBar: BarStyle
|
|
16
|
+
/**
|
|
17
|
+
* The line style for the current value.
|
|
18
|
+
*/
|
|
19
|
+
valueLine: LineStyle
|
|
20
|
+
/**
|
|
21
|
+
* The line style for the mean value.
|
|
22
|
+
*/
|
|
23
|
+
meanValueLine: LineStyle
|
|
24
|
+
/**
|
|
25
|
+
* The line style for the windowed-mean value.
|
|
26
|
+
*/
|
|
27
|
+
windowedMeanValueLine: LineStyle
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface BarStyle {
|
|
31
|
+
widthFraction: number
|
|
32
|
+
fill: SvgFillStyle
|
|
33
|
+
stroke: SvgStrokeStyle
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface LineStyle {
|
|
37
|
+
regular: SvgStrokeStyle
|
|
38
|
+
highlight: SvgStrokeStyle
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function defaultMinMaxBarStyle(color: string = "#008aad"): BarStyle {
|
|
42
|
+
return {
|
|
43
|
+
widthFraction: 0.65,
|
|
44
|
+
fill: {
|
|
45
|
+
color,
|
|
46
|
+
opacity: 0.4
|
|
47
|
+
},
|
|
48
|
+
stroke: {
|
|
49
|
+
width: 1,
|
|
50
|
+
opacity: 0.6,
|
|
51
|
+
color,
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export function defaultWindowedMinMaxBarStyle(color: string = "#008aad"): BarStyle {
|
|
57
|
+
return {
|
|
58
|
+
widthFraction: 0.25,
|
|
59
|
+
fill: {
|
|
60
|
+
color: d3.color(color)?.darker(0.3).toString() ?? color,
|
|
61
|
+
opacity: 0.6
|
|
62
|
+
},
|
|
63
|
+
stroke: {
|
|
64
|
+
width: 0,
|
|
65
|
+
opacity: 0,
|
|
66
|
+
color: d3.color(color)?.darker(0.3).toString() ?? color,
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export function defaultValueLineStyle(color: string = "#008aad"): LineStyle {
|
|
72
|
+
return {
|
|
73
|
+
regular: {
|
|
74
|
+
color,
|
|
75
|
+
opacity: 0.6,
|
|
76
|
+
width: 3
|
|
77
|
+
},
|
|
78
|
+
highlight: {
|
|
79
|
+
color,
|
|
80
|
+
opacity: 1,
|
|
81
|
+
width: 5
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export function defaultMeanValueLineStyle(color: string = "#008aad"): LineStyle {
|
|
87
|
+
return {
|
|
88
|
+
regular: {
|
|
89
|
+
color,
|
|
90
|
+
opacity: 0.6,
|
|
91
|
+
width: 1
|
|
92
|
+
},
|
|
93
|
+
highlight: {
|
|
94
|
+
color,
|
|
95
|
+
opacity: 1,
|
|
96
|
+
width: 3
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export function defaultWindowedMeanValueLineStyle(color: string = "#008aad"): LineStyle {
|
|
102
|
+
return {
|
|
103
|
+
regular: {
|
|
104
|
+
color: 'red',
|
|
105
|
+
opacity: 0.6,
|
|
106
|
+
width: 1
|
|
107
|
+
},
|
|
108
|
+
highlight: {
|
|
109
|
+
color: 'red',
|
|
110
|
+
opacity: 1,
|
|
111
|
+
width: 3
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export function defaultBarSeriesStyle(color: string = "#008aad"): BarSeriesStyle {
|
|
117
|
+
return {
|
|
118
|
+
color,
|
|
119
|
+
highlightColor: color,
|
|
120
|
+
minMaxBar: defaultMinMaxBarStyle(color),
|
|
121
|
+
windowedMinMaxBar: defaultWindowedMinMaxBarStyle(color),
|
|
122
|
+
valueLine: defaultValueLineStyle(color),
|
|
123
|
+
meanValueLine: defaultMeanValueLineStyle(color),
|
|
124
|
+
windowedMeanValueLine: defaultWindowedMeanValueLineStyle(color),
|
|
125
|
+
}
|
|
126
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import {plotDimensionsFrom, Margin, containerDimensionsFrom} from "./margins";
|
|
2
|
+
|
|
3
|
+
describe('adjusted dimension should correct for margins', () => {
|
|
4
|
+
const margins: Margin = {top: 11, bottom: 12, left: 13, right: 14};
|
|
5
|
+
const width = 100;
|
|
6
|
+
const height = 200;
|
|
7
|
+
const dimensions = plotDimensionsFrom(width, height, margins);
|
|
8
|
+
|
|
9
|
+
test('adjusted width should have the left and right margins removed', () => {
|
|
10
|
+
expect(dimensions.width).toBe(width - margins.right - margins.left);
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
test('adjusted height should have the top and bottom margins removed', () => {
|
|
14
|
+
expect(dimensions.height).toBe(height - margins.top - margins.bottom);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
test('should be able to get back the container dimensions after calculate the plot dimensions', () => {
|
|
18
|
+
const {width: containerWidth, height: containerHeight} = containerDimensionsFrom(plotDimensionsFrom(width, height, margins), margins);
|
|
19
|
+
expect(containerWidth).toBe(width);
|
|
20
|
+
expect(containerHeight).toBe(height);
|
|
21
|
+
})
|
|
22
|
+
})
|