stream-charts 1.0.1 → 1.1.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 (271) hide show
  1. package/README.md +756 -343
  2. package/changes.md +7 -0
  3. package/dist/src/app/charts/Chart.d.ts +116 -87
  4. package/dist/src/app/charts/Chart.js +96 -101
  5. package/dist/src/app/charts/Chart.js.map +1 -1
  6. package/dist/src/app/charts/axes/AxesState.d.ts +64 -0
  7. package/dist/src/app/charts/axes/AxesState.js +97 -0
  8. package/dist/src/app/charts/axes/AxesState.js.map +1 -0
  9. package/dist/src/app/charts/axes/AxesState.test.js +30 -0
  10. package/dist/src/app/charts/axes/AxesState.test.js.map +1 -0
  11. package/dist/src/app/charts/axes/AxisInterval.d.ts +92 -0
  12. package/dist/src/app/charts/axes/AxisInterval.js +126 -0
  13. package/dist/src/app/charts/axes/AxisInterval.js.map +1 -0
  14. package/dist/src/app/charts/axes/AxisInterval.test.js +120 -0
  15. package/dist/src/app/charts/axes/AxisInterval.test.js.map +1 -0
  16. package/dist/src/app/charts/axes/BaseAxisRange.d.ts +83 -0
  17. package/dist/src/app/charts/axes/BaseAxisRange.js +58 -0
  18. package/dist/src/app/charts/axes/BaseAxisRange.js.map +1 -0
  19. package/dist/src/app/charts/axes/ContinuousAxis.d.ts +22 -0
  20. package/dist/src/app/charts/axes/ContinuousAxis.js +96 -0
  21. package/dist/src/app/charts/axes/ContinuousAxis.js.map +1 -0
  22. package/dist/src/app/charts/axes/ContinuousAxisRange.d.ts +59 -0
  23. package/dist/src/app/charts/axes/ContinuousAxisRange.js +84 -0
  24. package/dist/src/app/charts/axes/ContinuousAxisRange.js.map +1 -0
  25. package/dist/src/app/charts/axes/ContinuousAxisRange.test.js +47 -0
  26. package/dist/src/app/charts/axes/ContinuousAxisRange.test.js.map +1 -0
  27. package/dist/src/app/charts/axes/OrdinalAxis.d.ts +23 -0
  28. package/dist/src/app/charts/axes/OrdinalAxis.js +124 -0
  29. package/dist/src/app/charts/axes/OrdinalAxis.js.map +1 -0
  30. package/dist/src/app/charts/axes/OrdinalAxisRange.d.ts +69 -0
  31. package/dist/src/app/charts/axes/OrdinalAxisRange.js +100 -0
  32. package/dist/src/app/charts/axes/OrdinalAxisRange.js.map +1 -0
  33. package/dist/src/app/charts/axes/OrdinalAxisRange.test.js +48 -0
  34. package/dist/src/app/charts/axes/OrdinalAxisRange.test.js.map +1 -0
  35. package/dist/src/app/charts/axes/axes.d.ts +391 -0
  36. package/dist/src/app/charts/axes/axes.js +1046 -0
  37. package/dist/src/app/charts/axes/axes.js.map +1 -0
  38. package/dist/src/app/charts/d3types.d.ts +10 -10
  39. package/dist/src/app/charts/filters/regexFilter.d.ts +9 -0
  40. package/dist/src/app/charts/filters/regexFilter.js +18 -0
  41. package/dist/src/app/charts/filters/regexFilter.js.map +1 -0
  42. package/dist/src/app/charts/filters/regexFilter.test.d.ts +1 -0
  43. package/dist/src/app/charts/filters/regexFilter.test.js +11 -0
  44. package/dist/src/app/charts/filters/regexFilter.test.js.map +1 -0
  45. package/dist/src/app/charts/hooks/useAxes.d.ts +144 -0
  46. package/dist/src/app/charts/hooks/useAxes.js +187 -0
  47. package/dist/src/app/charts/hooks/useAxes.js.map +1 -0
  48. package/dist/src/app/charts/hooks/useChart.d.ts +30 -201
  49. package/dist/src/app/charts/hooks/useChart.js +33 -134
  50. package/dist/src/app/charts/hooks/useChart.js.map +1 -1
  51. package/dist/src/app/charts/hooks/useDataObservable.d.ts +74 -0
  52. package/dist/src/app/charts/hooks/useDataObservable.js +76 -0
  53. package/dist/src/app/charts/hooks/useDataObservable.js.map +1 -0
  54. package/dist/src/app/charts/hooks/useInitialData.d.ts +38 -0
  55. package/dist/src/app/charts/hooks/useInitialData.js +29 -0
  56. package/dist/src/app/charts/hooks/useInitialData.js.map +1 -0
  57. package/dist/src/app/charts/hooks/useMouse.d.ts +53 -0
  58. package/dist/src/app/charts/hooks/useMouse.js +65 -0
  59. package/dist/src/app/charts/hooks/useMouse.js.map +1 -0
  60. package/dist/src/app/charts/hooks/usePlotDimensions.d.ts +34 -0
  61. package/dist/src/app/charts/hooks/usePlotDimensions.js +73 -0
  62. package/dist/src/app/charts/hooks/usePlotDimensions.js.map +1 -0
  63. package/dist/src/app/charts/hooks/useTooltip.d.ts +64 -0
  64. package/dist/src/app/charts/hooks/useTooltip.js +52 -0
  65. package/dist/src/app/charts/hooks/useTooltip.js.map +1 -0
  66. package/dist/src/app/charts/observables/ChartData.d.ts +23 -0
  67. package/dist/src/app/charts/observables/ChartData.js +20 -0
  68. package/dist/src/app/charts/observables/ChartData.js.map +1 -0
  69. package/dist/src/app/charts/observables/iterates.d.ts +52 -0
  70. package/dist/src/app/charts/observables/iterates.js +121 -0
  71. package/dist/src/app/charts/observables/iterates.js.map +1 -0
  72. package/dist/src/app/charts/observables/iterates.test.d.ts +1 -0
  73. package/dist/src/app/charts/observables/iterates.test.js +180 -0
  74. package/dist/src/app/charts/observables/iterates.test.js.map +1 -0
  75. package/dist/src/app/charts/observables/ordinals.d.ts +75 -0
  76. package/dist/src/app/charts/observables/ordinals.js +141 -0
  77. package/dist/src/app/charts/observables/ordinals.js.map +1 -0
  78. package/dist/src/app/charts/observables/ordinals.test.d.ts +1 -0
  79. package/dist/src/app/charts/observables/ordinals.test.js +102 -0
  80. package/dist/src/app/charts/observables/ordinals.test.js.map +1 -0
  81. package/dist/src/app/charts/plots/BarPlot.d.ts +81 -0
  82. package/dist/src/app/charts/plots/BarPlot.js +557 -0
  83. package/dist/src/app/charts/plots/BarPlot.js.map +1 -0
  84. package/dist/src/app/charts/plots/PoincarePlot.d.ts +78 -0
  85. package/dist/src/app/charts/plots/PoincarePlot.js +504 -0
  86. package/dist/src/app/charts/plots/PoincarePlot.js.map +1 -0
  87. package/dist/src/app/charts/{RasterPlot.d.ts → plots/RasterPlot.d.ts} +1 -1
  88. package/dist/src/app/charts/{RasterPlot.js → plots/RasterPlot.js} +152 -133
  89. package/dist/src/app/charts/plots/RasterPlot.js.map +1 -0
  90. package/dist/src/app/charts/{ScatterPlot.d.ts → plots/ScatterPlot.d.ts} +10 -8
  91. package/dist/src/app/charts/plots/ScatterPlot.js +379 -0
  92. package/dist/src/app/charts/plots/ScatterPlot.js.map +1 -0
  93. package/dist/src/app/charts/{plot.d.ts → plots/plot.d.ts} +12 -14
  94. package/dist/src/app/charts/{plot.js → plots/plot.js} +19 -17
  95. package/dist/src/app/charts/plots/plot.js.map +1 -0
  96. package/dist/src/app/charts/series/baseSeries.d.ts +38 -0
  97. package/dist/src/app/charts/series/baseSeries.js +36 -0
  98. package/dist/src/app/charts/series/baseSeries.js.map +1 -0
  99. package/dist/src/app/charts/series/datumSeries.test.d.ts +1 -0
  100. package/dist/src/app/charts/series/datumSeries.test.js +50 -0
  101. package/dist/src/app/charts/series/datumSeries.test.js.map +1 -0
  102. package/dist/src/app/charts/series/iterateSeries.d.ts +42 -0
  103. package/dist/src/app/charts/series/iterateSeries.js +34 -0
  104. package/dist/src/app/charts/series/iterateSeries.js.map +1 -0
  105. package/dist/src/app/charts/series/ordinalSeries.d.ts +54 -0
  106. package/dist/src/app/charts/series/ordinalSeries.js +98 -0
  107. package/dist/src/app/charts/series/ordinalSeries.js.map +1 -0
  108. package/dist/src/app/charts/series/timeSeries.d.ts +30 -0
  109. package/dist/src/app/charts/series/timeSeries.js +19 -0
  110. package/dist/src/app/charts/series/timeSeries.js.map +1 -0
  111. package/dist/src/app/charts/{chartData.d.ts → series/timeSeriesChartData.d.ts} +11 -6
  112. package/dist/src/app/charts/series/timeSeriesChartData.js +32 -0
  113. package/dist/src/app/charts/series/timeSeriesChartData.js.map +1 -0
  114. package/dist/src/app/charts/styling/barPlotStyle.d.ts +41 -0
  115. package/dist/src/app/charts/styling/barPlotStyle.js +84 -0
  116. package/dist/src/app/charts/styling/barPlotStyle.js.map +1 -0
  117. package/dist/src/app/charts/{margins.d.ts → styling/margins.d.ts} +7 -5
  118. package/dist/src/app/charts/{margins.js → styling/margins.js} +19 -9
  119. package/dist/src/app/charts/styling/margins.js.map +1 -0
  120. package/dist/src/app/charts/styling/margins.test.d.ts +1 -0
  121. package/dist/src/app/charts/styling/margins.test.js +19 -0
  122. package/dist/src/app/charts/styling/margins.test.js.map +1 -0
  123. package/dist/src/app/charts/styling/svgStyle.d.ts +76 -0
  124. package/dist/src/app/charts/styling/svgStyle.js +84 -0
  125. package/dist/src/app/charts/styling/svgStyle.js.map +1 -0
  126. package/dist/src/app/charts/subscriptions/subscription.test.d.ts +1 -0
  127. package/dist/src/app/charts/subscriptions/subscription.test.js +395 -0
  128. package/dist/src/app/charts/subscriptions/subscription.test.js.map +1 -0
  129. package/dist/src/app/charts/subscriptions/subscriptions.d.ts +100 -0
  130. package/dist/src/app/charts/subscriptions/subscriptions.js +449 -0
  131. package/dist/src/app/charts/subscriptions/subscriptions.js.map +1 -0
  132. package/dist/src/app/charts/tooltips/BarPlotTooltipContent.d.ts +90 -0
  133. package/dist/src/app/charts/tooltips/BarPlotTooltipContent.js +302 -0
  134. package/dist/src/app/charts/tooltips/BarPlotTooltipContent.js.map +1 -0
  135. package/dist/src/app/charts/tooltips/PoincarePlotTooltipContent.d.ts +100 -0
  136. package/dist/src/app/charts/tooltips/PoincarePlotTooltipContent.js +190 -0
  137. package/dist/src/app/charts/tooltips/PoincarePlotTooltipContent.js.map +1 -0
  138. package/dist/src/app/charts/{RasterPlotTooltipContent.js → tooltips/RasterPlotTooltipContent.js} +40 -44
  139. package/dist/src/app/charts/tooltips/RasterPlotTooltipContent.js.map +1 -0
  140. package/dist/src/app/charts/tooltips/ScatterPlotTooltipContent.js +154 -0
  141. package/dist/src/app/charts/tooltips/ScatterPlotTooltipContent.js.map +1 -0
  142. package/dist/src/app/charts/{Tooltip.d.ts → tooltips/Tooltip.d.ts} +4 -2
  143. package/dist/src/app/charts/{Tooltip.js → tooltips/Tooltip.js} +23 -28
  144. package/dist/src/app/charts/tooltips/Tooltip.js.map +1 -0
  145. package/dist/src/app/charts/{tooltipUtils.d.ts → tooltips/tooltipUtils.d.ts} +11 -6
  146. package/dist/src/app/charts/{tooltipUtils.js → tooltips/tooltipUtils.js} +33 -17
  147. package/dist/src/app/charts/tooltips/tooltipUtils.js.map +1 -0
  148. package/dist/src/app/charts/{Tracker.d.ts → trackers/Tracker.d.ts} +6 -5
  149. package/dist/src/app/charts/trackers/Tracker.js +60 -0
  150. package/dist/src/app/charts/trackers/Tracker.js.map +1 -0
  151. package/dist/src/app/charts/{trackerUtils.d.ts → trackers/trackerUtils.d.ts} +13 -8
  152. package/dist/src/app/charts/trackers/trackerUtils.js +359 -0
  153. package/dist/src/app/charts/trackers/trackerUtils.js.map +1 -0
  154. package/dist/src/app/charts/utils.d.ts +22 -32
  155. package/dist/src/app/charts/utils.js +36 -37
  156. package/dist/src/app/charts/utils.js.map +1 -1
  157. package/dist/src/index.d.ts +48 -15
  158. package/dist/src/index.js +71 -15
  159. package/dist/src/index.js.map +1 -1
  160. package/package.json +30 -20
  161. package/src/app/charts/Chart.tsx +334 -0
  162. package/src/app/charts/axes/AxesState.test.ts +34 -0
  163. package/src/app/charts/axes/AxesState.ts +112 -0
  164. package/src/app/charts/axes/AxisInterval.test.ts +143 -0
  165. package/src/app/charts/axes/AxisInterval.ts +139 -0
  166. package/src/app/charts/axes/BaseAxisRange.ts +113 -0
  167. package/src/app/charts/axes/ContinuousAxis.tsx +192 -0
  168. package/src/app/charts/axes/ContinuousAxisRange.test.ts +55 -0
  169. package/src/app/charts/axes/ContinuousAxisRange.ts +96 -0
  170. package/src/app/charts/axes/OrdinalAxis.tsx +223 -0
  171. package/src/app/charts/axes/OrdinalAxisRange.test.ts +55 -0
  172. package/src/app/charts/axes/OrdinalAxisRange.ts +112 -0
  173. package/src/app/charts/axes/axes.ts +1569 -0
  174. package/src/app/charts/d3types.ts +16 -0
  175. package/src/app/charts/filters/regexFilter.test.ts +13 -0
  176. package/src/app/charts/filters/regexFilter.ts +17 -0
  177. package/src/app/charts/hooks/useAxes.tsx +341 -0
  178. package/src/app/charts/hooks/useChart.tsx +159 -0
  179. package/src/app/charts/hooks/useDataObservable.tsx +175 -0
  180. package/src/app/charts/hooks/useInitialData.tsx +65 -0
  181. package/src/app/charts/hooks/useMouse.tsx +125 -0
  182. package/src/app/charts/hooks/usePlotDimensions.tsx +120 -0
  183. package/src/app/charts/hooks/useTooltip.tsx +112 -0
  184. package/src/app/charts/observables/ChartData.ts +31 -0
  185. package/src/app/charts/observables/iterates.test.ts +201 -0
  186. package/src/app/charts/observables/iterates.ts +203 -0
  187. package/src/app/charts/observables/ordinals.test.ts +135 -0
  188. package/src/app/charts/observables/ordinals.ts +248 -0
  189. package/src/app/charts/plots/BarPlot.tsx +1088 -0
  190. package/src/app/charts/plots/PoincarePlot.tsx +832 -0
  191. package/src/app/charts/plots/RasterPlot.tsx +676 -0
  192. package/src/app/charts/plots/ScatterPlot.tsx +653 -0
  193. package/src/app/charts/plots/plot.ts +75 -0
  194. package/src/app/charts/series/baseSeries.ts +52 -0
  195. package/src/app/charts/series/datumSeries.test.ts +60 -0
  196. package/src/app/charts/series/iterateSeries.ts +56 -0
  197. package/src/app/charts/series/ordinalSeries.ts +164 -0
  198. package/src/app/charts/series/timeSeries.ts +40 -0
  199. package/src/app/charts/series/timeSeriesChartData.ts +68 -0
  200. package/src/app/charts/styling/barPlotStyle.ts +126 -0
  201. package/src/app/charts/styling/margins.test.ts +22 -0
  202. package/src/app/charts/styling/margins.ts +58 -0
  203. package/src/app/charts/styling/svgStyle.ts +118 -0
  204. package/src/app/charts/subscriptions/subscription.test.ts +499 -0
  205. package/src/app/charts/subscriptions/subscriptions.ts +635 -0
  206. package/src/app/charts/tooltips/BarPlotTooltipContent.tsx +440 -0
  207. package/src/app/charts/tooltips/PoincarePlotTooltipContent.tsx +352 -0
  208. package/src/app/charts/tooltips/RasterPlotTooltipContent.tsx +274 -0
  209. package/src/app/charts/tooltips/ScatterPlotTooltipContent.tsx +319 -0
  210. package/src/app/charts/tooltips/Tooltip.tsx +148 -0
  211. package/src/app/charts/tooltips/tooltipUtils.ts +216 -0
  212. package/src/app/charts/trackers/Tracker.tsx +129 -0
  213. package/src/app/charts/trackers/trackerUtils.ts +494 -0
  214. package/src/app/charts/utils.ts +109 -0
  215. package/dist/src/app/charts/CategoryAxis.d.ts +0 -20
  216. package/dist/src/app/charts/CategoryAxis.js +0 -112
  217. package/dist/src/app/charts/CategoryAxis.js.map +0 -1
  218. package/dist/src/app/charts/ContinuousAxis.d.ts +0 -16
  219. package/dist/src/app/charts/ContinuousAxis.js +0 -186
  220. package/dist/src/app/charts/ContinuousAxis.js.map +0 -1
  221. package/dist/src/app/charts/RasterPlot.js.map +0 -1
  222. package/dist/src/app/charts/RasterPlotTooltipContent.js.map +0 -1
  223. package/dist/src/app/charts/ScatterPlot.js +0 -351
  224. package/dist/src/app/charts/ScatterPlot.js.map +0 -1
  225. package/dist/src/app/charts/ScatterPlotTooltipContent.js +0 -163
  226. package/dist/src/app/charts/ScatterPlotTooltipContent.js.map +0 -1
  227. package/dist/src/app/charts/Tooltip.js.map +0 -1
  228. package/dist/src/app/charts/Tracker.js +0 -65
  229. package/dist/src/app/charts/Tracker.js.map +0 -1
  230. package/dist/src/app/charts/axes.d.ts +0 -132
  231. package/dist/src/app/charts/axes.js +0 -265
  232. package/dist/src/app/charts/axes.js.map +0 -1
  233. package/dist/src/app/charts/chartData.js +0 -32
  234. package/dist/src/app/charts/chartData.js.map +0 -1
  235. package/dist/src/app/charts/continuousAxisRangeFor.d.ts +0 -20
  236. package/dist/src/app/charts/continuousAxisRangeFor.js +0 -68
  237. package/dist/src/app/charts/continuousAxisRangeFor.js.map +0 -1
  238. package/dist/src/app/charts/datumSeries.d.ts +0 -59
  239. package/dist/src/app/charts/datumSeries.js +0 -55
  240. package/dist/src/app/charts/datumSeries.js.map +0 -1
  241. package/dist/src/app/charts/datumSeries.test.js +0 -50
  242. package/dist/src/app/charts/datumSeries.test.js.map +0 -1
  243. package/dist/src/app/charts/hooks/AxesState.d.ts +0 -37
  244. package/dist/src/app/charts/hooks/AxesState.js +0 -44
  245. package/dist/src/app/charts/hooks/AxesState.js.map +0 -1
  246. package/dist/src/app/charts/margins.js.map +0 -1
  247. package/dist/src/app/charts/margins.test.js +0 -14
  248. package/dist/src/app/charts/margins.test.js.map +0 -1
  249. package/dist/src/app/charts/plot.js.map +0 -1
  250. package/dist/src/app/charts/regexFilter.d.ts +0 -9
  251. package/dist/src/app/charts/regexFilter.js +0 -17
  252. package/dist/src/app/charts/regexFilter.js.map +0 -1
  253. package/dist/src/app/charts/regexFilter.test.js +0 -11
  254. package/dist/src/app/charts/regexFilter.test.js.map +0 -1
  255. package/dist/src/app/charts/subscriptions.d.ts +0 -43
  256. package/dist/src/app/charts/subscriptions.js +0 -213
  257. package/dist/src/app/charts/subscriptions.js.map +0 -1
  258. package/dist/src/app/charts/svgStyle.d.ts +0 -27
  259. package/dist/src/app/charts/svgStyle.js +0 -32
  260. package/dist/src/app/charts/svgStyle.js.map +0 -1
  261. package/dist/src/app/charts/timeRange.test.js +0 -54
  262. package/dist/src/app/charts/timeRange.test.js.map +0 -1
  263. package/dist/src/app/charts/tooltipUtils.js.map +0 -1
  264. package/dist/src/app/charts/trackerUtils.js +0 -130
  265. package/dist/src/app/charts/trackerUtils.js.map +0 -1
  266. /package/dist/src/app/charts/{datumSeries.test.d.ts → axes/AxesState.test.d.ts} +0 -0
  267. /package/dist/src/app/charts/{margins.test.d.ts → axes/AxisInterval.test.d.ts} +0 -0
  268. /package/dist/src/app/charts/{regexFilter.test.d.ts → axes/ContinuousAxisRange.test.d.ts} +0 -0
  269. /package/dist/src/app/charts/{timeRange.test.d.ts → axes/OrdinalAxisRange.test.d.ts} +0 -0
  270. /package/dist/src/app/charts/{RasterPlotTooltipContent.d.ts → tooltips/RasterPlotTooltipContent.d.ts} +0 -0
  271. /package/dist/src/app/charts/{ScatterPlotTooltipContent.d.ts → tooltips/ScatterPlotTooltipContent.d.ts} +0 -0
@@ -0,0 +1,440 @@
1
+ import {Dimensions, Margin} from "../styling/margins";
2
+ import {defaultTooltipStyle, TooltipDimensions, TooltipStyle, tooltipX, tooltipY} from "./tooltipUtils";
3
+ import * as d3 from "d3";
4
+ import {formatNumber, formatTime, formatValue} from "../utils";
5
+ import {useEffect, useMemo} from "react";
6
+ import {useChart} from "../hooks/useChart";
7
+ import {ContinuousNumericAxis, SeriesLineStyle} from "../axes/axes";
8
+ import {usePlotDimensions} from "../hooks/usePlotDimensions";
9
+ import {emptyOrdinalDatum, OrdinalDatum} from "../series/ordinalSeries";
10
+ import {TooltipData} from "../hooks/useTooltip";
11
+ import {WindowedOrdinalStats} from "../subscriptions/subscriptions";
12
+ import {DataFrame} from "data-frame-ts";
13
+ import {createTable, Padding, TableData, TableFont, TableFormatter, TableStyler} from "svg-table";
14
+ import {defaultOrdinalValueStats} from "../observables/ordinals";
15
+ import {Dimension} from "svg-table/stylings";
16
+ import {BAR_CHART_TOOLTIP_PROVIDER_IDS} from "../plots/BarPlot";
17
+ import {ContinuousAxisRange} from "../axes/ContinuousAxisRange";
18
+
19
+ /**
20
+ # Want to write your own tooltip-content component?
21
+
22
+ Here's how to write your own tooltip-content component.
23
+
24
+ To create your own tooltip content `<MyTooltipContent/>` you must do the following:
25
+ 1. Create a react component for your tooltip content (see for example, {@link ScatterPlotTooltipContent}
26
+ as a reference.
27
+ 2. Use the {@link useChart} hook to get the {@link registerTooltipContentProvider} registration function.
28
+ 3. When your tooltip content component (`<MyTooltipContent/>`) mounts, use the {@link registerTooltipContentProvider}
29
+ function to register your tooltip content provider.
30
+ 4. When the chart dimensions, margin, container, etc, change, register your tooltip content provider
31
+ again (you can register as many times as you like because it only uses the last content provider
32
+ registered).
33
+
34
+ That's it! A bit more details below.
35
+
36
+ The {@link registerTooltipContentProvider} function from the {@link useChart} hook allows you to register
37
+ one tooltip content provider. A second call to this function will cause the {@link useChart} hook to drop
38
+ the first one in favor of the second one.
39
+
40
+ The {@link registerTooltipContentProvider} function from the {@link useChart} hook accepts a higher-order
41
+ function that allowing a closure on content/chart-specific data. Specifically, you must hand the
42
+ {@link registerTooltipContentProvider} a function of the form:
43
+
44
+ `(seriesName: string, time: number, series: TimeSeries, mouseCoords: [x: number, y: number]) => TooltipDimensions`
45
+
46
+ Your function to add that actual content will be what this function calls whenever d3 fires a mouse-over
47
+ event on one you the time-series in the chart.
48
+
49
+ The code snippet below is from the `useEffect` call in the {@link ScatterPlotTooltipContent}.
50
+ Note that the first four arguments to the {@link addTooltipContent} function are those provided by the {@link useChart} hook
51
+ when a d3 mouse-over event occurs on one of your series. The additional six arguments are from the closure formed
52
+ on the variables in your component. The `chartId`, `container`, `margin`, and `plotDimensions` are from the
53
+ {@link useChart} hook called by the {@link ScatterPlotTooltipContent} component. The last two
54
+ arguments, `defaultTooltipStyle` and `options` are specific to the {@link ScatterPlotTooltipContent}.
55
+ For example, the `options` property is set by the caller of the {@link ScatterPlotTooltipContent}
56
+ component.
57
+
58
+ ```typescript
59
+ // register the tooltip content provider function with the chart hook (useChart) so that
60
+ // it is visible to all children of the Chart (i.e. the <Tooltip>).
61
+ registerTooltipContentProvider(
62
+ (seriesName: string,
63
+ time: number,
64
+ tooltipData: TooltipData<OrdinalDatum, WindowedOrdinalStats>,
65
+ mouseCoords: [x: number, y: number]
66
+ ) => {
67
+ return addTooltipContent(
68
+ seriesName, tooltipData, mouseCoords,
69
+ chartId, container, margin, plotDimensions, tooltipStyle,
70
+ ordinalUnits
71
+ )
72
+ }
73
+ )
74
+ ```
75
+
76
+ This pattern allows you to supplement that `useChart` mouse-over callback with information specific to your component.
77
+
78
+ */
79
+
80
+ /**
81
+ * Properties for rendering the tooltip content. The properties are applied as
82
+ * shown below.
83
+ * ```
84
+ * series name
85
+ * xFormatter, yFormatter
86
+ * ```
87
+ */
88
+ interface Props {
89
+ ordinalUnits?: string
90
+ style?: Partial<TooltipStyle>
91
+ }
92
+
93
+ /**
94
+ * Adds tooltip content that shows the series name and the (time, value) of the selected point.
95
+ * ```
96
+ * series name
97
+ * time, value
98
+ * ```
99
+ *
100
+ * Registers the tooltip-content provider with the `ChartContext` so that when d3 fires a mouse-over
101
+ * event on a series. The content provider is returns the {@link addTooltipContent} function
102
+ * when called. And when called the {@link addTooltipContent} function adds the actual tooltip
103
+ * content to the SVG element.
104
+ * @param props The properties describing the tooltip content
105
+ * @return null
106
+ * @constructor
107
+ */
108
+ export function BarPlotTooltipContent(props: Props): null {
109
+ const {
110
+ chartId,
111
+ container,
112
+ tooltip,
113
+ axes
114
+ } = useChart<OrdinalDatum, SeriesLineStyle, WindowedOrdinalStats, ContinuousAxisRange, ContinuousNumericAxis>()
115
+
116
+ const {registerTooltipContentProvider} = tooltip
117
+ const {yAxesState, axisAssignmentsFor} = axes
118
+ const {margin, plotDimensions} = usePlotDimensions()
119
+ const {style, ordinalUnits = ""} = props
120
+ const tooltipStyle = useMemo(() => ({...defaultTooltipStyle, ...style}), [style])
121
+
122
+ // register the tooltip content provider, which when called on mouse-enter-series events
123
+ // will render the tooltip container and then the tooltip content. recall that that the
124
+ // tooltip content is generated in this plot (because this is the plot that holds all the
125
+ // information needed to render it), and the container for the content is rendered by
126
+ // the <Tooltip>, which this know nothing about.
127
+ //
128
+ // the 'registration function accepts a function of the form (seriesName, time, series) => TooltipDimensions.
129
+ // and that function has a closure on the content-specific information needed to add the
130
+ // actual content
131
+ useEffect(
132
+ () => {
133
+ if (container) {
134
+ // register the tooltip content provider function with the chart hook (useChart) so that
135
+ // it is visible to all children of the Chart (i.e. the <Tooltip>).
136
+ registerTooltipContentProvider(
137
+ /**
138
+ *
139
+ * @param seriesName The name of the series
140
+ * @param time The mouse time
141
+ * @param tooltipData The series data and metadata
142
+ * @param mouseCoords The coordinates of the mouse
143
+ * @param providerId The ID of the tooltip content provider
144
+ * @return The tooltip contents
145
+ */
146
+ (seriesName: string,
147
+ time: number,
148
+ tooltipData: TooltipData<OrdinalDatum, WindowedOrdinalStats>,
149
+ mouseCoords: [x: number, y: number],
150
+ providerId?: string
151
+ ) => {
152
+ if (providerId !== undefined) {
153
+ return addTooltipContent(
154
+ seriesName, providerId, tooltipData, mouseCoords,
155
+ chartId, container, margin, plotDimensions, tooltipStyle,
156
+ ordinalUnits
157
+ )
158
+ }
159
+ return {x: 0, y: 0, contentWidth: 0, contentHeight: 0}
160
+ //
161
+ // switch (providerId) {
162
+ // case BAR_CHART_TOOLTIP_PROVIDER_IDS.currentValue:
163
+ // return addTooltipContent(
164
+ // seriesName, 'current value', tooltipData, mouseCoords,
165
+ // chartId, container, margin, plotDimensions, tooltipStyle,
166
+ // ordinalUnits
167
+ // )
168
+ // case BAR_CHART_TOOLTIP_PROVIDER_IDS.meanValue:
169
+ // return addTooltipContent(
170
+ // seriesName, 'mean value', tooltipData, mouseCoords,
171
+ // chartId, container, margin, plotDimensions, tooltipStyle,
172
+ // ordinalUnits
173
+ // )
174
+ // case BAR_CHART_TOOLTIP_PROVIDER_IDS.minMax:
175
+ // return addTooltipContent(
176
+ // seriesName, 'min/max', tooltipData, mouseCoords,
177
+ // chartId, container, margin, plotDimensions, tooltipStyle,
178
+ // ordinalUnits
179
+ // )
180
+ // case BAR_CHART_TOOLTIP_PROVIDER_IDS.windowedMeanValue:
181
+ // return addTooltipContent(
182
+ // seriesName, 'windowed mean', tooltipData, mouseCoords,
183
+ // chartId, container, margin, plotDimensions, tooltipStyle,
184
+ // ordinalUnits
185
+ // )
186
+ // case BAR_CHART_TOOLTIP_PROVIDER_IDS.windowedMinMax:
187
+ // return addTooltipContent(
188
+ // seriesName, 'windowed min/max', tooltipData, mouseCoords,
189
+ // chartId, container, margin, plotDimensions, tooltipStyle,
190
+ // ordinalUnits
191
+ // )
192
+ //
193
+ //
194
+ // default:
195
+ // return {x: 0, y: 0, contentWidth: 0, contentHeight: 0}
196
+ // }
197
+ }
198
+ )
199
+ }
200
+ },
201
+ [
202
+ chartId, container, margin, plotDimensions, registerTooltipContentProvider,
203
+ tooltipStyle,
204
+ yAxesState, axisAssignmentsFor,
205
+ ordinalUnits
206
+ ]
207
+ )
208
+
209
+ return null
210
+ }
211
+
212
+ const dimension: Dimension = {
213
+ width: 60,
214
+ defaultWidth: 70,
215
+ minWidth: 50,
216
+ maxWidth: 100,
217
+
218
+ height: 15,
219
+ defaultHeight: 15,
220
+ minHeight: 10,
221
+ maxHeight: 50
222
+ }
223
+
224
+ /**
225
+ * Creates the label to display in the tooltip header
226
+ * @param providerId The tooltip provider ID for which to create the label
227
+ * @return The label to display in the tooltip header
228
+ */
229
+ function labelForProviderId(providerId: string): string {
230
+ switch (providerId) {
231
+ case BAR_CHART_TOOLTIP_PROVIDER_IDS.currentValue:
232
+ return 'current value'
233
+ case BAR_CHART_TOOLTIP_PROVIDER_IDS.meanValue:
234
+ return 'mean value'
235
+ case BAR_CHART_TOOLTIP_PROVIDER_IDS.minMax:
236
+ return 'min/max'
237
+ case BAR_CHART_TOOLTIP_PROVIDER_IDS.windowedMeanValue:
238
+ return 'windowed mean'
239
+ case BAR_CHART_TOOLTIP_PROVIDER_IDS.windowedMinMax:
240
+ return 'windowed min/max'
241
+
242
+ default:
243
+ return ''
244
+ }
245
+ }
246
+
247
+ /**
248
+ * Callback function that adds tooltip content and returns the tooltip width and text height
249
+ * @param seriesName The name of the series (i.e. the neuron ID)
250
+ * @param providerId The tooltip content provider ID (i.e. the name of the tooltip)
251
+ * @param tooltipData The series data and metadata
252
+ * @param mouseCoords The coordinates of the mouse when the event was fired (relative to the plot container)
253
+ * @param chartId The ID of this chart
254
+ * @param container The plot container (SVGSVGElement)
255
+ * @param margin The plot margins
256
+ * @param tooltipStyle The style properties for the tooltip
257
+ * @param plotDimensions The dimensions of the plot
258
+ * @param ordinalUnits The units of the ordinal data (i.e. "mV")
259
+ * @return The width and text height of the tooltip content
260
+ */
261
+ function addTooltipContent(
262
+ seriesName: string,
263
+ providerId: string,
264
+ tooltipData: TooltipData<OrdinalDatum, WindowedOrdinalStats>,
265
+ mouseCoords: [x: number, y: number],
266
+ chartId: number,
267
+ container: SVGSVGElement,
268
+ margin: Margin,
269
+ plotDimensions: Dimensions,
270
+ tooltipStyle: TooltipStyle,
271
+ ordinalUnits: string
272
+ ): TooltipDimensions {
273
+ const [x, y] = mouseCoords
274
+ const {series, metadata: statistics} = tooltipData
275
+ const currentDatum = series.length > 0 ? series[series.length - 1] : emptyOrdinalDatum
276
+ const valueStats = statistics.valueStatsForSeries.get(seriesName) || defaultOrdinalValueStats()
277
+ const windowedValueStats = statistics.windowedValueStatsForSeries.get(seriesName) || defaultOrdinalValueStats()
278
+ const displayOrdinalUnits = ordinalUnits.length > 0 ? ` ${ordinalUnits}` : ""
279
+
280
+ // display the neuron ID in the tooltip
281
+ const header = d3.select<SVGSVGElement | null, any>(container)
282
+ .append<SVGTextElement>("text")
283
+ .attr('id', `tn${currentDatum.time}-${seriesName}-${chartId}`)
284
+ .attr('class', 'tooltip')
285
+ .attr('fill', tooltipStyle.fontColor)
286
+ .attr('font-family', 'sans-serif')
287
+ .attr('font-size', tooltipStyle.fontSize)
288
+ .attr('font-weight', tooltipStyle.fontWeight)
289
+ .text(() => `${seriesName} (${labelForProviderId(providerId)})`)
290
+
291
+
292
+ // display the series name and the current value
293
+ const text = d3.select<SVGSVGElement | null, any>(container)
294
+ .append<SVGTextElement>("text")
295
+ .attr('id', `t${currentDatum.time}-${seriesName}-${chartId}`)
296
+ .attr('class', 'tooltip')
297
+ .attr('fill', tooltipStyle.fontColor)
298
+ .attr('font-family', 'sans-serif')
299
+ .attr('font-size', tooltipStyle.fontSize + 2)
300
+ .attr('font-weight', tooltipStyle.fontWeight + 150)
301
+ .text(() => `${formatValue(currentDatum.value)}${displayOrdinalUnits} (${formatTime(currentDatum.time)} ms)`)
302
+
303
+ // calculate the max width and height of the text (we'll adjust the coordinates of the header
304
+ // text once we have the table dimensions)
305
+ const headerTextHeight = header.node()?.getBBox()?.height || 0;
306
+ const idHeight = text.node()?.getBBox()?.height || 0;
307
+ const textHeight = headerTextHeight + idHeight;
308
+
309
+ const font: TableFont = {
310
+ size: tooltipStyle.fontSize,
311
+ family: tooltipStyle.fontFamily,
312
+ color: tooltipStyle.fontColor,
313
+ weight: tooltipStyle.fontWeight
314
+ }
315
+
316
+ const padding: Padding = {
317
+ top: tooltipStyle.paddingTop,
318
+ bottom: tooltipStyle.paddingBottom,
319
+ right: tooltipStyle.paddingRight,
320
+ left: tooltipStyle.paddingLeft
321
+ }
322
+
323
+ const units = ordinalUnits.length > 0 ? ` (${ordinalUnits})` : ""
324
+ return DataFrame
325
+ .from<number | string>([
326
+ [windowedValueStats.count, valueStats.count],
327
+ [windowedValueStats.min.value, valueStats.min.value],
328
+ [windowedValueStats.max.value, valueStats.max.value],
329
+ [windowedValueStats.mean, valueStats.mean],
330
+ ])
331
+ // create the table data that has the column headers
332
+ .flatMap(df => TableData
333
+ .fromDataFrame(df)
334
+ .withColumnHeader(["Windowed", "All"])
335
+ .flatMap(td => td.withRowHeader(["Count", `Min${units}`, `Max${units}`, `Mean${units}`]))
336
+ )
337
+ // add the data formatters for statistics
338
+ .flatMap(tableData => TableFormatter.fromTableData(tableData)
339
+ .addRowFormatters([2, 3, 4], value => formatValue(value as number))
340
+ .flatMap(tf => tf.addRowFormatter(1, value => formatNumber(value as number, " ,.0f")))
341
+ .flatMap(tf => tf.formatTable())
342
+ )
343
+ .map(tableData => TableStyler.fromTableData(tableData)
344
+ .withTableFont(font)
345
+ .withPadding(padding)
346
+ .withColumnHeaderStyle({
347
+ font: {...font, weight: 650},
348
+ padding: {top: 15, bottom: 0},
349
+ dimension: {...dimension, maxHeight: 70},
350
+ alignText: 'right',
351
+ })
352
+ .withRowHeaderStyle({
353
+ font: {...font, weight: 650},
354
+ padding: {left: 0, right: 10},
355
+ dimension: dimension,
356
+ alignText: 'left',
357
+ })
358
+ .withColumnStyles([], {
359
+ padding: {left: 10, right: 10},
360
+ alignText: 'right',
361
+ })
362
+ .withRowStyles([], {
363
+ font,
364
+ dimension: {...dimension, maxHeight: 20},
365
+ padding: {top: 0, bottom: 0}
366
+ }
367
+ )
368
+ .withCellStyleWhen((_, row, column) => {
369
+ // apply the style to the cell corresponding to the chart element that the user
370
+ // moused-over.
371
+ const coordinates = coordinatesForProviderId(providerId)
372
+ if (coordinates.length > 0) {
373
+ return coordinates.findIndex(c => c.row === row && c.column === column) > -1
374
+ }
375
+ return false
376
+ },
377
+ {font: {...font, weight: font.weight + 300}, alignText: 'right', padding: {left: 10, right: 10, top: 0, bottom: 0}},
378
+ 100
379
+ )
380
+ .styleTable()
381
+ )
382
+ .flatMap(styledTable =>
383
+ createTable(styledTable, container, `t${currentDatum.time}-${seriesName}-header-${chartId}`, tooltipCoordinates)
384
+ )
385
+ .map(renderingInfo => {
386
+ // the calculated table coordinates and dimensions. we'll move the header text into place,
387
+ // and then move the table down so that it fits
388
+ const {tableX: x, tableY: y, tableWidth: contentWidth, tableHeight: contentHeight} = renderingInfo
389
+
390
+ // set the location of the header (series name) and text (value and time)
391
+ header
392
+ .attr('x', () => x + tooltipStyle.paddingLeft)
393
+ .attr('y', () => y - idHeight)
394
+ text
395
+ .attr('x', () => x + tooltipStyle.paddingLeft)
396
+ .attr('y', () => y)
397
+
398
+ return {x, y: y - textHeight, contentWidth, contentHeight: contentHeight + textHeight + padding.top}
399
+ })
400
+ .getOrThrow()
401
+
402
+ /**
403
+ * Calculates the coordinates that are affected by the provider ID
404
+ * @param providerId The ID of the provider for the element type being moused-over
405
+ * @return An array of coordinates that are affected by the provider ID
406
+ */
407
+ function coordinatesForProviderId(providerId: string): Array<{ row: number, column: number }> {
408
+ switch (providerId) {
409
+ case BAR_CHART_TOOLTIP_PROVIDER_IDS.currentValue:
410
+ return []
411
+ case BAR_CHART_TOOLTIP_PROVIDER_IDS.meanValue:
412
+ return [{row: 4, column: 2}]
413
+ case BAR_CHART_TOOLTIP_PROVIDER_IDS.minMax:
414
+ return [{row: 2, column: 2}, {row: 3, column: 2}]
415
+ case BAR_CHART_TOOLTIP_PROVIDER_IDS.windowedMeanValue:
416
+ return [{row: 4, column: 1}]
417
+ case BAR_CHART_TOOLTIP_PROVIDER_IDS.windowedMinMax:
418
+ return [{row: 2, column: 1}, {row: 3, column: 1}]
419
+
420
+ default:
421
+ return []
422
+ }
423
+ }
424
+
425
+ /**
426
+ * Calculates the coordinates of the tooltip based on the width and height of the SVG
427
+ * table. This is needed because the tooltip needs to be adjusted relative mouse location
428
+ * when the mouse coordinates are too close to an edge.
429
+ * @param width The SVG table width
430
+ * @param height The SVG table height
431
+ * @return The updated tooltip coordinates
432
+ */
433
+ function tooltipCoordinates(width: number, height: number): [x: number, y: number] {
434
+ return [
435
+ tooltipX(x, width, plotDimensions, tooltipStyle, margin),
436
+ tooltipY(y + textHeight + padding.top, height, plotDimensions, tooltipStyle, margin)
437
+ ]
438
+ }
439
+
440
+ }