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,129 @@
1
+ import {noop} from "../utils";
2
+ import {useChart} from "../hooks/useChart";
3
+ import {TrackerSelection} from "../d3types";
4
+ import {
5
+ defaultTrackerLabelFont,
6
+ defaultTrackerStyle,
7
+ removeTrackerControl,
8
+ trackerControlInstance,
9
+ TrackerLabelFont,
10
+ TrackerStyle
11
+ } from "./trackerUtils";
12
+ import * as d3 from "d3";
13
+ import {useEffect, useMemo, useRef} from "react";
14
+ import {AxisLocation, BaseAxis, ContinuousNumericAxis} from "../axes/axes";
15
+ import {usePlotDimensions} from "../hooks/usePlotDimensions";
16
+
17
+ export interface TrackerAxisInfo {
18
+ x: number
19
+ axisLocation: AxisLocation
20
+ }
21
+
22
+ // map(axis_id -> tracker_axis_info)
23
+ export type TrackerAxisUpdate = Map<string, TrackerAxisInfo>
24
+
25
+ export enum TrackerLabelLocation {
26
+ Nowhere,
27
+ ByAxis,
28
+ }
29
+
30
+ interface Props {
31
+ visible: boolean
32
+ trackerAxis?: AxisLocation
33
+ labelLocation?: TrackerLabelLocation
34
+ labelFormatter?: (value: number) => string
35
+ style?: Partial<TrackerStyle>,
36
+ font?: Partial<TrackerLabelFont>,
37
+ onTrackerUpdate?: (update: TrackerAxisUpdate) => void
38
+ }
39
+
40
+ /**
41
+ * A tracker line that displays or reports the x or y coordinates at the mouse location. The tracker
42
+ * handles single axes and dual axes.
43
+ * @param props The tracker control properties
44
+ * @return null component
45
+ * @constructor
46
+ */
47
+ export function Tracker(props: Props): null {
48
+ const {
49
+ visible,
50
+ trackerAxis = AxisLocation.Bottom,
51
+ labelLocation = TrackerLabelLocation.ByAxis,
52
+ labelFormatter,
53
+ style,
54
+ font,
55
+ onTrackerUpdate = noop
56
+ } = props
57
+ const {
58
+ chartId,
59
+ container,
60
+ axes,
61
+ backgroundColor
62
+ } = useChart()
63
+
64
+ const {xAxesState, yAxesState} = axes
65
+ const axisState = (trackerAxis === AxisLocation.Bottom || trackerAxis === AxisLocation.Top) ?
66
+ xAxesState :
67
+ yAxesState
68
+
69
+ const {plotDimensions, margin} = usePlotDimensions()
70
+
71
+ const trackerStyle = useMemo(() => ({...defaultTrackerStyle, ...style}), [style])
72
+ const trackerFont = useMemo(() => ({...defaultTrackerLabelFont, ...font}), [font])
73
+ const trackerRef = useRef<TrackerSelection>(undefined)
74
+
75
+ const axisRef = useRef<Map<string, ContinuousNumericAxis>>(new Map())
76
+ useEffect(
77
+ () => {
78
+ const axes = new Map<string, ContinuousNumericAxis>()
79
+ axisState.axes.forEach((axis: BaseAxis, id: string) => axes.set(id, axis as ContinuousNumericAxis))
80
+ axisRef.current = axes
81
+ },
82
+ [axisState]
83
+ )
84
+
85
+ // when the container, tracker-control function, or visibility change, then we need to update the
86
+ // tracker control
87
+ useEffect(
88
+ () => {
89
+ if (container) {
90
+ const svg = d3.select<SVGSVGElement, any>(container)
91
+ if (visible && container) {
92
+ const trackerLabels = new Map<ContinuousNumericAxis, (x: number) => string>(
93
+ Array.from(axisRef.current.values()).map(axis => {
94
+ const formatter = labelFormatter ??
95
+ ((value: number) => labelLocation === TrackerLabelLocation.Nowhere ?
96
+ "" :
97
+ `${d3.format(",.0f")(value)}`
98
+ )
99
+ return [axis, formatter]
100
+ })
101
+ )
102
+
103
+ trackerRef.current = trackerControlInstance(
104
+ chartId,
105
+ container,
106
+ svg,
107
+ plotDimensions,
108
+ margin,
109
+ trackerStyle,
110
+ trackerFont,
111
+ trackerLabels,
112
+ labelLocation,
113
+ onTrackerUpdate,
114
+ trackerAxis,
115
+ backgroundColor
116
+ )
117
+ }
118
+ // if the tracker was defined and is now no longer defined (i.e., props changed, then remove the tracker)
119
+ else if (!visible && trackerRef.current !== undefined) {
120
+ removeTrackerControl(svg, trackerAxis)
121
+ trackerRef.current = undefined
122
+ }
123
+ }
124
+ },
125
+ [backgroundColor, chartId, container, labelFormatter, labelLocation, margin, onTrackerUpdate, plotDimensions, trackerAxis, trackerFont, trackerStyle, visible]
126
+ )
127
+
128
+ return null
129
+ }
@@ -0,0 +1,494 @@
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";
10
+
11
+ export interface TrackerLabelFont {
12
+ size: number
13
+ color: string
14
+ family: string
15
+ weight: number
16
+ }
17
+
18
+ export const defaultTrackerLabelFont: TrackerLabelFont = {
19
+ size: 12,
20
+ color: '#d2933f',
21
+ weight: 300,
22
+ family: 'sans-serif'
23
+ }
24
+
25
+ export interface TrackerStyle {
26
+ visible: boolean;
27
+ color: string,
28
+ lineWidth: number,
29
+ }
30
+
31
+ export const defaultTrackerStyle: TrackerStyle = {
32
+ visible: false,
33
+ color: '#d2933f',
34
+ lineWidth: 1,
35
+ }
36
+
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
+ const TRACKER_ID = "stream-chart-tracker"
42
+
43
+ /**
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
56
+ */
57
+ function horizontalTrackerLineId(chartId: number): string {
58
+ return `${TRACKER_ID}-line-horizontal-${chartId}`
59
+ }
60
+
61
+ /**
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
66
+ */
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
+ }
77
+
78
+ /**
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).
81
+ * @param chartId The ID of the chart
82
+ * @param container The SVG container
83
+ * @param svg The SVG selection
84
+ * @param plotDimensions The dimensions of the plot
85
+ * @param margin The margins around the plot
86
+ * @param style The tracker style
87
+ * @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)
90
+ * @param onTrackerUpdate A callback function that accepts the current tracker's axis information
91
+ * @param [axisLocation = AxisLocation.Bottom] The optional location of the axis for which the tracker is to
92
+ * be shown. Default is bottom.
93
+ * @param backgroundColor The background color of the tracker label
94
+ * @return The tracker selection
95
+ */
96
+ export function trackerControlInstance(
97
+ chartId: number,
98
+ container: SVGSVGElement,
99
+ svg: SvgSelection,
100
+ plotDimensions: Dimensions,
101
+ margin: Margin,
102
+ style: TrackerStyle,
103
+ labelFont: TrackerLabelFont,
104
+ label: Map<ContinuousNumericAxis, (x: number) => string>,
105
+ labelStyle: TrackerLabelLocation,
106
+ onTrackerUpdate: (update: TrackerAxisUpdate) => void,
107
+ axisLocation: AxisLocation = AxisLocation.Bottom,
108
+ backgroundColor: string
109
+ ): TrackerSelection {
110
+ switch (axisLocation) {
111
+ case AxisLocation.Bottom:
112
+ case AxisLocation.Top:
113
+ return verticalTrackerControlInstance(chartId, container, svg, plotDimensions, margin, style, labelFont, label, labelStyle, onTrackerUpdate, backgroundColor)
114
+ case AxisLocation.Left:
115
+ case AxisLocation.Right:
116
+ default:
117
+ return horizontalTrackerControlInstance(chartId, container, svg, plotDimensions, margin, style, labelFont, label, labelStyle, onTrackerUpdate, backgroundColor)
118
+ }
119
+ }
120
+
121
+ /**
122
+ * Creates or returns the existing SVG elements for displaying a vertical tracker line
123
+ * @param chartId The ID of the chart
124
+ * @param container The SVG container
125
+ * @param svg The SVG selection
126
+ * @param plotDimensions The dimensions of the plot
127
+ * @param margin The margins around the plot
128
+ * @param style The tracker style
129
+ * @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)
132
+ * @param onTrackerUpdate A callback function that accepts the current tracker's axis information
133
+ * @param backgroundColor The background color of the tracker label
134
+ * @return The tracker selection
135
+ */
136
+ function verticalTrackerControlInstance(
137
+ chartId: number,
138
+ container: SVGSVGElement,
139
+ svg: SvgSelection,
140
+ plotDimensions: Dimensions,
141
+ margin: Margin,
142
+ style: TrackerStyle,
143
+ labelFont: TrackerLabelFont,
144
+ label: Map<ContinuousNumericAxis, (x: number) => string>,
145
+ labelStyle: TrackerLabelLocation,
146
+ onTrackerUpdate: (update: TrackerAxisUpdate) => void,
147
+ 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(() => '')
183
+ })
184
+ }
185
+
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
+ )
193
+
194
+ return trackerLine
195
+ }
196
+
197
+ /**
198
+ * Creates or returns the existing SVG elements for displaying a horizontal tracker line
199
+ * @param chartId The ID of the chart
200
+ * @param container The SVG container
201
+ * @param svg The SVG selection
202
+ * @param plotDimensions The dimensions of the plot
203
+ * @param margin The margins around the plot
204
+ * @param style The tracker style
205
+ * @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)
208
+ * @param onTrackerUpdate A callback function that accepts the current tracker's axis information
209
+ * @param backgroundColor The background color of the tracker label
210
+ * @return The tracker selection
211
+ */
212
+ function horizontalTrackerControlInstance(
213
+ chartId: number,
214
+ container: SVGSVGElement,
215
+ svg: SvgSelection,
216
+ plotDimensions: Dimensions,
217
+ margin: Margin,
218
+ style: TrackerStyle,
219
+ labelFont: TrackerLabelFont,
220
+ label: Map<ContinuousNumericAxis, (x: number) => string>,
221
+ labelStyle: TrackerLabelLocation,
222
+ onTrackerUpdate: (update: TrackerAxisUpdate) => void,
223
+ 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)
286
+ }
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
+
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')
347
+
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))
380
+ }
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>
419
+ }
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
+ }
482
+
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))
492
+ }
493
+ }
494
+