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,102 @@
1
+ import {useEffect, useRef} from "react";
2
+ import type {Optional} from "result-fn";
3
+ import type {BaseAxis, ContinuousNumericAxis} from "../axes/axes";
4
+ import type {BaseAxisRange} from "../axes/BaseAxisRange";
5
+ import {ContinuousAxisRange} from "../axes/ContinuousAxisRange";
6
+ import {grownDomain} from "../axes/autoScale";
7
+
8
+ /**
9
+ * What a plot needs from its chart's axes to auto-scale its y-axes (see `ContinuousAxis`'s
10
+ * `autoScale` prop)
11
+ */
12
+ export type AutoScaleAxes = {
13
+ /**
14
+ * The plot's y-axes, by their IDs
15
+ */
16
+ yAxes: Map<string, BaseAxis>
17
+ /**
18
+ * The (current and original) range of the specified axis
19
+ */
20
+ axisRangeFor: (axisId: string) => Optional<BaseAxisRange>
21
+ /**
22
+ * Updates the specified axes' ranges (which updates the axes)
23
+ */
24
+ updateAxisRanges: (ranges: Map<string, ContinuousAxisRange>) => void
25
+ }
26
+
27
+ /**
28
+ * The axis' range, updated to the specified domain (or a new range for it, when the axis has none)
29
+ * @param axisId The axis' ID
30
+ * @param domain The domain
31
+ * @param axisRangeFor The (current and original) range of the specified axis
32
+ * @return The updated range
33
+ */
34
+ function rangeFor(
35
+ axisId: string,
36
+ [min, max]: [min: number, max: number],
37
+ axisRangeFor: AutoScaleAxes['axisRangeFor']
38
+ ): ContinuousAxisRange {
39
+ return axisRangeFor(axisId)
40
+ .map(range => range.update(min, max) as ContinuousAxisRange)
41
+ .getOrElse(ContinuousAxisRange.from(min, max))
42
+ }
43
+
44
+ /**
45
+ * Grows the auto-scaling y-axes to fit the specified extents of the data plotted against them
46
+ * (within their limits, and with their padding -- see `grownDomain`). Meant to be called from a
47
+ * draw function registered to run before the axes draw (they're at z-index 0), so that the axes
48
+ * and the data are drawn with the grown domain in the same frame.
49
+ * @param extents The extent of the (visible) data plotted against each y-axis, by axis ID
50
+ * @param axes The plot's y-axes, and their ranges
51
+ */
52
+ export function growAutoScaledYAxes(
53
+ extents: Map<string, [min: number, max: number]>,
54
+ axes: AutoScaleAxes
55
+ ): void {
56
+ const {yAxes, axisRangeFor, updateAxisRanges} = axes
57
+ const updates = new Map<string, ContinuousAxisRange>()
58
+ extents.forEach((extent, axisId) => {
59
+ const axis = yAxes.get(axisId) as ContinuousNumericAxis | undefined
60
+ if (axis?.autoScale === undefined) return
61
+ const [currentMin, currentMax] = axis.scale.domain()
62
+ const [min, max] = grownDomain([currentMin, currentMax], extent, axis.autoScale, axis.scale)
63
+ if (min !== currentMin || max !== currentMax) {
64
+ updates.set(axisId, rangeFor(axisId, [min, max], axisRangeFor))
65
+ }
66
+ })
67
+ if (updates.size > 0) updateAxisRanges(updates)
68
+ }
69
+
70
+ /**
71
+ * New data, new scale: when the plot's data source is replaced (e.g. on a reset, or a change to
72
+ * the number of series), restarts the auto-scaling y-axes from their starts (and they then grow
73
+ * to fit the new data). Only on a *change* of data source -- not when the plot mounts with its
74
+ * data source, which would throw away an axis' kept growth (see `ContinuousAxis`'s
75
+ * `autoScaledDomain`). The axes are read through a ref, so that this only acts when the data
76
+ * source changes -- not, say, when an axis is added.
77
+ * @param dataSource The plot's data source
78
+ * @param axes The plot's y-axes, and their ranges
79
+ */
80
+ export function useAutoScaleRestart(dataSource: unknown, axes: AutoScaleAxes): void {
81
+ const axesRef = useRef(axes)
82
+ useEffect(() => {
83
+ axesRef.current = axes
84
+ })
85
+
86
+ const dataSourceRef = useRef(dataSource)
87
+ useEffect(
88
+ () => {
89
+ if (dataSourceRef.current === dataSource) return
90
+ dataSourceRef.current = dataSource
91
+
92
+ const {yAxes, axisRangeFor, updateAxisRanges} = axesRef.current
93
+ const updates = new Map<string, ContinuousAxisRange>()
94
+ yAxes.forEach((axis, axisId) => {
95
+ const {autoScale} = axis as ContinuousNumericAxis
96
+ if (autoScale !== undefined) updates.set(axisId, rangeFor(axisId, autoScale.domain, axisRangeFor))
97
+ })
98
+ if (updates.size > 0) updateAxisRanges(updates)
99
+ },
100
+ [dataSource]
101
+ )
102
+ }
@@ -0,0 +1,185 @@
1
+ import * as d3 from "d3";
2
+ import type {CurveFactory} from "d3";
3
+
4
+ /**
5
+ * The default color of a colorized line's start (its oldest point): a blue
6
+ */
7
+ export const DEFAULT_LINE_START_COLOR = '#2f6cf6'
8
+ /**
9
+ * The default color of a colorized line's end (its newest point): a red
10
+ */
11
+ export const DEFAULT_LINE_END_COLOR = '#e8423f'
12
+
13
+ /**
14
+ * The default number of points it takes a colorized line's color to sweep from its start color to
15
+ * its end color (see `sweepFraction`)
16
+ */
17
+ export const DEFAULT_LINE_COLOR_STEPS = 1000
18
+
19
+ // a piece of a line, as d3's line generator traced it: where it starts and ends, and how to draw
20
+ // it (from its start) onto a canvas path
21
+ type LinePiece = {
22
+ start: [x: number, y: number]
23
+ end: [x: number, y: number]
24
+ draw: (context: CanvasPath) => void
25
+ }
26
+
27
+ /**
28
+ * Records the pieces of the line that d3's line generator traces (one per drawing command:
29
+ * `lineTo`, `bezierCurveTo`, ...), rather than drawing them, so that each piece can be stroked in
30
+ * its own color while keeping the curve's exact shape
31
+ */
32
+ class LineRecorder {
33
+ readonly pieces: Array<LinePiece> = []
34
+ private current: [x: number, y: number] = [0, 0]
35
+ private subpathStart: [x: number, y: number] = [0, 0]
36
+
37
+ moveTo(x: number, y: number): void {
38
+ this.current = [x, y]
39
+ this.subpathStart = [x, y]
40
+ }
41
+
42
+ lineTo(x: number, y: number): void {
43
+ this.add([x, y], context => context.lineTo(x, y))
44
+ }
45
+
46
+ bezierCurveTo(cp1x: number, cp1y: number, cp2x: number, cp2y: number, x: number, y: number): void {
47
+ this.add([x, y], context => context.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y))
48
+ }
49
+
50
+ quadraticCurveTo(cpx: number, cpy: number, x: number, y: number): void {
51
+ this.add([x, y], context => context.quadraticCurveTo(cpx, cpy, x, y))
52
+ }
53
+
54
+ arcTo(x1: number, y1: number, x2: number, y2: number, radius: number): void {
55
+ this.add([x2, y2], context => context.arcTo(x1, y1, x2, y2, radius))
56
+ }
57
+
58
+ arc(x: number, y: number, radius: number, startAngle: number, endAngle: number, counterclockwise?: boolean): void {
59
+ const end: [number, number] = [x + radius * Math.cos(endAngle), y + radius * Math.sin(endAngle)]
60
+ this.add(end, context => context.arc(x, y, radius, startAngle, endAngle, counterclockwise))
61
+ }
62
+
63
+ closePath(): void {
64
+ const [x, y] = this.subpathStart
65
+ this.add([x, y], context => context.lineTo(x, y))
66
+ }
67
+
68
+ rect(x: number, y: number, width: number, height: number): void {
69
+ this.moveTo(x, y)
70
+ this.lineTo(x + width, y)
71
+ this.lineTo(x + width, y + height)
72
+ this.lineTo(x, y + height)
73
+ this.closePath()
74
+ }
75
+
76
+ private add(end: [x: number, y: number], draw: (context: CanvasPath) => void): void {
77
+ this.pieces.push({start: this.current, end, draw})
78
+ this.current = end
79
+ }
80
+ }
81
+
82
+ /**
83
+ * Creates the function that gives the color at a fraction of the way along a colorized line:
84
+ * from the start color (at 0) to the end color (at 1), sweeping the long way around the hue
85
+ * circle, so that the line passes through the colors of the spectrum in between (e.g. from blue,
86
+ * through cyan, green, and yellow, to red)
87
+ * @param startColor The color at the line's start
88
+ * @param endColor The color at the line's end
89
+ * @return The color at a fraction (from 0 to 1) of the way along the line
90
+ */
91
+ export function lineColorScale(startColor: string, endColor: string): (fraction: number) => string {
92
+ return d3.interpolateHslLong(startColor, endColor)
93
+ }
94
+
95
+ /**
96
+ * Where a point is in the color sweep of a colorized line: the line's color advances one step per
97
+ * point, sweeping from the start color (0) to the end color (1) over `steps` points, then back to
98
+ * the start color over the next `steps` points, and so on -- so the color never jumps
99
+ * @param pointNumber The point's overall sequence number in its series (from 0)
100
+ * @param steps The number of points (steps) a sweep from the start color to the end color takes
101
+ * @return The fraction (from 0, the start color, to 1, the end color) of the way through the sweep
102
+ */
103
+ export function sweepFraction(pointNumber: number, steps: number): number {
104
+ const span = Math.max(1, steps)
105
+ const phase = (Math.max(0, pointNumber) / span) % 2
106
+ return phase <= 1 ? phase : 2 - phase
107
+ }
108
+
109
+ /**
110
+ * Creates the function that gives the color of a colorized line at a point: from the start color,
111
+ * one step per point, to the end color, and back (see {@link sweepFraction}), sweeping the spectrum
112
+ * in between (see {@link lineColorScale})
113
+ * @param startColor The color the sweep starts at
114
+ * @param endColor The color the sweep ends at
115
+ * @param steps The number of points (steps) a sweep from the start color to the end color takes
116
+ * @return The color at a point, given its overall sequence number in its series
117
+ */
118
+ export function pointColorScale(startColor: string, endColor: string, steps: number): (pointNumber: number) => string {
119
+ const colorAt = lineColorScale(startColor, endColor)
120
+ return pointNumber => colorAt(sweepFraction(pointNumber, steps))
121
+ }
122
+
123
+ /**
124
+ * Strokes a line through the specified points, with the specified curve, whose color changes
125
+ * along it: each piece of the line, as the curve traces it (e.g. the segment between two points),
126
+ * gets the color of the point it's at (pieces are matched to points by their position along the
127
+ * line, since some curves trace more, or fewer, pieces than there are segments). Consecutive
128
+ * pieces of the same color are stroked together. The curve's shape is exactly the same as
129
+ * stroking the whole line at once. The context's current line width (and other stroke settings)
130
+ * are used.
131
+ * @param context The canvas 2D context to stroke onto
132
+ * @param points The points, in order
133
+ * @param x The x-coordinate (in the context's space) of a point
134
+ * @param y The y-coordinate (in the context's space) of a point
135
+ * @param curve The curve (interpolation) between the points
136
+ * @param colorOf The color of the line at the point with the specified index (in `points`)
137
+ * @template P The type of the points
138
+ */
139
+ export function strokeColorizedLine<P>(
140
+ context: CanvasRenderingContext2D,
141
+ points: Array<P>,
142
+ x: (point: P) => number,
143
+ y: (point: P) => number,
144
+ curve: CurveFactory,
145
+ colorOf: (index: number) => string
146
+ ): void {
147
+ // (with a single point, there's no line to draw -- d3 would close the path back on itself)
148
+ if (points.length < 2) return
149
+
150
+ const recorder = new LineRecorder()
151
+ d3.line<P>().x(x).y(y).curve(curve).context(recorder as unknown as CanvasRenderingContext2D)(points)
152
+ const {pieces} = recorder
153
+ if (pieces.length === 0) return
154
+
155
+ // the index of the point a piece is at (for e.g. a linear curve, a segment's starting point)
156
+ const pointIndexOf = (pieceIndex: number) => pieces.length === 1 ?
157
+ 0 :
158
+ Math.round(pieceIndex / (pieces.length - 1) * (points.length - 2))
159
+ const sameSpot = (a: [number, number], b: [number, number]) => a[0] === b[0] && a[1] === b[1]
160
+
161
+ context.save()
162
+ // (round joins and caps, so that consecutive runs of different colors meet without a notch)
163
+ context.lineJoin = 'round'
164
+ context.lineCap = 'round'
165
+ let color: string | undefined = undefined
166
+ let previousEnd: [number, number] | undefined = undefined
167
+ pieces.forEach((piece, index) => {
168
+ const pieceColor = colorOf(pointIndexOf(index))
169
+ if (pieceColor !== color) {
170
+ // a new color: stroke the run so far, and start a new one at this piece
171
+ if (color !== undefined) context.stroke()
172
+ color = pieceColor
173
+ context.strokeStyle = color
174
+ context.beginPath()
175
+ context.moveTo(piece.start[0], piece.start[1])
176
+ } else if (previousEnd === undefined || !sameSpot(previousEnd, piece.start)) {
177
+ // (a gap in the line, e.g. a new subpath)
178
+ context.moveTo(piece.start[0], piece.start[1])
179
+ }
180
+ piece.draw(context)
181
+ previousEnd = piece.end
182
+ })
183
+ context.stroke()
184
+ context.restore()
185
+ }
@@ -0,0 +1,16 @@
1
+ // A sentinel that represents that no curve factory is to be used, which means
2
+ // that no line will be drawn between the iterates (kinda gross)
3
+ import type {CurveFactory} from "d3";
4
+ import type {BarChartElementId} from "./BarPlot";
5
+
6
+ export const NoCurveFactory: CurveFactory = undefined as unknown as CurveFactory; // constants identifying the bar-chart elements for which mouse-over/mouse-leave events are defined
7
+
8
+ export const STREAM_CHARTS_BAR_CHART_ID = 'stream-charts-bar-chart'
9
+ export const TOOLTIP_PROVIDER_ID = STREAM_CHARTS_BAR_CHART_ID + '-tooltip-provider'
10
+ export const BAR_CHART_TOOLTIP_PROVIDER_IDS: BarChartElementId = {
11
+ currentValue: TOOLTIP_PROVIDER_ID + '-current-value',
12
+ meanValue: TOOLTIP_PROVIDER_ID + '-mean-value',
13
+ minMax: TOOLTIP_PROVIDER_ID + '-min-max',
14
+ windowedMeanValue: TOOLTIP_PROVIDER_ID + '-windowed-min-max',
15
+ windowedMinMax: TOOLTIP_PROVIDER_ID + '-windowed-mean'
16
+ }
@@ -0,0 +1,198 @@
1
+ // Canvas has no per-shape mouse events (no SVG `.on("mouseover", ...)` equivalent) -- everything is
2
+ // just pixels on a bitmap. So instead of attaching a handler to each `<path>`/`<circle>`, plots
3
+ // register their drawn geometry (in canvas/pixel coordinates) here, and a single `mousemove`
4
+ // listener on the shared canvas element hit-tests the mouse position against that geometry to
5
+ // figure out which series (if any) the mouse is over.
6
+
7
+ /** A single (x, y) point in canvas drawing coordinates (i.e. already includes the plot's margin offset). */
8
+ export type Point = [x: number, y: number]
9
+
10
+ /** An axis-aligned rectangle, in canvas coordinates. */
11
+ export interface Rect {
12
+ x: number
13
+ y: number
14
+ width: number
15
+ height: number
16
+ }
17
+
18
+ /**
19
+ * The screen-space geometry for one series, as last drawn, used for hit-testing on `mousemove`.
20
+ * Points/segments/rects are in the same canvas coordinate space the series was drawn in
21
+ * (margin-offset already applied).
22
+ */
23
+ export interface SeriesGeometry {
24
+ /** the points that make up the series, in drawing order (ignored when `segments`/`rects` is set) */
25
+ points: Array<Point>
26
+ /**
27
+ * When set, `points` is hit-tested as a single *connected* polyline (mouse must be within
28
+ * `hitRadius` pixels of a line segment between consecutive points). When unset and
29
+ * `segments`/`rects` is also unset, `points` are hit-tested individually as circles of radius
30
+ * `hitRadius` (e.g. for marker/bar-style plots where there's no connecting line).
31
+ */
32
+ asLine?: boolean
33
+ /**
34
+ * A set of *disjoint* line segments (e.g. one per raster spike) that are hit-tested
35
+ * independently -- unlike `asLine`, consecutive entries are NOT assumed to connect to each
36
+ * other. Takes precedence over `points`/`asLine` when set.
37
+ */
38
+ segments?: Array<[Point, Point]>
39
+ /**
40
+ * A set of axis-aligned rectangles (e.g. bar-chart bars), hit-tested as filled regions (exact
41
+ * containment, not a `hitRadius` proximity test). Takes precedence over `segments`/`points`.
42
+ */
43
+ rects?: Array<Rect>
44
+ /** how close (in pixels) the mouse must be to register a hit (ignored when `rects` is set) */
45
+ hitRadius: number
46
+ }
47
+
48
+ /**
49
+ * Squared distance from a point to a line segment (avoids a sqrt when just comparing distances).
50
+ * @param px The point's x-coordinate
51
+ * @param py The point's y-coordinate
52
+ * @param x1 The x-coordinate of the segment's start
53
+ * @param y1 The y-coordinate of the segment's start
54
+ * @param x2 The x-coordinate of the segment's end
55
+ * @param y2 The y-coordinate of the segment's end
56
+ * @return The squared distance from the point to the nearest point on the segment
57
+ */
58
+ function distanceSquaredToSegment(px: number, py: number, x1: number, y1: number, x2: number, y2: number): number {
59
+ const dx = x2 - x1
60
+ const dy = y2 - y1
61
+ const lengthSquared = dx * dx + dy * dy
62
+ if (lengthSquared === 0) {
63
+ const ddx = px - x1
64
+ const ddy = py - y1
65
+ return ddx * ddx + ddy * ddy
66
+ }
67
+ // project point onto the segment, clamped to the segment's extent
68
+ let t = ((px - x1) * dx + (py - y1) * dy) / lengthSquared
69
+ t = Math.max(0, Math.min(1, t))
70
+ const closestX = x1 + t * dx
71
+ const closestY = y1 + t * dy
72
+ const ddx = px - closestX
73
+ const ddy = py - closestY
74
+ return ddx * ddx + ddy * ddy
75
+ }
76
+
77
+ /**
78
+ * The result of a hit-test: which series was hit, and the index of the specific point (for
79
+ * point/polyline geometry) or segment (for disjoint-segment geometry) that matched -- so callers
80
+ * can look up the specific datum involved (e.g. for a tooltip) rather than just the series name.
81
+ */
82
+ export interface SeriesHit {
83
+ /** the name of the series that was hit */
84
+ name: string
85
+ /**
86
+ * the index of the point (for point or polyline geometry -- for a polyline, whichever end of
87
+ * the hit segment is nearer the mouse), segment, or rect that was hit
88
+ */
89
+ index: number
90
+ }
91
+
92
+ /**
93
+ * Finds the series (and specific point/segment within it) hit by the given mouse position.
94
+ * Entries are checked in *reverse* insertion order -- i.e. most-recently-added first -- and the
95
+ * first entry with any qualifying match wins, matching normal DOM/SVG hit-testing (the topmost
96
+ * element captures the pointer) rather than picking whichever entry happens to report the smallest
97
+ * geometric distance across all entries.
98
+ *
99
+ * This distinction matters whenever two entries visually overlap: e.g. a bar-chart's value-line
100
+ * segment is drawn on top of (and can extend slightly beyond) its min/max bar's rect. A rect is a
101
+ * containment test -- any point inside it is unambiguously "hit," with no notion of "how close" --
102
+ * so comparing it against a segment's proximity-based distance would let the rect win everywhere
103
+ * the two overlap, even dead-center on the line, since 0 distance beats any nonzero one. Since
104
+ * plots insert geometry in the same order they draw it, checking entries topmost-first resolves
105
+ * this the way it looks on screen: whichever shape is drawn last (visually on top) claims the
106
+ * pointer first, and only falls through to earlier (lower) entries where it doesn't match at all.
107
+ *
108
+ * Within a single entry (e.g. Scatter's many polyline segments, or Raster's many disjoint spikes)
109
+ * the closest qualifying point/segment still wins, since there's no z-order to speak of among
110
+ * pieces of the same drawn shape.
111
+ * @param mouseX The mouse's x-coordinate, in the same canvas coordinate space the geometry was recorded in
112
+ * @param mouseY The mouse's y-coordinate, in the same canvas coordinate space the geometry was recorded in
113
+ * @param geometry A `map(series_name -> SeriesGeometry)` as last drawn, in draw order
114
+ * @return The hit series and matched index, or `undefined` if the mouse isn't over any series
115
+ */
116
+ export function seriesAt(mouseX: number, mouseY: number, geometry: Map<string, SeriesGeometry>): SeriesHit | undefined {
117
+ const entries = Array.from(geometry.entries()).reverse()
118
+
119
+ for (const [name, {points, asLine, segments, rects, hitRadius}] of entries) {
120
+ const hitRadiusSquared = hitRadius * hitRadius
121
+
122
+ if (rects !== undefined) {
123
+ const index = rects.findIndex(rect =>
124
+ mouseX >= rect.x && mouseX <= rect.x + rect.width &&
125
+ mouseY >= rect.y && mouseY <= rect.y + rect.height
126
+ )
127
+ if (index >= 0) return {name, index}
128
+ continue
129
+ }
130
+
131
+ if (segments !== undefined) {
132
+ let bestIndex = -1
133
+ let bestDistanceSquared = Infinity
134
+ segments.forEach(([[x1, y1], [x2, y2]], index) => {
135
+ const distanceSquared = distanceSquaredToSegment(mouseX, mouseY, x1, y1, x2, y2)
136
+ if (distanceSquared <= hitRadiusSquared && distanceSquared < bestDistanceSquared) {
137
+ bestDistanceSquared = distanceSquared
138
+ bestIndex = index
139
+ }
140
+ })
141
+ if (bestIndex >= 0) return {name, index: bestIndex}
142
+ continue
143
+ }
144
+
145
+ if (points.length === 0) continue
146
+
147
+ if (asLine) {
148
+ let bestIndex = -1
149
+ let bestDistanceSquared = Infinity
150
+ for (let i = 0; i < points.length - 1; i++) {
151
+ const [x1, y1] = points[i]
152
+ const [x2, y2] = points[i + 1]
153
+ const distanceSquared = distanceSquaredToSegment(mouseX, mouseY, x1, y1, x2, y2)
154
+ if (distanceSquared <= hitRadiusSquared && distanceSquared < bestDistanceSquared) {
155
+ bestDistanceSquared = distanceSquared
156
+ // attribute the hit to whichever endpoint of the segment is nearer
157
+ const toStart = (mouseX - x1) ** 2 + (mouseY - y1) ** 2
158
+ const toEnd = (mouseX - x2) ** 2 + (mouseY - y2) ** 2
159
+ bestIndex = toStart <= toEnd ? i : i + 1
160
+ }
161
+ }
162
+ if (bestIndex >= 0) return {name, index: bestIndex}
163
+ continue
164
+ }
165
+
166
+ let bestIndex = -1
167
+ let bestDistanceSquared = Infinity
168
+ points.forEach(([x, y], index) => {
169
+ const distanceSquared = (mouseX - x) ** 2 + (mouseY - y) ** 2
170
+ if (distanceSquared <= hitRadiusSquared && distanceSquared < bestDistanceSquared) {
171
+ bestDistanceSquared = distanceSquared
172
+ bestIndex = index
173
+ }
174
+ })
175
+ if (bestIndex >= 0) return {name, index: bestIndex}
176
+ }
177
+
178
+ return undefined
179
+ }
180
+
181
+ /**
182
+ * Converts a `MouseEvent` (as received by a `canvas.addEventListener('mousemove', ...)` handler)
183
+ * into canvas-local coordinates, accounting for the canvas's on-page position and any CSS scaling
184
+ * between the canvas's backing-store size and its displayed size.
185
+ * @param event The mouse event
186
+ * @param canvas The canvas element the event was dispatched to
187
+ * @return The `[x, y]` position of the event, in the canvas's own CSS-pixel coordinate space
188
+ * (i.e. the same space `ctx` drawing calls use once the devicePixelRatio transform is applied)
189
+ */
190
+ export function canvasLocalPoint(event: MouseEvent, canvas: HTMLCanvasElement): Point {
191
+ const rect = canvas.getBoundingClientRect()
192
+ const scaleX = rect.width > 0 ? canvas.clientWidth / rect.width : 1
193
+ const scaleY = rect.height > 0 ? canvas.clientHeight / rect.height : 1
194
+ return [
195
+ (event.clientX - rect.left) * scaleX,
196
+ (event.clientY - rect.top) * scaleY
197
+ ]
198
+ }