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,57 +1,141 @@
1
- import {Dimensions} from "../styling/margins";
2
- import * as d3 from "d3";
3
- import {GSelection} from "../d3types";
1
+ import type {Dimensions} from "../styling/margins";
2
+ import type {CanvasContext, DrawFn, DrawHandle} from "../d3types";
3
+ import type {FastShiftArray} from "fast-shift-array";
4
+ import type {BaseAxisRange} from "../axes/BaseAxisRange";
5
+ import type {AxisInterval} from "../axes/AxisInterval";
4
6
 
5
- export type Series<D> = Array<D>
7
+ /**
8
+ * A series' data: a plain array, or the `FastShiftArray` that backs a {@link BaseSeries}
9
+ */
10
+ export type Series<D> = Array<D> | FastShiftArray<D>
11
+
12
+ // a draw function registered with the canvas context, and where it falls in the drawing order
13
+ interface RegisteredDraw {
14
+ draw: DrawFn
15
+ zIndex: number
16
+ }
6
17
 
7
18
  /**
8
- * Creates the main SVG for holding the plot.
19
+ * Creates the {@link CanvasContext} for the chart -- the drawing context plus the redraw
20
+ * registration/scheduling API that axes, plots, and the tracker use to (re)paint themselves.
21
+ * Replaces the old `createPlotContainer`, which appended the root SVG `<g>`.
22
+ * Each redraw clears the canvas, and then calls every registered draw function in z-index order
23
+ * (lowest first); a draw function that throws is logged and skipped, so it doesn't blank the rest.
24
+ * The canvas isn't sized here: call {@link resizeCanvasTo} immediately after this with the actual
25
+ * container dimensions.
9
26
  * @param chartId A unique value identifying the chart.
10
- * @param container The SVG element interface
11
- * @param plotDimensions The dimensions of the plot
12
- * @param color The SVG `color` attribute used for the axis
27
+ * @param canvas The `<canvas>` DOM element backing the chart.
28
+ * @param color The default `color` used for text/strokes when nothing more specific is set.
29
+ * @return The canvas context
30
+ * @throws Error when the canvas has no 2D rendering context
13
31
  */
14
- export function createPlotContainer(
32
+ export function createCanvasContext(
15
33
  chartId: number,
16
- container: SVGSVGElement,
17
- plotDimensions: Dimensions,
34
+ canvas: HTMLCanvasElement,
18
35
  color: string
19
- ): GSelection {
20
- const {width, height} = plotDimensions
21
- return d3.select<SVGSVGElement, any>(container)
22
- .attr('width', Math.max(0, width))
23
- .attr('height', Math.max(0, height))
24
- .attr('color', color)
25
- .append<SVGGElement>('g')
26
- .attr('id', `main-container-${chartId}`)
36
+ ): CanvasContext {
37
+ const context = canvas.getContext('2d')
38
+ if (!context) {
39
+ throw new Error(`Unable to acquire a 2D rendering context for chart ${chartId}`)
40
+ }
41
+
42
+ const dpr = window.devicePixelRatio || 1
43
+ context.textBaseline = 'alphabetic'
44
+ context.strokeStyle = color
45
+ context.fillStyle = color
46
+
47
+ const drawFns = new Map<DrawHandle, RegisteredDraw>()
48
+ let animationFrameId: number | null = null
49
+
50
+ const redrawNow = (): void => {
51
+ animationFrameId = null
52
+
53
+ // clear the full backing-store (not just the CSS-pixel size, since the backing store is
54
+ // scaled by devicePixelRatio and the current transform includes that scale)
55
+ context.save()
56
+ context.setTransform(1, 0, 0, 1, 0, 0)
57
+ context.clearRect(0, 0, canvas.width, canvas.height)
58
+ context.restore()
59
+
60
+ Array.from(drawFns.entries())
61
+ .sort(([, a], [, b]) => a.zIndex - b.zIndex)
62
+ .forEach(([id, {draw}]) => {
63
+ try {
64
+ draw(canvasContext)
65
+ } catch (error) {
66
+ // one registrant's draw failure (e.g. a misconfigured axis assignment) must not
67
+ // blank every other plot/axis/tracker sharing this canvas for the frame -- and
68
+ // since this runs on every subsequent data tick too, an uncaught throw here would
69
+ // otherwise wedge the chart's rendering permanently rather than just once
70
+ console.error(`Error while drawing "${id}"; chart_id: ${chartId}`, error)
71
+ }
72
+ })
73
+ }
74
+
75
+ const canvasContext: CanvasContext = {
76
+ chartId,
77
+ canvas,
78
+ context2D: context,
79
+ dpr,
80
+ register: (id, draw, zIndex = 0) => {
81
+ drawFns.set(id, {draw, zIndex})
82
+ canvasContext.requestRedraw()
83
+ },
84
+ unregister: (id) => {
85
+ drawFns.delete(id)
86
+ canvasContext.requestRedraw()
87
+ },
88
+ requestRedraw: () => {
89
+ if (animationFrameId === null) {
90
+ animationFrameId = window.requestAnimationFrame(redrawNow)
91
+ }
92
+ }
93
+ }
94
+
95
+ return canvasContext
96
+ }
97
+
98
+ /**
99
+ * Resizes the canvas's backing store to match `dimensions` at the current devicePixelRatio, so
100
+ * that drawing stays crisp on high-DPI displays, and re-applies the dpr scale to the drawing
101
+ * context so that one drawing-unit equals one CSS pixel. Replaces the old SVG `width`/`height`
102
+ * attribute updates. Call this whenever the container's pixel dimensions change, before the next
103
+ * redraw.
104
+ * @param context The canvas context
105
+ * @param dimensions The new overall (plot + margin) dimensions, in CSS pixels
106
+ */
107
+ export function resizeCanvasTo(context: CanvasContext, dimensions: Dimensions): void {
108
+ const {canvas, context2D, dpr} = context
109
+ const width = Math.max(0, dimensions.width)
110
+ const height = Math.max(0, dimensions.height)
111
+
112
+ canvas.style.width = `${width}px`
113
+ canvas.style.height = `${height}px`
114
+ canvas.width = Math.round(width * dpr)
115
+ canvas.height = Math.round(height * dpr)
116
+
117
+ context2D.setTransform(dpr, 0, 0, dpr, 0, 0)
27
118
  }
28
119
 
29
120
  /**
30
- * Adds a clip area for the chart to the specified SVG element. The clip-area is given
31
- * an `id` of `clip-series-<chart_id>`, which because the chart ID should be unique, makes
32
- * this unique as well.
33
- * @param chartId The ID of the chart to which the clip area is to be added.
34
- * @param plotGroup The SVG group element to which the clip area is to be added.
35
- * @param plotDimensions The dimensions of the plot.
36
- * @return The ID of the clip-path.
121
+ * Clips subsequent drawing to a rectangular area. Replaces the old SVG `<clipPath>`/
122
+ * `setClipPathG`/`setClipPath`. Canvas clip regions are stack-based: callers must `ctx.save()`
123
+ * before calling this and `ctx.restore()` once the clipped drawing is done, or the clip will leak
124
+ * into unrelated draw calls later in the same frame.
125
+ * @param context The canvas context
126
+ * @param dimensions The dimensions of the area to clip to
127
+ * @param origin The top-left corner of the clip area, in canvas drawing coordinates (defaults to
128
+ * `(0, 0)`; pass the margin's `(left, top)` when clipping to the plot area, which is offset from
129
+ * the canvas origin)
37
130
  */
38
- export function setClipPathG(chartId: number, plotGroup: GSelection, plotDimensions: Dimensions): string {
39
- const clipPathId = `chart-clip-path-${chartId}`
40
-
41
- // remove the old clipping region and add a new one with the updated plot dimensions
42
- plotGroup.select(`#${clipPathId}-defs`).remove();
43
- plotGroup
44
- .append('defs')
45
- .attr('id', `${clipPathId}-defs`)
46
- .append("clipPath")
47
- .attr("id", clipPathId)
48
- .append("rect")
49
- .attr("x", 0)
50
- .attr("y", 0)
51
- .attr("width", Math.max(0, plotDimensions.width))
52
- .attr("height", Math.max(0, plotDimensions.height))
53
-
54
- return clipPathId
131
+ export function clipToArea(
132
+ context: CanvasContext,
133
+ dimensions: Dimensions,
134
+ origin: {x: number, y: number} = {x: 0, y: 0}
135
+ ): void {
136
+ context.context2D.beginPath()
137
+ context.context2D.rect(origin.x, origin.y, Math.max(0, dimensions.width), Math.max(0, dimensions.height))
138
+ context.context2D.clip()
55
139
  }
56
140
 
57
141
  /**
@@ -72,4 +156,14 @@ export interface AxesAssignment {
72
156
  */
73
157
  export const assignAxes = (xAxis: string, yAxis: string): AxesAssignment => ({xAxis, yAxis})
74
158
 
75
-
159
+ /**
160
+ * Converts a map holding the axes' ranges into a map holding the axes' current intervals. Used
161
+ * when reporting the axes' bounds to the code using the chart (see the plots' `onUpdateAxesInterval`).
162
+ * @param ranges A map associating an axis ID with that axis' range
163
+ * @return A map associating an axis ID with that axis' current interval
164
+ */
165
+ export function currentIntervalsFrom(ranges: Map<string, BaseAxisRange>): Map<string, AxisInterval> {
166
+ const intervals = new Map<string, AxisInterval>()
167
+ ranges.forEach((range, axisId) => intervals.set(axisId, range.current))
168
+ return intervals
169
+ }
@@ -0,0 +1,240 @@
1
+ import {useCallback, useEffect, useRef} from "react";
2
+ import * as d3 from "d3";
3
+ import type {D3ZoomEvent} from "d3";
4
+ import type {CanvasContext} from "../d3types";
5
+
6
+ /**
7
+ * A zoom gesture's step, as the plot's zoom handler gets it
8
+ */
9
+ export interface ZoomStep {
10
+ /**
11
+ * The zoom factor of this step alone, relative to the previous step (d3-zoom's own scale is
12
+ * cumulative; the zoom math in `axes.ts` is incremental -- see `ContinuousAxisRange.scale`)
13
+ */
14
+ factor: number
15
+ /**
16
+ * d3-zoom's cumulative scale (e.g. for ordinal axes, whose zoom snaps back to the original
17
+ * range exactly at 1 -- see `OrdinalAxisRange.scale`)
18
+ */
19
+ k: number
20
+ /**
21
+ * Where the mouse is, relative to the canvas
22
+ */
23
+ x: number
24
+ y: number
25
+ }
26
+
27
+ /**
28
+ * The options for {@link useCanvasZoomPan}
29
+ */
30
+ export interface CanvasZoomPanOptions {
31
+ /**
32
+ * Whether dragging pans the plot
33
+ */
34
+ panEnabled: boolean
35
+ /**
36
+ * Whether the mouse wheel zooms the plot
37
+ */
38
+ zoomEnabled: boolean
39
+ /**
40
+ * Whether zooming requires the shift (or ctrl) key to be held down
41
+ */
42
+ keyModifiersRequired: boolean
43
+ /**
44
+ * The smallest and largest (cumulative) zoom scales
45
+ */
46
+ scaleExtent: [min: number, max: number]
47
+ /**
48
+ * Whether the wheel changes d3-zoom's scale the opposite way to d3-zoom's default, so that all
49
+ * the plots zoom the same way for the same gesture. Plots differ in which way their axes move
50
+ * with the scale: a continuous axis's range *widens* as the scale goes up (an incremental factor
51
+ * above 1 grows it), while an ordinal axis's (pixel) range widens its bands as the scale goes
52
+ * up. So the continuous-axis plots use d3-zoom's default, and the bar plot (with its ordinal
53
+ * axis) inverts the wheel to match them. Defaults to `false`.
54
+ */
55
+ invertWheel?: boolean
56
+ /**
57
+ * The plot's margin and dimensions, which bound the zoom's translation
58
+ */
59
+ translateExtent: [[left: number, top: number], [right: number, bottom: number]]
60
+ /**
61
+ * Called when a pan (drag) starts (e.g. to suppress tooltips while panning)
62
+ */
63
+ onPanStart?: () => void
64
+ /**
65
+ * Called for each step of a pan
66
+ * @param dx The horizontal distance (px) moved since the previous step
67
+ * @param dy The vertical distance (px) moved since the previous step
68
+ */
69
+ onPan: (dx: number, dy: number) => void
70
+ /**
71
+ * Called when a pan ends
72
+ */
73
+ onPanEnd?: () => void
74
+ /**
75
+ * Called for each step of a zoom gesture (a real one: programmatic changes to d3-zoom's
76
+ * transform, e.g. a reset, aren't reported)
77
+ * @param step The step's zoom factor, d3-zoom's cumulative scale, and the mouse position
78
+ */
79
+ onZoom: (step: ZoomStep) => void
80
+ /**
81
+ * The plot's `onZoomReset` property: called (whenever zooming is set up) with a function that
82
+ * resets the zoom -- d3-zoom's own transform, and then the plot's view (see `resetView`)
83
+ */
84
+ onZoomReset?: (resetZoom: () => void) => void
85
+ /**
86
+ * Restores the plot's view (its axes' original ranges) when the zoom is reset (see `onZoomReset`)
87
+ */
88
+ resetView?: () => void
89
+ }
90
+
91
+ /**
92
+ * The zoom controls a plot gets back from {@link useCanvasZoomPan}
93
+ */
94
+ export interface CanvasZoomPanControls {
95
+ /**
96
+ * Resets d3-zoom's own (cumulative) transform to identity, e.g. when the plot's axes are reset
97
+ * to their original ranges -- otherwise the next zoom gesture would continue from the stale,
98
+ * accumulated scale
99
+ */
100
+ resetZoomTransform: () => void
101
+ /**
102
+ * Sets d3-zoom's own (cumulative) scale, e.g. when restoring a saved zoom state. Sets it
103
+ * directly (where d3-zoom keeps it), without dispatching a "zoom" event.
104
+ * @param k The scale
105
+ */
106
+ setZoomScale: (k: number) => void
107
+ }
108
+
109
+ /**
110
+ * How far a wheel event scrolls (positive when scrolling down, toward you), scaled as d3-zoom's
111
+ * default `wheelDelta` scales it (which negates it, so that scrolling up raises the scale)
112
+ * @param event The wheel event
113
+ * @return The scroll amount, in d3-zoom's units
114
+ */
115
+ function wheelDeltaOf(event: WheelEvent): number {
116
+ return event.deltaY * (event.deltaMode === 1 ? 0.05 : event.deltaMode ? 1 : 0.002) * (event.ctrlKey ? 10 : 1)
117
+ }
118
+
119
+ /**
120
+ * Sets up panning (dragging) and zooming (the mouse wheel) on a plot's canvas, with d3's drag and
121
+ * zoom behaviors, and detaches them when the plot unmounts (or the canvas, or the settings they
122
+ * depend on, change).
123
+ *
124
+ * - Zooming only responds to wheel events (and, when required, only with the shift or ctrl key
125
+ * down): d3-zoom also handles mouse drags on its own, which would otherwise fire zoom events for
126
+ * the same gesture the dedicated drag behavior pans with.
127
+ * - d3-zoom's scale is cumulative; each zoom step is also handed to the plot as an incremental
128
+ * factor (relative to the previous step), which is reset whenever d3-zoom's transform is.
129
+ * - The handlers are always the plot's latest ones, so the behaviors needn't be re-attached when
130
+ * the handlers change.
131
+ * @param canvasContext The plot's canvas context (`null` until the canvas exists)
132
+ * @param options Whether panning and zooming are enabled, their extents, and the handlers
133
+ * @return The controls for d3-zoom's own transform (reset it, or set its scale)
134
+ */
135
+ export function useCanvasZoomPan(canvasContext: CanvasContext | null, options: CanvasZoomPanOptions): CanvasZoomPanControls {
136
+ const {
137
+ panEnabled,
138
+ zoomEnabled,
139
+ keyModifiersRequired,
140
+ scaleExtent: [minScale, maxScale],
141
+ invertWheel = false,
142
+ translateExtent: [[left, top], [right, bottom]],
143
+ onZoomReset,
144
+ } = options
145
+
146
+ // the latest handlers (the behaviors call these, so they needn't be re-attached when they change)
147
+ const handlersRef = useRef(options)
148
+ useEffect(() => {
149
+ handlersRef.current = options
150
+ })
151
+
152
+ // d3-zoom's cumulative scale as of the previous zoom step, to turn its next one into an
153
+ // incremental factor
154
+ const lastKRef = useRef<number>(1)
155
+ // the attached zoom behavior (undefined while zooming isn't set up)
156
+ const zoomRef = useRef<d3.ZoomBehavior<HTMLCanvasElement, unknown>>(undefined)
157
+
158
+ const resetZoomTransform = useCallback(
159
+ (): void => {
160
+ if (canvasContext !== null && zoomRef.current !== undefined) {
161
+ d3.select<HTMLCanvasElement, unknown>(canvasContext.canvas).call(zoomRef.current.transform, d3.zoomIdentity)
162
+ }
163
+ lastKRef.current = 1
164
+ },
165
+ [canvasContext]
166
+ )
167
+
168
+ const setZoomScale = useCallback(
169
+ (k: number): void => {
170
+ if (canvasContext !== null) {
171
+ // (d3-zoom keeps an element's transform in its `__zoom` property)
172
+ d3.select(canvasContext.canvas).property("__zoom", d3.zoomIdentity.scale(k))
173
+ }
174
+ lastKRef.current = k
175
+ },
176
+ [canvasContext]
177
+ )
178
+
179
+ useEffect(
180
+ () => {
181
+ if (canvasContext === null) return
182
+ const canvasSelection = d3.select<HTMLCanvasElement, unknown>(canvasContext.canvas)
183
+
184
+ if (panEnabled) {
185
+ const drag = d3.drag<HTMLCanvasElement, unknown>()
186
+ .on("start", () => {
187
+ canvasSelection.style("cursor", "move")
188
+ handlersRef.current.onPanStart?.()
189
+ })
190
+ .on("drag", event => handlersRef.current.onPan(event.dx, event.dy))
191
+ .on("end", () => {
192
+ canvasSelection.style("cursor", "auto")
193
+ handlersRef.current.onPanEnd?.()
194
+ })
195
+ canvasSelection.call(drag)
196
+ }
197
+
198
+ if (zoomEnabled) {
199
+ const zoom = d3.zoom<HTMLCanvasElement, unknown>()
200
+ // wheel events only -- see the doc comment above
201
+ .filter(event => event.type === 'wheel' && (!keyModifiersRequired || event.shiftKey || event.ctrlKey))
202
+ // (the same gesture zooms every plot the same way -- see `invertWheel`)
203
+ .wheelDelta(event => (invertWheel ? 1 : -1) * wheelDeltaOf(event))
204
+ .scaleExtent([minScale, maxScale])
205
+ .translateExtent([[left, top], [right, bottom]])
206
+ .on("zoom", (event: D3ZoomEvent<HTMLCanvasElement, unknown>) => {
207
+ // a `null` source event means a programmatic change to the transform (e.g. a
208
+ // reset), not a user's gesture: there's nothing for the plot to do
209
+ if (event.sourceEvent === null) return
210
+ const k = event.transform.k
211
+ const factor = k / lastKRef.current
212
+ lastKRef.current = k
213
+ const {offsetX, offsetY} = event.sourceEvent as MouseEvent
214
+ handlersRef.current.onZoom({factor, k, x: offsetX, y: offsetY})
215
+ })
216
+ canvasSelection.call(zoom)
217
+ zoomRef.current = zoom
218
+
219
+ onZoomReset?.(() => {
220
+ resetZoomTransform()
221
+ handlersRef.current.resetView?.()
222
+ })
223
+ }
224
+
225
+ return () => {
226
+ if (panEnabled) canvasSelection.on(".drag", null)
227
+ if (zoomEnabled) {
228
+ canvasSelection.on(".zoom", null)
229
+ zoomRef.current = undefined
230
+ }
231
+ }
232
+ },
233
+ [
234
+ canvasContext, panEnabled, zoomEnabled, keyModifiersRequired, invertWheel,
235
+ minScale, maxScale, left, top, right, bottom, onZoomReset, resetZoomTransform
236
+ ]
237
+ )
238
+
239
+ return {resetZoomTransform, setZoomScale}
240
+ }