stream-charts 1.2.1 → 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 +36 -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
@@ -1,8 +1,9 @@
1
- import {Series} from "../plots/plot";
2
- import * as d3 from "d3";
3
- import {Datum} from "../series/timeSeries";
4
- import {Dimensions, Margin} from "../styling/margins";
5
- import {OrdinalStringAxis} from "../axes/axes";
1
+ import type {Series} from "../plots/plot";
2
+ import type {Dimensions, Margin} from "../styling/margins";
3
+ import type {OrdinalStringAxis} from "../axes/axes";
4
+ import type {ScaleContinuousNumeric} from "d3";
5
+ import type {Datum} from "../series/timeSeries";
6
+ import {firstIndexAtOrAfter} from "../utils";
6
7
 
7
8
  /**
8
9
  * Properties for rendering the tooltip. This is the style for the container
@@ -48,6 +49,9 @@ export interface TooltipStyle {
48
49
  paddingBottom: number;
49
50
  }
50
51
 
52
+ /**
53
+ * The default tooltip style
54
+ */
51
55
  export const defaultTooltipStyle: TooltipStyle = {
52
56
  visible: false,
53
57
 
@@ -72,91 +76,76 @@ export const defaultTooltipStyle: TooltipStyle = {
72
76
  paddingBottom: 10,
73
77
  };
74
78
 
75
- export interface TooltipDimensions {
76
- x: number,
77
- y: number,
78
- contentWidth: number,
79
- contentHeight: number
80
- }
81
-
82
79
  /**
83
- * Removes the tooltip when the mouse has moved away from the spike
84
- */
85
- export function removeTooltip() {
86
- d3.selectAll<SVGPathElement, Datum>('.tooltip').remove()
87
- }
88
-
89
- /**
90
- * Calculates the x-coordinate of the upper left-hand side of the tooltip rectangle (obviously without
91
- * "rounded corners"). Adjusts the x-coordinate so that tooltip is visible on the edges of the plot.
92
- * @param x The current x-coordinate of the mouse
93
- * @param textWidth The width of the tooltip text
80
+ * Calculates the x-coordinate of the left side of the tooltip. The tooltip goes to the right of the
81
+ * mouse, unless it would run past the right edge of the plot, in which case it goes to the left of
82
+ * the mouse (and never past the left edge of the chart).
83
+ * @param x The x-coordinate of the mouse, relative to the chart
84
+ * @param width The tooltip's (rendered) width, including its padding and border
94
85
  * @param plotDimensions The dimensions of the plot
95
- * @param tooltipStyle The tooltip style information
86
+ * @param tooltipStyle The tooltip style information (its left padding is used as the gap between
87
+ * the mouse and the tooltip)
96
88
  * @param margin The plot margin
97
- * @return The x-coordinate of the lower left-hand side of the tooltip rectangle
89
+ * @return The x-coordinate of the tooltip's left side, relative to the chart
98
90
  */
99
- export function tooltipX(x: number, textWidth: number, plotDimensions: Dimensions, tooltipStyle: TooltipStyle, margin: Margin): number {
100
- if (x > plotDimensions.width + margin.left - (textWidth + tooltipStyle.paddingLeft + tooltipStyle.paddingRight)) {
101
- return x - textWidth - margin.right + tooltipStyle.paddingRight + tooltipStyle.paddingLeft
91
+ export function tooltipX(x: number, width: number, plotDimensions: Dimensions, tooltipStyle: TooltipStyle, margin: Margin): number {
92
+ const gap = tooltipStyle.paddingLeft
93
+ if (x + gap + width <= margin.left + plotDimensions.width) {
94
+ return x + gap
102
95
  }
103
- return x + tooltipStyle.paddingLeft
96
+ return Math.max(0, x - gap - width)
104
97
  }
105
98
 
106
99
  /**
107
- * Calculates the y-coordinate of the upper-left-hand corner of the tooltip rectangle. Adjusts the y-coordinate
108
- * so that the tooltip is visible on the upper edge of the plot
109
- * @param y The y-coordinate of the mouse
110
- * @param textHeight The height of the header and neuron ID text
100
+ * Calculates the y-coordinate of the top of the tooltip. The tooltip goes below the mouse, unless it
101
+ * would run past the bottom of the plot, in which case it's moved up so that its bottom lines up
102
+ * with the plot's bottom (and never past the top edge of the chart).
103
+ * @param y The y-coordinate of the mouse, relative to the chart
104
+ * @param height The tooltip's (rendered) height, including its padding and border
111
105
  * @param plotDimensions The dimensions of the plot
112
- * @param tooltipStyle The tooltip style information
106
+ * @param tooltipStyle The tooltip style information (its top padding is used as the gap between
107
+ * the mouse and the tooltip)
113
108
  * @param margin The plot margin
114
- * @return The y-coordinate of the lower-left-hand corner of the tooltip rectangle
109
+ * @return The y-coordinate of the tooltip's top, relative to the chart
115
110
  */
116
- export function tooltipY(y: number, textHeight: number, plotDimensions: Dimensions, tooltipStyle: TooltipStyle, margin: Margin): number {
117
- if (y > plotDimensions.height + margin.top - (textHeight + tooltipStyle.paddingTop + tooltipStyle.paddingBottom)) {
118
- return plotDimensions.height + margin.top - (textHeight + tooltipStyle.paddingTop + tooltipStyle.paddingBottom)
111
+ export function tooltipY(y: number, height: number, plotDimensions: Dimensions, tooltipStyle: TooltipStyle, margin: Margin): number {
112
+ const gap = tooltipStyle.paddingTop
113
+ if (y + gap + height <= margin.top + plotDimensions.height) {
114
+ return y + gap
119
115
  }
120
- return y + tooltipStyle.paddingTop
116
+ return Math.max(0, margin.top + plotDimensions.height - height)
121
117
  }
122
118
 
123
119
  /**
124
- * Calculates the y-coordinate for the upper-left-hand the tooltip rectangle. Adjusts the y-coordinate so
125
- * that the tooltip is visible on the upper and lower edges of the plot
126
- * @param seriesName The name of the series
127
- * @param textHeight The height of the header and neuron ID text
120
+ * Calculates the y-coordinate of the top of a tooltip for a category (e.g. a raster plot's row):
121
+ * the tooltip is centered on the category, but kept within the plot's top and bottom edges.
122
+ * @param seriesName The name of the series (the category)
123
+ * @param height The tooltip's (rendered) height, including its padding and border
128
124
  * @param axis The category axis for determining the y-value of the tooltip
129
- * @param tooltipStyle The tooltip style
130
125
  * @param margin The plot margin
131
126
  * @param categoryHeight The height (in pixels) of the category
132
127
  * @param plotDimensions The dimensions of the plot
133
- * @return The y-coordinate of the lower-left-hand corner of the tooltip rectangle
128
+ * @return The y-coordinate of the tooltip's top, relative to the chart
134
129
  */
135
130
  export function categoryTooltipY(
136
131
  seriesName: string,
137
- textHeight: number,
132
+ height: number,
138
133
  axis: OrdinalStringAxis,
139
- tooltipStyle: TooltipStyle,
140
134
  margin: Margin,
141
135
  categoryHeight: number,
142
136
  plotDimensions: Dimensions
143
137
  ): number {
144
- const y = axis.scale(seriesName) || 0
145
- const halfHeight = (tooltipStyle.paddingBottom + textHeight + tooltipStyle.paddingTop) / 2
146
- if (y < halfHeight) {
147
- return margin.top
148
- }
149
- if (y > plotDimensions.height + margin.top - halfHeight) {
150
- return plotDimensions.height + margin.top - textHeight
151
- }
152
- return y + margin.top - halfHeight + categoryHeight / 2
138
+ const categoryCenter = margin.top + (axis.scale(seriesName) || 0) + categoryHeight / 2
139
+ const top = categoryCenter - height / 2
140
+ const lowest = margin.top + plotDimensions.height - height
141
+ return Math.max(margin.top, Math.min(top, lowest))
153
142
  }
154
143
 
155
144
  /**
156
145
  * Returns the index of the data point whose time is the upper boundary on the specified
157
- * time. If the specified time is larger than any time in the specified data, the returns
146
+ * time. If the specified time is larger than any time in the specified data, then returns
158
147
  * the length of the data array. If the specified time is smaller than all the values in
159
- * the specified array, then returns -1.
148
+ * the specified array, then returns 0. The data must not be empty.
160
149
  * @param data The array of points from which to select the
161
150
  * boundary.
162
151
  * @param value The time for which to find the bounding points
@@ -185,11 +174,17 @@ function boundingPointsIndex<D>(data: Series<D>, value: number, xFrom: (value: D
185
174
  * @param xFrom A function that extracts the x-value from the datum
186
175
  * @param emptyDatum A function that returns an empty datum
187
176
  * @template D The type of the datum in the data-series
188
- * @return {[[number, number], [number, number]]} the (time, value) point that comes just before
189
- * the mouse and just after the mouse. If the mouse is after the last point, then the "after" point
190
- * is `[NaN, NaN]`. If the mouse is before the first point, then the "before" point is `[NaN, NaN]`.
177
+ * @return The point that comes just before the mouse and just after the mouse. If the mouse is
178
+ * after the last point, then the "after" point is the empty datum. If the mouse is before the
179
+ * first point, then the "before" point is the empty datum. (Both are, for an empty series.)
191
180
  */
192
181
  export function boundingPoints<D>(data: Series<D>, value: number, xFrom: (value: D) => number, emptyDatum: () => D): [D, D] {
182
+ // an empty series has no bounding points at all -- guard here (not just inside
183
+ // boundingPointsIndex) since this function's own upperIndex<=0/>=data.length fallbacks below
184
+ // also read data[0]/data[data.length-1], which are just as undefined on an empty array
185
+ if (data.length === 0) {
186
+ return [emptyDatum(), emptyDatum()]
187
+ }
193
188
  const upperIndex = boundingPointsIndex<D>(data, value, xFrom)
194
189
  if (upperIndex <= 0) {
195
190
  return [emptyDatum(), data[0]]
@@ -200,6 +195,19 @@ export function boundingPoints<D>(data: Series<D>, value: number, xFrom: (value:
200
195
  return [data[upperIndex - 1], data[upperIndex]]
201
196
  }
202
197
 
198
+ /**
199
+ * Finds the first point whose x-value is within the tolerance of the specified value, along with
200
+ * the points before and after it
201
+ * @param data The series' data
202
+ * @param value The x-value to look for
203
+ * @param tolerance How far (in the x-value's units) a point's x-value may be from the value
204
+ * @param xFrom A function that extracts the x-value from the datum
205
+ * @param emptyDatum A function that returns an empty datum (for a point that doesn't exist)
206
+ * @return The point before, the point, the point after, and the point's index (-1 when no point
207
+ * is within the tolerance, in which case the point and the point before are empty, and the point
208
+ * after is the series' first point)
209
+ * @template D The type of the datum in the data-series
210
+ */
203
211
  export function findPointAndNeighbors<D>(
204
212
  data: Series<D>,
205
213
  value: number,
@@ -214,3 +222,293 @@ export function findPointAndNeighbors<D>(
214
222
  const upper = (index < data.length - 1) ? data[index+1] : emptyDatum()
215
223
  return [lower, point, upper, index]
216
224
  }
225
+
226
+ /**
227
+ * The points of a scatter series that a tooltip shows (and the plot highlights), depending on
228
+ * where the mouse is over the series:
229
+ * - directly over a data point: that `point`, along with the points `before` and `after` it
230
+ * - over a line segment between two points: the points `before` and `after` the mouse
231
+ *
232
+ * `before` and `after` are undefined when there's no such point (e.g. before the first point).
233
+ */
234
+ export type ScatterTooltipPoints =
235
+ | { kind: 'point', before?: Datum, point: Datum, after?: Datum }
236
+ | { kind: 'segment', before?: Datum, after?: Datum }
237
+
238
+ /**
239
+ * The scatter plot's tooltip metadata: the points the tooltip shows
240
+ */
241
+ export interface ScatterTooltipMetadata {
242
+ points: ScatterTooltipPoints
243
+ }
244
+
245
+ /**
246
+ * Determines which of a scatter series' points a tooltip shows, from where the mouse is: when the
247
+ * mouse is over a data point, that point (and its neighbors); otherwise the points on either side
248
+ * of the mouse (the segment it's over).
249
+ *
250
+ * The mouse is over a point when it's within `pointRadius` pixels of it -- or, when the point's
251
+ * nearest neighbor is closer than three times that, within a third of the way to that neighbor.
252
+ * Otherwise, with dense data (points a few pixels apart), the mouse would almost always be within
253
+ * the radius of some point, and the segments between them could hardly be hovered at all.
254
+ * @param data The series' data, ordered by x
255
+ * @param mouse The mouse's coordinates, within the plot area (i.e. in the axes' ranges)
256
+ * @param xScale The series' x-axis scale
257
+ * @param yScale The series' y-axis scale
258
+ * @param pointRadius How close (in pixels) the mouse must be to a data point to be over it
259
+ * @return The points the tooltip shows
260
+ */
261
+ export function scatterTooltipPoints(
262
+ data: { length: number, [index: number]: Datum },
263
+ mouse: [x: number, y: number],
264
+ xScale: ScaleContinuousNumeric<number, number>,
265
+ yScale: ScaleContinuousNumeric<number, number>,
266
+ pointRadius: number
267
+ ): ScatterTooltipPoints {
268
+ const [mouseX, mouseY] = mouse
269
+ const pointAt = (index: number): Datum | undefined => index >= 0 && index < data.length ? data[index] : undefined
270
+ // the first point at, or after, the mouse's x-value
271
+ const index = firstIndexAtOrAfter(data, xScale.invert(mouseX), datum => datum.x)
272
+
273
+ // the on-screen distance between two points
274
+ const distanceBetween = (a: Datum, b: Datum): number => Math.hypot(xScale(a.x) - xScale(b.x), yScale(a.y) - yScale(b.y))
275
+ // how close the mouse must be to the point (see above)
276
+ const radiusFor = (candidate: number): number => {
277
+ const neighborDistances = [pointAt(candidate - 1), pointAt(candidate + 1)]
278
+ .filter((neighbor): neighbor is Datum => neighbor !== undefined)
279
+ .map(neighbor => distanceBetween(data[candidate], neighbor))
280
+ return Math.min(pointRadius, ...neighborDistances.map(distance => distance / 3))
281
+ }
282
+
283
+ // the nearest point (on screen) that the mouse is over, among those around the mouse's x-value
284
+ let nearest: number | undefined = undefined
285
+ let nearestDistance = Infinity
286
+ for (let candidate = index - 2; candidate <= index + 1; candidate++) {
287
+ const datum = pointAt(candidate)
288
+ if (datum === undefined) continue
289
+ const distance = Math.hypot(xScale(datum.x) - mouseX, yScale(datum.y) - mouseY)
290
+ if (distance <= radiusFor(candidate) && distance < nearestDistance) {
291
+ nearestDistance = distance
292
+ nearest = candidate
293
+ }
294
+ }
295
+
296
+ if (nearest !== undefined) {
297
+ return {kind: 'point', before: pointAt(nearest - 1), point: data[nearest], after: pointAt(nearest + 1)}
298
+ }
299
+ return {kind: 'segment', before: pointAt(index - 1), after: pointAt(index)}
300
+ }
301
+
302
+ /**
303
+ * The points a scatter tooltip shows, as a list (e.g. for highlighting them)
304
+ * @param points The points the tooltip shows
305
+ * @return The points, in order
306
+ */
307
+ export function scatterTooltipPointList(points: ScatterTooltipPoints): Array<Datum> {
308
+ const list = points.kind === 'point' ?
309
+ [points.before, points.point, points.after] :
310
+ [points.before, points.after]
311
+ return list.filter((datum): datum is Datum => datum !== undefined)
312
+ }
313
+
314
+ /**
315
+ * A sparkline: a small line chart of a series' values over time (e.g. for a tooltip), as an SVG
316
+ * path, and where its last point is
317
+ */
318
+ export interface Sparkline {
319
+ // the SVG path of the line, within the sparkline's width and height
320
+ path: string
321
+ // where the line ends (the latest value)
322
+ end: [x: number, y: number]
323
+ // where the marked point is (see `sparklineFor`'s `markedTime`), when one was asked for, and found
324
+ mark?: [x: number, y: number]
325
+ }
326
+
327
+ /**
328
+ * Creates a sparkline of the specified (time-ordered) values: time runs left to right across the
329
+ * width, and the values are scaled to fill the height (the highest at the top). Values that
330
+ * aren't finite are skipped.
331
+ *
332
+ * A long series is reduced to (at most) four points per pixel column -- the column's first,
333
+ * lowest, highest, and last values, in the order they occurred -- so that the path stays small,
334
+ * while still tracing the line's true shape, spikes included.
335
+ * @param data The values, ordered by time
336
+ * @param width The sparkline's width (in pixels)
337
+ * @param height The sparkline's height (in pixels)
338
+ * @param padding The space (in pixels) to leave around the line, within the width and height
339
+ * @param valueRange The (fixed) range of values the height spans (values outside it are drawn at
340
+ * its edge) -- by default, the range of the values themselves
341
+ * @param markedTime The time of a point to mark (e.g. the hovered point), whose position is
342
+ * returned as the sparkline's `mark` -- by default, none
343
+ * @return The sparkline, or `undefined` when there are fewer than two values to draw
344
+ */
345
+ export function sparklineFor(
346
+ data: { length: number, [index: number]: { time: number, value: number } },
347
+ width: number,
348
+ height: number,
349
+ padding: number = 2,
350
+ valueRange?: [min: number, max: number],
351
+ markedTime?: number
352
+ ): Sparkline | undefined {
353
+ const points: Array<{ time: number, value: number }> = []
354
+ for (let i = 0; i < data.length; i++) {
355
+ if (Number.isFinite(data[i].time) && Number.isFinite(data[i].value)) points.push(data[i])
356
+ }
357
+ if (points.length < 2) return undefined
358
+
359
+ const startTime = points[0].time
360
+ const timeSpan = points[points.length - 1].time - startTime
361
+ let minValue = Infinity
362
+ let maxValue = -Infinity
363
+ if (valueRange !== undefined) {
364
+ [minValue, maxValue] = valueRange
365
+ } else {
366
+ points.forEach(({value}) => {
367
+ minValue = Math.min(minValue, value)
368
+ maxValue = Math.max(maxValue, value)
369
+ })
370
+ }
371
+ const innerWidth = width - 2 * padding
372
+ const innerHeight = height - 2 * padding
373
+ const xOf = (time: number) => padding + (timeSpan > 0 ? (time - startTime) / timeSpan * innerWidth : innerWidth / 2)
374
+ // (a flat line sits in the middle)
375
+ const yOf = (value: number) => padding + (maxValue > minValue ?
376
+ (maxValue - Math.min(maxValue, Math.max(minValue, value))) / (maxValue - minValue) * innerHeight :
377
+ innerHeight / 2)
378
+
379
+ // each pixel column's first, lowest, highest, and last values, in the order they occurred
380
+ const reduced: Array<{ time: number, value: number }> = []
381
+ let column: Array<{ index: number, point: { time: number, value: number } }> = []
382
+ let columnX = Math.floor(xOf(points[0].time))
383
+ const flushColumn = () => {
384
+ if (column.length === 0) return
385
+ const lowest = column.reduce((low, entry) => entry.point.value < low.point.value ? entry : low)
386
+ const highest = column.reduce((high, entry) => entry.point.value > high.point.value ? entry : high)
387
+ const kept = new Map([column[0], lowest, highest, column[column.length - 1]].map(entry => [entry.index, entry.point]))
388
+ Array.from(kept.entries()).sort(([a], [b]) => a - b).forEach(([, point]) => reduced.push(point))
389
+ column = []
390
+ }
391
+ points.forEach((point, index) => {
392
+ const x = Math.floor(xOf(point.time))
393
+ if (x !== columnX) {
394
+ flushColumn()
395
+ columnX = x
396
+ }
397
+ column.push({index, point})
398
+ })
399
+ flushColumn()
400
+
401
+ const coordinates = reduced.map(({time, value}) => [xOf(time), yOf(value)] as [number, number])
402
+ const round = (value: number) => Math.round(value * 100) / 100
403
+ const marked = markedTime === undefined ? undefined : points.find(point => point.time === markedTime)
404
+ return {
405
+ path: coordinates.map(([x, y], index) => `${index === 0 ? 'M' : 'L'}${round(x)},${round(y)}`).join(' '),
406
+ end: coordinates[coordinates.length - 1],
407
+ ...(marked !== undefined ? {mark: [xOf(marked.time), yOf(marked.value)] as [number, number]} : {}),
408
+ }
409
+ }
410
+
411
+ /**
412
+ * The raster plot's tooltip metadata: all of the hovered series' spikes that the chart holds (the
413
+ * tooltip data's `series` holds just the hovered spike)
414
+ */
415
+ export interface RasterTooltipMetadata {
416
+ spikes: Series<Datum>
417
+ }
418
+
419
+ /**
420
+ * Statistics of a series' (time, value) points -- e.g. a raster chart's spikes, or a scatter
421
+ * chart's points -- over the window of data that the chart holds. Those that need at least two
422
+ * points are undefined when there's only one.
423
+ */
424
+ export interface SeriesStatistics {
425
+ // the number of points
426
+ count: number
427
+ // the mean of the points' values
428
+ meanValue: number | undefined
429
+ // the (sample) standard deviation of the points' values
430
+ valueStandardDeviation: number | undefined
431
+ // the mean time between consecutive points
432
+ meanInterval: number | undefined
433
+ }
434
+
435
+ /**
436
+ * Calculates the statistics of a series' (time, value) points: their count, the mean and the
437
+ * (sample) standard deviation of their values, and the mean time between consecutive points.
438
+ * Points whose value or time isn't finite are skipped.
439
+ * @param spikes The points (e.g. spikes), ordered by time
440
+ * @return The statistics
441
+ */
442
+ export function seriesStatistics(spikes: { length: number, [index: number]: Datum }): SeriesStatistics {
443
+ const valid: Array<Datum> = []
444
+ for (let i = 0; i < spikes.length; i++) {
445
+ if (Number.isFinite(spikes[i].x) && Number.isFinite(spikes[i].y)) valid.push(spikes[i])
446
+ }
447
+ const count = valid.length
448
+ if (count === 0) return {count, meanValue: undefined, valueStandardDeviation: undefined, meanInterval: undefined}
449
+
450
+ const meanValue = valid.reduce((sum, spike) => sum + spike.y, 0) / count
451
+ if (count < 2) return {count, meanValue, valueStandardDeviation: undefined, meanInterval: undefined}
452
+
453
+ const sumOfSquares = valid.reduce((sum, spike) => sum + (spike.y - meanValue) ** 2, 0)
454
+ return {
455
+ count,
456
+ meanValue,
457
+ valueStandardDeviation: Math.sqrt(sumOfSquares / (count - 1)),
458
+ // the intervals between consecutive spikes sum to the span from the first to the last
459
+ meanInterval: (valid[count - 1].x - valid[0].x) / (count - 1),
460
+ }
461
+ }
462
+
463
+ /**
464
+ * Formats a value, or shows a dash when there isn't one (e.g. the standard deviation of a single
465
+ * point)
466
+ * @param value The value, if there is one
467
+ * @param formatter Formats the value
468
+ * @return The formatted value, or a dash
469
+ */
470
+ export function valueOrMissing(value: number | undefined, formatter: (value: number) => string): string {
471
+ return value === undefined ? '–' : formatter(value)
472
+ }
473
+
474
+ // the largest lag (in points) for which the autocorrelation is calculated by default
475
+ const MAX_AUTOCORRELATION_LAG = 50
476
+
477
+ /**
478
+ * Calculates the (sample) autocorrelation of a series' values, by lag: for each lag `k` (in
479
+ * points, not time -- a series' points needn't be evenly spaced in time), the correlation between
480
+ * the values and the values `k` points later,
481
+ * <p>`r[k] = sum[t](x[t] - mean) * (x[t+k] - mean) / sum[t](x[t] - mean)^2`</p>
482
+ * so `r[0]` is 1, and the values are between -1 and 1. Points whose value or time isn't finite are
483
+ * skipped.
484
+ * @param points The series' points, ordered by time
485
+ * @param maxLag The largest lag -- by default, a quarter of the number of points (the usual rule
486
+ * of thumb, since the estimates for larger lags rest on too few pairs of points), but no more than 50
487
+ * @return The autocorrelation for each lag, from 0 to the largest lag, or `undefined` when there
488
+ * are fewer than four points (so no lag beyond 0), or the values don't vary
489
+ */
490
+ export function autocorrelation(
491
+ points: { length: number, [index: number]: Datum },
492
+ maxLag?: number
493
+ ): Array<number> | undefined {
494
+ const values: Array<number> = []
495
+ for (let i = 0; i < points.length; i++) {
496
+ if (Number.isFinite(points[i].x) && Number.isFinite(points[i].y)) values.push(points[i].y)
497
+ }
498
+ const count = values.length
499
+ const largestLag = Math.min(count - 1, maxLag ?? Math.min(MAX_AUTOCORRELATION_LAG, Math.floor(count / 4)))
500
+ if (largestLag < 1) return undefined
501
+
502
+ const mean = values.reduce((sum, value) => sum + value, 0) / count
503
+ const deviations = values.map(value => value - mean)
504
+ const variance = deviations.reduce((sum, deviation) => sum + deviation * deviation, 0)
505
+ if (variance === 0) return undefined
506
+
507
+ const correlations: Array<number> = []
508
+ for (let lag = 0; lag <= largestLag; lag++) {
509
+ let sum = 0
510
+ for (let t = 0; t + lag < count; t++) sum += deviations[t] * deviations[t + lag]
511
+ correlations.push(sum / variance)
512
+ }
513
+ return correlations
514
+ }
@@ -0,0 +1,68 @@
1
+ import {type JSX, createContext, useContext} from "react"
2
+ import type {OutlierBandTooltipMetadata} from "../plots/OutlierPlot"
3
+ import type {TooltipStyle} from "./tooltipUtils"
4
+
5
+ /**
6
+ * What the outlier tooltip shows: the name of the series, and the band (and, for an outlier, the
7
+ * datum) under the mouse
8
+ */
9
+ export type OutlierTooltipData<M extends readonly number[] = readonly number[]> =
10
+ {seriesName: string} & OutlierBandTooltipMetadata<M>
11
+
12
+ /**
13
+ * The (optional) formatters for the outlier tooltip's content
14
+ */
15
+ export type OutlierTooltipContentFormatters = {
16
+ /**
17
+ * Formatter for the datum
18
+ * @param x X-coordinate of the datum
19
+ * @param y Y-coordinate of the datum
20
+ * @return a human-readable description of the datum
21
+ */
22
+ datumFormatter?: (x: number, y: number) => string | JSX.Element
23
+ /**
24
+ * Formatter for the band (it's handed the band's measures, not its bounds)
25
+ * @param lower The measure of the band's inner edge (the measure of the next tighter band, or
26
+ * 0 for the tightest band)
27
+ * @param upper The measure of the band's outer edge (the hovered band's own measure)
28
+ * @return a human-readable description of the band
29
+ */
30
+ bandFormatter?: (lower: number, upper: number) => string | JSX.Element
31
+ /**
32
+ * Formatter for the description of the band's measure: the probabilities of a point being in,
33
+ * and outside, the band
34
+ * @param innerProb Probability of points being within this band
35
+ * @param outerProb Probability of points being outside this band
36
+ * @return a human-readable description of the band: text, JSX, or an array of lines (shown
37
+ * one per line)
38
+ */
39
+ measureFormatter?: (innerProb: number, outerProb: number) => string | JSX.Element | Array<string>
40
+ }
41
+
42
+ /**
43
+ * The outlier tooltip's context: what it shows, its style, and its formatters (the
44
+ * `measureFormatter`'s lines, when it returns an array of them, already laid out one per line)
45
+ */
46
+ export type OutlierTooltipContextValue = {
47
+ tooltipContent: OutlierTooltipData
48
+ tooltipStyle: TooltipStyle
49
+ datumFormatter: (x: number, y: number) => string | JSX.Element
50
+ bandFormatter: (lower: number, upper: number) => string | JSX.Element
51
+ measureFormatter: (innerProb: number, outerProb: number) => string | JSX.Element
52
+ }
53
+
54
+ export const UseOutlierTooltip = createContext<OutlierTooltipContextValue | null>(null)
55
+
56
+ /**
57
+ * Hook for consuming the outlier tooltip context inside a child of
58
+ * {@link OutlierPlotTooltipContent} (for writing your own content for the outlier tooltip)
59
+ * @return What the tooltip shows, its style, and its formatters
60
+ * @throws Error when used outside an `<OutlierPlotTooltipContent>`
61
+ */
62
+ export function useOutlierTooltip(): OutlierTooltipContextValue {
63
+ const context = useContext(UseOutlierTooltip)
64
+ if (context === null) {
65
+ throw new Error('useOutlierTooltip must be used inside OutlierPlotTooltipContent')
66
+ }
67
+ return context
68
+ }
@@ -0,0 +1,86 @@
1
+ import {type RefObject, useLayoutEffect} from "react";
2
+ import type {Dimensions, Margin} from "../styling/margins";
3
+ import {type TooltipStyle, tooltipX, tooltipY} from "./tooltipUtils";
4
+
5
+ /**
6
+ * Where a tooltip is anchored: the mouse, when the tooltip's content was captured
7
+ */
8
+ export type TooltipAnchor = {
9
+ /**
10
+ * The mouse's coordinates, relative to the chart (its canvas)
11
+ */
12
+ mouse: [x: number, y: number]
13
+ /**
14
+ * The chart's (canvas') position in the viewport, when the content was captured
15
+ */
16
+ canvasLeft: number
17
+ canvasTop: number
18
+ /**
19
+ * Optional: the y-coordinate (relative to the chart) of the tooltip's top, given its rendered
20
+ * height, for a tooltip that isn't placed below the mouse (e.g. one centered on a raster
21
+ * plot's category). Defaults to `tooltipY`.
22
+ */
23
+ topFor?: (height: number) => number
24
+ }
25
+
26
+ /**
27
+ * Positions a tooltip (a `position: fixed` element, e.g. a tooltip content's portal) next to the
28
+ * mouse, based on its *rendered* size: after each render, measures the tooltip and sets its
29
+ * `left` and `top` directly, before the browser paints (so the tooltip never shows in the wrong
30
+ * place). The tooltip goes to the right of the mouse, or to the left when it would run past the
31
+ * plot's right edge (see `tooltipX` and `tooltipY`).
32
+ *
33
+ * A tooltip's size depends on its content, so it can only be known once the content has been
34
+ * rendered -- positioning it from an estimate of its size put a narrower-than-estimated tooltip
35
+ * far from the mouse when it flipped to the mouse's left.
36
+ * @param tooltipRef The tooltip's element
37
+ * @param anchor Where the tooltip is anchored (the mouse), or `null` when no tooltip is shown
38
+ * @param plotDimensions The dimensions of the plot
39
+ * @param margin The plot margin
40
+ * @param tooltipStyle The tooltip's style
41
+ */
42
+ export function useTooltipPlacement(
43
+ tooltipRef: RefObject<HTMLElement | null>,
44
+ anchor: TooltipAnchor | null,
45
+ plotDimensions: Dimensions,
46
+ margin: Margin,
47
+ tooltipStyle: TooltipStyle,
48
+ ): void {
49
+ useLayoutEffect(
50
+ () => {
51
+ const tooltip = tooltipRef.current
52
+ if (tooltip === null || anchor === null) return
53
+ // measured at the viewport's top-left corner, where nothing limits its width: a
54
+ // `position: fixed` element near the viewport's right edge only gets the width left to
55
+ // the edge, so its content could wrap, and it would measure narrower than it really is
56
+ tooltip.style.left = '0px'
57
+ tooltip.style.top = '0px'
58
+ const {width, height} = tooltip.getBoundingClientRect()
59
+ const [x, y] = anchor.mouse
60
+ const left = tooltipX(x, width, plotDimensions, tooltipStyle, margin)
61
+ const top = anchor.topFor !== undefined ?
62
+ anchor.topFor(height) :
63
+ tooltipY(y, height, plotDimensions, tooltipStyle, margin)
64
+ tooltip.style.left = `${anchor.canvasLeft + left}px`
65
+ tooltip.style.top = `${anchor.canvasTop + top}px`
66
+ }
67
+ )
68
+ }
69
+
70
+ /**
71
+ * Creates a tooltip's anchor: the mouse, relative to the chart, and the chart's position in the
72
+ * viewport
73
+ * @param mouseCoords The mouse's coordinates, relative to the chart (its canvas)
74
+ * @param canvas The chart's canvas
75
+ * @param topFor Optional: the y-coordinate of the tooltip's top for its rendered height (see
76
+ * {@link TooltipAnchor.topFor})
77
+ * @return The anchor
78
+ */
79
+ export function tooltipAnchorFor(
80
+ mouseCoords: [x: number, y: number],
81
+ canvas: HTMLCanvasElement,
82
+ topFor?: (height: number) => number
83
+ ): TooltipAnchor {
84
+ const canvasRect = canvas.getBoundingClientRect()
85
+ return {mouse: mouseCoords, canvasLeft: canvasRect.left, canvasTop: canvasRect.top, topFor}
86
+ }
@@ -0,0 +1,15 @@
1
+ import {createContext, useContext} from "react";
2
+ import {defaultTooltipStyle, type TooltipStyle} from "./tooltipUtils";
3
+
4
+ /**
5
+ * The style of the enclosing {@link Tooltip} (its `style`, over the default tooltip style)
6
+ */
7
+ export const TooltipStyleContext = createContext<TooltipStyle>(defaultTooltipStyle)
8
+
9
+ /**
10
+ * @return The style of the enclosing {@link Tooltip}: its `style` property over the default tooltip
11
+ * style (or just the default style, outside a tooltip)
12
+ */
13
+ export function useTooltipStyle(): TooltipStyle {
14
+ return useContext(TooltipStyleContext)
15
+ }