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,90 @@
1
+ import type {OutlierChartData} from "../observables/outliers";
2
+ import type {OutlierDatum, OutlierSeries} from "../series/outlierSeries";
3
+ import {emptySeries} from "../series/baseSeries";
4
+ import {BaseStreamingDataSource, type DataGenerator} from "./StreamingDataSource";
5
+
6
+ export interface OutlierDataSourceOptions<M extends readonly number[]> {
7
+ /**
8
+ * The initial series, owned (and mutated in place) by the source from here on
9
+ */
10
+ initialData: Array<OutlierSeries<M>>
11
+ /**
12
+ * Creates the observable of chart data each time the source starts
13
+ */
14
+ generator: DataGenerator<OutlierChartData<M>, OutlierSeries<M>>
15
+ /**
16
+ * Data older than this (ms), relative to the newest datum in the same chunk of new data, is
17
+ * dropped as new data arrives. Defaults to `Infinity` (never drop).
18
+ */
19
+ dropDataAfter?: number
20
+ /**
21
+ * Called with each series' new data as it arrives
22
+ */
23
+ onUpdateData?: (seriesName: string, data: Array<OutlierDatum<M>>) => void
24
+ }
25
+
26
+ /**
27
+ * A data source for outlier charts. Unlike time-series charts, series that aren't in the initial
28
+ * data are added as they first appear in the stream.
29
+ */
30
+ export class OutlierDataSource<M extends readonly number[]>
31
+ extends BaseStreamingDataSource<OutlierChartData<M>, OutlierDatum<M>, OutlierSeries<M>> {
32
+
33
+ private dropDataAfter: number
34
+ private readonly onUpdateData: ((seriesName: string, data: Array<OutlierDatum<M>>) => void) | undefined
35
+
36
+ /**
37
+ * Creates a outlier data source (stopped: call {@link start} to start it)
38
+ * @param options The initial data, the generator, and the data-retention settings
39
+ */
40
+ constructor(options: OutlierDataSourceOptions<M>) {
41
+ super(options.initialData, options.generator)
42
+ this.dropDataAfter = options.dropDataAfter ?? Infinity
43
+ this.onUpdateData = options.onUpdateData
44
+ }
45
+
46
+ /**
47
+ * Changes how long data is kept; takes effect as the next data arrives
48
+ * @param dropDataAfter Data older than this (ms) is dropped
49
+ */
50
+ setDropDataAfter(dropDataAfter: number): void {
51
+ this.dropDataAfter = dropDataAfter
52
+ }
53
+
54
+ /**
55
+ * @return The latest time (the `datum.x` of the last datum) over all the series, or
56
+ * `-Infinity` when there is no data
57
+ */
58
+ latestTime(): number {
59
+ return this.seriesList().reduce(
60
+ (tMax, series) => Math.max(tMax, series.last().map(datum => datum.datum.x).getOrElse(tMax)),
61
+ -Infinity
62
+ )
63
+ }
64
+
65
+ /**
66
+ * Adds each series' new points to it (adding the series itself the first time it appears),
67
+ * and drops the points that are older than `dropDataAfter` relative to the newest of the
68
+ * series' new points. Calls `onUpdateData` with each series' new points.
69
+ * @param data The chunk of chart data emitted by the generator
70
+ */
71
+ protected ingest(data: OutlierChartData<M>): void {
72
+ data.newPoints.forEach((newData, name) => {
73
+ // register a series the first time it shows up in the stream
74
+ const series = this.seriesMap.get(name) || emptySeries<OutlierDatum<M>>(name) as OutlierSeries<M>
75
+ if (!this.seriesMap.has(name)) this.seriesMap.set(name, series)
76
+
77
+ if (this.onUpdateData) this.onUpdateData(name, newData)
78
+
79
+ series.data.push(...newData)
80
+
81
+ // drop data older than the max time-window, relative to this chunk's newest datum
82
+ const currentTime = Math.max(...newData.map(datum => datum.datum.x), -Infinity)
83
+ if (Number.isFinite(currentTime)) {
84
+ while (series.data.length > 0 && currentTime - series.data[0].datum.x > this.dropDataAfter) {
85
+ series.data.shift()
86
+ }
87
+ }
88
+ })
89
+ }
90
+ }
@@ -0,0 +1,133 @@
1
+ import type {Datum, TimeSeries} from "../series/timeSeries";
2
+ import type {TimeSeriesChartData} from "../series/timeSeriesChartData";
3
+ import {emptySeries} from "../series/baseSeries";
4
+ import {BaseStreamingDataSource, type DataGenerator} from "./StreamingDataSource";
5
+
6
+ /**
7
+ * Maps a series name to the "time group" whose clock governs it. Series in the same group share
8
+ * one current time (the max time over all of them), which is what `dropDataAfter` is measured
9
+ * against. Plots group series by their x-axis, so this is typically
10
+ * `name => axisAssignments.get(name)?.xAxis ?? defaultXAxisId`.
11
+ */
12
+ export type TimeGroupFor = (seriesName: string) => string
13
+
14
+ /**
15
+ * The default time grouping: one group, holding all the series
16
+ */
17
+ const SINGLE_TIME_GROUP: TimeGroupFor = () => ""
18
+
19
+ /**
20
+ * Calculates the current time for each time group present in the chart data: the max over the
21
+ * group's series of each series' own max time (falling back to the chart-wide max time). Shared
22
+ * by the data source (for dropping old data) and the plots' view drivers (for advancing each
23
+ * x-axis), so both agree on what "now" is for each axis.
24
+ * @param data The chart data
25
+ * @param timeGroupFor Maps each series to its time group
26
+ * @return A map(group -> current_time)
27
+ */
28
+ export function currentTimesByGroup(data: TimeSeriesChartData, timeGroupFor: TimeGroupFor): Map<string, number> {
29
+ const times = new Map<string, number>()
30
+ data.seriesNames.forEach(name => {
31
+ const group = timeGroupFor(name)
32
+ const seriesTime = data.maxTimes.get(name) || data.maxTime
33
+ times.set(group, Math.max(times.get(group) ?? -Infinity, seriesTime))
34
+ })
35
+ return times
36
+ }
37
+
38
+ export interface TimeSeriesDataSourceOptions {
39
+ /**
40
+ * The initial series, owned (and mutated in place) by the source from here on
41
+ */
42
+ initialData: Array<TimeSeries>
43
+ /**
44
+ * Creates the observable of chart data each time the source starts
45
+ */
46
+ generator: DataGenerator<TimeSeriesChartData, TimeSeries>
47
+ /**
48
+ * Data older than this (ms), relative to its time group's current time, is dropped as new
49
+ * data arrives. Defaults to `Infinity` (never drop).
50
+ */
51
+ dropDataAfter?: number
52
+ /**
53
+ * Assigns each series to a time group (see {@link TimeGroupFor}). Defaults to one group for
54
+ * all series.
55
+ */
56
+ timeGroupFor?: TimeGroupFor
57
+ /**
58
+ * Called with each series' new data as it arrives
59
+ */
60
+ onUpdateData?: (seriesName: string, data: Array<Datum>) => void
61
+ }
62
+
63
+ /**
64
+ * A data source for time-series charts (e.g. the scatter and raster plots)
65
+ */
66
+ export class TimeSeriesDataSource extends BaseStreamingDataSource<TimeSeriesChartData, Datum, TimeSeries> {
67
+ private dropDataAfter: number
68
+ private readonly timeGroupFor: TimeGroupFor
69
+ private readonly onUpdateData: ((seriesName: string, data: Array<Datum>) => void) | undefined
70
+
71
+ /**
72
+ * Creates a time-series data source (stopped: call {@link start} to start it)
73
+ * @param options The initial data, the generator, and the data-retention settings
74
+ */
75
+ constructor(options: TimeSeriesDataSourceOptions) {
76
+ super(options.initialData, options.generator)
77
+ this.dropDataAfter = options.dropDataAfter ?? Infinity
78
+ this.timeGroupFor = options.timeGroupFor ?? SINGLE_TIME_GROUP
79
+ this.onUpdateData = options.onUpdateData
80
+ }
81
+
82
+ /**
83
+ * Changes how long data is kept; takes effect as the next data arrives
84
+ * @param dropDataAfter Data older than this (ms) is dropped
85
+ */
86
+ setDropDataAfter(dropDataAfter: number): void {
87
+ this.dropDataAfter = dropDataAfter
88
+ }
89
+
90
+ /**
91
+ * @return The latest time (the `x` of the last datum) over all the series, or
92
+ * `-Infinity` when there is no data
93
+ */
94
+ latestTime(): number {
95
+ return this.seriesList().reduce(
96
+ (tMax, series) => Math.max(tMax, series.last().map(datum => datum.x).getOrElse(tMax)),
97
+ -Infinity
98
+ )
99
+ }
100
+
101
+ /**
102
+ * Adds each series' new points to it, and drops the points that are older than
103
+ * `dropDataAfter` relative to the current time of the series' time group (see
104
+ * `currentTimesByGroup`). New points for a series that isn't in the source are ignored
105
+ * (time-series charts have a fixed set of series). Calls `onUpdateData` with each series' new
106
+ * points.
107
+ * @param data The chunk of chart data emitted by the generator
108
+ */
109
+ protected ingest(data: TimeSeriesChartData): void {
110
+ const groupTimes = currentTimesByGroup(data, this.timeGroupFor)
111
+
112
+ // add each new point to its corresponding series, the new points is a
113
+ // map(series_name -> new_point[])
114
+ data.newPoints.forEach((newData, name) => {
115
+ // note: as in the original subscription code, data for a series that isn't already in
116
+ // the source is accepted but not kept (time-series charts have a fixed set of series)
117
+ const series = this.seriesMap.get(name) || emptySeries<Datum>(name)
118
+
119
+ if (this.onUpdateData) this.onUpdateData(name, newData)
120
+
121
+ series.data.push(...newData)
122
+
123
+ // drop data that is older than the max time-window -- guarded on series.data.length so
124
+ // a sibling series in the same time group advancing the group's time past every point
125
+ // this series holds (e.g. this series stalls/updates slower) can't shift it down to
126
+ // empty and then throw on series.data[0].x
127
+ const currentTime = groupTimes.get(this.timeGroupFor(name)) || data.maxTime
128
+ while (series.data.length > 0 && currentTime - series.data[0].x > this.dropDataAfter) {
129
+ series.data.shift()
130
+ }
131
+ })
132
+ }
133
+ }
@@ -1,17 +1,57 @@
1
- import {failureResult, Result, successResult} from "result-fn";
1
+ import {failureResult, type Result, successResult} from "result-fn";
2
+ import safeRegex from "safe-regex";
2
3
 
3
4
  /**
4
- * Wraps the creation of the regex in a try/catch and returns the regex, wrapped in an option,
5
+ * Checks whether a regex is reasonably safe from catastrophic (exponential-time) backtracking --
6
+ * e.g. `/(a+)+$/`, the classic case that freezes on a long non-matching input. Every plot
7
+ * component tests a compiled `seriesFilter` regex against every series name on every redraw
8
+ * frame (not just once), so an unvetted pattern from a free-text filter field can hang the whole
9
+ * render loop, not just one call. Delegates to the `safe-regex` package, which walks the regex's
10
+ * actual parsed structure (via `regexp-tree`) rather than pattern-matching its source string, so
11
+ * it catches more than a hand-rolled "look for nested quantifiers" check would.
12
+ * @param pattern The regex (or its string source) to check
13
+ * @return `true` if the pattern is reasonably safe to run against arbitrary input; `false` if it
14
+ * risks catastrophic backtracking
15
+ */
16
+ export function isSafeRegex(pattern: RegExp | string): boolean {
17
+ return safeRegex(pattern)
18
+ }
19
+
20
+ /**
21
+ * Wraps the creation of the regex in a try/catch and returns the regex, wrapped in a `Result`,
5
22
  * when it is valid. This can be used, for example, in a text field where the user types a regex.
23
+ * Also rejects a pattern that compiles fine but risks catastrophic backtracking (see
24
+ * {@link isSafeRegex}) -- a syntax error and an exponential-time pattern are both "can't use this"
25
+ * outcomes from the caller's point of view, so both are reported the same way.
6
26
  * @param regexString The string representation of the regex
7
- * @return The regular expression (`RegExp`) wrapped in an option. If the regexp
8
- * is invalid, then the option is none.
27
+ * @return The regular expression (`RegExp`) wrapped in a successful `Result`. If the regex is
28
+ * invalid, or is unsafe, then a failed `Result` holding a message that says why.
9
29
  */
10
30
  export function regexFilter(regexString: string): Result<RegExp, string> {
11
31
  try {
12
32
  const regex = new RegExp(regexString)
33
+ if (!isSafeRegex(regex)) {
34
+ return failureResult(
35
+ `Refusing to use a regex that risks catastrophic backtracking; regex_expression: ${regexString}`
36
+ )
37
+ }
13
38
  return successResult(regex)
14
39
  } catch(error) {
15
- return failureResult(`Unable to compile the regex expression; regex_expression: ${regexString}`)
40
+ return failureResult(
41
+ `Unable to compile the regex expression; regex_expression: ${regexString}; error: ${error}`
42
+ )
16
43
  }
17
44
  }
45
+
46
+ /**
47
+ * Builds a regex that matches `text` literally, for callers (e.g. a series-name filter input)
48
+ * who want to search for plain text without regex metacharacters (`.`, `*`, `+`, `(`, etc.) in it
49
+ * being given unintended regex semantics. Escapes those metacharacters before handing the result
50
+ * to {@link regexFilter}, so it shares the same `Result`-wrapped, never-throws contract.
51
+ * @param text The literal text to match
52
+ * @return The regular expression (`RegExp`) matching `text` literally, wrapped in a `Result` (see
53
+ * {@link regexFilter})
54
+ */
55
+ export function literalFilter(text: string): Result<RegExp, string> {
56
+ return regexFilter(text.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'))
57
+ }
@@ -0,0 +1,301 @@
1
+ import {AxisInterval} from "../axes/AxisInterval";
2
+ import {type JSX, useCallback, useMemo, useRef, useState} from "react";
3
+ import {BaseAxisRange} from "../axes/BaseAxisRange";
4
+ import type {BaseAxis} from "../axes/axes";
5
+ import {usePlotDimensions} from "./usePlotDimensions";
6
+ import {AxesState} from "../axes/AxesState";
7
+ import type {AxesAssignment} from "../plots/plot";
8
+ import type {Dimensions} from "../styling/margins";
9
+ import {Optional} from "result-fn";
10
+ import {AxesContext, type UseAxesValues} from "./useAxes";
11
+
12
+ export type Props = {
13
+ /**
14
+ * Callback when axes bounds change.
15
+ * @param ranges The ranges (start, end) for each axis in the plot
16
+ */
17
+ onUpdateAxesInterval?: (ranges: Map<string, AxisInterval>) => void
18
+
19
+ children: JSX.Element | Array<JSX.Element>
20
+ }
21
+ /**
22
+ * The React context provider for the {@link UseAxesValues}
23
+ * @param props The properties
24
+ * @return The children wrapped in this provider
25
+ * @template AR The type of the axis range (e.g. {@link ContinuousAxisRange} or {@link OrdinalAxisRange})
26
+ * @template A The axis type
27
+ */
28
+ export default function AxesProvider<AR extends BaseAxisRange, A extends BaseAxis>(props: Props): JSX.Element {
29
+ const {onUpdateAxesInterval, children} = props
30
+
31
+ const plotDimensions = usePlotDimensions()
32
+
33
+ const [xAxesState, setXAxesState] = useState<AxesState<A>>(AxesState.empty<A>())
34
+ const [yAxesState, setYAxesState] = useState<AxesState<A>>(AxesState.empty<A>())
35
+ const axisAssignmentsRef = useRef<Map<string, AxesAssignment>>(new Map())
36
+ const axesBoundsUpdateHandlersRef = useRef<Map<string, (updates: Map<string, AR>, plotDim: Dimensions) => void>>(new Map())
37
+ const axesRangeRef = useRef<Map<string, AR>>(new Map())
38
+
39
+ /**
40
+ * Retrieves the x-axis and y-axis assignments for the specified series. If the series does not
41
+ * have an assignment, then we assume it is using the default x- and y-axes.
42
+ * @param seriesName The name of the series for which to retrieve the axes assignments
43
+ * @return An {@link AxesAssignment} for the specified axes.
44
+ */
45
+ const axisAssignmentsFor = useCallback(
46
+ (seriesName: string): AxesAssignment =>
47
+ axisAssignmentsRef.current.get(seriesName) || {
48
+ xAxis: xAxesState.axisDefaultId().getOrElse(""),
49
+ yAxis: yAxesState.axisDefaultId().getOrElse("")
50
+ },
51
+ [xAxesState, yAxesState]
52
+ )
53
+
54
+ /**
55
+ * Called when the domain/range is updated on one or more of the chart's axes (generally x-axes). Stores
56
+ * the updated ranges, and in turn, dispatches the update to all the registered domain/range update
57
+ * handlers (e.g. the axes, which redraw themselves with their new domain).
58
+ * @param updates A map holding the axis ID to the updated axis time-range (i.e., map(axis_id, axis_time_range))
59
+ */
60
+ const updateAxisRanges = useCallback(
61
+ (updates: Map<string, AR>): void => {
62
+ // update the current time-ranges reference
63
+ updates.forEach((range, id) => {
64
+ axesRangeRef.current.set(id, range)
65
+ })
66
+ // dispatch the updates to all the registered handlers
67
+ axesBoundsUpdateHandlersRef.current
68
+ .forEach((handler,) => handler(updates, plotDimensions.plotDimensions))
69
+ },
70
+ [plotDimensions.plotDimensions]
71
+ )
72
+
73
+ /**
74
+ * Sets the axis ranges specified in the input map (without dispatching them to the update handlers)
75
+ * @param ranges The ranges to set
76
+ */
77
+ const setAxesRanges = useCallback(
78
+ (ranges: Map<string, AR>): void => {
79
+ ranges.forEach((range, id) => {
80
+ axesRangeRef.current.set(id, range)
81
+ })
82
+ },
83
+ []
84
+ )
85
+
86
+ /**
87
+ * Sets the axis range for the specified axis ID (without dispatching it to the update handlers)
88
+ * @param axisId The axis ID
89
+ * @param range The range to set
90
+ */
91
+ const setAxisRangeFor = useCallback(
92
+ (axisId: string, range: AR): void => {
93
+ axesRangeRef.current.set(axisId, range)
94
+ },
95
+ []
96
+ )
97
+
98
+ /**
99
+ * Sets the axis bounds (the current range) for the specified axis ID. Note that this does not
100
+ * change the original axis interval, doesn't dispatch the change to the update handlers, and
101
+ * does nothing when the axis has no range yet.
102
+ * @param axisId The axis ID
103
+ * @param interval The interval
104
+ */
105
+ const setAxisIntervalFor = useCallback(
106
+ (axisId: string, interval: AxisInterval): void => {
107
+ Optional.ofNullable(axesRangeRef.current.get(axisId))
108
+ .map(range => range.update(interval.start, interval.end) as AR)
109
+ .ifPresent(updatedRange => axesRangeRef.current.set(axisId, updatedRange))
110
+ },
111
+ []
112
+ )
113
+
114
+ /**
115
+ * Sets the original axis interval for the axis range (does nothing when the axis has no range yet)
116
+ * @param axisId The axis ID
117
+ * @param interval The interval to which to set the origin interval
118
+ */
119
+ const setOriginalAxisIntervalFor = useCallback(
120
+ (axisId: string, interval: AxisInterval): void => {
121
+ Optional.ofNullable(axesRangeRef.current.get(axisId))
122
+ .map(range => range.updateOriginal(interval.start, interval.end) as AR)
123
+ .ifPresent(updatedRange => axesRangeRef.current.set(axisId, updatedRange))
124
+ },
125
+ []
126
+ )
127
+
128
+ /**
129
+ * Re-applies the specified axis' stored range: dispatches it, unchanged, to the update handlers
130
+ * (so that the axis redraws with it). Note that this does *not* restore the axis' original
131
+ * range. Does nothing when the axis has no range.
132
+ * @param axisId The ID of the axis
133
+ */
134
+ const resetAxisIntervalFor = useCallback(
135
+ (axisId: string): void => {
136
+ Optional
137
+ .ofNullable(axesRangeRef.current.get(axisId))
138
+ .map(range => new Map<string, AR>([[axisId, range]]))
139
+ .ifPresent(updates => updateAxisRanges(updates))
140
+ },
141
+ [updateAxisRanges]
142
+ )
143
+
144
+ /**
145
+ * Sets the ranges of the axes in the specified map, and dispatches them to the update handlers
146
+ * (the same as {@link updateAxisRanges}). Axes that aren't in the map are left as they are, so
147
+ * the default (empty) map changes nothing.
148
+ * @param [axesRanges=new Map()] An optional map holds bounds for specified axes. The map
149
+ * associates an axis ID with the new bounds.
150
+ */
151
+ const resetAxesRanges = useCallback(
152
+ (axesRanges: Map<string, AR> = new Map()): void => {
153
+ updateAxisRanges(axesRanges)
154
+ },
155
+ [updateAxisRanges]
156
+ )
157
+
158
+ /**
159
+ * Adds a handler to deal with updates to the bounds of the axes
160
+ * @param handlerId the unique ID of the handler
161
+ * @param handler The handler function that accepts a map of updates and a plot dimension
162
+ * @return A map with all the handlers
163
+ * @throws Error when a handler with the same ID is already registered
164
+ */
165
+ const addAxesRangesUpdateHandler = useCallback(
166
+ (
167
+ handlerId: string,
168
+ handler: (updates: Map<string, AR>, plotDim: Dimensions) => void
169
+ ): Map<string, (updates: Map<string, AR>, plotDim: Dimensions) => void> => {
170
+ if (axesBoundsUpdateHandlersRef.current.has(handlerId)) {
171
+ throw new Error(
172
+ `Handler with ID already exists, please remove it before adding it; ` +
173
+ `handler_id: ${handlerId}; ` +
174
+ `existing_handler_ids: [${Array.from(axesBoundsUpdateHandlersRef.current.keys()).join(", ")}]`
175
+ )
176
+ }
177
+ return axesBoundsUpdateHandlersRef.current.set(handlerId, handler)
178
+ },
179
+ []
180
+ )
181
+
182
+ /**
183
+ * Removes the axis-update handler with the specified ID
184
+ * @param handlerId The ID of the handler to remove
185
+ * @return `true` when the handler was registered (and has been removed); `false` otherwise
186
+ */
187
+ const removeAxesRangesUpdateHandler = useCallback(
188
+ (handlerId: string): boolean => axesBoundsUpdateHandlersRef.current.delete(handlerId),
189
+ []
190
+ )
191
+
192
+ /**
193
+ * Adds an x-axis to the x-axes state (a new state object, so dependents re-render)
194
+ * @param axis The axis to add
195
+ * @param id The ID of the axis to add
196
+ * @param [range] The initial axis range (when given, it's stored as the axis' range)
197
+ */
198
+ const addXAxis = useCallback(
199
+ (axis: A, id: string, range?: AR): void => {
200
+ setXAxesState(xAxesState.addAxis(axis, id))
201
+ if (range !== undefined) {
202
+ axesRangeRef.current.set(id, range)
203
+ }
204
+ },
205
+ [xAxesState]
206
+ )
207
+
208
+ /**
209
+ * Adds a y-axis to the y-axes state (a new state object, so dependents re-render)
210
+ * @param axis The axis to add
211
+ * @param id The ID of the axis to add
212
+ * @param [range] The initial axis range (when given, it's stored as the axis' range)
213
+ */
214
+ const addYAxis = useCallback(
215
+ (axis: A, id: string, range?: AR): void => {
216
+ setYAxesState(yAxesState.addAxis(axis, id))
217
+ if (range !== undefined) {
218
+ axesRangeRef.current.set(id, range)
219
+ }
220
+ },
221
+ [yAxesState]
222
+ )
223
+
224
+ /**
225
+ * Sets the axes assigned to each series (replacing any earlier assignments)
226
+ * @param assignments The assignment of the series to their axes
227
+ */
228
+ const setAxisAssignments = useCallback(
229
+ (assignments: Map<string, AxesAssignment>): void => {
230
+ axisAssignmentsRef.current = assignments
231
+ },
232
+ []
233
+ )
234
+
235
+ /**
236
+ * @return A copy of the map of the axes' current ranges, by axis ID
237
+ */
238
+ const axesRanges = useCallback(
239
+ (): Map<string, AR> => new Map<string, AR>(axesRangeRef.current),
240
+ []
241
+ )
242
+
243
+ /**
244
+ * Retrieves the current axis range for the specified axis ID
245
+ * @param axisId The ID of the axis
246
+ * @return The axis' range, or an empty `Optional` when the axis has no range
247
+ */
248
+ const axisRangeFor = useCallback(
249
+ (axisId: string) => Optional.ofNullable(axesRangeRef.current.get(axisId)),
250
+ []
251
+ )
252
+
253
+ // the context's `value` prop is typed as `unknown` (see `AxesContext` in `useAxes.tsx`), so
254
+ // the object literal needs its own explicit type here to give the handler functions below
255
+ // their parameter types -- otherwise they'd fall back to implicit `any`.
256
+ //
257
+ // Memoized so consumers relying on this context value's identity (e.g. a `useMemo`/effect
258
+ // keyed on it) don't re-run on essentially every render of anything above this provider --
259
+ // previously a fresh object literal every render, with every method inside it also a fresh
260
+ // closure. This is the same class of bug already documented/worked around in ScatterPlot.tsx/
261
+ // RasterPlot.tsx/OutlierPlot.tsx (their own comments on `axesRanges` never being memoized
262
+ // here) -- those workarounds (refs populated imperatively instead of `useMemo([axesRanges])`)
263
+ // are left in place; they're redundant once this is memoized, but harmless, and removing them
264
+ // isn't part of this change.
265
+ const value: UseAxesValues<AR, A> = useMemo(
266
+ () => ({
267
+ xAxesState,
268
+ yAxesState,
269
+ addXAxis,
270
+ addYAxis,
271
+ setAxisAssignments,
272
+ axisAssignmentsFor,
273
+ updateAxisRanges,
274
+ axesRanges,
275
+ axisRangeFor,
276
+ setAxesRanges,
277
+ setAxisRangeFor,
278
+ setAxisIntervalFor,
279
+ setOriginalAxisIntervalFor,
280
+ resetAxesRanges,
281
+ resetAxisIntervalFor,
282
+ onUpdateAxesInterval,
283
+ addAxesRangesUpdateHandler,
284
+ removeAxesRangesUpdateHandler,
285
+ }),
286
+ [
287
+ xAxesState, yAxesState,
288
+ addXAxis, addYAxis,
289
+ setAxisAssignments, axisAssignmentsFor,
290
+ updateAxisRanges, axesRanges, axisRangeFor,
291
+ setAxesRanges, setAxisRangeFor, setAxisIntervalFor, setOriginalAxisIntervalFor,
292
+ resetAxesRanges, resetAxisIntervalFor,
293
+ onUpdateAxesInterval,
294
+ addAxesRangesUpdateHandler, removeAxesRangesUpdateHandler,
295
+ ]
296
+ )
297
+
298
+ return <AxesContext.Provider value={value}>
299
+ {children}
300
+ </AxesContext.Provider>
301
+ }