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
@@ -1,13 +1,13 @@
1
- import {SvgSelection, TrackerSelection} from "../d3types";
2
- import * as d3 from "d3";
3
- import {Selection} from "d3";
4
- import {Datum} from "../series/timeSeries";
5
- import {containerDimensionsFrom, Dimensions, Margin, plotDimensionsFrom} from "../styling/margins";
6
- import {BoundingBox, mouseInPlotAreaFor, textDimensions} from "../utils";
7
- import {AxisLocation, ContinuousNumericAxis} from "../axes/axes";
8
- import {TrackerAxisInfo, TrackerAxisUpdate, TrackerLabelLocation} from "./Tracker";
9
- import React from "react";
1
+ import type {CanvasContext, DrawHandle} from "../d3types";
2
+ import {containerDimensionsFrom, type Dimensions, type Margin} from "../styling/margins";
3
+ import {fontStringFor, mouseInPlotAreaFor, textDimensions} from "../utils";
4
+ import {canvasLocalPoint} from "../plots/hitTesting";
5
+ import {AxisLocation, type ContinuousNumericAxis} from "../axes/axes";
6
+ import {type TrackerAxisInfo, type TrackerAxisUpdate} from "./Tracker";
10
7
 
8
+ /**
9
+ * The font of the tracker's labels
10
+ */
11
11
  export interface TrackerLabelFont {
12
12
  size: number
13
13
  color: string
@@ -15,6 +15,9 @@ export interface TrackerLabelFont {
15
15
  weight: number
16
16
  }
17
17
 
18
+ /**
19
+ * The default font of the tracker's labels
20
+ */
18
21
  export const defaultTrackerLabelFont: TrackerLabelFont = {
19
22
  size: 12,
20
23
  color: '#d2933f',
@@ -22,81 +25,69 @@ export const defaultTrackerLabelFont: TrackerLabelFont = {
22
25
  family: 'sans-serif'
23
26
  }
24
27
 
28
+ /**
29
+ * The style of the tracker's line (and whether it's shown)
30
+ */
25
31
  export interface TrackerStyle {
26
32
  visible: boolean;
27
33
  color: string,
28
34
  lineWidth: number,
29
35
  }
30
36
 
37
+ /**
38
+ * The default tracker style (hidden)
39
+ */
31
40
  export const defaultTrackerStyle: TrackerStyle = {
32
41
  visible: false,
33
42
  color: '#d2933f',
34
43
  lineWidth: 1,
35
44
  }
36
45
 
37
- // create namespaced "mousemoved" event names to distinguish between vertical and horizontal trackers
38
- const MOUSE_MOVED_EVENT_VERTICAL_AXIS = "mousemove.vertical"
39
- const MOUSE_MOVED_EVENT_HORIZONTAL_AXIS = "mousemove.horizontal"
40
-
41
46
  const TRACKER_ID = "stream-chart-tracker"
42
47
 
43
48
  /**
44
- * SVG ID for the vertical tracker line
45
- * @param chartId The ID of the chart
46
- * @return SVG ID for the vertical tracker line
47
- */
48
- function verticalTrackerLineId(chartId: number): string {
49
- return `${TRACKER_ID}-line-vertical-${chartId}`
50
- }
51
-
52
- /**
53
- * SVG ID for the horizontal tracker line
54
- * @param chartId The ID of the chart
55
- * @return SVG ID for the vertical tracker line
49
+ * The location of the tracker label
50
+ * Note: replaces enums to support `erasableSyntaxOnly`
51
+ * TS1294: This syntax is not allowed when 'erasableSyntaxOnly' is enabled.
56
52
  */
57
- function horizontalTrackerLineId(chartId: number): string {
58
- return `${TRACKER_ID}-line-horizontal-${chartId}`
59
- }
53
+ export const TrackerLabelLocation = {
54
+ Nowhere: "Nowhere",
55
+ ByAxis: "ByAxis",
56
+ } as const
57
+ export type TrackerLabelLocation = (typeof TrackerLabelLocation)[keyof typeof TrackerLabelLocation]
60
58
 
61
59
  /**
62
- * SVG ID for the tracker label
63
- * @param chartId The ID of the chart
64
- * @param axisLocation The location of the axis for which the tracker label is to be shown
65
- * @return SVG ID for the vertical tracker line
60
+ * A small, fixed corner radius (px) used for the tracker label's background, matching the old
61
+ * SVG version's hard-coded `rx: '5px'`.
66
62
  */
67
- function trackerLabelId(chartId: number, axisLocation: AxisLocation): string {
68
- switch (axisLocation) {
69
- case AxisLocation.Bottom:
70
- case AxisLocation.Top:
71
- return `${TRACKER_ID}-label-vertical-${chartId}-${axisLocation}`
72
- case AxisLocation.Left:
73
- case AxisLocation.Right:
74
- return `${TRACKER_ID}-label-horizontal-${chartId}-${axisLocation}`
75
- }
76
- }
63
+ const LABEL_BACKGROUND_RADIUS = 5
77
64
 
78
65
  /**
79
- * Creates or returns the existing SVG elements for displaying a tracker line that is either
80
- * vertical (for x-axes) or horizontal (for y-axes).
66
+ * Registers a tracker (a line that follows the mouse, with optional per-axis labels) with the
67
+ * canvas context. Replaces the old `trackerControlInstance`, which created SVG `<line>`/`<text>`/
68
+ * `<rect>` elements and updated them via a namespaced `mousemove` handler on the `<svg>`. The
69
+ * canvas version instead registers a draw function that reads the mouse's last-known position
70
+ * (tracked via its own `mousemove` listener on the canvas) and paints the tracker fresh every
71
+ * redraw.
72
+ * @param cc The canvas context to register the tracker's draw function with
81
73
  * @param chartId The ID of the chart
82
- * @param container The SVG container
83
- * @param svg The SVG selection
84
74
  * @param plotDimensions The dimensions of the plot
85
75
  * @param margin The margins around the plot
86
76
  * @param style The tracker style
87
77
  * @param labelFont The font used for the axis labels
88
- * @param label A function that returns the tracker label string for a given x-value
89
- * @param labelStyle The location style for the tracker (i.e. on the axes, next to the mouse, none shown)
78
+ * @param label A map associating each axis with the function that formats the tracker's label for that axis' value
79
+ * @param labelStyle Where the tracker's labels are shown (by the axes, or nowhere)
90
80
  * @param onTrackerUpdate A callback function that accepts the current tracker's axis information
91
81
  * @param [axisLocation = AxisLocation.Bottom] The optional location of the axis for which the tracker is to
92
82
  * be shown. Default is bottom.
93
83
  * @param backgroundColor The background color of the tracker label
94
- * @return The tracker selection
84
+ * @return A cleanup function that unregisters the tracker's draw function and removes its
85
+ * `mousemove` listener. Call this when the tracker becomes invisible or unmounts (replaces the
86
+ * old `removeTrackerControl`).
95
87
  */
96
88
  export function trackerControlInstance(
89
+ cc: CanvasContext,
97
90
  chartId: number,
98
- container: SVGSVGElement,
99
- svg: SvgSelection,
100
91
  plotDimensions: Dimensions,
101
92
  margin: Margin,
102
93
  style: TrackerStyle,
@@ -106,37 +97,38 @@ export function trackerControlInstance(
106
97
  onTrackerUpdate: (update: TrackerAxisUpdate) => void,
107
98
  axisLocation: AxisLocation = AxisLocation.Bottom,
108
99
  backgroundColor: string
109
- ): TrackerSelection {
100
+ ): () => void {
110
101
  switch (axisLocation) {
111
102
  case AxisLocation.Bottom:
112
103
  case AxisLocation.Top:
113
- return verticalTrackerControlInstance(chartId, container, svg, plotDimensions, margin, style, labelFont, label, labelStyle, onTrackerUpdate, backgroundColor)
104
+ return verticalTrackerControlInstance(cc, chartId, plotDimensions, margin, style, labelFont, label, labelStyle, onTrackerUpdate, backgroundColor)
114
105
  case AxisLocation.Left:
115
106
  case AxisLocation.Right:
116
107
  default:
117
- return horizontalTrackerControlInstance(chartId, container, svg, plotDimensions, margin, style, labelFont, label, labelStyle, onTrackerUpdate, backgroundColor)
108
+ return horizontalTrackerControlInstance(cc, chartId, plotDimensions, margin, style, labelFont, label, labelStyle, onTrackerUpdate, backgroundColor)
118
109
  }
119
110
  }
120
111
 
121
112
  /**
122
- * Creates or returns the existing SVG elements for displaying a vertical tracker line
113
+ * Registers a vertical tracker line (for x-axes) with the canvas context: the line follows the
114
+ * mouse across the plot area, with a label by each x-axis showing that axis' value at the mouse
115
+ * (see {@link trackerControlInstance}).
116
+ * @param cc The canvas context to register the tracker's draw function with
123
117
  * @param chartId The ID of the chart
124
- * @param container The SVG container
125
- * @param svg The SVG selection
126
118
  * @param plotDimensions The dimensions of the plot
127
119
  * @param margin The margins around the plot
128
120
  * @param style The tracker style
129
121
  * @param labelFont The font used for the axis labels
130
- * @param label A function that returns the tracker label string for a given x-value
131
- * @param labelStyle The location style for the tracker (i.e. on the axes, next to the mouse, none shown)
122
+ * @param label A map associating each axis with the function that formats the tracker's label for that axis' value
123
+ * @param labelStyle Where the tracker's labels are shown (by the axes, or nowhere)
132
124
  * @param onTrackerUpdate A callback function that accepts the current tracker's axis information
133
125
  * @param backgroundColor The background color of the tracker label
134
- * @return The tracker selection
126
+ * @return A cleanup function that unregisters the tracker's draw function and removes its mouse listeners
135
127
  */
128
+
136
129
  function verticalTrackerControlInstance(
130
+ cc: CanvasContext,
137
131
  chartId: number,
138
- container: SVGSVGElement,
139
- svg: SvgSelection,
140
132
  plotDimensions: Dimensions,
141
133
  margin: Margin,
142
134
  style: TrackerStyle,
@@ -145,74 +137,124 @@ function verticalTrackerControlInstance(
145
137
  labelStyle: TrackerLabelLocation,
146
138
  onTrackerUpdate: (update: TrackerAxisUpdate) => void,
147
139
  backgroundColor: string
148
- ): TrackerSelection {
149
- const trackerLine = svg
150
- .append<SVGLineElement>('line')
151
- .attr('id', verticalTrackerLineId(chartId))
152
- .attr('class', 'tracker')
153
- .attr('y1', margin.top)
154
- .attr('y2', plotDimensions.height + margin.top)
155
- .attr('stroke', style.color)
156
- .attr('stroke-width', style.lineWidth)
157
- .attr('opacity', 0) as Selection<SVGLineElement, Datum, null, undefined>
158
-
159
- if (labelStyle === TrackerLabelLocation.ByAxis) {
160
- label.forEach((_, axis) => {
161
- // create the text element holding the tracker time
162
- const labelY = axis.location === AxisLocation.Top ?
163
- Math.max(0, margin.top - 20) :
164
- Math.max(0, plotDimensions.height + margin.top - 3)
165
-
166
- svg
167
- .append<SVGRectElement>('rect')
168
- .attr('id', `${trackerLabelId(chartId, axis.location)}-background`)
169
- .attr('y', labelY)
170
- .attr('fill', backgroundColor)
171
- .attr('opacity', 0)
172
-
173
- svg
174
- .append<SVGTextElement>('text')
175
- .attr('id', trackerLabelId(chartId, axis.location))
176
- .attr('y', labelY)
177
- .attr('fill', labelFont.color)
178
- .attr('font-family', labelFont.family)
179
- .attr('font-size', labelFont.size)
180
- .attr('font-weight', labelFont.weight)
181
- .attr('opacity', 0)
182
- .text(() => '')
140
+ ): () => void {
141
+ const drawHandle: DrawHandle = `${TRACKER_ID}-vertical-${chartId}`
142
+
143
+ // the mouse's last-known position, in canvas coordinates; null when the mouse is outside the canvas
144
+ let mouseX: number | null = null
145
+ let mouseY: number | null = null
146
+
147
+ const draw = (context: CanvasContext) => {
148
+ if (mouseX === null || mouseY === null) return
149
+ const {context2D} = context
150
+ const dimensions = containerDimensionsFrom(plotDimensions, margin)
151
+ const inPlot = mouseInPlotAreaFor(mouseX, mouseY, margin, dimensions)
152
+
153
+ context2D.save()
154
+ context2D.globalAlpha = inPlot ? 1 : 0
155
+ context2D.strokeStyle = style.color
156
+ context2D.lineWidth = style.lineWidth
157
+ context2D.beginPath()
158
+ context2D.moveTo(mouseX, margin.top)
159
+ context2D.lineTo(mouseX, plotDimensions.height + margin.top)
160
+ context2D.stroke()
161
+ context2D.restore()
162
+
163
+ const updateInfo: Array<[string, TrackerAxisInfo]> = []
164
+
165
+ label.forEach((trackerLabel, axis) => {
166
+ if (labelStyle === TrackerLabelLocation.ByAxis) {
167
+ const value = axis.scale.invert(mouseX! - margin.left)
168
+ const text = trackerLabel(value)
169
+
170
+ context2D.save()
171
+ context2D.font = fontStringFor(labelFont.size, labelFont.family, labelFont.weight)
172
+ const {width: labelWidth, height: labelHeight} = textDimensions(context2D, text)
173
+
174
+ const space = 10
175
+ const labelY = axis.location === AxisLocation.Top ?
176
+ margin.top + labelFont.size + space :
177
+ margin.top + plotDimensions.height - space
178
+ const xOffset = 10
179
+ const labelX = Math.min(dimensions.width - margin.right - labelWidth, mouseX! + xOffset)
180
+
181
+ // label background
182
+ const padding = 3
183
+ context2D.globalAlpha = inPlot ? 0.8 : 0
184
+ context2D.fillStyle = backgroundColor
185
+ context2D.beginPath()
186
+ context2D.roundRect(
187
+ labelX - padding,
188
+ labelY - labelHeight - padding,
189
+ labelWidth + 2 * padding,
190
+ labelHeight + 2 * padding,
191
+ LABEL_BACKGROUND_RADIUS
192
+ )
193
+ context2D.fill()
194
+
195
+ // label text
196
+ context2D.globalAlpha = inPlot ? 1 : 0
197
+ context2D.fillStyle = labelFont.color
198
+ context2D.textAlign = 'left'
199
+ context2D.textBaseline = 'alphabetic'
200
+ context2D.fillText(text, labelX, labelY)
201
+ context2D.restore()
202
+ }
203
+
204
+ updateInfo.push([axis.axisId, {
205
+ x: axis.scale.invert(mouseX! - margin.left),
206
+ axisLocation: axis.location
207
+ }])
183
208
  })
209
+
210
+ if (inPlot) {
211
+ onTrackerUpdate(new Map<string, TrackerAxisInfo>(updateInfo))
212
+ }
184
213
  }
185
214
 
186
- const containerDimensions = containerDimensionsFrom(plotDimensions, margin)
187
- svg.on(
188
- MOUSE_MOVED_EVENT_VERTICAL_AXIS,
189
- event => handleShowVerticalTracker(
190
- chartId, container, event, margin, containerDimensions, style, labelFont, label, labelStyle, onTrackerUpdate, backgroundColor
191
- )
192
- )
215
+ cc.register(drawHandle, draw, 20)
193
216
 
194
- return trackerLine
217
+ const handleMouseMove = (event: MouseEvent) => {
218
+ const [x, y] = canvasLocalPoint(event, cc.canvas)
219
+ mouseX = x
220
+ mouseY = y
221
+ cc.requestRedraw()
222
+ }
223
+ const handleMouseLeave = () => {
224
+ mouseX = null
225
+ mouseY = null
226
+ cc.requestRedraw()
227
+ }
228
+ cc.canvas.addEventListener('mousemove', handleMouseMove)
229
+ cc.canvas.addEventListener('mouseleave', handleMouseLeave)
230
+
231
+ return () => {
232
+ cc.unregister(drawHandle)
233
+ cc.canvas.removeEventListener('mousemove', handleMouseMove)
234
+ cc.canvas.removeEventListener('mouseleave', handleMouseLeave)
235
+ }
195
236
  }
196
237
 
197
238
  /**
198
- * Creates or returns the existing SVG elements for displaying a horizontal tracker line
239
+ * Registers a horizontal tracker line (for y-axes) with the canvas context: the line follows the
240
+ * mouse up and down the plot area, with a label by each y-axis showing that axis' value at the
241
+ * mouse (see {@link trackerControlInstance}).
242
+ * @param cc The canvas context to register the tracker's draw function with
199
243
  * @param chartId The ID of the chart
200
- * @param container The SVG container
201
- * @param svg The SVG selection
202
244
  * @param plotDimensions The dimensions of the plot
203
245
  * @param margin The margins around the plot
204
246
  * @param style The tracker style
205
247
  * @param labelFont The font used for the axis labels
206
- * @param label A function that returns the tracker label string for a given x-value
207
- * @param labelStyle The location style for the tracker (i.e. on the axes, next to the mouse, none shown)
248
+ * @param label A map associating each axis with the function that formats the tracker's label for that axis' value
249
+ * @param labelStyle Where the tracker's labels are shown (by the axes, or nowhere)
208
250
  * @param onTrackerUpdate A callback function that accepts the current tracker's axis information
209
251
  * @param backgroundColor The background color of the tracker label
210
- * @return The tracker selection
252
+ * @return A cleanup function that unregisters the tracker's draw function and removes its mouse listeners
211
253
  */
254
+
212
255
  function horizontalTrackerControlInstance(
256
+ cc: CanvasContext,
213
257
  chartId: number,
214
- container: SVGSVGElement,
215
- svg: SvgSelection,
216
258
  plotDimensions: Dimensions,
217
259
  margin: Margin,
218
260
  style: TrackerStyle,
@@ -221,274 +263,119 @@ function horizontalTrackerControlInstance(
221
263
  labelStyle: TrackerLabelLocation,
222
264
  onTrackerUpdate: (update: TrackerAxisUpdate) => void,
223
265
  backgroundColor: string
224
- ): TrackerSelection {
225
- const trackerLine = svg
226
- .append<SVGLineElement>('line')
227
- .attr('id', horizontalTrackerLineId(chartId))
228
- .attr('class', 'tracker')
229
- .attr('x1', margin.left)
230
- .attr('x2', plotDimensions.width + margin.left)
231
- .attr('stroke', style.color)
232
- .attr('stroke-width', style.lineWidth)
233
- .attr('opacity', 0) as Selection<SVGLineElement, Datum, null, undefined>
234
-
235
- label.forEach((_, axis) => {
236
- // create the text element holding the tracker time
237
- const labelY = axis.location === AxisLocation.Left ?
238
- Math.max(0, margin.left - 20) :
239
- Math.max(0, plotDimensions.width + margin.left - 3)
240
-
241
- svg
242
- .append<SVGRectElement>('rect')
243
- .attr('id', `${trackerLabelId(chartId, axis.location)}-background`)
244
- .attr('y', labelY)
245
- .attr('fill', backgroundColor)
246
- .attr('opacity', 0)
247
-
248
- svg
249
- .append<SVGTextElement>('text')
250
- .attr('id', trackerLabelId(chartId, axis.location))
251
- .attr('y', labelY)
252
- .attr('fill', labelFont.color)
253
- .attr('font-family', labelFont.family)
254
- .attr('font-size', labelFont.size)
255
- .attr('font-weight', labelFont.weight)
256
- .attr('opacity', 0)
257
- .text(() => '')
258
- })
259
-
260
- const containerDimensions = containerDimensionsFrom(plotDimensions, margin)
261
- svg.on(
262
- MOUSE_MOVED_EVENT_HORIZONTAL_AXIS,
263
- event => handleShowHorizontalTracker(
264
- chartId, container, event, margin, containerDimensions, style, labelFont, label, labelStyle, onTrackerUpdate, backgroundColor
265
- )
266
- )
267
-
268
- return trackerLine
269
- }
270
-
271
- /**
272
- * Removes the tracker control from the chart
273
- * @param svg The svg selection holding the tracker control
274
- * @param axisLocation The location of the axis for which the tracker is to be removed.
275
- */
276
- export function removeTrackerControl(svg: SvgSelection, axisLocation: AxisLocation) {
277
- switch (axisLocation) {
278
- case AxisLocation.Bottom:
279
- case AxisLocation.Top:
280
- svg.on(MOUSE_MOVED_EVENT_VERTICAL_AXIS, () => null)
281
- break
282
- case AxisLocation.Left:
283
- case AxisLocation.Right:
284
- default:
285
- svg.on(MOUSE_MOVED_EVENT_HORIZONTAL_AXIS, () => null)
266
+ ): () => void {
267
+ const drawHandle: DrawHandle = `${TRACKER_ID}-horizontal-${chartId}`
268
+
269
+ let mouseX: number | null = null
270
+ let mouseY: number | null = null
271
+
272
+ const draw = (context: CanvasContext) => {
273
+ if (mouseX === null || mouseY === null) return
274
+ const {context2D} = context
275
+ const dimensions = containerDimensionsFrom(plotDimensions, margin)
276
+ const inPlot = mouseInPlotAreaFor(mouseX, mouseY, margin, dimensions)
277
+
278
+ context2D.save()
279
+ context2D.globalAlpha = inPlot ? 1 : 0
280
+ context2D.strokeStyle = style.color
281
+ context2D.lineWidth = style.lineWidth
282
+ context2D.beginPath()
283
+ context2D.moveTo(margin.left, mouseY)
284
+ context2D.lineTo(plotDimensions.width + margin.left, mouseY)
285
+ context2D.stroke()
286
+ context2D.restore()
287
+
288
+ type AxisAndLabelInfo = {
289
+ axis: ContinuousNumericAxis
290
+ text: string
291
+ labelWidth: number
292
+ labelHeight: number
293
+ }
294
+
295
+ // need to calculate each axis-label position separately, because at the plot edges, the axis-label
296
+ // positions depend on each other. For example, at the left edge, the left-axis label needs to move
297
+ // to the right of the mouse to remain in the plot area. Therefore, the right-axis label needs
298
+ // to move as well but needs to know the width of the left-axis label to do so.
299
+ //
300
+ // measure all the labels first, then position them (mirrors the old two-phase SVG approach,
301
+ // where text had to be set before `getBBox()` would return a meaningful size)
302
+ context2D.font = fontStringFor(labelFont.size, labelFont.family, labelFont.weight)
303
+ const boundingBoxes: Map<AxisLocation, AxisAndLabelInfo> = new Map(Array.from(label.entries())
304
+ .map(([axis, trackerLabel]) => {
305
+ const text = trackerLabel(axis.scale.invert(mouseY! - margin.top))
306
+ const {width: labelWidth, height: labelHeight} = textDimensions(context2D, text)
307
+ return [axis.location, {axis, text, labelWidth, labelHeight}]
308
+ }))
309
+
310
+ // place the labels so that they remain in the plot area
311
+ const space = 10
312
+ const rightLabelWidth = (boundingBoxes.get(AxisLocation.Right)?.labelWidth || -space) + space
313
+
314
+ const updateInfo: Array<[string, TrackerAxisInfo]> = Array.from(boundingBoxes.entries())
315
+ .map(([location, {axis, text, labelWidth, labelHeight}]) => {
316
+ if (labelStyle === TrackerLabelLocation.ByAxis) {
317
+ const labelX = location === AxisLocation.Left ?
318
+ margin.left + space :
319
+ margin.left + plotDimensions.width - rightLabelWidth - space
320
+
321
+ const yOffset = space
322
+ const labelY = Math.max(mouseY! - yOffset, margin.top + yOffset + labelHeight)
323
+
324
+ // label background
325
+ const padding = 5
326
+ context2D.save()
327
+ context2D.globalAlpha = inPlot ? 0.8 : 0
328
+ context2D.fillStyle = backgroundColor
329
+ context2D.beginPath()
330
+ context2D.roundRect(
331
+ labelX - padding,
332
+ labelY - labelHeight - 1,
333
+ labelWidth + 2 * padding,
334
+ labelHeight + 2 * padding,
335
+ LABEL_BACKGROUND_RADIUS
336
+ )
337
+ context2D.fill()
338
+
339
+ // label text
340
+ context2D.globalAlpha = inPlot ? 1 : 0
341
+ context2D.fillStyle = labelFont.color
342
+ context2D.textAlign = 'left'
343
+ context2D.textBaseline = 'alphabetic'
344
+ context2D.fillText(text, labelX, labelY)
345
+ context2D.restore()
346
+ }
347
+
348
+ const trackerInfo: TrackerAxisInfo = {
349
+ x: axis.scale.invert(mouseY! - margin.top + margin.bottom),
350
+ axisLocation: axis.location
351
+ }
352
+ return [axis.axisId, trackerInfo]
353
+ })
354
+
355
+ if (inPlot) {
356
+ onTrackerUpdate(new Map<string, TrackerAxisInfo>(updateInfo))
357
+ }
286
358
  }
287
- }
288
-
289
- /**
290
- * Callback when the vertical mouse tracker is to be shown
291
- * @param chartId The ID number of the chart
292
- * @param container The svg container
293
- * @param event The mouse-over series event
294
- * @param margin The plot margins
295
- * @param dimensions The container dimensions (i.e., the plot dimensions plus its margins)
296
- * @param trackerStyle The style settings for the tracker line
297
- * @param labelFont The style settings for the tracker font
298
- * @param label A function that returns the tracker label string
299
- * @param labelStyle Where to display the tracker labels (i.e., with-mouse, with-axes, no-where)
300
- * @param onTrackerUpdate A callback function that accepts the current tracker's axis information
301
- * @param backgroundColor The background color of the tracker label
302
- */
303
- function handleShowVerticalTracker(
304
- chartId: number,
305
- container: SVGSVGElement,
306
- event: React.MouseEvent<SVGSVGElement>,
307
- margin: Margin,
308
- dimensions: Dimensions,
309
- trackerStyle: TrackerStyle,
310
- labelFont: TrackerLabelFont,
311
- label: Map<ContinuousNumericAxis, (x: number) => string>,
312
- labelStyle: TrackerLabelLocation,
313
- onTrackerUpdate: (update: TrackerAxisUpdate) => void,
314
- backgroundColor: string
315
- ): void {
316
- // determine whether the mouse is in the plot area
317
- const [x, y] = d3.pointer(event, container)
318
- const inPlot = mouseInPlotAreaFor(x, y, margin, dimensions)
319
-
320
- const updateInfo: Array<[string, TrackerAxisInfo]> = Array.from(label.entries())
321
- .map(([axis, trackerLabel]) => {
322
- // when the mouse is in the plot area, then set the opacity of the tracker line and label to 1,
323
- // which means it is fully visible. when the mouse is not in the plot area, set the opacity to 0,
324
- // which means the tracker line and label are invisible.
325
- d3.select<SVGLineElement, Datum>(`#${verticalTrackerLineId(chartId)}`)
326
- .attr('x1', x)
327
- .attr('x2', x)
328
- .attr('stroke', trackerStyle.color)
329
- .attr('stroke-width', trackerStyle.lineWidth)
330
- .attr('opacity', () => inPlot ? 1 : 0)
331
-
332
- // when the label-style is to be with the mouse
333
- if (labelStyle === TrackerLabelLocation.ByAxis) {
334
- const label = d3.select<SVGTextElement, any>(`#${trackerLabelId(chartId, axis.location)}`)
335
- .attr('fill', labelFont.color)
336
- .attr('font-family', labelFont.family)
337
- .attr('font-size', labelFont.size)
338
- .attr('font-weight', labelFont.weight)
339
- .attr('opacity', () => inPlot ? 1 : 0)
340
- .text(() => trackerLabel(axis.scale.invert(x - margin.left)))
341
-
342
359
 
343
- const labelBackground = d3.select<SVGRectElement, any>(`#${trackerLabelId(chartId, axis.location)}-background`)
344
- .attr('fill', backgroundColor)
345
- .attr('opacity', () => inPlot ? 0.8 : 0)
346
- .attr('rx', '5px')
360
+ cc.register(drawHandle, draw, 20)
347
361
 
348
- const space = 10
349
- const {height} = plotDimensionsFrom(dimensions.width, dimensions.height, margin)
350
- const labelY = axis.location === AxisLocation.Top ?
351
- margin.top + labelFont.size + space :
352
- margin.top + height - space
353
- label.attr('y', labelY)
354
-
355
- // adjust the label position when the tracker is at the right-most edges of the plot so that
356
- // the label remains visible (i.e., doesn't get clipped)
357
- const xOffset = TrackerLabelLocation.ByAxis ? 10 : 0
358
- const {width: labelWidth, height: labelHeight} = textDimensions(label)
359
- const labelX = Math.min(dimensions.width - margin.right - labelWidth, x + xOffset)
360
- label.attr('x', labelX)
361
-
362
- // set the background location and width
363
- const padding: number = 3
364
- labelBackground
365
- .attr('x', labelX - padding)
366
- .attr('y', labelY - labelHeight - padding)
367
- .attr('width', labelWidth + 2 * padding)
368
- .attr('height', labelHeight + 2 * padding)
369
- }
370
-
371
- const trackerInfo: TrackerAxisInfo = {
372
- x: axis.scale.invert(x - margin.left),
373
- axisLocation: axis.location
374
- }
375
- return [axis.axisId, trackerInfo]
376
- })
377
-
378
- if (inPlot) {
379
- onTrackerUpdate(new Map<string, TrackerAxisInfo>(updateInfo))
362
+ const handleMouseMove = (event: MouseEvent) => {
363
+ const [x, y] = canvasLocalPoint(event, cc.canvas)
364
+ mouseX = x
365
+ mouseY = y
366
+ cc.requestRedraw()
380
367
  }
381
- }
382
-
383
- /**
384
- * Callback when the horizontal mouse tracker is to be shown
385
- * @param chartId The ID number of the chart
386
- * @param container The svg container
387
- * @param event The mouse-over series event
388
- * @param margin The plot margins
389
- * @param dimensions The container dimensions (i.e., the plot dimensions plus its margins)
390
- * @param trackerStyle The style settings for the tracker line
391
- * @param labelFont The style settings for the tracker font
392
- * @param label A function that returns the tracker label string
393
- * @param labelStyle Where to display the tracker labels (i.e., with-mouse, with-axes, no-where)
394
- * @param onTrackerUpdate A callback function that accepts the current tracker's axis information
395
- * @param backgroundColor The background color of the tracker label
396
- */
397
- function handleShowHorizontalTracker(
398
- chartId: number,
399
- container: SVGSVGElement,
400
- event: React.MouseEvent<SVGSVGElement>,
401
- margin: Margin,
402
- dimensions: Dimensions,
403
- trackerStyle: TrackerStyle,
404
- labelFont: TrackerLabelFont,
405
- label: Map<ContinuousNumericAxis, (x: number) => string>,
406
- labelStyle: TrackerLabelLocation,
407
- onTrackerUpdate: (update: TrackerAxisUpdate) => void,
408
- backgroundColor: string
409
- ): void {
410
- // determine whether the mouse is in the plot area
411
- const [x, y] = d3.pointer(event, container)
412
- const inPlot = mouseInPlotAreaFor(x, y, margin, dimensions)
413
-
414
- type AxisAndLabelInfo = {
415
- axis: ContinuousNumericAxis
416
- labelSelection: d3.Selection<SVGTextElement, any, HTMLElement, any>
417
- labelBoundingBox: BoundingBox,
418
- labelBackground: d3.Selection<SVGRectElement, any, HTMLElement, any>
368
+ const handleMouseLeave = () => {
369
+ mouseX = null
370
+ mouseY = null
371
+ cc.requestRedraw()
419
372
  }
420
- //
421
- // need to calculate each axis-label position separately, because at the plot edges, the axis-label
422
- // positions depend on each other. For example, at the left edge, the left-axis label needs to move
423
- // to the right of the mouse to remain in the plot area. Therefore, the right-axis label needs
424
- // to move as well but needs to know the width of the left-axis label to do so.
425
- //
426
- // add the labels and calculate the bounding boxes
427
- const boundingBoxes: Map<AxisLocation, AxisAndLabelInfo> = new Map(Array.from(label.entries())
428
- .map(([axis, trackerLabel]) => {
429
- // when the mouse is in the plot area, then set the opacity of the tracker line and label to 1,
430
- // which means it is fully visible. when the mouse is not in the plot area, set the opacity to 0,
431
- // which means the tracker line and label are invisible.
432
- d3.select<SVGLineElement, Datum>(`#${horizontalTrackerLineId(chartId)}`)
433
- .attr('y1', y)
434
- .attr('y2', y)
435
- .attr('stroke', trackerStyle.color)
436
- .attr('stroke-width', trackerStyle.lineWidth)
437
- .attr('opacity', () => inPlot ? 1 : 0)
438
-
439
- const label = d3.select<SVGTextElement, any>(`#${trackerLabelId(chartId, axis.location)}`)
440
- .attr('fill', labelFont.color)
441
- .attr('font-family', labelFont.family)
442
- .attr('font-size', labelFont.size)
443
- .attr('font-weight', labelFont.weight)
444
- .attr('opacity', () => inPlot ? 1 : 0)
445
- .text(() => trackerLabel(axis.scale.invert(y - margin.top)))
446
-
447
- const labelBackground = d3.select<SVGRectElement, any>(`#${trackerLabelId(chartId, axis.location)}-background`)
448
- .attr('fill', backgroundColor)
449
- .attr('opacity', () => inPlot && labelStyle !== TrackerLabelLocation.Nowhere ? 0.8 : 0)
450
- .attr('rx', '5px')
451
-
452
- return [axis.location, {axis, labelSelection: label, labelBoundingBox: textDimensions(label), labelBackground}]
453
- }))
454
-
455
- // place the labels so that they remain in the plot area
456
- const space = 10
457
- const rightLabelWidth = (boundingBoxes.get(AxisLocation.Right)?.labelBoundingBox.width || -space) + space
458
-
459
- const updateInfo: Array<[string, TrackerAxisInfo]> = Array.from(boundingBoxes.entries())
460
- .map(([location, {axis, labelSelection, labelBoundingBox, labelBackground}]) => {
461
- if (labelStyle === TrackerLabelLocation.ByAxis) {
462
- const {width} = plotDimensionsFrom(dimensions.width, dimensions.height, margin)
463
- const labelX = location === AxisLocation.Left ?
464
- margin.left + space :
465
- margin.left + width - rightLabelWidth - space
466
- labelSelection.attr('x', labelX)
467
-
468
- // adjust the label position when the tracker is at the right-most edges of the plot so that
469
- // the label remains visible (i.e., doesn't get clipped)
470
- const yOffset: number = labelStyle === TrackerLabelLocation.ByAxis ? space : 0
471
- const labelY = Math.max(y - yOffset, margin.top + yOffset + labelBoundingBox.height)
472
- labelSelection.attr('y', labelY)
473
-
474
- // set the background location and width
475
- const padding: number = 5
476
- labelBackground
477
- .attr('x', labelX - padding)
478
- .attr('y', labelY - labelBoundingBox.height - 1)
479
- .attr('width', labelBoundingBox.width + 2 * padding)
480
- .attr('height', labelBoundingBox.height + 2 * padding)
481
- }
373
+ cc.canvas.addEventListener('mousemove', handleMouseMove)
374
+ cc.canvas.addEventListener('mouseleave', handleMouseLeave)
482
375
 
483
- const trackerInfo: TrackerAxisInfo = {
484
- x: axis.scale.invert(y - margin.top + margin.bottom),
485
- axisLocation: axis.location
486
- }
487
- return [axis.axisId, trackerInfo]
488
- })
489
-
490
- if (inPlot) {
491
- onTrackerUpdate(new Map<string, TrackerAxisInfo>(updateInfo))
376
+ return () => {
377
+ cc.unregister(drawHandle)
378
+ cc.canvas.removeEventListener('mousemove', handleMouseMove)
379
+ cc.canvas.removeEventListener('mouseleave', handleMouseLeave)
492
380
  }
493
381
  }
494
-