stream-charts 1.0.1 → 1.1.1

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 +757 -342
  2. package/changes.md +11 -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,352 @@
1
+ import {
2
+ CellStyle,
3
+ createTable,
4
+ type Margin,
5
+ TableFont,
6
+ TableData,
7
+ TableFormatter,
8
+ TableStyler, Padding
9
+ } from "svg-table";
10
+ import {
11
+ defaultTooltipStyle,
12
+ findPointAndNeighbors,
13
+ TooltipDimensions,
14
+ TooltipStyle,
15
+ tooltipX,
16
+ tooltipY
17
+ } from "./tooltipUtils";
18
+ import {formatTime, formatTimeChange, formatValue, formatValueChange} from "../utils";
19
+ import {useEffect, useMemo} from "react";
20
+ import {NoTooltipMetadata, useChart} from "../hooks/useChart";
21
+ import {usePlotDimensions} from "../hooks/usePlotDimensions";
22
+ import {emptyIterateDatum, IterateDatum} from "../series/iterateSeries";
23
+ import {ContinuousNumericAxis, SeriesLineStyle} from "../axes/axes";
24
+ import {TooltipData} from "../hooks/useTooltip";
25
+ import {DataFrame} from "data-frame-ts";
26
+ import {Dimensions} from "../styling/margins";
27
+ import {Background, Border, BorderElement, Dimension} from "svg-table/stylings";
28
+ import {ContinuousAxisRange} from "../axes/ContinuousAxisRange";
29
+
30
+ /**
31
+ # Want to write your own tooltip-content component?
32
+
33
+ Here's how to write your own tooltip-content component.
34
+
35
+ To create your own tooltip content `<MyTooltipContent/>` you must do the following:
36
+ 1. Create a react component for your tooltip content (see for example, {@link PoincarePlotTooltipContent}
37
+ as a reference.
38
+ 2. Use the {@link useChart} hook to get the {@link registerTooltipContentProvider} registration function.
39
+ 3. When your tooltip content component (`<MyTooltipContent/>`) mounts, use the {@link registerTooltipContentProvider}
40
+ function to register your tooltip content provider.
41
+ 4. When the chart dimensions, margin, container, etc, change, register your tooltip content provider
42
+ again (you can register as many times as you like because it only uses the last content provider
43
+ registered).
44
+
45
+ That's it! A few more details are below.
46
+
47
+ The {@link registerTooltipContentProvider} function from the {@link useChart} hook allows you to register
48
+ one tooltip content provider. A second call to this function will cause the {@link useChart} hook to drop
49
+ the first one in favor of the second one.
50
+
51
+ The {@link registerTooltipContentProvider} function from the {@link useChart} hook accepts a higher-order
52
+ function that allowing a closure on content/chart-specific data. Specifically, you must hand the
53
+ {@link registerTooltipContentProvider} a function of the form:
54
+
55
+ `(seriesName: string, time: number, series: TimeSeries, mouseCoords: [x: number, y: number]) => TooltipDimensions`
56
+
57
+ Your function to add that actual content will be what this function calls whenever d3 fires a mouse-over
58
+ event on one you the time-series in the chart.
59
+
60
+ The code snippet below is from the `useEffect` call in the {@link PoincarePlotTooltipContent}.
61
+ Note that the first four arguments to the {@link addTooltipContent} function are those provided by the {@link useChart} hook
62
+ when a d3 mouse-over event occurs on one of your series. The additional six arguments are from the closure formed
63
+ on the variables in your component. The `chartId`, `container`, `margin`, and `plotDimensions` are from the
64
+ {@link useChart} hook called by the {@link PoincarePlotTooltipContent} component. The last two
65
+ arguments, `defaultTooltipStyle` and `options` are specific to the {@link PoincarePlotTooltipContent}.
66
+ For example, the `options` property is set by the caller of the {@link PoincarePlotTooltipContent}
67
+ component.
68
+
69
+ ```ts
70
+ // register the tooltip content provider function with the chart hook (useChart) so that
71
+ // it is visible to all children of the Chart (i.e. the <Tooltip>).
72
+ registerTooltipContentProvider(
73
+ (seriesName: string, time: number, series: TimeSeries, mouseCoords: [x: number, y: number]) =>
74
+ addTooltipContent(
75
+ seriesName, time, series, mouseCoords,
76
+ chartId, container, margin, plotDimensions,
77
+ defaultTooltipStyle, options
78
+ )
79
+ )
80
+ ```
81
+
82
+ This pattern allows you to supplement that `useChart` mouse-over callback with information specific to your component.
83
+
84
+ */
85
+
86
+ /**
87
+ * Properties for rendering the tooltip content. The properties are applied as
88
+ * shown below.
89
+ * ```
90
+ * series name
91
+ * beforeHeader afterHeader deltaHeader
92
+ * xLabel xValueFormatter xValueFormatter xChangeFormatter
93
+ * yLabel yValueFormatter yValueFormatter yChangeFormatter
94
+ * ```
95
+ */
96
+ interface Props {
97
+ // label for the x-values (x-value row header)
98
+ xLabel: string
99
+ yLabel: string
100
+ nMinusLagHeader?: string
101
+ nHeader?: string
102
+ nPlusLagHeader?: string
103
+ xValueFormatter?: (value: number) => string
104
+ yValueFormatter?: (value: number) => string
105
+ xChangeFormatter?: (value1: number, value2: number) => string,
106
+ yChangeFormatter?: (value1: number, value2: number) => string,
107
+ style?: Partial<TooltipStyle>
108
+ }
109
+
110
+ /**
111
+ * Adds tooltip content as a table. The columns of the table are the "label", the value before
112
+ * the mouse cursor, then value after the mouse cursor, and the difference between the two values.
113
+ * The rows of the table are x-values for the first row, and the y-values for the second row.
114
+ * The table has the following form.
115
+ * ```
116
+ * series name
117
+ * previous current next
118
+ * time x_tb x_ta x_ta - x_tb
119
+ * value y_tb y_ta y_ta - y_tb
120
+ * ```
121
+ *
122
+ * Registers the tooltip-content provider with the `ChartContext` so that when d3 fires a mouse-over
123
+ * event on a series. The content provider is returns the {@link addTooltipContent} function
124
+ * when called. And when called the {@link addTooltipContent} function adds the actual tooltip
125
+ * content to the SVG element.
126
+ * @param props The properties describing the tooltip content
127
+ * @return null
128
+ * @constructor
129
+ */
130
+ export function PoincarePlotTooltipContent(props: Props): null {
131
+ const {
132
+ chartId,
133
+ container,
134
+ tooltip
135
+ } = useChart<IterateDatum, SeriesLineStyle, NoTooltipMetadata, ContinuousAxisRange, ContinuousNumericAxis>()
136
+
137
+ const {registerTooltipContentProvider} = tooltip
138
+
139
+ const {
140
+ margin,
141
+ plotDimensions,
142
+ } = usePlotDimensions()
143
+
144
+ const {
145
+ xLabel,
146
+ yLabel,
147
+ nMinusLagHeader = ' f[n-1](x)',
148
+ nHeader = ' f[n](x) ',
149
+ nPlusLagHeader = ' f[n+1](x)',
150
+ xValueFormatter = formatTime,
151
+ yValueFormatter = formatValue,
152
+ xChangeFormatter = formatTimeChange,
153
+ yChangeFormatter = formatValueChange,
154
+ style,
155
+ } = props
156
+
157
+ const tooltipStyle = useMemo(() => ({...defaultTooltipStyle, ...style}), [style])
158
+
159
+ // register the tooltip content provider, which when called on mouse-enter-series events
160
+ // will render the tooltip container and then the tooltip content. recall that the
161
+ // tooltip content is generated in this plot (because this is the plot that holds all the
162
+ // information needed to render it), and the container for the content is rendered by
163
+ // the <Tooltip>, which this knows nothing about.
164
+ //
165
+ // the 'registration function accepts a function of the form (seriesName, time, series) => TooltipDimensions.
166
+ // and that function has a closure on the content-specific information needed to add the
167
+ // actual content
168
+ useEffect(
169
+ () => {
170
+ if (container) {
171
+ // register the tooltip content provider function with the chart hook (useChart) so that
172
+ // it is visible to all children of the Chart (i.e. the <Tooltip>).
173
+ registerTooltipContentProvider(
174
+ (seriesName: string, time: number, tooltipData: TooltipData<IterateDatum, NoTooltipMetadata>, mouseCoords: [x: number, y: number]) =>
175
+ addTooltipContent(
176
+ seriesName, time, tooltipData, mouseCoords,
177
+ chartId, container, margin, plotDimensions, tooltipStyle,
178
+ )
179
+ )
180
+ }
181
+ },
182
+ [
183
+ chartId, container, margin, plotDimensions, registerTooltipContentProvider,
184
+ xLabel, xChangeFormatter, xValueFormatter,
185
+ yLabel, yChangeFormatter, yValueFormatter,
186
+ nMinusLagHeader, nHeader, nPlusLagHeader,
187
+ tooltipStyle
188
+ ]
189
+ )
190
+
191
+ return null
192
+ }
193
+
194
+ const dimension: Dimension = {
195
+ width: 60,
196
+ defaultWidth: 70,
197
+ minWidth: 50,
198
+ maxWidth: 100,
199
+
200
+ height: 15,
201
+ defaultHeight: 15,
202
+ minHeight: 10,
203
+ maxHeight: 50
204
+ }
205
+
206
+ /**
207
+ * Callback function that adds tooltip content and returns the tooltip width and text height
208
+ * @param seriesName The name of the series (i.e. the neuron ID)
209
+ * @param time The time (x-coordinate value) corresponding to the mouse location
210
+ * @param tooltipData The series data and metadata
211
+ * @param mouseCoords The coordinates of the mouse when the event was fired (relative to the plot container)
212
+ * @param chartId The ID of this chart
213
+ * @param container The plot container (SVGSVGElement)
214
+ * @param margin The plot margins
215
+ * @param tooltipStyle The style properties for the tooltip
216
+ * @param plotDimensions The dimensions of the plot
217
+ * @return The width and text height of the tooltip content
218
+ */
219
+ function addTooltipContent(
220
+ seriesName: string,
221
+ time: number,
222
+ tooltipData: TooltipData<IterateDatum, NoTooltipMetadata>,
223
+ mouseCoords: [x: number, y: number],
224
+ chartId: number,
225
+ container: SVGSVGElement,
226
+ margin: Margin,
227
+ plotDimensions: Dimensions,
228
+ tooltipStyle: TooltipStyle
229
+ ): TooltipDimensions {
230
+ const [x, y] = mouseCoords
231
+ const {series} = tooltipData
232
+ const [lower, point, upper, index] = findPointAndNeighbors(
233
+ series, time, 0.1, value => value.time, () => emptyIterateDatum
234
+ )
235
+
236
+ const defaultBorderElement: BorderElement = {
237
+ color: tooltipStyle.borderColor,
238
+ radius: 0,
239
+ width: 0,
240
+ opacity: 0
241
+ }
242
+
243
+ const border: Border = {
244
+ top: defaultBorderElement,
245
+ bottom: defaultBorderElement,
246
+ left: defaultBorderElement,
247
+ right: defaultBorderElement,
248
+ }
249
+
250
+ const background: Background = {
251
+ color: tooltipStyle.backgroundColor,
252
+ opacity: tooltipStyle.backgroundOpacity
253
+ }
254
+
255
+ const font: TableFont = {
256
+ size: tooltipStyle.fontSize,
257
+ family: tooltipStyle.fontFamily,
258
+ color: tooltipStyle.fontColor,
259
+ weight: tooltipStyle.fontWeight
260
+ }
261
+
262
+ const padding: Padding = {
263
+ top: tooltipStyle.paddingTop,
264
+ bottom: tooltipStyle.paddingBottom,
265
+ right: tooltipStyle.paddingRight,
266
+ left: tooltipStyle.paddingLeft
267
+ }
268
+
269
+ const currentIterateStyle: CellStyle = {
270
+ border,
271
+ dimension,
272
+ background,
273
+ font: {...font, weight: 550},
274
+ padding,
275
+ alignText: 'right',
276
+ verticalAlignText: 'middle'
277
+ }
278
+
279
+ return DataFrame
280
+ .from<number | string>([
281
+ [lower.time, point.time, upper.time],
282
+ [lower.iterateN_1, point.iterateN_1, upper.iterateN_1]
283
+ ])
284
+ // create the table data that has the column headers
285
+ .flatMap(df => TableData
286
+ .fromDataFrame(df)
287
+ .withColumnHeader([
288
+ index > 0 ? `f[${index - 1}](x)` : '- n/a -',
289
+ `f[${index}](x)`,
290
+ index < series.length - 1 ? `f[${index + 1}](x)` : '- n/a -'
291
+ ])
292
+ .flatMap(td => td.withRowHeader(['t (ms)', 'value']))
293
+ )
294
+ // add the dat formatters for the (x, y) values of the iterates
295
+ .flatMap(tableData => TableFormatter.fromTableData(tableData)
296
+ .addRowFormatter(1, value => formatTime(value as number, ""))
297
+ .flatMap(tf => tf.addRowFormatter(2, value => formatValue(value as number)))
298
+ .flatMap(tf => tf.formatTable())
299
+ )
300
+ .map(tableData => TableStyler.fromTableData(tableData)
301
+ .withTableFont(font)
302
+ .withPadding(padding)
303
+ .withColumnHeaderStyle({
304
+ font: {...font, weight: 650},
305
+ padding: {top: 0, bottom: 10},
306
+ dimension: {...dimension, maxHeight: 70},
307
+ alignText: 'center',
308
+ })
309
+ .withRowHeaderStyle({
310
+ font: {...font, weight: 650},
311
+ padding: {left: 0, right: 10},
312
+ dimension: dimension,
313
+ alignText: 'center',
314
+ })
315
+ .withColumnStyles([], {
316
+ padding: {left: 10, right: 10},
317
+ alignText: 'right',
318
+ })
319
+ .withCellStyle(1, 2, currentIterateStyle)
320
+ .withCellStyle(2, 2, currentIterateStyle)
321
+ .withRowStyles([], {
322
+ font,
323
+ dimension: {...dimension, maxHeight: 20},
324
+ padding: {top: 0, bottom: 0}}
325
+ )
326
+ .styleTable()
327
+ )
328
+ .flatMap(styledTable =>
329
+ createTable(styledTable, container, `t${time}-${seriesName}-header-${chartId}`, tooltipCoordinates)
330
+ )
331
+ .map(renderingInfo => {
332
+ const {tableX: x, tableY: y, tableWidth: contentWidth, tableHeight: contentHeight} = renderingInfo
333
+ return {x, y, contentWidth, contentHeight}
334
+ })
335
+ .getOrThrow()
336
+
337
+ /**
338
+ * Calculates the coordinates of the tooltip based on the width and height of the SVG
339
+ * table. This is needed because the tooltip needs to be adjusted relative mouse location
340
+ * when the mouse coordinates are too close to an edge.
341
+ * @param width The SVG table width
342
+ * @param height The SVG table height
343
+ * @return The updated tooltip coordinates
344
+ */
345
+ function tooltipCoordinates(width: number, height: number): [x: number, y: number] {
346
+ return [
347
+ tooltipX(x, width, plotDimensions, tooltipStyle, margin),
348
+ tooltipY(y, height, plotDimensions, tooltipStyle, margin)
349
+ ]
350
+ }
351
+
352
+ }
@@ -0,0 +1,274 @@
1
+ import {Dimensions, Margin} from "../styling/margins";
2
+ import {categoryTooltipY, defaultTooltipStyle, TooltipDimensions, TooltipStyle, tooltipX} from "./tooltipUtils";
3
+ import * as d3 from "d3";
4
+ import {formatTime, formatValue} from "../utils";
5
+ import {useEffect, useMemo} from "react";
6
+ import {NoTooltipMetadata, useChart} from "../hooks/useChart";
7
+ import {OrdinalStringAxis, SeriesLineStyle} from "../axes/axes";
8
+ import {usePlotDimensions} from "../hooks/usePlotDimensions";
9
+ import {Datum} from "../series/timeSeries";
10
+ import {TooltipData} from "../hooks/useTooltip";
11
+ import {ContinuousAxisRange} from "../axes/ContinuousAxisRange";
12
+
13
+ /**
14
+ # Want to write your own tooltip-content component?
15
+
16
+ Here's how to write your own tooltip-content component.
17
+
18
+ To create your own tooltip content `<MyTooltipContent/>` you must do the following:
19
+ 1. Create a react component for your tooltip content (see for example, {@link ScatterPlotTooltipContent}
20
+ as a reference.
21
+ 2. Use the {@link useChart} hook to get the {@link registerTooltipContentProvider} registration function.
22
+ 3. When your tooltip content component (`<MyTooltipContent/>`) mounts, use the {@link registerTooltipContentProvider}
23
+ function to register your tooltip content provider.
24
+ 4. When the chart dimensions, margin, container, etc, change, register your tooltip content provider
25
+ again (you can register as many times as you like because it only uses the last content provider
26
+ registered).
27
+
28
+ That's it! A bit more details below.
29
+
30
+ The {@link registerTooltipContentProvider} function from the {@link useChart} hook allows you to register
31
+ one tooltip content provider. A second call to this function will cause the {@link useChart} hook to drop
32
+ the first one in favor of the second one.
33
+
34
+ The {@link registerTooltipContentProvider} function from the {@link useChart} hook accepts a higher-order
35
+ function that allowing a closure on content/chart-specific data. Specifically, you must hand the
36
+ {@link registerTooltipContentProvider} a function of the form:
37
+
38
+ `(seriesName: string, time: number, series: TimeSeries, mouseCoords: [x: number, y: number]) => TooltipDimensions`
39
+
40
+ Your function to add that actual content will be what this function calls whenever d3 fires a mouse-over
41
+ event on one you the time-series in the chart.
42
+
43
+ The code snippet below is from the `useEffect` call in the {@link ScatterPlotTooltipContent}.
44
+ Note that the first four arguments to the {@link addTooltipContent} function are those provided by the {@link useChart} hook
45
+ when a d3 mouse-over event occurs on one of your series. The additional six arguments are from the closure formed
46
+ on the variables in your component. The `chartId`, `container`, `margin`, and `plotDimensions` are from the
47
+ {@link useChart} hook called by the {@link ScatterPlotTooltipContent} component. The last two
48
+ arguments, `defaultTooltipStyle` and `options` are specific to the {@link ScatterPlotTooltipContent}.
49
+ For example, the `options` property is set by the caller of the {@link ScatterPlotTooltipContent}
50
+ component.
51
+
52
+ ```ts
53
+ // register the tooltip content provider function with the chart hook (useChart) so that
54
+ // it is visible to all children of the Chart (i.e. the <Tooltip>).
55
+ registerTooltipContentProvider(
56
+ (seriesName: string, time: number, series: TimeSeries, mouseCoords: [x: number, y: number]) =>
57
+ addTooltipContent(
58
+ seriesName, time, series, mouseCoords,
59
+ chartId, container, margin, plotDimensions,
60
+ defaultTooltipStyle, options
61
+ )
62
+ )
63
+ ```
64
+
65
+ This pattern allows you to supplement that `useChart` mouse-over callback with information specific to you component.
66
+
67
+ */
68
+
69
+ /**
70
+ * Options for displaying the tooltip content. These options are specific to this
71
+ * particular implementation of a tooltip content. The options effect are applied
72
+ * as shown below.
73
+ * ```
74
+ * series name
75
+ * formatters.x(x), formatters.y(y)
76
+ * ```
77
+ */
78
+ interface TooltipOptions {
79
+ formatters: {
80
+ x: (value: number) => string,
81
+ y: (value: number) => string,
82
+ }
83
+ }
84
+
85
+ /**
86
+ * Properties for rendering the tooltip content. The properties are applied as
87
+ * shown below.
88
+ * ```
89
+ * series name
90
+ * xFormatter, yFormatter
91
+ * ```
92
+ */
93
+ interface Props {
94
+ xFormatter?: (value: number) => string
95
+ yFormatter?: (value: number) => string
96
+ style?: Partial<TooltipStyle>
97
+ }
98
+
99
+ /**
100
+ * Adds tooltip content that shows the series name and the (time, value) of the selected point.
101
+ * ```
102
+ * series name
103
+ * time, value
104
+ * ```
105
+ *
106
+ * Registers the tooltip-content provider with the `ChartContext` so that when d3 fires a mouse-over
107
+ * event on a series. The content provider is returns the {@link addTooltipContent} function
108
+ * when called. And when called the {@link addTooltipContent} function adds the actual tooltip
109
+ * content to the SVG element.
110
+ * @param props The properties describing the tooltip content
111
+ * @return null
112
+ * @constructor
113
+ */
114
+ export function RasterPlotTooltipContent(props: Props): null {
115
+ const {
116
+ chartId,
117
+ container,
118
+ tooltip,
119
+ axes
120
+ } = useChart<Datum, SeriesLineStyle, NoTooltipMetadata, ContinuousAxisRange, OrdinalStringAxis>()
121
+
122
+ const {registerTooltipContentProvider} = tooltip
123
+
124
+ const {
125
+ yAxesState,
126
+ axisAssignmentsFor
127
+ } = axes
128
+
129
+ const {margin, plotDimensions} = usePlotDimensions()
130
+
131
+ const {
132
+ xFormatter = formatTime,
133
+ yFormatter = formatValue,
134
+ style,
135
+ } = props
136
+
137
+ const tooltipStyle = useMemo(() => ({...defaultTooltipStyle, ...style}), [style])
138
+
139
+ // register the tooltip content provider, which when called on mouse-enter-series events
140
+ // will render the tooltip container and then the tooltip content. recall that that the
141
+ // tooltip content is generated in this plot (because this is the plot that holds all the
142
+ // information needed to render it), and the container for the content is rendered by
143
+ // the <Tooltip>, which this know nothing about.
144
+ //
145
+ // the 'registration function accepts a function of the form (seriesName, time, series) => TooltipDimensions.
146
+ // and that function has a closure on the content-specific information needed to add the
147
+ // actual content
148
+ useEffect(
149
+ () => {
150
+ if (container) {
151
+ // assemble the options for adding the tooltip
152
+ const options: TooltipOptions = {
153
+ formatters: {
154
+ x: xFormatter,
155
+ y: yFormatter,
156
+ }
157
+ }
158
+
159
+ // register the tooltip content provider function with the chart hook (useChart) so that
160
+ // it is visible to all children of the Chart (i.e. the <Tooltip>).
161
+ registerTooltipContentProvider(
162
+ /**
163
+ *
164
+ * @param seriesName The name of the series
165
+ * @param time The mouse time
166
+ * @param tooltipData The tooltip data holding the series and metadata (data about the series)
167
+ * @param mouseCoords The coordinates of the mouse
168
+ * @return The tooltip contents
169
+ */
170
+ (seriesName: string, time: number, tooltipData: TooltipData<Datum, NoTooltipMetadata>, mouseCoords: [x: number, y: number]) => {
171
+ const yAxisId = axisAssignmentsFor(seriesName).yAxis
172
+ const assignedAxis = yAxesState
173
+ .axisFor(yAxisId)
174
+ // .getOrElse(undefined as unknown as OrdinalStringAxis)
175
+ .getOrThrow(() => new Error(`No assigned y-axis exists; axis_id: ${yAxisId}`))
176
+ return addTooltipContent(
177
+ seriesName, time, tooltipData.series[0], mouseCoords,
178
+ chartId, container, margin, plotDimensions, tooltipStyle,
179
+ assignedAxis,
180
+ options
181
+ )
182
+ }
183
+ )
184
+ }
185
+ },
186
+ [
187
+ chartId, container, margin, plotDimensions, registerTooltipContentProvider,
188
+ xFormatter,
189
+ yFormatter,
190
+ tooltipStyle,
191
+ yAxesState, axisAssignmentsFor
192
+ ]
193
+ )
194
+
195
+ return null
196
+ }
197
+
198
+ /**
199
+ * Callback function that adds tooltip content and returns the tooltip width and text height
200
+ * @param seriesName The name of the series (i.e. the neuron ID)
201
+ * @param time The time (x-coordinate value) corresponding to the mouse location
202
+ * @param selected The selected datum (time, value)
203
+ * @param mouseCoords The coordinates of the mouse when the event was fired (relative to the plot container)
204
+ * @param chartId The ID of this chart
205
+ * @param container The plot container (SVGSVGElement)
206
+ * @param margin The plot margins
207
+ * @param tooltipStyle The style properties for the tooltip
208
+ * @param axis The category axis to which the time-series is associated
209
+ * @param plotDimensions The dimensions of the plot
210
+ * @param options The options passed through the the function that adds the tooltip content
211
+ * @return The width and text height of the tooltip content
212
+ */
213
+ function addTooltipContent(
214
+ seriesName: string,
215
+ time: number,
216
+ selected: Datum,
217
+ mouseCoords: [x: number, y: number],
218
+ chartId: number,
219
+ container: SVGSVGElement,
220
+ margin: Margin,
221
+ plotDimensions: Dimensions,
222
+ tooltipStyle: TooltipStyle,
223
+ axis: OrdinalStringAxis,
224
+ options: TooltipOptions
225
+ ): TooltipDimensions {
226
+ const {formatters} = options
227
+ const [x, ] = mouseCoords
228
+ const {time: spikeTime, value} = selected
229
+
230
+ // display the neuron ID in the tooltip
231
+ const header = d3.select<SVGSVGElement | null, any>(container)
232
+ .append<SVGTextElement>("text")
233
+ .attr('id', `tn${spikeTime}-${seriesName}-${chartId}`)
234
+ .attr('class', 'tooltip')
235
+ .attr('fill', tooltipStyle.fontColor)
236
+ .attr('font-family', 'sans-serif')
237
+ .attr('font-size', tooltipStyle.fontSize)
238
+ .attr('font-weight', tooltipStyle.fontWeight)
239
+ .text(() => seriesName)
240
+
241
+ // display the time (ms) and spike strength (mV) in the tooltip
242
+ const text = d3.select<SVGSVGElement | null, any>(container)
243
+ .append<SVGTextElement>("text")
244
+ .attr('id', `t${spikeTime}-${seriesName}-${chartId}`)
245
+ .attr('class', 'tooltip')
246
+ .attr('fill', tooltipStyle.fontColor)
247
+ .attr('font-family', 'sans-serif')
248
+ .attr('font-size', tooltipStyle.fontSize + 2)
249
+ .attr('font-weight', tooltipStyle.fontWeight + 150)
250
+ .text(() => `${formatters.x(spikeTime)}, ${formatters.y(value)}`)
251
+
252
+ // calculate the max width and height of the text
253
+ const tooltipWidth = Math.max(header.node()?.getBBox()?.width || 0, text.node()?.getBBox()?.width || 0);
254
+ const headerTextHeight = header.node()?.getBBox()?.height || 0;
255
+ const idHeight = text.node()?.getBBox()?.height || 0;
256
+ const textHeight = headerTextHeight + idHeight;
257
+
258
+ // set the header text location
259
+ // const spikeHeight = plotDimensions.height / liveDataRef.current.size
260
+ const xCoord = tooltipX(x, tooltipWidth, plotDimensions, tooltipStyle, margin)
261
+ const yCoord = categoryTooltipY(seriesName, textHeight, axis, tooltipStyle, margin, axis.scale.bandwidth(), plotDimensions)
262
+ const xTooltip = xCoord + tooltipStyle.paddingLeft
263
+ const yTooltip = yCoord + tooltipStyle.paddingTop
264
+ header
265
+ .attr('x', () => xTooltip)
266
+ .attr('y', () => yTooltip - idHeight + textHeight)
267
+
268
+ // set the tooltip text (i.e. neuron ID) location
269
+ text
270
+ .attr('x', () => xTooltip)
271
+ .attr('y', () => yTooltip + textHeight)
272
+
273
+ return {x: xCoord, y: yCoord, contentWidth: tooltipWidth, contentHeight: textHeight}
274
+ }