stream-charts 1.0.1 → 1.1.1

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.
Files changed (271) hide show
  1. package/README.md +757 -342
  2. package/changes.md +11 -0
  3. package/dist/src/app/charts/Chart.d.ts +116 -87
  4. package/dist/src/app/charts/Chart.js +96 -101
  5. package/dist/src/app/charts/Chart.js.map +1 -1
  6. package/dist/src/app/charts/axes/AxesState.d.ts +64 -0
  7. package/dist/src/app/charts/axes/AxesState.js +97 -0
  8. package/dist/src/app/charts/axes/AxesState.js.map +1 -0
  9. package/dist/src/app/charts/axes/AxesState.test.js +30 -0
  10. package/dist/src/app/charts/axes/AxesState.test.js.map +1 -0
  11. package/dist/src/app/charts/axes/AxisInterval.d.ts +92 -0
  12. package/dist/src/app/charts/axes/AxisInterval.js +126 -0
  13. package/dist/src/app/charts/axes/AxisInterval.js.map +1 -0
  14. package/dist/src/app/charts/axes/AxisInterval.test.js +120 -0
  15. package/dist/src/app/charts/axes/AxisInterval.test.js.map +1 -0
  16. package/dist/src/app/charts/axes/BaseAxisRange.d.ts +83 -0
  17. package/dist/src/app/charts/axes/BaseAxisRange.js +58 -0
  18. package/dist/src/app/charts/axes/BaseAxisRange.js.map +1 -0
  19. package/dist/src/app/charts/axes/ContinuousAxis.d.ts +22 -0
  20. package/dist/src/app/charts/axes/ContinuousAxis.js +96 -0
  21. package/dist/src/app/charts/axes/ContinuousAxis.js.map +1 -0
  22. package/dist/src/app/charts/axes/ContinuousAxisRange.d.ts +59 -0
  23. package/dist/src/app/charts/axes/ContinuousAxisRange.js +84 -0
  24. package/dist/src/app/charts/axes/ContinuousAxisRange.js.map +1 -0
  25. package/dist/src/app/charts/axes/ContinuousAxisRange.test.js +47 -0
  26. package/dist/src/app/charts/axes/ContinuousAxisRange.test.js.map +1 -0
  27. package/dist/src/app/charts/axes/OrdinalAxis.d.ts +23 -0
  28. package/dist/src/app/charts/axes/OrdinalAxis.js +124 -0
  29. package/dist/src/app/charts/axes/OrdinalAxis.js.map +1 -0
  30. package/dist/src/app/charts/axes/OrdinalAxisRange.d.ts +69 -0
  31. package/dist/src/app/charts/axes/OrdinalAxisRange.js +100 -0
  32. package/dist/src/app/charts/axes/OrdinalAxisRange.js.map +1 -0
  33. package/dist/src/app/charts/axes/OrdinalAxisRange.test.js +48 -0
  34. package/dist/src/app/charts/axes/OrdinalAxisRange.test.js.map +1 -0
  35. package/dist/src/app/charts/axes/axes.d.ts +391 -0
  36. package/dist/src/app/charts/axes/axes.js +1046 -0
  37. package/dist/src/app/charts/axes/axes.js.map +1 -0
  38. package/dist/src/app/charts/d3types.d.ts +10 -10
  39. package/dist/src/app/charts/filters/regexFilter.d.ts +9 -0
  40. package/dist/src/app/charts/filters/regexFilter.js +18 -0
  41. package/dist/src/app/charts/filters/regexFilter.js.map +1 -0
  42. package/dist/src/app/charts/filters/regexFilter.test.d.ts +1 -0
  43. package/dist/src/app/charts/filters/regexFilter.test.js +11 -0
  44. package/dist/src/app/charts/filters/regexFilter.test.js.map +1 -0
  45. package/dist/src/app/charts/hooks/useAxes.d.ts +144 -0
  46. package/dist/src/app/charts/hooks/useAxes.js +187 -0
  47. package/dist/src/app/charts/hooks/useAxes.js.map +1 -0
  48. package/dist/src/app/charts/hooks/useChart.d.ts +30 -201
  49. package/dist/src/app/charts/hooks/useChart.js +33 -134
  50. package/dist/src/app/charts/hooks/useChart.js.map +1 -1
  51. package/dist/src/app/charts/hooks/useDataObservable.d.ts +74 -0
  52. package/dist/src/app/charts/hooks/useDataObservable.js +76 -0
  53. package/dist/src/app/charts/hooks/useDataObservable.js.map +1 -0
  54. package/dist/src/app/charts/hooks/useInitialData.d.ts +38 -0
  55. package/dist/src/app/charts/hooks/useInitialData.js +29 -0
  56. package/dist/src/app/charts/hooks/useInitialData.js.map +1 -0
  57. package/dist/src/app/charts/hooks/useMouse.d.ts +53 -0
  58. package/dist/src/app/charts/hooks/useMouse.js +65 -0
  59. package/dist/src/app/charts/hooks/useMouse.js.map +1 -0
  60. package/dist/src/app/charts/hooks/usePlotDimensions.d.ts +34 -0
  61. package/dist/src/app/charts/hooks/usePlotDimensions.js +73 -0
  62. package/dist/src/app/charts/hooks/usePlotDimensions.js.map +1 -0
  63. package/dist/src/app/charts/hooks/useTooltip.d.ts +64 -0
  64. package/dist/src/app/charts/hooks/useTooltip.js +52 -0
  65. package/dist/src/app/charts/hooks/useTooltip.js.map +1 -0
  66. package/dist/src/app/charts/observables/ChartData.d.ts +23 -0
  67. package/dist/src/app/charts/observables/ChartData.js +20 -0
  68. package/dist/src/app/charts/observables/ChartData.js.map +1 -0
  69. package/dist/src/app/charts/observables/iterates.d.ts +52 -0
  70. package/dist/src/app/charts/observables/iterates.js +121 -0
  71. package/dist/src/app/charts/observables/iterates.js.map +1 -0
  72. package/dist/src/app/charts/observables/iterates.test.d.ts +1 -0
  73. package/dist/src/app/charts/observables/iterates.test.js +180 -0
  74. package/dist/src/app/charts/observables/iterates.test.js.map +1 -0
  75. package/dist/src/app/charts/observables/ordinals.d.ts +75 -0
  76. package/dist/src/app/charts/observables/ordinals.js +141 -0
  77. package/dist/src/app/charts/observables/ordinals.js.map +1 -0
  78. package/dist/src/app/charts/observables/ordinals.test.d.ts +1 -0
  79. package/dist/src/app/charts/observables/ordinals.test.js +102 -0
  80. package/dist/src/app/charts/observables/ordinals.test.js.map +1 -0
  81. package/dist/src/app/charts/plots/BarPlot.d.ts +81 -0
  82. package/dist/src/app/charts/plots/BarPlot.js +557 -0
  83. package/dist/src/app/charts/plots/BarPlot.js.map +1 -0
  84. package/dist/src/app/charts/plots/PoincarePlot.d.ts +78 -0
  85. package/dist/src/app/charts/plots/PoincarePlot.js +504 -0
  86. package/dist/src/app/charts/plots/PoincarePlot.js.map +1 -0
  87. package/dist/src/app/charts/{RasterPlot.d.ts → plots/RasterPlot.d.ts} +1 -1
  88. package/dist/src/app/charts/{RasterPlot.js → plots/RasterPlot.js} +152 -133
  89. package/dist/src/app/charts/plots/RasterPlot.js.map +1 -0
  90. package/dist/src/app/charts/{ScatterPlot.d.ts → plots/ScatterPlot.d.ts} +10 -8
  91. package/dist/src/app/charts/plots/ScatterPlot.js +379 -0
  92. package/dist/src/app/charts/plots/ScatterPlot.js.map +1 -0
  93. package/dist/src/app/charts/{plot.d.ts → plots/plot.d.ts} +12 -14
  94. package/dist/src/app/charts/{plot.js → plots/plot.js} +19 -17
  95. package/dist/src/app/charts/plots/plot.js.map +1 -0
  96. package/dist/src/app/charts/series/baseSeries.d.ts +38 -0
  97. package/dist/src/app/charts/series/baseSeries.js +36 -0
  98. package/dist/src/app/charts/series/baseSeries.js.map +1 -0
  99. package/dist/src/app/charts/series/datumSeries.test.d.ts +1 -0
  100. package/dist/src/app/charts/series/datumSeries.test.js +50 -0
  101. package/dist/src/app/charts/series/datumSeries.test.js.map +1 -0
  102. package/dist/src/app/charts/series/iterateSeries.d.ts +42 -0
  103. package/dist/src/app/charts/series/iterateSeries.js +34 -0
  104. package/dist/src/app/charts/series/iterateSeries.js.map +1 -0
  105. package/dist/src/app/charts/series/ordinalSeries.d.ts +54 -0
  106. package/dist/src/app/charts/series/ordinalSeries.js +98 -0
  107. package/dist/src/app/charts/series/ordinalSeries.js.map +1 -0
  108. package/dist/src/app/charts/series/timeSeries.d.ts +30 -0
  109. package/dist/src/app/charts/series/timeSeries.js +19 -0
  110. package/dist/src/app/charts/series/timeSeries.js.map +1 -0
  111. package/dist/src/app/charts/{chartData.d.ts → series/timeSeriesChartData.d.ts} +11 -6
  112. package/dist/src/app/charts/series/timeSeriesChartData.js +32 -0
  113. package/dist/src/app/charts/series/timeSeriesChartData.js.map +1 -0
  114. package/dist/src/app/charts/styling/barPlotStyle.d.ts +41 -0
  115. package/dist/src/app/charts/styling/barPlotStyle.js +84 -0
  116. package/dist/src/app/charts/styling/barPlotStyle.js.map +1 -0
  117. package/dist/src/app/charts/{margins.d.ts → styling/margins.d.ts} +7 -5
  118. package/dist/src/app/charts/{margins.js → styling/margins.js} +19 -9
  119. package/dist/src/app/charts/styling/margins.js.map +1 -0
  120. package/dist/src/app/charts/styling/margins.test.d.ts +1 -0
  121. package/dist/src/app/charts/styling/margins.test.js +19 -0
  122. package/dist/src/app/charts/styling/margins.test.js.map +1 -0
  123. package/dist/src/app/charts/styling/svgStyle.d.ts +76 -0
  124. package/dist/src/app/charts/styling/svgStyle.js +84 -0
  125. package/dist/src/app/charts/styling/svgStyle.js.map +1 -0
  126. package/dist/src/app/charts/subscriptions/subscription.test.d.ts +1 -0
  127. package/dist/src/app/charts/subscriptions/subscription.test.js +395 -0
  128. package/dist/src/app/charts/subscriptions/subscription.test.js.map +1 -0
  129. package/dist/src/app/charts/subscriptions/subscriptions.d.ts +100 -0
  130. package/dist/src/app/charts/subscriptions/subscriptions.js +449 -0
  131. package/dist/src/app/charts/subscriptions/subscriptions.js.map +1 -0
  132. package/dist/src/app/charts/tooltips/BarPlotTooltipContent.d.ts +90 -0
  133. package/dist/src/app/charts/tooltips/BarPlotTooltipContent.js +302 -0
  134. package/dist/src/app/charts/tooltips/BarPlotTooltipContent.js.map +1 -0
  135. package/dist/src/app/charts/tooltips/PoincarePlotTooltipContent.d.ts +100 -0
  136. package/dist/src/app/charts/tooltips/PoincarePlotTooltipContent.js +190 -0
  137. package/dist/src/app/charts/tooltips/PoincarePlotTooltipContent.js.map +1 -0
  138. package/dist/src/app/charts/{RasterPlotTooltipContent.js → tooltips/RasterPlotTooltipContent.js} +40 -44
  139. package/dist/src/app/charts/tooltips/RasterPlotTooltipContent.js.map +1 -0
  140. package/dist/src/app/charts/tooltips/ScatterPlotTooltipContent.js +154 -0
  141. package/dist/src/app/charts/tooltips/ScatterPlotTooltipContent.js.map +1 -0
  142. package/dist/src/app/charts/{Tooltip.d.ts → tooltips/Tooltip.d.ts} +4 -2
  143. package/dist/src/app/charts/{Tooltip.js → tooltips/Tooltip.js} +23 -28
  144. package/dist/src/app/charts/tooltips/Tooltip.js.map +1 -0
  145. package/dist/src/app/charts/{tooltipUtils.d.ts → tooltips/tooltipUtils.d.ts} +11 -6
  146. package/dist/src/app/charts/{tooltipUtils.js → tooltips/tooltipUtils.js} +33 -17
  147. package/dist/src/app/charts/tooltips/tooltipUtils.js.map +1 -0
  148. package/dist/src/app/charts/{Tracker.d.ts → trackers/Tracker.d.ts} +6 -5
  149. package/dist/src/app/charts/trackers/Tracker.js +60 -0
  150. package/dist/src/app/charts/trackers/Tracker.js.map +1 -0
  151. package/dist/src/app/charts/{trackerUtils.d.ts → trackers/trackerUtils.d.ts} +13 -8
  152. package/dist/src/app/charts/trackers/trackerUtils.js +359 -0
  153. package/dist/src/app/charts/trackers/trackerUtils.js.map +1 -0
  154. package/dist/src/app/charts/utils.d.ts +22 -32
  155. package/dist/src/app/charts/utils.js +36 -37
  156. package/dist/src/app/charts/utils.js.map +1 -1
  157. package/dist/src/index.d.ts +48 -15
  158. package/dist/src/index.js +71 -15
  159. package/dist/src/index.js.map +1 -1
  160. package/package.json +30 -20
  161. package/src/app/charts/Chart.tsx +334 -0
  162. package/src/app/charts/axes/AxesState.test.ts +34 -0
  163. package/src/app/charts/axes/AxesState.ts +112 -0
  164. package/src/app/charts/axes/AxisInterval.test.ts +143 -0
  165. package/src/app/charts/axes/AxisInterval.ts +139 -0
  166. package/src/app/charts/axes/BaseAxisRange.ts +113 -0
  167. package/src/app/charts/axes/ContinuousAxis.tsx +192 -0
  168. package/src/app/charts/axes/ContinuousAxisRange.test.ts +55 -0
  169. package/src/app/charts/axes/ContinuousAxisRange.ts +96 -0
  170. package/src/app/charts/axes/OrdinalAxis.tsx +223 -0
  171. package/src/app/charts/axes/OrdinalAxisRange.test.ts +55 -0
  172. package/src/app/charts/axes/OrdinalAxisRange.ts +112 -0
  173. package/src/app/charts/axes/axes.ts +1569 -0
  174. package/src/app/charts/d3types.ts +16 -0
  175. package/src/app/charts/filters/regexFilter.test.ts +13 -0
  176. package/src/app/charts/filters/regexFilter.ts +17 -0
  177. package/src/app/charts/hooks/useAxes.tsx +341 -0
  178. package/src/app/charts/hooks/useChart.tsx +159 -0
  179. package/src/app/charts/hooks/useDataObservable.tsx +175 -0
  180. package/src/app/charts/hooks/useInitialData.tsx +65 -0
  181. package/src/app/charts/hooks/useMouse.tsx +125 -0
  182. package/src/app/charts/hooks/usePlotDimensions.tsx +120 -0
  183. package/src/app/charts/hooks/useTooltip.tsx +112 -0
  184. package/src/app/charts/observables/ChartData.ts +31 -0
  185. package/src/app/charts/observables/iterates.test.ts +201 -0
  186. package/src/app/charts/observables/iterates.ts +203 -0
  187. package/src/app/charts/observables/ordinals.test.ts +135 -0
  188. package/src/app/charts/observables/ordinals.ts +248 -0
  189. package/src/app/charts/plots/BarPlot.tsx +1088 -0
  190. package/src/app/charts/plots/PoincarePlot.tsx +832 -0
  191. package/src/app/charts/plots/RasterPlot.tsx +676 -0
  192. package/src/app/charts/plots/ScatterPlot.tsx +653 -0
  193. package/src/app/charts/plots/plot.ts +75 -0
  194. package/src/app/charts/series/baseSeries.ts +52 -0
  195. package/src/app/charts/series/datumSeries.test.ts +60 -0
  196. package/src/app/charts/series/iterateSeries.ts +56 -0
  197. package/src/app/charts/series/ordinalSeries.ts +164 -0
  198. package/src/app/charts/series/timeSeries.ts +40 -0
  199. package/src/app/charts/series/timeSeriesChartData.ts +68 -0
  200. package/src/app/charts/styling/barPlotStyle.ts +126 -0
  201. package/src/app/charts/styling/margins.test.ts +22 -0
  202. package/src/app/charts/styling/margins.ts +58 -0
  203. package/src/app/charts/styling/svgStyle.ts +118 -0
  204. package/src/app/charts/subscriptions/subscription.test.ts +499 -0
  205. package/src/app/charts/subscriptions/subscriptions.ts +635 -0
  206. package/src/app/charts/tooltips/BarPlotTooltipContent.tsx +440 -0
  207. package/src/app/charts/tooltips/PoincarePlotTooltipContent.tsx +352 -0
  208. package/src/app/charts/tooltips/RasterPlotTooltipContent.tsx +274 -0
  209. package/src/app/charts/tooltips/ScatterPlotTooltipContent.tsx +319 -0
  210. package/src/app/charts/tooltips/Tooltip.tsx +148 -0
  211. package/src/app/charts/tooltips/tooltipUtils.ts +216 -0
  212. package/src/app/charts/trackers/Tracker.tsx +129 -0
  213. package/src/app/charts/trackers/trackerUtils.ts +494 -0
  214. package/src/app/charts/utils.ts +109 -0
  215. package/dist/src/app/charts/CategoryAxis.d.ts +0 -20
  216. package/dist/src/app/charts/CategoryAxis.js +0 -112
  217. package/dist/src/app/charts/CategoryAxis.js.map +0 -1
  218. package/dist/src/app/charts/ContinuousAxis.d.ts +0 -16
  219. package/dist/src/app/charts/ContinuousAxis.js +0 -186
  220. package/dist/src/app/charts/ContinuousAxis.js.map +0 -1
  221. package/dist/src/app/charts/RasterPlot.js.map +0 -1
  222. package/dist/src/app/charts/RasterPlotTooltipContent.js.map +0 -1
  223. package/dist/src/app/charts/ScatterPlot.js +0 -351
  224. package/dist/src/app/charts/ScatterPlot.js.map +0 -1
  225. package/dist/src/app/charts/ScatterPlotTooltipContent.js +0 -163
  226. package/dist/src/app/charts/ScatterPlotTooltipContent.js.map +0 -1
  227. package/dist/src/app/charts/Tooltip.js.map +0 -1
  228. package/dist/src/app/charts/Tracker.js +0 -65
  229. package/dist/src/app/charts/Tracker.js.map +0 -1
  230. package/dist/src/app/charts/axes.d.ts +0 -132
  231. package/dist/src/app/charts/axes.js +0 -265
  232. package/dist/src/app/charts/axes.js.map +0 -1
  233. package/dist/src/app/charts/chartData.js +0 -32
  234. package/dist/src/app/charts/chartData.js.map +0 -1
  235. package/dist/src/app/charts/continuousAxisRangeFor.d.ts +0 -20
  236. package/dist/src/app/charts/continuousAxisRangeFor.js +0 -68
  237. package/dist/src/app/charts/continuousAxisRangeFor.js.map +0 -1
  238. package/dist/src/app/charts/datumSeries.d.ts +0 -59
  239. package/dist/src/app/charts/datumSeries.js +0 -55
  240. package/dist/src/app/charts/datumSeries.js.map +0 -1
  241. package/dist/src/app/charts/datumSeries.test.js +0 -50
  242. package/dist/src/app/charts/datumSeries.test.js.map +0 -1
  243. package/dist/src/app/charts/hooks/AxesState.d.ts +0 -37
  244. package/dist/src/app/charts/hooks/AxesState.js +0 -44
  245. package/dist/src/app/charts/hooks/AxesState.js.map +0 -1
  246. package/dist/src/app/charts/margins.js.map +0 -1
  247. package/dist/src/app/charts/margins.test.js +0 -14
  248. package/dist/src/app/charts/margins.test.js.map +0 -1
  249. package/dist/src/app/charts/plot.js.map +0 -1
  250. package/dist/src/app/charts/regexFilter.d.ts +0 -9
  251. package/dist/src/app/charts/regexFilter.js +0 -17
  252. package/dist/src/app/charts/regexFilter.js.map +0 -1
  253. package/dist/src/app/charts/regexFilter.test.js +0 -11
  254. package/dist/src/app/charts/regexFilter.test.js.map +0 -1
  255. package/dist/src/app/charts/subscriptions.d.ts +0 -43
  256. package/dist/src/app/charts/subscriptions.js +0 -213
  257. package/dist/src/app/charts/subscriptions.js.map +0 -1
  258. package/dist/src/app/charts/svgStyle.d.ts +0 -27
  259. package/dist/src/app/charts/svgStyle.js +0 -32
  260. package/dist/src/app/charts/svgStyle.js.map +0 -1
  261. package/dist/src/app/charts/timeRange.test.js +0 -54
  262. package/dist/src/app/charts/timeRange.test.js.map +0 -1
  263. package/dist/src/app/charts/tooltipUtils.js.map +0 -1
  264. package/dist/src/app/charts/trackerUtils.js +0 -130
  265. package/dist/src/app/charts/trackerUtils.js.map +0 -1
  266. /package/dist/src/app/charts/{datumSeries.test.d.ts → axes/AxesState.test.d.ts} +0 -0
  267. /package/dist/src/app/charts/{margins.test.d.ts → axes/AxisInterval.test.d.ts} +0 -0
  268. /package/dist/src/app/charts/{regexFilter.test.d.ts → axes/ContinuousAxisRange.test.d.ts} +0 -0
  269. /package/dist/src/app/charts/{timeRange.test.d.ts → axes/OrdinalAxisRange.test.d.ts} +0 -0
  270. /package/dist/src/app/charts/{RasterPlotTooltipContent.d.ts → tooltips/RasterPlotTooltipContent.d.ts} +0 -0
  271. /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
+ })