stream-charts 1.2.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (463) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +809 -1022
  3. package/changes.md +40 -0
  4. package/dist/app/charts/Chart.d.ts +35 -139
  5. package/dist/app/charts/Chart.d.ts.map +1 -0
  6. package/dist/app/charts/Chart.js +74 -65
  7. package/dist/app/charts/Chart.js.map +1 -1
  8. package/dist/app/charts/axes/AxesState.d.ts +26 -18
  9. package/dist/app/charts/axes/AxesState.d.ts.map +1 -0
  10. package/dist/app/charts/axes/AxesState.js +26 -24
  11. package/dist/app/charts/axes/AxesState.js.map +1 -1
  12. package/dist/app/charts/axes/AxisInterval.d.ts +44 -26
  13. package/dist/app/charts/axes/AxisInterval.d.ts.map +1 -0
  14. package/dist/app/charts/axes/AxisInterval.js +48 -29
  15. package/dist/app/charts/axes/AxisInterval.js.map +1 -1
  16. package/dist/app/charts/axes/BaseAxisRange.d.ts +46 -22
  17. package/dist/app/charts/axes/BaseAxisRange.d.ts.map +1 -0
  18. package/dist/app/charts/axes/BaseAxisRange.js +17 -12
  19. package/dist/app/charts/axes/BaseAxisRange.js.map +1 -1
  20. package/dist/app/charts/axes/ContinuousAxis.d.ts +47 -6
  21. package/dist/app/charts/axes/ContinuousAxis.d.ts.map +1 -0
  22. package/dist/app/charts/axes/ContinuousAxis.js +160 -27
  23. package/dist/app/charts/axes/ContinuousAxis.js.map +1 -1
  24. package/dist/app/charts/axes/ContinuousAxisRange.d.ts +29 -10
  25. package/dist/app/charts/axes/ContinuousAxisRange.d.ts.map +1 -0
  26. package/dist/app/charts/axes/ContinuousAxisRange.js +29 -11
  27. package/dist/app/charts/axes/ContinuousAxisRange.js.map +1 -1
  28. package/dist/app/charts/axes/EmptyAxis.d.ts +5 -2
  29. package/dist/app/charts/axes/EmptyAxis.d.ts.map +1 -0
  30. package/dist/app/charts/axes/EmptyAxis.js +30 -9
  31. package/dist/app/charts/axes/EmptyAxis.js.map +1 -1
  32. package/dist/app/charts/axes/OrdinalAxis.d.ts +5 -3
  33. package/dist/app/charts/axes/OrdinalAxis.d.ts.map +1 -0
  34. package/dist/app/charts/axes/OrdinalAxis.js +39 -16
  35. package/dist/app/charts/axes/OrdinalAxis.js.map +1 -1
  36. package/dist/app/charts/axes/OrdinalAxisRange.d.ts +76 -13
  37. package/dist/app/charts/axes/OrdinalAxisRange.d.ts.map +1 -0
  38. package/dist/app/charts/axes/OrdinalAxisRange.js +95 -16
  39. package/dist/app/charts/axes/OrdinalAxisRange.js.map +1 -1
  40. package/dist/app/charts/axes/autoScale.d.ts +111 -0
  41. package/dist/app/charts/axes/autoScale.d.ts.map +1 -0
  42. package/dist/app/charts/axes/autoScale.js +188 -0
  43. package/dist/app/charts/axes/autoScale.js.map +1 -0
  44. package/dist/app/charts/axes/axes.d.ts +273 -150
  45. package/dist/app/charts/axes/axes.d.ts.map +1 -0
  46. package/dist/app/charts/axes/axes.js +808 -583
  47. package/dist/app/charts/axes/axes.js.map +1 -1
  48. package/dist/app/charts/d3types.d.ts +40 -11
  49. package/dist/app/charts/d3types.d.ts.map +1 -0
  50. package/dist/app/charts/d3types.js +3 -0
  51. package/dist/app/charts/d3types.js.map +1 -1
  52. package/dist/app/charts/datasources/StreamingDataSource.d.ts +149 -0
  53. package/dist/app/charts/datasources/StreamingDataSource.d.ts.map +1 -0
  54. package/dist/app/charts/datasources/StreamingDataSource.js +110 -0
  55. package/dist/app/charts/datasources/StreamingDataSource.js.map +1 -0
  56. package/dist/app/charts/datasources/iteratesDataSource.d.ts +73 -0
  57. package/dist/app/charts/datasources/iteratesDataSource.d.ts.map +1 -0
  58. package/dist/app/charts/datasources/iteratesDataSource.js +87 -0
  59. package/dist/app/charts/datasources/iteratesDataSource.js.map +1 -0
  60. package/dist/app/charts/datasources/ordinalDataSource.d.ts +75 -0
  61. package/dist/app/charts/datasources/ordinalDataSource.d.ts.map +1 -0
  62. package/dist/app/charts/datasources/ordinalDataSource.js +135 -0
  63. package/dist/app/charts/datasources/ordinalDataSource.js.map +1 -0
  64. package/dist/app/charts/datasources/outlierDataSource.d.ts +53 -0
  65. package/dist/app/charts/datasources/outlierDataSource.d.ts.map +1 -0
  66. package/dist/app/charts/datasources/outlierDataSource.js +57 -0
  67. package/dist/app/charts/datasources/outlierDataSource.js.map +1 -0
  68. package/dist/app/charts/datasources/timeSeriesDataSource.d.ts +77 -0
  69. package/dist/app/charts/datasources/timeSeriesDataSource.d.ts.map +1 -0
  70. package/dist/app/charts/datasources/timeSeriesDataSource.js +85 -0
  71. package/dist/app/charts/datasources/timeSeriesDataSource.js.map +1 -0
  72. package/dist/app/charts/filters/regexFilter.d.ts +31 -4
  73. package/dist/app/charts/filters/regexFilter.d.ts.map +1 -0
  74. package/dist/app/charts/filters/regexFilter.js +38 -4
  75. package/dist/app/charts/filters/regexFilter.js.map +1 -1
  76. package/dist/app/charts/hooks/AxesProvider.d.ts +21 -0
  77. package/dist/app/charts/hooks/AxesProvider.d.ts.map +1 -0
  78. package/dist/app/charts/hooks/AxesProvider.js +213 -0
  79. package/dist/app/charts/hooks/AxesProvider.js.map +1 -0
  80. package/dist/app/charts/hooks/CanvasSurfaceProvider.d.ts +25 -0
  81. package/dist/app/charts/hooks/CanvasSurfaceProvider.d.ts.map +1 -0
  82. package/dist/app/charts/hooks/CanvasSurfaceProvider.js +76 -0
  83. package/dist/app/charts/hooks/CanvasSurfaceProvider.js.map +1 -0
  84. package/dist/app/charts/hooks/ChartProvider.d.ts +40 -0
  85. package/dist/app/charts/hooks/ChartProvider.d.ts.map +1 -0
  86. package/dist/app/charts/hooks/ChartProvider.js +33 -0
  87. package/dist/app/charts/hooks/ChartProvider.js.map +1 -0
  88. package/dist/app/charts/hooks/InteractionProvider.d.ts +23 -0
  89. package/dist/app/charts/hooks/InteractionProvider.d.ts.map +1 -0
  90. package/dist/app/charts/hooks/InteractionProvider.js +60 -0
  91. package/dist/app/charts/hooks/InteractionProvider.js.map +1 -0
  92. package/dist/app/charts/hooks/PlotDimensionsProvider.d.ts +16 -0
  93. package/dist/app/charts/hooks/PlotDimensionsProvider.d.ts.map +1 -0
  94. package/dist/app/charts/hooks/PlotDimensionsProvider.js +76 -0
  95. package/dist/app/charts/hooks/PlotDimensionsProvider.js.map +1 -0
  96. package/dist/app/charts/hooks/defaultAxesValues.d.ts +11 -0
  97. package/dist/app/charts/hooks/defaultAxesValues.d.ts.map +1 -0
  98. package/dist/app/charts/hooks/defaultAxesValues.js +36 -0
  99. package/dist/app/charts/hooks/defaultAxesValues.js.map +1 -0
  100. package/dist/app/charts/hooks/defaultMouseValues.d.ts +9 -0
  101. package/dist/app/charts/hooks/defaultMouseValues.d.ts.map +1 -0
  102. package/dist/app/charts/hooks/defaultMouseValues.js +23 -0
  103. package/dist/app/charts/hooks/defaultMouseValues.js.map +1 -0
  104. package/dist/app/charts/hooks/defaultPlotDimensions.d.ts +13 -0
  105. package/dist/app/charts/hooks/defaultPlotDimensions.d.ts.map +1 -0
  106. package/dist/app/charts/hooks/defaultPlotDimensions.js +23 -0
  107. package/dist/app/charts/hooks/defaultPlotDimensions.js.map +1 -0
  108. package/dist/app/charts/hooks/defaultTooltipValues.d.ts +9 -0
  109. package/dist/app/charts/hooks/defaultTooltipValues.d.ts.map +1 -0
  110. package/dist/app/charts/hooks/defaultTooltipValues.js +21 -0
  111. package/dist/app/charts/hooks/defaultTooltipValues.js.map +1 -0
  112. package/dist/app/charts/hooks/defaultUseChartValues.d.ts +14 -0
  113. package/dist/app/charts/hooks/defaultUseChartValues.d.ts.map +1 -0
  114. package/dist/app/charts/hooks/defaultUseChartValues.js +30 -0
  115. package/dist/app/charts/hooks/defaultUseChartValues.js.map +1 -0
  116. package/dist/app/charts/hooks/useAxes.d.ts +49 -36
  117. package/dist/app/charts/hooks/useAxes.d.ts.map +1 -0
  118. package/dist/app/charts/hooks/useAxes.js +16 -176
  119. package/dist/app/charts/hooks/useAxes.js.map +1 -1
  120. package/dist/app/charts/hooks/useCanvasSurface.d.ts +25 -0
  121. package/dist/app/charts/hooks/useCanvasSurface.d.ts.map +1 -0
  122. package/dist/app/charts/hooks/useCanvasSurface.js +18 -0
  123. package/dist/app/charts/hooks/useCanvasSurface.js.map +1 -0
  124. package/dist/app/charts/hooks/useChart.d.ts +30 -44
  125. package/dist/app/charts/hooks/useChart.d.ts.map +1 -0
  126. package/dist/app/charts/hooks/useChart.js +26 -48
  127. package/dist/app/charts/hooks/useChart.js.map +1 -1
  128. package/dist/app/charts/hooks/useDataSource.d.ts +68 -0
  129. package/dist/app/charts/hooks/useDataSource.d.ts.map +1 -0
  130. package/dist/app/charts/hooks/useDataSource.js +63 -0
  131. package/dist/app/charts/hooks/useDataSource.js.map +1 -0
  132. package/dist/app/charts/hooks/useHoveredSeries.d.ts +25 -0
  133. package/dist/app/charts/hooks/useHoveredSeries.d.ts.map +1 -0
  134. package/dist/app/charts/hooks/useHoveredSeries.js +15 -0
  135. package/dist/app/charts/hooks/useHoveredSeries.js.map +1 -0
  136. package/dist/app/charts/hooks/useMouse.d.ts +46 -22
  137. package/dist/app/charts/hooks/useMouse.d.ts.map +1 -0
  138. package/dist/app/charts/hooks/useMouse.js +12 -56
  139. package/dist/app/charts/hooks/useMouse.js.map +1 -1
  140. package/dist/app/charts/hooks/usePlotDimensions.d.ts +25 -13
  141. package/dist/app/charts/hooks/usePlotDimensions.d.ts.map +1 -0
  142. package/dist/app/charts/hooks/usePlotDimensions.js +6 -62
  143. package/dist/app/charts/hooks/usePlotDimensions.js.map +1 -1
  144. package/dist/app/charts/hooks/useTooltip.d.ts +24 -26
  145. package/dist/app/charts/hooks/useTooltip.d.ts.map +1 -0
  146. package/dist/app/charts/hooks/useTooltip.js +12 -42
  147. package/dist/app/charts/hooks/useTooltip.js.map +1 -1
  148. package/dist/app/charts/index.d.ts +66 -0
  149. package/dist/app/charts/index.d.ts.map +1 -0
  150. package/dist/app/charts/index.js +87 -0
  151. package/dist/app/charts/index.js.map +1 -0
  152. package/dist/app/charts/legends/Legend.d.ts +33 -12
  153. package/dist/app/charts/legends/Legend.d.ts.map +1 -0
  154. package/dist/app/charts/legends/Legend.js +138 -379
  155. package/dist/app/charts/legends/Legend.js.map +1 -1
  156. package/dist/app/charts/legends/constants.d.ts +19 -0
  157. package/dist/app/charts/legends/constants.d.ts.map +1 -0
  158. package/dist/app/charts/legends/constants.js +34 -0
  159. package/dist/app/charts/legends/constants.js.map +1 -0
  160. package/dist/app/charts/observables/ChartData.d.ts +1 -0
  161. package/dist/app/charts/observables/ChartData.d.ts.map +1 -0
  162. package/dist/app/charts/observables/iterates.d.ts +13 -7
  163. package/dist/app/charts/observables/iterates.d.ts.map +1 -0
  164. package/dist/app/charts/observables/iterates.js +42 -9
  165. package/dist/app/charts/observables/iterates.js.map +1 -1
  166. package/dist/app/charts/observables/ordinals.d.ts +70 -12
  167. package/dist/app/charts/observables/ordinals.d.ts.map +1 -0
  168. package/dist/app/charts/observables/ordinals.js +127 -48
  169. package/dist/app/charts/observables/ordinals.js.map +1 -1
  170. package/dist/app/charts/observables/outliers.d.ts +18 -0
  171. package/dist/app/charts/observables/outliers.d.ts.map +1 -0
  172. package/dist/app/charts/observables/outliers.js +2 -0
  173. package/dist/app/charts/observables/outliers.js.map +1 -0
  174. package/dist/app/charts/plots/BarPlot.d.ts +87 -13
  175. package/dist/app/charts/plots/BarPlot.d.ts.map +1 -0
  176. package/dist/app/charts/plots/BarPlot.js +603 -356
  177. package/dist/app/charts/plots/BarPlot.js.map +1 -1
  178. package/dist/app/charts/plots/OutlierPlot.d.ts +123 -0
  179. package/dist/app/charts/plots/OutlierPlot.d.ts.map +1 -0
  180. package/dist/app/charts/plots/OutlierPlot.js +430 -0
  181. package/dist/app/charts/plots/OutlierPlot.js.map +1 -0
  182. package/dist/app/charts/plots/PoincarePlot.d.ts +92 -14
  183. package/dist/app/charts/plots/PoincarePlot.d.ts.map +1 -0
  184. package/dist/app/charts/plots/PoincarePlot.js +523 -364
  185. package/dist/app/charts/plots/PoincarePlot.js.map +1 -1
  186. package/dist/app/charts/plots/RasterPlot.d.ts +31 -10
  187. package/dist/app/charts/plots/RasterPlot.d.ts.map +1 -0
  188. package/dist/app/charts/plots/RasterPlot.js +198 -306
  189. package/dist/app/charts/plots/RasterPlot.js.map +1 -1
  190. package/dist/app/charts/plots/ScatterPlot.d.ts +77 -21
  191. package/dist/app/charts/plots/ScatterPlot.d.ts.map +1 -0
  192. package/dist/app/charts/plots/ScatterPlot.js +359 -302
  193. package/dist/app/charts/plots/ScatterPlot.js.map +1 -1
  194. package/dist/app/charts/plots/autoScaleYAxes.d.ts +43 -0
  195. package/dist/app/charts/plots/autoScaleYAxes.d.ts.map +1 -0
  196. package/dist/app/charts/plots/autoScaleYAxes.js +71 -0
  197. package/dist/app/charts/plots/autoScaleYAxes.js.map +1 -0
  198. package/dist/app/charts/plots/colorizedLine.d.ts +61 -0
  199. package/dist/app/charts/plots/colorizedLine.d.ts.map +1 -0
  200. package/dist/app/charts/plots/colorizedLine.js +157 -0
  201. package/dist/app/charts/plots/colorizedLine.js.map +1 -0
  202. package/dist/app/charts/plots/constants.d.ts +7 -0
  203. package/dist/app/charts/plots/constants.d.ts.map +1 -0
  204. package/dist/app/charts/plots/constants.js +11 -0
  205. package/dist/app/charts/plots/constants.js.map +1 -0
  206. package/dist/app/charts/plots/hitTesting.d.ts +88 -0
  207. package/dist/app/charts/plots/hitTesting.d.ts.map +1 -0
  208. package/dist/app/charts/plots/hitTesting.js +136 -0
  209. package/dist/app/charts/plots/hitTesting.js.map +1 -0
  210. package/dist/app/charts/plots/plot.d.ts +52 -16
  211. package/dist/app/charts/plots/plot.d.ts.map +1 -0
  212. package/dist/app/charts/plots/plot.js +108 -35
  213. package/dist/app/charts/plots/plot.js.map +1 -1
  214. package/dist/app/charts/plots/useCanvasZoomPan.d.ts +119 -0
  215. package/dist/app/charts/plots/useCanvasZoomPan.d.ts.map +1 -0
  216. package/dist/app/charts/plots/useCanvasZoomPan.js +113 -0
  217. package/dist/app/charts/plots/useCanvasZoomPan.js.map +1 -0
  218. package/dist/app/charts/plots/useStreamingTimeAxes.d.ts +103 -0
  219. package/dist/app/charts/plots/useStreamingTimeAxes.d.ts.map +1 -0
  220. package/dist/app/charts/plots/useStreamingTimeAxes.js +257 -0
  221. package/dist/app/charts/plots/useStreamingTimeAxes.js.map +1 -0
  222. package/dist/app/charts/series/baseSeries.d.ts +60 -8
  223. package/dist/app/charts/series/baseSeries.d.ts.map +1 -0
  224. package/dist/app/charts/series/baseSeries.js +53 -8
  225. package/dist/app/charts/series/baseSeries.js.map +1 -1
  226. package/dist/app/charts/series/iterateSeries.d.ts +9 -8
  227. package/dist/app/charts/series/iterateSeries.d.ts.map +1 -0
  228. package/dist/app/charts/series/iterateSeries.js +7 -7
  229. package/dist/app/charts/series/iterateSeries.js.map +1 -1
  230. package/dist/app/charts/series/ordinalSeries.d.ts +27 -13
  231. package/dist/app/charts/series/ordinalSeries.d.ts.map +1 -0
  232. package/dist/app/charts/series/ordinalSeries.js +29 -15
  233. package/dist/app/charts/series/ordinalSeries.js.map +1 -1
  234. package/dist/app/charts/series/outlierSeries.d.ts +142 -0
  235. package/dist/app/charts/series/outlierSeries.d.ts.map +1 -0
  236. package/dist/app/charts/series/outlierSeries.js +82 -0
  237. package/dist/app/charts/series/outlierSeries.js.map +1 -0
  238. package/dist/app/charts/series/timeSeries.d.ts +13 -9
  239. package/dist/app/charts/series/timeSeries.d.ts.map +1 -0
  240. package/dist/app/charts/series/timeSeries.js +6 -3
  241. package/dist/app/charts/series/timeSeries.js.map +1 -1
  242. package/dist/app/charts/series/timeSeriesChartData.d.ts +18 -10
  243. package/dist/app/charts/series/timeSeriesChartData.d.ts.map +1 -0
  244. package/dist/app/charts/series/timeSeriesChartData.js +28 -14
  245. package/dist/app/charts/series/timeSeriesChartData.js.map +1 -1
  246. package/dist/app/charts/styling/barPlotStyle.d.ts +46 -2
  247. package/dist/app/charts/styling/barPlotStyle.d.ts.map +1 -0
  248. package/dist/app/charts/styling/barPlotStyle.js +37 -3
  249. package/dist/app/charts/styling/barPlotStyle.js.map +1 -1
  250. package/dist/app/charts/styling/canvasStyle.d.ts +53 -0
  251. package/dist/app/charts/styling/canvasStyle.d.ts.map +1 -0
  252. package/dist/app/charts/styling/canvasStyle.js +71 -0
  253. package/dist/app/charts/styling/canvasStyle.js.map +1 -0
  254. package/dist/app/charts/styling/margins.d.ts +21 -2
  255. package/dist/app/charts/styling/margins.d.ts.map +1 -0
  256. package/dist/app/charts/styling/margins.js +25 -4
  257. package/dist/app/charts/styling/margins.js.map +1 -1
  258. package/dist/app/charts/styling/svgStyle.d.ts +10 -56
  259. package/dist/app/charts/styling/svgStyle.d.ts.map +1 -0
  260. package/dist/app/charts/styling/svgStyle.js +3 -78
  261. package/dist/app/charts/styling/svgStyle.js.map +1 -1
  262. package/dist/app/charts/subscriptions/viewDrivers.d.ts +124 -0
  263. package/dist/app/charts/subscriptions/viewDrivers.d.ts.map +1 -0
  264. package/dist/app/charts/subscriptions/viewDrivers.js +338 -0
  265. package/dist/app/charts/subscriptions/viewDrivers.js.map +1 -0
  266. package/dist/app/charts/tooltips/BarPlotTooltipContent.d.ts +12 -78
  267. package/dist/app/charts/tooltips/BarPlotTooltipContent.d.ts.map +1 -0
  268. package/dist/app/charts/tooltips/BarPlotTooltipContent.js +65 -257
  269. package/dist/app/charts/tooltips/BarPlotTooltipContent.js.map +1 -1
  270. package/dist/app/charts/tooltips/DefaultOutlierTooltipContent.d.ts +9 -0
  271. package/dist/app/charts/tooltips/DefaultOutlierTooltipContent.d.ts.map +1 -0
  272. package/dist/app/charts/tooltips/DefaultOutlierTooltipContent.js +16 -0
  273. package/dist/app/charts/tooltips/DefaultOutlierTooltipContent.js.map +1 -0
  274. package/dist/app/charts/tooltips/OutlierPlotTooltipContent.d.ts +30 -0
  275. package/dist/app/charts/tooltips/OutlierPlotTooltipContent.d.ts.map +1 -0
  276. package/dist/app/charts/tooltips/OutlierPlotTooltipContent.js +26 -0
  277. package/dist/app/charts/tooltips/OutlierPlotTooltipContent.js.map +1 -0
  278. package/dist/app/charts/tooltips/PoincarePlotTooltipContent.d.ts +22 -72
  279. package/dist/app/charts/tooltips/PoincarePlotTooltipContent.d.ts.map +1 -0
  280. package/dist/app/charts/tooltips/PoincarePlotTooltipContent.js +104 -171
  281. package/dist/app/charts/tooltips/PoincarePlotTooltipContent.js.map +1 -1
  282. package/dist/app/charts/tooltips/RasterPlotTooltipContent.d.ts +32 -8
  283. package/dist/app/charts/tooltips/RasterPlotTooltipContent.d.ts.map +1 -0
  284. package/dist/app/charts/tooltips/RasterPlotTooltipContent.js +62 -115
  285. package/dist/app/charts/tooltips/RasterPlotTooltipContent.js.map +1 -1
  286. package/dist/app/charts/tooltips/ScatterPlotTooltipContent.d.ts +39 -12
  287. package/dist/app/charts/tooltips/ScatterPlotTooltipContent.d.ts.map +1 -0
  288. package/dist/app/charts/tooltips/ScatterPlotTooltipContent.js +162 -134
  289. package/dist/app/charts/tooltips/ScatterPlotTooltipContent.js.map +1 -1
  290. package/dist/app/charts/tooltips/Tooltip.d.ts +27 -32
  291. package/dist/app/charts/tooltips/Tooltip.d.ts.map +1 -0
  292. package/dist/app/charts/tooltips/Tooltip.js +37 -81
  293. package/dist/app/charts/tooltips/Tooltip.js.map +1 -1
  294. package/dist/app/charts/tooltips/TooltipContent.d.ts +81 -0
  295. package/dist/app/charts/tooltips/TooltipContent.d.ts.map +1 -0
  296. package/dist/app/charts/tooltips/TooltipContent.js +99 -0
  297. package/dist/app/charts/tooltips/TooltipContent.js.map +1 -0
  298. package/dist/app/charts/tooltips/tooltipUtils.d.ts +186 -36
  299. package/dist/app/charts/tooltips/tooltipUtils.d.ts.map +1 -0
  300. package/dist/app/charts/tooltips/tooltipUtils.js +277 -48
  301. package/dist/app/charts/tooltips/tooltipUtils.js.map +1 -1
  302. package/dist/app/charts/tooltips/useOutlierTooltip.d.ts +59 -0
  303. package/dist/app/charts/tooltips/useOutlierTooltip.d.ts.map +1 -0
  304. package/dist/app/charts/tooltips/useOutlierTooltip.js +16 -0
  305. package/dist/app/charts/tooltips/useOutlierTooltip.js.map +1 -0
  306. package/dist/app/charts/tooltips/useTooltipPlacement.d.ts +51 -0
  307. package/dist/app/charts/tooltips/useTooltipPlacement.d.ts.map +1 -0
  308. package/dist/app/charts/tooltips/useTooltipPlacement.js +52 -0
  309. package/dist/app/charts/tooltips/useTooltipPlacement.js.map +1 -0
  310. package/dist/app/charts/tooltips/useTooltipStyle.d.ts +11 -0
  311. package/dist/app/charts/tooltips/useTooltipStyle.d.ts.map +1 -0
  312. package/dist/app/charts/tooltips/useTooltipStyle.js +14 -0
  313. package/dist/app/charts/tooltips/useTooltipStyle.js.map +1 -0
  314. package/dist/app/charts/trackers/Tracker.d.ts +22 -6
  315. package/dist/app/charts/trackers/Tracker.d.ts.map +1 -0
  316. package/dist/app/charts/trackers/Tracker.js +36 -22
  317. package/dist/app/charts/trackers/Tracker.js.map +1 -1
  318. package/dist/app/charts/trackers/trackerUtils.d.ts +40 -18
  319. package/dist/app/charts/trackers/trackerUtils.d.ts.map +1 -0
  320. package/dist/app/charts/trackers/trackerUtils.js +213 -300
  321. package/dist/app/charts/trackers/trackerUtils.js.map +1 -1
  322. package/dist/app/charts/utils.d.ts +72 -33
  323. package/dist/app/charts/utils.d.ts.map +1 -0
  324. package/dist/app/charts/utils.js +87 -42
  325. package/dist/app/charts/utils.js.map +1 -1
  326. package/dist/index.d.ts +2 -45
  327. package/dist/index.d.ts.map +1 -0
  328. package/dist/index.js +2 -72
  329. package/dist/index.js.map +1 -1
  330. package/package.json +87 -46
  331. package/src/app/charts/Chart.tsx +132 -168
  332. package/src/app/charts/axes/AxesState.ts +27 -29
  333. package/src/app/charts/axes/AxisInterval.ts +57 -32
  334. package/src/app/charts/axes/BaseAxisRange.ts +47 -27
  335. package/src/app/charts/axes/ContinuousAxis.tsx +235 -39
  336. package/src/app/charts/axes/ContinuousAxisRange.ts +29 -11
  337. package/src/app/charts/axes/EmptyAxis.tsx +52 -17
  338. package/src/app/charts/axes/OrdinalAxis.tsx +54 -28
  339. package/src/app/charts/axes/OrdinalAxisRange.ts +96 -16
  340. package/src/app/charts/axes/autoScale.ts +244 -0
  341. package/src/app/charts/axes/axes.ts +954 -735
  342. package/src/app/charts/d3types.ts +42 -13
  343. package/src/app/charts/datasources/StreamingDataSource.ts +214 -0
  344. package/src/app/charts/datasources/iteratesDataSource.ts +122 -0
  345. package/src/app/charts/datasources/ordinalDataSource.ts +205 -0
  346. package/src/app/charts/datasources/outlierDataSource.ts +90 -0
  347. package/src/app/charts/datasources/timeSeriesDataSource.ts +133 -0
  348. package/src/app/charts/filters/regexFilter.ts +45 -5
  349. package/src/app/charts/hooks/AxesProvider.tsx +301 -0
  350. package/src/app/charts/hooks/CanvasSurfaceProvider.tsx +117 -0
  351. package/src/app/charts/hooks/ChartProvider.tsx +79 -0
  352. package/src/app/charts/hooks/InteractionProvider.tsx +88 -0
  353. package/src/app/charts/hooks/PlotDimensionsProvider.tsx +109 -0
  354. package/src/app/charts/hooks/defaultAxesValues.ts +40 -0
  355. package/src/app/charts/hooks/defaultMouseValues.ts +24 -0
  356. package/src/app/charts/hooks/defaultPlotDimensions.ts +27 -0
  357. package/src/app/charts/hooks/defaultTooltipValues.tsx +23 -0
  358. package/src/app/charts/hooks/defaultUseChartValues.tsx +36 -0
  359. package/src/app/charts/hooks/useAxes.tsx +60 -228
  360. package/src/app/charts/hooks/useCanvasSurface.tsx +35 -0
  361. package/src/app/charts/hooks/useChart.tsx +47 -106
  362. package/src/app/charts/hooks/useDataSource.tsx +106 -0
  363. package/src/app/charts/hooks/useHoveredSeries.tsx +33 -0
  364. package/src/app/charts/hooks/useMouse.tsx +58 -82
  365. package/src/app/charts/hooks/usePlotDimensions.tsx +25 -89
  366. package/src/app/charts/hooks/useTooltip.tsx +32 -63
  367. package/src/app/charts/index.ts +213 -0
  368. package/src/app/charts/legends/Legend.tsx +198 -479
  369. package/src/app/charts/legends/constants.ts +37 -0
  370. package/src/app/charts/observables/iterates.ts +32 -12
  371. package/src/app/charts/observables/ordinals.ts +141 -67
  372. package/src/app/charts/observables/outliers.ts +20 -0
  373. package/src/app/charts/plots/BarPlot.tsx +784 -666
  374. package/src/app/charts/plots/OutlierPlot.tsx +685 -0
  375. package/src/app/charts/plots/PoincarePlot.tsx +707 -489
  376. package/src/app/charts/plots/RasterPlot.tsx +253 -445
  377. package/src/app/charts/plots/ScatterPlot.tsx +480 -463
  378. package/src/app/charts/plots/autoScaleYAxes.ts +102 -0
  379. package/src/app/charts/plots/colorizedLine.ts +185 -0
  380. package/src/app/charts/plots/constants.ts +16 -0
  381. package/src/app/charts/plots/hitTesting.ts +198 -0
  382. package/src/app/charts/plots/plot.ts +138 -44
  383. package/src/app/charts/plots/useCanvasZoomPan.ts +240 -0
  384. package/src/app/charts/plots/useStreamingTimeAxes.ts +384 -0
  385. package/src/app/charts/series/baseSeries.ts +81 -14
  386. package/src/app/charts/series/iterateSeries.ts +8 -8
  387. package/src/app/charts/series/ordinalSeries.ts +35 -20
  388. package/src/app/charts/series/outlierSeries.ts +188 -0
  389. package/src/app/charts/series/timeSeries.ts +14 -12
  390. package/src/app/charts/series/timeSeriesChartData.ts +31 -17
  391. package/src/app/charts/styling/barPlotStyle.ts +48 -5
  392. package/src/app/charts/styling/canvasStyle.ts +86 -0
  393. package/src/app/charts/styling/margins.ts +28 -4
  394. package/src/app/charts/styling/svgStyle.ts +10 -91
  395. package/src/app/charts/subscriptions/viewDrivers.ts +447 -0
  396. package/src/app/charts/tooltips/BarPlotTooltipContent.tsx +156 -380
  397. package/src/app/charts/tooltips/DefaultOutlierTooltipContent.tsx +40 -0
  398. package/src/app/charts/tooltips/OutlierPlotTooltipContent.tsx +67 -0
  399. package/src/app/charts/tooltips/PoincarePlotTooltipContent.tsx +229 -292
  400. package/src/app/charts/tooltips/RasterPlotTooltipContent.tsx +164 -217
  401. package/src/app/charts/tooltips/ScatterPlotTooltipContent.tsx +373 -236
  402. package/src/app/charts/tooltips/Tooltip.tsx +58 -124
  403. package/src/app/charts/tooltips/TooltipContent.tsx +177 -0
  404. package/src/app/charts/tooltips/tooltipUtils.ts +359 -61
  405. package/src/app/charts/tooltips/useOutlierTooltip.tsx +68 -0
  406. package/src/app/charts/tooltips/useTooltipPlacement.ts +86 -0
  407. package/src/app/charts/tooltips/useTooltipStyle.ts +15 -0
  408. package/src/app/charts/trackers/Tracker.tsx +68 -33
  409. package/src/app/charts/trackers/trackerUtils.ts +263 -376
  410. package/src/app/charts/utils.ts +90 -48
  411. package/src/index.ts +2 -322
  412. package/dist/app/charts/axes/AxesState.test.d.ts +0 -1
  413. package/dist/app/charts/axes/AxesState.test.js +0 -30
  414. package/dist/app/charts/axes/AxesState.test.js.map +0 -1
  415. package/dist/app/charts/axes/AxisInterval.test.d.ts +0 -1
  416. package/dist/app/charts/axes/AxisInterval.test.js +0 -120
  417. package/dist/app/charts/axes/AxisInterval.test.js.map +0 -1
  418. package/dist/app/charts/axes/ContinuousAxisRange.test.d.ts +0 -1
  419. package/dist/app/charts/axes/ContinuousAxisRange.test.js +0 -47
  420. package/dist/app/charts/axes/ContinuousAxisRange.test.js.map +0 -1
  421. package/dist/app/charts/axes/OrdinalAxisRange.test.d.ts +0 -1
  422. package/dist/app/charts/axes/OrdinalAxisRange.test.js +0 -48
  423. package/dist/app/charts/axes/OrdinalAxisRange.test.js.map +0 -1
  424. package/dist/app/charts/filters/regexFilter.test.d.ts +0 -1
  425. package/dist/app/charts/filters/regexFilter.test.js +0 -11
  426. package/dist/app/charts/filters/regexFilter.test.js.map +0 -1
  427. package/dist/app/charts/hooks/useDataObservable.d.ts +0 -72
  428. package/dist/app/charts/hooks/useDataObservable.js +0 -74
  429. package/dist/app/charts/hooks/useDataObservable.js.map +0 -1
  430. package/dist/app/charts/hooks/useInitialData.d.ts +0 -36
  431. package/dist/app/charts/hooks/useInitialData.js +0 -28
  432. package/dist/app/charts/hooks/useInitialData.js.map +0 -1
  433. package/dist/app/charts/observables/iterates.test.d.ts +0 -1
  434. package/dist/app/charts/observables/iterates.test.js +0 -180
  435. package/dist/app/charts/observables/iterates.test.js.map +0 -1
  436. package/dist/app/charts/observables/ordinals.test.d.ts +0 -1
  437. package/dist/app/charts/observables/ordinals.test.js +0 -102
  438. package/dist/app/charts/observables/ordinals.test.js.map +0 -1
  439. package/dist/app/charts/series/datumSeries.test.d.ts +0 -1
  440. package/dist/app/charts/series/datumSeries.test.js +0 -50
  441. package/dist/app/charts/series/datumSeries.test.js.map +0 -1
  442. package/dist/app/charts/styling/margins.test.d.ts +0 -1
  443. package/dist/app/charts/styling/margins.test.js +0 -19
  444. package/dist/app/charts/styling/margins.test.js.map +0 -1
  445. package/dist/app/charts/subscriptions/subscription.test.d.ts +0 -1
  446. package/dist/app/charts/subscriptions/subscription.test.js +0 -395
  447. package/dist/app/charts/subscriptions/subscription.test.js.map +0 -1
  448. package/dist/app/charts/subscriptions/subscriptions.d.ts +0 -100
  449. package/dist/app/charts/subscriptions/subscriptions.js +0 -449
  450. package/dist/app/charts/subscriptions/subscriptions.js.map +0 -1
  451. package/src/app/charts/axes/AxesState.test.ts +0 -34
  452. package/src/app/charts/axes/AxisInterval.test.ts +0 -143
  453. package/src/app/charts/axes/ContinuousAxisRange.test.ts +0 -55
  454. package/src/app/charts/axes/OrdinalAxisRange.test.ts +0 -55
  455. package/src/app/charts/filters/regexFilter.test.ts +0 -13
  456. package/src/app/charts/hooks/useDataObservable.tsx +0 -170
  457. package/src/app/charts/hooks/useInitialData.tsx +0 -64
  458. package/src/app/charts/observables/iterates.test.ts +0 -201
  459. package/src/app/charts/observables/ordinals.test.ts +0 -135
  460. package/src/app/charts/series/datumSeries.test.ts +0 -60
  461. package/src/app/charts/styling/margins.test.ts +0 -22
  462. package/src/app/charts/subscriptions/subscription.test.ts +0 -499
  463. package/src/app/charts/subscriptions/subscriptions.ts +0 -635
@@ -0,0 +1,384 @@
1
+ import {type RefObject, useCallback, useEffect, useEffectEvent, useMemo, useRef} from "react";
2
+ import {Optional} from "result-fn";
3
+ import {
4
+ axesForSeriesGen,
5
+ type ContinuousNumericAxis,
6
+ continuousAxisIntervals,
7
+ continuousAxisRanges,
8
+ continuousAxisZoomHandler,
9
+ defaultLineStyle,
10
+ panHandler,
11
+ type SeriesLineStyle,
12
+ } from "../axes/axes";
13
+ import {AxisInterval} from "../axes/AxisInterval";
14
+ import {ContinuousAxisRange} from "../axes/ContinuousAxisRange";
15
+ import type {CanvasContext} from "../d3types";
16
+ import type {StreamingDataSource} from "../datasources/StreamingDataSource";
17
+ import {useChart} from "../hooks/useChart";
18
+ import {useHoveredSeries} from "../hooks/useHoveredSeries";
19
+ import {usePlotDimensions} from "../hooks/usePlotDimensions";
20
+ import {useStreamingSettings} from "../hooks/useDataSource";
21
+ import type {ChartData} from "../observables/ChartData";
22
+ import type {BaseSeries} from "../series/baseSeries";
23
+ import {type AxisTimesFor, timeAxisViewDriverFor, TimeWindowBehavior} from "../subscriptions/viewDrivers";
24
+ import {noop} from "../utils";
25
+ import {type AxesAssignment, currentIntervalsFrom} from "./plot";
26
+ import {useCanvasZoomPan} from "./useCanvasZoomPan";
27
+
28
+ /**
29
+ * The options for {@link useStreamingTimeAxes}
30
+ * @template CD The type of the chart data
31
+ * @template D The type of the series' datum
32
+ */
33
+ export interface StreamingTimeAxesOptions<CD extends ChartData, D> {
34
+ /**
35
+ * The plot's canvas context (`null` until the canvas exists)
36
+ */
37
+ canvasContext: CanvasContext | null
38
+ /**
39
+ * The data source (and whether it's running)
40
+ */
41
+ dataSource: StreamingDataSource<CD, D> | undefined
42
+ running: boolean
43
+ /**
44
+ * The series the data source held when it was handed to the chart (see `useInitialData`)
45
+ */
46
+ initialData: Array<BaseSeries<D>>
47
+ /**
48
+ * The time of a datum (its x-value)
49
+ */
50
+ timeOf: (datum: D) => number
51
+ /**
52
+ * Gives the current time of each x-axis that a chunk of data has new points for (see
53
+ * `timeSeriesAxisTimes` and `outlierAxisTimes`)
54
+ */
55
+ axisTimesFor: AxisTimesFor<CD>
56
+ /**
57
+ * The assignment of the series to their x- and y-axes
58
+ */
59
+ axisAssignments: Map<string, AxesAssignment>
60
+ /**
61
+ * Draws the plot (registers its draw function with the canvas context, and requests a redraw)
62
+ */
63
+ updatePlot: (canvasContext: CanvasContext) => void
64
+ /**
65
+ * Resets the plot's own references to the data, when the data source is replaced -- called just
66
+ * before the axes are reset and the plot is redrawn
67
+ */
68
+ onDataReset: () => void
69
+ /**
70
+ * Whether the plot may show tooltips: when given, it's cleared while panning and while the data
71
+ * source is running, and restored afterward
72
+ */
73
+ allowTooltipRef?: RefObject<boolean>
74
+ /**
75
+ * Panning and zooming (see {@link useCanvasZoomPan})
76
+ */
77
+ panEnabled: boolean
78
+ zoomEnabled: boolean
79
+ zoomKeyModifiersRequired: boolean
80
+ /**
81
+ * The plot's `onZoomReset` property (see {@link useCanvasZoomPan})
82
+ */
83
+ onZoomReset?: (resetZoom: () => void) => void
84
+ /**
85
+ * The time (ms) between cadence ticks (none, when undefined -- see `timeAxisViewDriverFor`)
86
+ */
87
+ withCadenceOf?: number
88
+ /**
89
+ * Whether the time axes scroll or squeeze as data passes their ends (defaults to SCROLL)
90
+ */
91
+ timeWindowBehavior?: TimeWindowBehavior
92
+ /**
93
+ * When true, the x- and y-axes of the hovered series are highlighted (in the series' own
94
+ * highlight color and width)
95
+ */
96
+ highlightAxesOnMouseOver: boolean
97
+ }
98
+
99
+ /**
100
+ * The time (x-) axes of a streaming time plot (the scatter, raster, and outlier plots): keeps each
101
+ * x-axis's range in step with the data, and with the user's panning and zooming, and reports the
102
+ * ranges.
103
+ *
104
+ * - **The ranges.** One map of the x-axes' ranges, built once and mutated in place: the zoom and
105
+ * pan handlers, and the view driver, all work on the same map, so that neither undoes the
106
+ * other (the view driver hands its map back through `updateTimingAndPlot`, which re-points the
107
+ * map at it).
108
+ * - **The view driver.** While the data source runs, a view driver (see `timeAxisViewDriverFor`)
109
+ * advances the ranges as the data arrives (or with cadence), records each axis's current time,
110
+ * and redraws the plot. It belongs to this plot alone, and is torn down with it.
111
+ * - **Panning and zooming.** While running, the zoom pivots on each axis's current time ("now");
112
+ * while paused, on the mouse. A zoom reset restores the axes' original ranges (as captured when
113
+ * the data source was handed to the plot).
114
+ * - **Reporting.** The axes' intervals are reported to the chart's `onUpdateAxesBounds` (at most
115
+ * once per animation frame, since zooming and panning fire many events).
116
+ * - **A new data source** (new initial data) resets the plot's data, the axes' ranges (starting at
117
+ * the data's first time), and the original ranges a zoom reset restores.
118
+ * - **Highlighting.** Optionally, highlights the hovered series' axes.
119
+ * @param options The plot's canvas, data, handlers, and settings
120
+ * @template CD The type of the chart data
121
+ * @template D The type of the series' datum
122
+ */
123
+ export function useStreamingTimeAxes<CD extends ChartData, D>(options: StreamingTimeAxesOptions<CD, D>): void {
124
+ const {
125
+ canvasContext, dataSource, running, initialData, timeOf, axisTimesFor, axisAssignments,
126
+ updatePlot, onDataReset, allowTooltipRef,
127
+ panEnabled, zoomEnabled, zoomKeyModifiersRequired, onZoomReset,
128
+ withCadenceOf, timeWindowBehavior = TimeWindowBehavior.SCROLL,
129
+ highlightAxesOnMouseOver,
130
+ } = options
131
+
132
+ const {chartId, color, axes, seriesStyles} = useChart<D, SeriesLineStyle, unknown, ContinuousAxisRange, ContinuousNumericAxis>()
133
+ const {xAxesState, yAxesState, setAxisIntervalFor, updateAxisRanges = noop, onUpdateAxesInterval} = axes
134
+ const {plotDimensions, margin} = usePlotDimensions()
135
+ const {windowingTime, dataUpdatePeriod} = useStreamingSettings()
136
+ const {hoveredSeriesName} = useHoveredSeries()
137
+
138
+ // the x-axes' ranges: built once, and mutated in place by the zoom and pan handlers (and
139
+ // re-pointed at the view driver's map by `updateTimingAndPlot`)
140
+ const timeRangesRef = useRef<Map<string, ContinuousAxisRange>>(new Map())
141
+ // map(axis_id -> current_time), recorded by the view driver; the zoom pivots on it while
142
+ // running. Empty (rather than 0 per axis) until the driver records a time, so that the zoom
143
+ // pivot falls back to the axis' own domain
144
+ const currentTimeRef = useRef<Map<string, number>>(new Map())
145
+ // the axes' true original (un-zoomed) bounds, which a zoom reset restores, and each axis' pinned
146
+ // start time for SQUEEZE -- captured when the data source is handed to the plot (see
147
+ // `resetForNewData`), rather than via a `useMemo` on the axes context, which re-samples the
148
+ // ranges' `.original` as auto-scroll moves it
149
+ const initialAxisIntervalsRef = useRef<Map<string, [start: number, end: number]>>(new Map())
150
+ const initialTimesRef = useRef<Map<string, number>>(new Map())
151
+
152
+ // the latest draw and axis-range-update functions (called from the view driver, and the zoom
153
+ // and pan handlers)
154
+ const updatePlotRef = useRef(updatePlot)
155
+ useEffect(() => {
156
+ updatePlotRef.current = updatePlot
157
+ }, [updatePlot])
158
+ const updateAxisRangesRef = useRef(updateAxisRanges)
159
+ useEffect(() => {
160
+ updateAxisRangesRef.current = updateAxisRanges
161
+ }, [updateAxisRanges])
162
+
163
+ // reports the axes' intervals to the chart's `onUpdateAxesBounds`, at most once per animation
164
+ // frame (zooming and panning fire many events per gesture, and the callback generally updates
165
+ // the application's state). Coalescing loses nothing: the deferred notification reports the
166
+ // *latest* ranges (`pendingRangesRef`), not those of the call that scheduled it -- the ranges
167
+ // map is sometimes replaced (e.g. on a reset), and reporting a stale map would write stale
168
+ // intervals into the application's state.
169
+ const notifyIntervalsRef = useRef<(ranges: Map<string, ContinuousAxisRange>) => void>(noop)
170
+ const notifyFrameRef = useRef<number>(0)
171
+ const pendingRangesRef = useRef<Map<string, ContinuousAxisRange>>(new Map())
172
+ useEffect(() => {
173
+ notifyIntervalsRef.current = onUpdateAxesInterval === undefined ?
174
+ noop :
175
+ ranges => {
176
+ pendingRangesRef.current = ranges
177
+ if (notifyFrameRef.current !== 0) return
178
+ notifyFrameRef.current = requestAnimationFrame(() => {
179
+ notifyFrameRef.current = 0
180
+ onUpdateAxesInterval(currentIntervalsFrom(pendingRangesRef.current))
181
+ })
182
+ }
183
+ }, [onUpdateAxesInterval])
184
+ // don't leave a scheduled notification pointing at an unmounted plot
185
+ useEffect(() => () => {
186
+ if (notifyFrameRef.current !== 0) {
187
+ cancelAnimationFrame(notifyFrameRef.current)
188
+ notifyFrameRef.current = 0
189
+ }
190
+ }, [])
191
+
192
+ // new x-axes: forget the current times (see `currentTimeRef`)
193
+ useEffect(() => {
194
+ currentTimeRef.current = new Map()
195
+ }, [xAxesState])
196
+
197
+ // highlights the hovered series' x- and y-axes, and un-highlights them (in the effect's
198
+ // cleanup) when the hover moves to a different series, or ends
199
+ useEffect(() => {
200
+ if (!highlightAxesOnMouseOver || hoveredSeriesName === null) return
201
+ const assignment = axisAssignments.get(hoveredSeriesName)
202
+ const xAxis = xAxesState.axisFor(assignment?.xAxis || "").getOrUndefined()
203
+ const yAxis = yAxesState.axisFor(assignment?.yAxis || "").getOrUndefined()
204
+ const {highlightColor, highlightWidth} = seriesStyles.get(hoveredSeriesName) || defaultLineStyle()
205
+ xAxis?.setHighlighted(true, highlightColor, highlightWidth)
206
+ yAxis?.setHighlighted(true, highlightColor, highlightWidth)
207
+ return () => {
208
+ xAxis?.setHighlighted(false)
209
+ yAxis?.setHighlighted(false)
210
+ }
211
+ }, [highlightAxesOnMouseOver, hoveredSeriesName, axisAssignments, xAxesState, yAxesState, seriesStyles])
212
+
213
+ // the distinct x-axes that the series use
214
+ const axesForSeries = useMemo(
215
+ (): Array<string> => axesForSeriesGen<D, ContinuousNumericAxis>(initialData, axisAssignments, xAxesState),
216
+ [initialData, axisAssignments, xAxesState]
217
+ )
218
+
219
+ // hands new ranges to the axes, makes them the plot's ranges (see `timeRangesRef`), redraws the
220
+ // plot, and reports the axes' intervals
221
+ const updateTimingAndPlot = useCallback(
222
+ (ranges: Map<string, ContinuousAxisRange>): void => {
223
+ if (canvasContext === null) return
224
+ updateAxisRangesRef.current(ranges)
225
+ timeRangesRef.current = ranges
226
+ updatePlotRef.current(canvasContext)
227
+ notifyIntervalsRef.current(ranges)
228
+ },
229
+ [canvasContext]
230
+ )
231
+
232
+ // a new data source (new initial data): resets the plot's data, the current times, and the
233
+ // original bounds (for a zoom reset), and starts each axis at the data's first time. (An effect
234
+ // event, so that it runs only when the initial data changes, with the latest everything else.)
235
+ const resetForNewData = useEffectEvent(() => {
236
+ onDataReset()
237
+ currentTimeRef.current = new Map()
238
+
239
+ const freshRanges = continuousAxisRanges(xAxesState.axes)
240
+ initialAxisIntervalsRef.current = new Map(
241
+ Array.from(freshRanges.entries()).map(([id, range]) => [id, range.original.asTuple()])
242
+ )
243
+ initialTimesRef.current = new Map(
244
+ Array.from(freshRanges.entries()).map(([id, range]) => [id, range.original.start])
245
+ )
246
+
247
+ updateTimingAndPlot(new Map(Array.from(freshRanges.entries()).map(([id, range]) => {
248
+ const [start, end] = range.original.asTuple()
249
+ const firstTime = initialData
250
+ .filter(series => axisAssignments.get(series.name)?.xAxis === id)
251
+ .reduce((tMin, series) => Math.min(tMin, !series.isEmpty() ? timeOf(series.data[0]) : tMin), Infinity)
252
+ const startTime = firstTime === Infinity ? 0 : firstTime
253
+ return [id, ContinuousAxisRange.from(startTime, startTime + end - start)]
254
+ })))
255
+ })
256
+ useEffect(() => {
257
+ resetForNewData()
258
+ }, [initialData])
259
+
260
+ // pans the axes (in place) by the dragged amount
261
+ const onPan = useCallback(
262
+ (x: number, ranges: Map<string, ContinuousAxisRange>) =>
263
+ panHandler(axesForSeries, margin, setAxisIntervalFor, xAxesState)(x, plotDimensions, ranges),
264
+ [axesForSeries, margin, setAxisIntervalFor, xAxesState, plotDimensions]
265
+ )
266
+
267
+ // zooms the axes (in place) by the incremental zoom factor, around each axis's pivot
268
+ const onZoom = useCallback(
269
+ (zoomFactor: number, pivotFor: (axisId: string, axis: ContinuousNumericAxis) => number, ranges: Map<string, ContinuousAxisRange>) =>
270
+ continuousAxisZoomHandler(axesForSeries, margin, setAxisIntervalFor, xAxesState)(zoomFactor, pivotFor, plotDimensions, ranges),
271
+ [axesForSeries, margin, setAxisIntervalFor, xAxesState, plotDimensions]
272
+ )
273
+
274
+ // what the zoom pivots on: while running, each axis's "now" (so the newest data stays put,
275
+ // whether or not the axis has started scrolling yet -- falling back to the axis' right edge
276
+ // until the view driver records a time); while paused, the mouse
277
+ const zoomPivotFor = useCallback(
278
+ (offsetX: number): (axisId: string, axis: ContinuousNumericAxis) => number =>
279
+ running ?
280
+ (axisId, axis) => currentTimeRef.current.get(axisId) ?? axis.scale.domain()[1] :
281
+ (_axisId, axis) => axis.scale.invert(offsetX - margin.left),
282
+ [running, margin]
283
+ )
284
+
285
+ useCanvasZoomPan(canvasContext, {
286
+ panEnabled,
287
+ zoomEnabled,
288
+ keyModifiersRequired: zoomKeyModifiersRequired,
289
+ scaleExtent: [0, 10],
290
+ translateExtent: [[margin.left, margin.top], [plotDimensions.width, plotDimensions.height]],
291
+ // (tooltips are suppressed while panning, so that one isn't left behind)
292
+ onPanStart: () => {
293
+ if (allowTooltipRef !== undefined) allowTooltipRef.current = false
294
+ },
295
+ onPan: dx => {
296
+ if (canvasContext === null) return
297
+ onPan(dx, timeRangesRef.current)
298
+ updatePlotRef.current(canvasContext)
299
+ // the pan updated the axes' ranges in place, so report the new intervals
300
+ notifyIntervalsRef.current(timeRangesRef.current)
301
+ },
302
+ onPanEnd: () => {
303
+ if (allowTooltipRef !== undefined) allowTooltipRef.current = !(dataSource?.running ?? false)
304
+ },
305
+ onZoom: ({factor, x}) => {
306
+ if (canvasContext === null) return
307
+ onZoom(factor, zoomPivotFor(x), timeRangesRef.current)
308
+ updatePlotRef.current(canvasContext)
309
+ // the zoom updated the axes' ranges in place, so report the new intervals
310
+ notifyIntervalsRef.current(timeRangesRef.current)
311
+ },
312
+ onZoomReset,
313
+ // restores each axis to its true original bounds (see `initialAxisIntervalsRef`), and does
314
+ // a full sync (through `updateTimingAndPlot`), so that the AxesProvider's own ranges pick up
315
+ // the reset `.original` too -- otherwise a reset while paused (with no ticks left to resync
316
+ // them) would leave them at the zoomed bounds, which a store-backed domain then reads back
317
+ resetView: () => {
318
+ initialAxisIntervalsRef.current.forEach(([start, end], axisId) => {
319
+ timeRangesRef.current.set(axisId, ContinuousAxisRange.from(start, end))
320
+ xAxesState.axisFor(axisId).ifPresent(
321
+ axis => axis.update(AxisInterval.from(start, end), plotDimensions, margin)
322
+ )
323
+ })
324
+ updateTimingAndPlot(timeRangesRef.current)
325
+ },
326
+ })
327
+
328
+ // keeps the ranges in step with the axes when the canvas, the axes, or the plot's dimensions
329
+ // change (creating them the first time, and afterward updating them in place, so that their
330
+ // `.original` -- and the map's identity -- survive), and redraws
331
+ useEffect(() => {
332
+ if (canvasContext === null) return
333
+ if (timeRangesRef.current.size === 0) {
334
+ continuousAxisRanges(xAxesState.axes).forEach((range, id) => timeRangesRef.current.set(id, range))
335
+ } else {
336
+ const intervals = continuousAxisIntervals(xAxesState.axes)
337
+ timeRangesRef.current.forEach((range, id, rangesMap) => {
338
+ const [start, end] = Optional.ofNullable(intervals.get(id))
339
+ .map(interval => interval.asTuple())
340
+ .getOrThrow(() => new Error(`Unable to retrieve interval for axis; axis_id: ${id}`))
341
+ if (!isNaN(start) && !isNaN(end)) {
342
+ rangesMap.set(id, range.update(start, end))
343
+ }
344
+ })
345
+ }
346
+ updatePlot(canvasContext)
347
+ }, [chartId, color, canvasContext, plotDimensions, updatePlot, xAxesState])
348
+
349
+ // the latest `updateTimingAndPlot`, for the view driver (created once per run) to call
350
+ const updateTimingAndPlotRef = useRef(updateTimingAndPlot)
351
+ useEffect(() => {
352
+ updateTimingAndPlotRef.current = updateTimingAndPlot
353
+ }, [updateTimingAndPlot])
354
+
355
+ // creates the view driver, with the current settings (an effect event, so that the driver is
356
+ // created only when the run starts, with the settings as they are then)
357
+ const createViewDriver = useEffectEvent(
358
+ (source: StreamingDataSource<CD, D>) => timeAxisViewDriverFor(
359
+ source, xAxesState, axisTimesFor,
360
+ ranges => updateTimingAndPlotRef.current(ranges),
361
+ (axisId, end) => currentTimeRef.current.set(axisId, end),
362
+ {
363
+ windowingTime,
364
+ dataUpdatePeriod,
365
+ cadencePeriod: withCadenceOf,
366
+ timeWindowBehavior,
367
+ initialTimes: initialTimesRef.current,
368
+ }
369
+ )
370
+ )
371
+
372
+ // while the data source runs (and the plot has a canvas and x-axes), drives the view from the
373
+ // data source's updates. The driver belongs to this plot alone, and is always torn down with it.
374
+ const hasXAxes = xAxesState.axes.size > 0
375
+ useEffect(() => {
376
+ if (dataSource === undefined || !running || canvasContext === null || !hasXAxes) return
377
+ if (allowTooltipRef !== undefined) allowTooltipRef.current = false
378
+ const driver = createViewDriver(dataSource)
379
+ return () => {
380
+ driver.unsubscribe()
381
+ if (allowTooltipRef !== undefined) allowTooltipRef.current = true
382
+ }
383
+ }, [dataSource, running, canvasContext, hasXAxes, allowTooltipRef])
384
+ }
@@ -1,52 +1,119 @@
1
- import {failureResult, Result, successResult} from "result-fn";
1
+ import {failureResult, type Result, successResult} from "result-fn";
2
+ import {FastShiftArray} from "fast-shift-array";
2
3
 
3
4
  /**
4
- * A spike series holding an array of spike (time, value) datum, the name and supplemental information
5
- * needed by the `RasterChart`
5
+ * A named series of data, the basis of every chart's series. Its data is held in a
6
+ * `FastShiftArray`, so that the oldest data can be dropped from its head cheaply as new data
7
+ * streams in.
8
+ * @template D The type of the series' datum
6
9
  */
7
10
  export interface BaseSeries<D> {
11
+ /**
12
+ * The name of the series (unique within a chart)
13
+ */
8
14
  readonly name: string;
9
- data: Array<D>;
15
+ /**
16
+ * The series' data, ordered by time
17
+ */
18
+ data: FastShiftArray<D>;
19
+ /**
20
+ * @return The last datum, or a failure when the series is empty
21
+ */
10
22
  readonly last: () => Result<D, string>;
23
+ /**
24
+ * @return The number of data in the series
25
+ */
11
26
  readonly length: () => number;
27
+ /**
28
+ * @return `true` when the series has no data; `false` otherwise
29
+ */
12
30
  readonly isEmpty: () => boolean;
13
31
  }
14
32
 
33
+ /**
34
+ * Default number of shifts a series' backing `FastShiftArray` accumulates before it's compacted,
35
+ * used whenever a caller doesn't specify one explicitly. This is deliberately much lower than
36
+ * `FastShiftArray`'s own default of 100,000: compaction is a single, blocking O(n) operation (it
37
+ * splices out all the accumulated dead slots in one call), so with the default threshold, a
38
+ * long-running streaming chart hits one large, very perceptible stutter once cumulative shifts
39
+ * cross 100,000 -- visible as a sudden jump/lag rather than a gradual slowdown. Compacting more
40
+ * often, on a much smaller batch each time, trades that one large pause for many much smaller
41
+ * (and much less noticeable) ones spread across the session.
42
+ *
43
+ * If a particular use case genuinely prefers fewer, larger pauses (e.g. a non-interactive/batch
44
+ * context where per-call overhead matters more than pause smoothness), pass a larger
45
+ * `compactingSize` explicitly to `seriesFrom`/`emptySeries`/`emptySeriesFor`.
46
+ */
47
+ export const DEFAULT_COMPACTING_SIZE = 10_000
48
+
15
49
  /**
16
50
  * Creates a series from the name and the optional array of `Datum`.
51
+ *
52
+ * **Ownership warning:** when `data` is a plain array (or already a {@link FastShiftArray}), it is
53
+ * wrapped **by reference**, not copied -- the returned series' backing storage *is* that same
54
+ * array/`FastShiftArray`. As the chart streams in new data and ages old data out, the library calls
55
+ * `shift()` on it (clearing the head slot, and periodically `splice`-ing it during compaction),
56
+ * mutating it in place. If you keep your own reference to the array you pass in (to reuse,
57
+ * snapshot, or compare later), you will see it change out from under you. If you need an
58
+ * independent copy, pass `data.slice()` instead -- see e.g. `StreamingBarChart.tsx`,
59
+ * `StreamingRasterChart.tsx`, and `StreamingPoincareChart.tsx`, which all do this when re-deriving
60
+ * initial series from data they still hold a reference to elsewhere.
17
61
  * @param name The name of the series (i.e. neuron)
18
62
  * @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
63
+ * @param compactingSize The number of shifts the series' backing array accumulates before it's
64
+ * compacted (see {@link DEFAULT_COMPACTING_SIZE}). Only applies when `data` is a plain array (and
65
+ * so a new `FastShiftArray` is created for it) -- ignored when `data` is already a `FastShiftArray`,
66
+ * since compaction size is fixed at that instance's own construction time.
67
+ * @return A {@link BaseSeries} that can be used in {@link Chart}s
20
68
  * @see seriesFromTuples
21
69
  * @see emptySeries
22
70
  */
23
- export function seriesFrom<D>(name: string, data: Array<D> = []): BaseSeries<D> {
71
+ export function seriesFrom<D>(
72
+ name: string,
73
+ data: Array<D> | FastShiftArray<D> = [],
74
+ compactingSize: number = DEFAULT_COMPACTING_SIZE
75
+ ): BaseSeries<D> {
76
+ // `backing` is the single source of truth stored in `.data` below -- `last`/`length`/`isEmpty`
77
+ // must close over this (not the original `data` param) so they go through FastShiftArray's own
78
+ // headIndex-aware accessors. When `data` is a plain array, `FastShiftArray.fromArray` wraps it
79
+ // by reference rather than copying, so reading `data.length` directly (the old behavior) read
80
+ // the raw backing array's physical length, which `shift()` never shrinks -- it only advances
81
+ // an internal headIndex.
82
+ const backing: FastShiftArray<D> = data instanceof Array ?
83
+ FastShiftArray.fromArray<D>(data, true, compactingSize) :
84
+ data
24
85
  return {
25
86
  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
87
+ data: backing,
88
+ last: () => backing.length > 0 ?
89
+ successResult<D, string>(backing[backing.length - 1]) :
90
+ failureResult<D, string>("Data is empty"),
91
+ length: () => backing.length,
92
+ isEmpty: () => backing.length === 0
30
93
  }
31
94
  }
32
95
 
33
96
  /**
34
97
  * Returns an empty series with the specified name
35
98
  * @param name The name of the series
99
+ * @param compactingSize The number of shifts the series' backing array accumulates before it's
100
+ * compacted (see {@link DEFAULT_COMPACTING_SIZE})
36
101
  * @return The empty series
37
102
  * @see seriesFrom
38
103
  * @see seriesFromTuples
39
104
  */
40
- export const emptySeries = <D>(name: string): BaseSeries<D> => seriesFrom(name);
105
+ export const emptySeries = <D>(name: string, compactingSize: number = DEFAULT_COMPACTING_SIZE): BaseSeries<D> =>
106
+ seriesFrom(name, [], compactingSize);
41
107
 
42
108
  /**
43
109
  * Creates an array of empty series, one for each specified name
44
110
  * @param names The names for each of the empty series
111
+ * @param compactingSize The number of shifts each series' backing array accumulates before it's
112
+ * compacted (see {@link DEFAULT_COMPACTING_SIZE})
45
113
  * @return An array of empty series with the specified names
46
114
  * @see emptySeries
47
115
  * @see seriesFrom
48
116
  * @see seriesFromTuples
49
117
  */
50
- export const emptySeriesFor = <D>(names: Array<string>): Array<BaseSeries<D>> => names.map(name => seriesFrom(name))
51
-
52
-
118
+ export const emptySeriesFor = <D>(names: Array<string>, compactingSize: number = DEFAULT_COMPACTING_SIZE): Array<BaseSeries<D>> =>
119
+ names.map(name => seriesFrom(name, [], compactingSize))
@@ -1,4 +1,4 @@
1
- import {BaseSeries, seriesFrom} from "./baseSeries";
1
+ import {type BaseSeries, seriesFrom} from "./baseSeries";
2
2
 
3
3
  /**
4
4
  * An immutable datum object that holds the iterate `(f[n](x), f[n+1](x))` with an
@@ -11,7 +11,7 @@ export interface IterateDatum {
11
11
  }
12
12
 
13
13
  /**
14
- * Creates an empty iterate datum
14
+ * An empty iterate datum (its time and iterates are all `NaN`)
15
15
  */
16
16
  export const emptyIterateDatum: IterateDatum = {time: NaN, iterateN: NaN, iterateN_1: NaN}
17
17
 
@@ -29,10 +29,10 @@ export const iterateDatumOf = (time: number, iterateN: number, iterateN_1: numbe
29
29
  })
30
30
 
31
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`
32
+ * Returns whether the iterate datum is non-empty. An iterate datum is considered empty when any
33
+ * of its time, `f[n](x)`, and `f[n+1](x)` values is `NaN`
34
34
  * @param datum The iterate datum to test
35
- * @return `true` if the iterate datum is empty; `false` otherwise
35
+ * @return `true` if the iterate datum is non-empty (none of its values is `NaN`); `false` otherwise
36
36
  */
37
37
  export const nonEmptyIterateDatum = (datum: IterateDatum): boolean =>
38
38
  !isNaN(datum.time) && !isNaN(datum.iterateN) && !isNaN(datum.iterateN_1)
@@ -43,10 +43,10 @@ export const nonEmptyIterateDatum = (datum: IterateDatum): boolean =>
43
43
  export type IterateSeries = BaseSeries<IterateDatum>
44
44
 
45
45
  /**
46
- * Creates a series from the name and the optional array of (x, y) pairs (tuples)
46
+ * Creates a series from the name and the optional array of `(time, f[n](x), f[n+1](x))` tuples
47
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`
48
+ * @param data The optional array of `(time, f[n](x), f[n+1](x))` tuples
49
+ * @return An {@link IterateSeries} that can be used by the `PoincarePlot`
50
50
  * @see seriesFrom
51
51
  * @see emptySeries
52
52
  */