stream-charts 1.1.2 → 1.2.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 (253) hide show
  1. package/README.md +70 -4
  2. package/changes.md +8 -0
  3. package/dist/{src/app → app}/charts/Chart.d.ts +27 -6
  4. package/dist/{src/app → app}/charts/Chart.js +2 -2
  5. package/dist/app/charts/Chart.js.map +1 -0
  6. package/dist/{src/app → app}/charts/axes/AxesState.d.ts +4 -4
  7. package/dist/{src/app → app}/charts/axes/AxesState.js +4 -4
  8. package/dist/app/charts/axes/AxesState.js.map +1 -0
  9. package/dist/app/charts/axes/AxesState.test.js.map +1 -0
  10. package/dist/app/charts/axes/AxisInterval.js.map +1 -0
  11. package/dist/app/charts/axes/AxisInterval.test.js.map +1 -0
  12. package/dist/app/charts/axes/BaseAxisRange.js.map +1 -0
  13. package/dist/{src/app → app}/charts/axes/ContinuousAxis.d.ts +1 -3
  14. package/dist/{src/app → app}/charts/axes/ContinuousAxis.js +2 -3
  15. package/dist/app/charts/axes/ContinuousAxis.js.map +1 -0
  16. package/dist/app/charts/axes/ContinuousAxisRange.js.map +1 -0
  17. package/dist/app/charts/axes/ContinuousAxisRange.test.js.map +1 -0
  18. package/dist/app/charts/axes/EmptyAxis.d.ts +12 -0
  19. package/dist/app/charts/axes/EmptyAxis.js +70 -0
  20. package/dist/app/charts/axes/EmptyAxis.js.map +1 -0
  21. package/dist/{src/app → app}/charts/axes/OrdinalAxis.d.ts +1 -3
  22. package/dist/{src/app → app}/charts/axes/OrdinalAxis.js +10 -4
  23. package/dist/app/charts/axes/OrdinalAxis.js.map +1 -0
  24. package/dist/app/charts/axes/OrdinalAxisRange.js.map +1 -0
  25. package/dist/app/charts/axes/OrdinalAxisRange.test.js.map +1 -0
  26. package/dist/{src/app → app}/charts/axes/axes.d.ts +28 -0
  27. package/dist/{src/app → app}/charts/axes/axes.js +86 -6
  28. package/dist/app/charts/axes/axes.js.map +1 -0
  29. package/dist/{src/app → app}/charts/d3types.js.map +1 -1
  30. package/dist/app/charts/filters/regexFilter.js.map +1 -0
  31. package/dist/app/charts/filters/regexFilter.test.js.map +1 -0
  32. package/dist/{src/app → app}/charts/hooks/useAxes.d.ts +3 -5
  33. package/dist/{src/app → app}/charts/hooks/useAxes.js +0 -1
  34. package/dist/app/charts/hooks/useAxes.js.map +1 -0
  35. package/dist/{src/app → app}/charts/hooks/useChart.d.ts +9 -5
  36. package/dist/{src/app → app}/charts/hooks/useChart.js +4 -3
  37. package/dist/app/charts/hooks/useChart.js.map +1 -0
  38. package/dist/{src/app → app}/charts/hooks/useDataObservable.d.ts +2 -4
  39. package/dist/{src/app → app}/charts/hooks/useDataObservable.js +0 -2
  40. package/dist/app/charts/hooks/useDataObservable.js.map +1 -0
  41. package/dist/{src/app → app}/charts/hooks/useInitialData.d.ts +2 -4
  42. package/dist/{src/app → app}/charts/hooks/useInitialData.js +0 -1
  43. package/dist/app/charts/hooks/useInitialData.js.map +1 -0
  44. package/dist/{src/app → app}/charts/hooks/useMouse.d.ts +6 -2
  45. package/dist/{src/app → app}/charts/hooks/useMouse.js +14 -14
  46. package/dist/app/charts/hooks/useMouse.js.map +1 -0
  47. package/dist/{src/app → app}/charts/hooks/usePlotDimensions.d.ts +1 -2
  48. package/dist/{src/app → app}/charts/hooks/usePlotDimensions.js +0 -1
  49. package/dist/app/charts/hooks/usePlotDimensions.js.map +1 -0
  50. package/dist/{src/app → app}/charts/hooks/useTooltip.d.ts +4 -4
  51. package/dist/{src/app → app}/charts/hooks/useTooltip.js +0 -1
  52. package/dist/app/charts/hooks/useTooltip.js.map +1 -0
  53. package/dist/app/charts/legends/Legend.d.ts +88 -0
  54. package/dist/app/charts/legends/Legend.js +425 -0
  55. package/dist/app/charts/legends/Legend.js.map +1 -0
  56. package/dist/app/charts/observables/ChartData.js.map +1 -0
  57. package/dist/app/charts/observables/iterates.js.map +1 -0
  58. package/dist/app/charts/observables/iterates.test.js.map +1 -0
  59. package/dist/app/charts/observables/ordinals.js.map +1 -0
  60. package/dist/app/charts/observables/ordinals.test.js.map +1 -0
  61. package/dist/{src/app → app}/charts/plots/BarPlot.d.ts +10 -12
  62. package/dist/{src/app → app}/charts/plots/BarPlot.js +14 -15
  63. package/dist/app/charts/plots/BarPlot.js.map +1 -0
  64. package/dist/{src/app → app}/charts/plots/PoincarePlot.d.ts +1 -3
  65. package/dist/{src/app → app}/charts/plots/PoincarePlot.js +0 -1
  66. package/dist/app/charts/plots/PoincarePlot.js.map +1 -0
  67. package/dist/{src/app → app}/charts/plots/RasterPlot.d.ts +1 -3
  68. package/dist/{src/app → app}/charts/plots/RasterPlot.js +12 -7
  69. package/dist/app/charts/plots/RasterPlot.js.map +1 -0
  70. package/dist/{src/app → app}/charts/plots/ScatterPlot.d.ts +1 -3
  71. package/dist/{src/app → app}/charts/plots/ScatterPlot.js +7 -6
  72. package/dist/app/charts/plots/ScatterPlot.js.map +1 -0
  73. package/dist/app/charts/plots/plot.js.map +1 -0
  74. package/dist/app/charts/series/baseSeries.js.map +1 -0
  75. package/dist/app/charts/series/datumSeries.test.js.map +1 -0
  76. package/dist/app/charts/series/iterateSeries.js.map +1 -0
  77. package/dist/app/charts/series/ordinalSeries.js.map +1 -0
  78. package/dist/app/charts/series/timeSeries.js.map +1 -0
  79. package/dist/app/charts/series/timeSeriesChartData.js.map +1 -0
  80. package/dist/app/charts/styling/barPlotStyle.js.map +1 -0
  81. package/dist/app/charts/styling/margins.js.map +1 -0
  82. package/dist/app/charts/styling/margins.test.js.map +1 -0
  83. package/dist/app/charts/styling/svgStyle.js.map +1 -0
  84. package/dist/app/charts/subscriptions/subscription.test.js.map +1 -0
  85. package/dist/app/charts/subscriptions/subscriptions.js.map +1 -0
  86. package/dist/{src/app → app}/charts/tooltips/BarPlotTooltipContent.d.ts +1 -3
  87. package/dist/{src/app → app}/charts/tooltips/BarPlotTooltipContent.js +0 -1
  88. package/dist/app/charts/tooltips/BarPlotTooltipContent.js.map +1 -0
  89. package/dist/{src/app → app}/charts/tooltips/PoincarePlotTooltipContent.d.ts +1 -3
  90. package/dist/{src/app → app}/charts/tooltips/PoincarePlotTooltipContent.js +0 -1
  91. package/dist/app/charts/tooltips/PoincarePlotTooltipContent.js.map +1 -0
  92. package/dist/{src/app → app}/charts/tooltips/RasterPlotTooltipContent.d.ts +1 -3
  93. package/dist/{src/app → app}/charts/tooltips/RasterPlotTooltipContent.js +0 -1
  94. package/dist/app/charts/tooltips/RasterPlotTooltipContent.js.map +1 -0
  95. package/dist/{src/app → app}/charts/tooltips/ScatterPlotTooltipContent.d.ts +1 -3
  96. package/dist/{src/app → app}/charts/tooltips/ScatterPlotTooltipContent.js +3 -2
  97. package/dist/app/charts/tooltips/ScatterPlotTooltipContent.js.map +1 -0
  98. package/dist/{src/app → app}/charts/tooltips/Tooltip.d.ts +10 -11
  99. package/dist/{src/app → app}/charts/tooltips/Tooltip.js +12 -12
  100. package/dist/app/charts/tooltips/Tooltip.js.map +1 -0
  101. package/dist/app/charts/tooltips/tooltipUtils.js.map +1 -0
  102. package/dist/{src/app → app}/charts/trackers/Tracker.d.ts +1 -3
  103. package/dist/{src/app → app}/charts/trackers/Tracker.js +0 -1
  104. package/dist/app/charts/trackers/Tracker.js.map +1 -0
  105. package/dist/app/charts/trackers/trackerUtils.js.map +1 -0
  106. package/dist/app/charts/utils.js.map +1 -0
  107. package/dist/{src/index.d.ts → index.d.ts} +20 -24
  108. package/dist/{src/index.js → index.js} +19 -19
  109. package/dist/index.js.map +1 -0
  110. package/package.json +20 -8
  111. package/src/app/charts/Chart.tsx +29 -5
  112. package/src/app/charts/axes/AxesState.ts +4 -4
  113. package/src/app/charts/axes/ContinuousAxis.tsx +3 -4
  114. package/src/app/charts/axes/EmptyAxis.tsx +119 -0
  115. package/src/app/charts/axes/OrdinalAxis.tsx +15 -4
  116. package/src/app/charts/axes/axes.ts +116 -0
  117. package/src/app/charts/hooks/useAxes.tsx +3 -4
  118. package/src/app/charts/hooks/useChart.tsx +13 -5
  119. package/src/app/charts/hooks/useDataObservable.tsx +2 -7
  120. package/src/app/charts/hooks/useInitialData.tsx +2 -3
  121. package/src/app/charts/hooks/useMouse.tsx +16 -13
  122. package/src/app/charts/hooks/usePlotDimensions.tsx +1 -2
  123. package/src/app/charts/hooks/useTooltip.tsx +4 -5
  124. package/src/app/charts/legends/Legend.tsx +600 -0
  125. package/src/app/charts/plots/BarPlot.tsx +15 -16
  126. package/src/app/charts/plots/PoincarePlot.tsx +1 -2
  127. package/src/app/charts/plots/RasterPlot.tsx +21 -8
  128. package/src/app/charts/plots/ScatterPlot.tsx +9 -11
  129. package/src/app/charts/tooltips/BarPlotTooltipContent.tsx +1 -2
  130. package/src/app/charts/tooltips/PoincarePlotTooltipContent.tsx +1 -2
  131. package/src/app/charts/tooltips/RasterPlotTooltipContent.tsx +1 -2
  132. package/src/app/charts/tooltips/ScatterPlotTooltipContent.tsx +3 -2
  133. package/src/app/charts/tooltips/Tooltip.tsx +11 -11
  134. package/src/app/charts/trackers/Tracker.tsx +1 -2
  135. package/src/index.ts +322 -0
  136. package/dist/src/app/charts/Chart.js.map +0 -1
  137. package/dist/src/app/charts/axes/AxesState.js.map +0 -1
  138. package/dist/src/app/charts/axes/AxesState.test.js.map +0 -1
  139. package/dist/src/app/charts/axes/AxisInterval.js.map +0 -1
  140. package/dist/src/app/charts/axes/AxisInterval.test.js.map +0 -1
  141. package/dist/src/app/charts/axes/BaseAxisRange.js.map +0 -1
  142. package/dist/src/app/charts/axes/ContinuousAxis.js.map +0 -1
  143. package/dist/src/app/charts/axes/ContinuousAxisRange.js.map +0 -1
  144. package/dist/src/app/charts/axes/ContinuousAxisRange.test.js.map +0 -1
  145. package/dist/src/app/charts/axes/OrdinalAxis.js.map +0 -1
  146. package/dist/src/app/charts/axes/OrdinalAxisRange.js.map +0 -1
  147. package/dist/src/app/charts/axes/OrdinalAxisRange.test.js.map +0 -1
  148. package/dist/src/app/charts/axes/axes.js.map +0 -1
  149. package/dist/src/app/charts/filters/regexFilter.js.map +0 -1
  150. package/dist/src/app/charts/filters/regexFilter.test.js.map +0 -1
  151. package/dist/src/app/charts/hooks/useAxes.js.map +0 -1
  152. package/dist/src/app/charts/hooks/useChart.js.map +0 -1
  153. package/dist/src/app/charts/hooks/useDataObservable.js.map +0 -1
  154. package/dist/src/app/charts/hooks/useInitialData.js.map +0 -1
  155. package/dist/src/app/charts/hooks/useMouse.js.map +0 -1
  156. package/dist/src/app/charts/hooks/usePlotDimensions.js.map +0 -1
  157. package/dist/src/app/charts/hooks/useTooltip.js.map +0 -1
  158. package/dist/src/app/charts/observables/ChartData.js.map +0 -1
  159. package/dist/src/app/charts/observables/iterates.js.map +0 -1
  160. package/dist/src/app/charts/observables/iterates.test.js.map +0 -1
  161. package/dist/src/app/charts/observables/ordinals.js.map +0 -1
  162. package/dist/src/app/charts/observables/ordinals.test.js.map +0 -1
  163. package/dist/src/app/charts/plots/BarPlot.js.map +0 -1
  164. package/dist/src/app/charts/plots/PoincarePlot.js.map +0 -1
  165. package/dist/src/app/charts/plots/RasterPlot.js.map +0 -1
  166. package/dist/src/app/charts/plots/ScatterPlot.js.map +0 -1
  167. package/dist/src/app/charts/plots/plot.js.map +0 -1
  168. package/dist/src/app/charts/series/baseSeries.js.map +0 -1
  169. package/dist/src/app/charts/series/datumSeries.test.js.map +0 -1
  170. package/dist/src/app/charts/series/iterateSeries.js.map +0 -1
  171. package/dist/src/app/charts/series/ordinalSeries.js.map +0 -1
  172. package/dist/src/app/charts/series/timeSeries.js.map +0 -1
  173. package/dist/src/app/charts/series/timeSeriesChartData.js.map +0 -1
  174. package/dist/src/app/charts/styling/barPlotStyle.js.map +0 -1
  175. package/dist/src/app/charts/styling/margins.js.map +0 -1
  176. package/dist/src/app/charts/styling/margins.test.js.map +0 -1
  177. package/dist/src/app/charts/styling/svgStyle.js.map +0 -1
  178. package/dist/src/app/charts/subscriptions/subscription.test.js.map +0 -1
  179. package/dist/src/app/charts/subscriptions/subscriptions.js.map +0 -1
  180. package/dist/src/app/charts/tooltips/BarPlotTooltipContent.js.map +0 -1
  181. package/dist/src/app/charts/tooltips/PoincarePlotTooltipContent.js.map +0 -1
  182. package/dist/src/app/charts/tooltips/RasterPlotTooltipContent.js.map +0 -1
  183. package/dist/src/app/charts/tooltips/ScatterPlotTooltipContent.js.map +0 -1
  184. package/dist/src/app/charts/tooltips/Tooltip.js.map +0 -1
  185. package/dist/src/app/charts/tooltips/tooltipUtils.js.map +0 -1
  186. package/dist/src/app/charts/trackers/Tracker.js.map +0 -1
  187. package/dist/src/app/charts/trackers/trackerUtils.js.map +0 -1
  188. package/dist/src/app/charts/utils.js.map +0 -1
  189. package/dist/src/index.js.map +0 -1
  190. /package/dist/{src/app → app}/charts/axes/AxesState.test.d.ts +0 -0
  191. /package/dist/{src/app → app}/charts/axes/AxesState.test.js +0 -0
  192. /package/dist/{src/app → app}/charts/axes/AxisInterval.d.ts +0 -0
  193. /package/dist/{src/app → app}/charts/axes/AxisInterval.js +0 -0
  194. /package/dist/{src/app → app}/charts/axes/AxisInterval.test.d.ts +0 -0
  195. /package/dist/{src/app → app}/charts/axes/AxisInterval.test.js +0 -0
  196. /package/dist/{src/app → app}/charts/axes/BaseAxisRange.d.ts +0 -0
  197. /package/dist/{src/app → app}/charts/axes/BaseAxisRange.js +0 -0
  198. /package/dist/{src/app → app}/charts/axes/ContinuousAxisRange.d.ts +0 -0
  199. /package/dist/{src/app → app}/charts/axes/ContinuousAxisRange.js +0 -0
  200. /package/dist/{src/app → app}/charts/axes/ContinuousAxisRange.test.d.ts +0 -0
  201. /package/dist/{src/app → app}/charts/axes/ContinuousAxisRange.test.js +0 -0
  202. /package/dist/{src/app → app}/charts/axes/OrdinalAxisRange.d.ts +0 -0
  203. /package/dist/{src/app → app}/charts/axes/OrdinalAxisRange.js +0 -0
  204. /package/dist/{src/app → app}/charts/axes/OrdinalAxisRange.test.d.ts +0 -0
  205. /package/dist/{src/app → app}/charts/axes/OrdinalAxisRange.test.js +0 -0
  206. /package/dist/{src/app → app}/charts/d3types.d.ts +0 -0
  207. /package/dist/{src/app → app}/charts/d3types.js +0 -0
  208. /package/dist/{src/app → app}/charts/filters/regexFilter.d.ts +0 -0
  209. /package/dist/{src/app → app}/charts/filters/regexFilter.js +0 -0
  210. /package/dist/{src/app → app}/charts/filters/regexFilter.test.d.ts +0 -0
  211. /package/dist/{src/app → app}/charts/filters/regexFilter.test.js +0 -0
  212. /package/dist/{src/app → app}/charts/observables/ChartData.d.ts +0 -0
  213. /package/dist/{src/app → app}/charts/observables/ChartData.js +0 -0
  214. /package/dist/{src/app → app}/charts/observables/iterates.d.ts +0 -0
  215. /package/dist/{src/app → app}/charts/observables/iterates.js +0 -0
  216. /package/dist/{src/app → app}/charts/observables/iterates.test.d.ts +0 -0
  217. /package/dist/{src/app → app}/charts/observables/iterates.test.js +0 -0
  218. /package/dist/{src/app → app}/charts/observables/ordinals.d.ts +0 -0
  219. /package/dist/{src/app → app}/charts/observables/ordinals.js +0 -0
  220. /package/dist/{src/app → app}/charts/observables/ordinals.test.d.ts +0 -0
  221. /package/dist/{src/app → app}/charts/observables/ordinals.test.js +0 -0
  222. /package/dist/{src/app → app}/charts/plots/plot.d.ts +0 -0
  223. /package/dist/{src/app → app}/charts/plots/plot.js +0 -0
  224. /package/dist/{src/app → app}/charts/series/baseSeries.d.ts +0 -0
  225. /package/dist/{src/app → app}/charts/series/baseSeries.js +0 -0
  226. /package/dist/{src/app → app}/charts/series/datumSeries.test.d.ts +0 -0
  227. /package/dist/{src/app → app}/charts/series/datumSeries.test.js +0 -0
  228. /package/dist/{src/app → app}/charts/series/iterateSeries.d.ts +0 -0
  229. /package/dist/{src/app → app}/charts/series/iterateSeries.js +0 -0
  230. /package/dist/{src/app → app}/charts/series/ordinalSeries.d.ts +0 -0
  231. /package/dist/{src/app → app}/charts/series/ordinalSeries.js +0 -0
  232. /package/dist/{src/app → app}/charts/series/timeSeries.d.ts +0 -0
  233. /package/dist/{src/app → app}/charts/series/timeSeries.js +0 -0
  234. /package/dist/{src/app → app}/charts/series/timeSeriesChartData.d.ts +0 -0
  235. /package/dist/{src/app → app}/charts/series/timeSeriesChartData.js +0 -0
  236. /package/dist/{src/app → app}/charts/styling/barPlotStyle.d.ts +0 -0
  237. /package/dist/{src/app → app}/charts/styling/barPlotStyle.js +0 -0
  238. /package/dist/{src/app → app}/charts/styling/margins.d.ts +0 -0
  239. /package/dist/{src/app → app}/charts/styling/margins.js +0 -0
  240. /package/dist/{src/app → app}/charts/styling/margins.test.d.ts +0 -0
  241. /package/dist/{src/app → app}/charts/styling/margins.test.js +0 -0
  242. /package/dist/{src/app → app}/charts/styling/svgStyle.d.ts +0 -0
  243. /package/dist/{src/app → app}/charts/styling/svgStyle.js +0 -0
  244. /package/dist/{src/app → app}/charts/subscriptions/subscription.test.d.ts +0 -0
  245. /package/dist/{src/app → app}/charts/subscriptions/subscription.test.js +0 -0
  246. /package/dist/{src/app → app}/charts/subscriptions/subscriptions.d.ts +0 -0
  247. /package/dist/{src/app → app}/charts/subscriptions/subscriptions.js +0 -0
  248. /package/dist/{src/app → app}/charts/tooltips/tooltipUtils.d.ts +0 -0
  249. /package/dist/{src/app → app}/charts/tooltips/tooltipUtils.js +0 -0
  250. /package/dist/{src/app → app}/charts/trackers/trackerUtils.d.ts +0 -0
  251. /package/dist/{src/app → app}/charts/trackers/trackerUtils.js +0 -0
  252. /package/dist/{src/app → app}/charts/utils.d.ts +0 -0
  253. /package/dist/{src/app → app}/charts/utils.js +0 -0
@@ -0,0 +1,600 @@
1
+ import {BaseAxis, defaultLineStyle, SeriesLineStyle, SeriesStyle} from "../axes/axes";
2
+ import {BaseAxisRange} from "../axes/BaseAxisRange";
3
+ import {usePlotDimensions} from "../hooks/usePlotDimensions";
4
+ import {useChart} from "../hooks/useChart";
5
+ import {useInitialData} from "../hooks/useInitialData";
6
+ import React, {useCallback, useEffect, useMemo, useRef, useState} from "react";
7
+ import {createPortal} from "react-dom";
8
+ import * as d3 from "d3";
9
+
10
+ export enum LegendLocation {
11
+ // noinspection JSUnusedGlobalSymbols
12
+ TOP_LEFT = "top-left",
13
+ TOP_RIGHT = "top-right",
14
+ BOTTOM_LEFT = "bottom-left",
15
+ BOTTOM_RIGHT = "bottom-right",
16
+ EXTERNAL_CONTAINER = "external-container"
17
+ }
18
+
19
+ export interface LegendStyle {
20
+ /** Font size for the legend labels */
21
+ fontSize: number
22
+ /** Font family for the legend labels */
23
+ fontFamily: string
24
+ /** Font color for the legend labels */
25
+ fontColor: string
26
+ /** Background fill color for the legend box */
27
+ backgroundColor: string
28
+ /** Background opacity for the legend box */
29
+ backgroundOpacity: number
30
+ /** Border/stroke color for the legend box */
31
+ borderColor: string
32
+ /** Border width for the legend box */
33
+ borderWidth: number
34
+ /** Border opacity for the legend box */
35
+ borderOpacity: number
36
+ /** Corner radius of the legend box */
37
+ borderRadius: number
38
+ /** Padding inside the legend box (in pixels) */
39
+ padding: number
40
+ /** Vertical space between legend entries */
41
+ rowGap: number
42
+ /** Width of the color swatch next to each label */
43
+ swatchWidth: number
44
+ /** Height of the color swatch next to each label */
45
+ swatchHeight: number
46
+ /** Gap between the swatch and the label text */
47
+ swatchLabelGap: number
48
+ /** Maximum height of the legend before it starts scrolling (in pixels). If not provided, defaults to the plot height. */
49
+ maxHeight?: number
50
+ /** Duration of the visibility transition in milliseconds */
51
+ transitionDuration: number
52
+ }
53
+
54
+ export const defaultLegendStyle: LegendStyle = {
55
+ fontSize: 12,
56
+ fontFamily: "sans-serif",
57
+ fontColor: "#d2933f",
58
+ backgroundColor: "#202020",
59
+ backgroundOpacity: 0.85,
60
+ borderColor: "#d2933f",
61
+ borderWidth: 1,
62
+ borderOpacity: 0.7,
63
+ borderRadius: 4,
64
+ padding: 8,
65
+ rowGap: 6,
66
+ swatchWidth: 16,
67
+ swatchHeight: 3,
68
+ swatchLabelGap: 6,
69
+ transitionDuration: 350,
70
+ }
71
+
72
+ export interface Props {
73
+ /** Whether the legend is visible */
74
+ visible: boolean
75
+ /**
76
+ * Where to anchor the legend within the plot area.
77
+ * Ignored when `container` is provided.
78
+ * @default LegendLocation.TOP_RIGHT
79
+ */
80
+ location?: LegendLocation
81
+ /** Style overrides for the legend */
82
+ style?: Partial<LegendStyle>
83
+ /**
84
+ * Optional offset in pixels from the chosen corner, applied after the margin.
85
+ * Ignored when `container` is provided.
86
+ * @default { x: 10, y: 10 }
87
+ */
88
+ offset?: { x: number; y: number }
89
+ /**
90
+ * When provided, the legend renders as an HTML element portal into this
91
+ * external container instead of inside the chart SVG. Position the container
92
+ * however you like — the legend fills it.
93
+ */
94
+ container?: React.RefObject<HTMLElement | null>
95
+ }
96
+
97
+ const LEGEND_CONTAINER_ID_PREFIX = "stream-charts-legend"
98
+
99
+ /**
100
+ * A legend component that can be placed inside any `<Chart>` alongside any Plot.
101
+ * It automatically reads the series names from the initial data and their colors
102
+ * from the `seriesStyles` map (falling back to the chart's base `color`).
103
+ * The legend respects the active `seriesFilter`, showing only the matching series.
104
+ *
105
+ * @example
106
+ * ```tsx
107
+ * <Chart ...>
108
+ * <ContinuousAxis ... />
109
+ * <ScatterPlot ... />
110
+ * <Legend visible={true} location={LegendLocation.TOP_RIGHT} />
111
+ * </Chart>
112
+ * ```
113
+ */
114
+ // noinspection JSUnusedGlobalSymbols
115
+ export function Legend<D, S extends SeriesStyle, TM, AR extends BaseAxisRange, A extends BaseAxis>(
116
+ props: Props
117
+ ): React.ReactElement | null {
118
+ const {
119
+ visible,
120
+ location = LegendLocation.TOP_RIGHT,
121
+ offset = {x: 10, y: 10},
122
+ style,
123
+ container: externalContainer
124
+ } = props
125
+
126
+ const {chartId, container, color, seriesStyles, seriesFilter, mouse, hoveredSeriesRef} = useChart<D, S, TM, AR, A>()
127
+ const {margin, plotDimensions} = usePlotDimensions()
128
+ const {initialData} = useInitialData<any, D>()
129
+
130
+ // the mouse over series name interferes with scrolling, so we keep track of the
131
+ // scrolling state so the series-name mouse-over can be disabled during scrolling
132
+ const wheelTimeoutRef = useRef<NodeJS.Timeout>(undefined)
133
+ const isWheelingRef = useRef(false)
134
+
135
+ const scrollYRef = useRef<number>(0)
136
+
137
+ // keep track of whether the mouse is in the legend so that we can restore the legend
138
+ // opacity when the mouse leaves and is not hovering over a series
139
+ const [mouseInLegend, setMouseInLegend] = useState<boolean>(false)
140
+
141
+ const legendStyle = useMemo<LegendStyle>(
142
+ () => ({
143
+ ...defaultLegendStyle,
144
+ maxHeight: style?.maxHeight ?? plotDimensions.height - 4 * Math.max(style?.swatchHeight ?? defaultLegendStyle.swatchHeight, style?.fontSize ?? defaultLegendStyle.swatchHeight),
145
+ ...style
146
+ }),
147
+ [style, plotDimensions.height]
148
+ )
149
+
150
+ // Refs don't trigger re-renders when populated, so track readiness in state
151
+ const [externalContainerReady, setExternalContainerReady] = useState(false)
152
+ useEffect(() => {
153
+ setExternalContainerReady(!!externalContainer?.current)
154
+ }, [externalContainer])
155
+
156
+ // Track the currently hovered series name so legend entries can be highlighted
157
+ const [hoveredSeriesName, setHoveredSeriesName] = useState<string | null>(null)
158
+ useEffect(() => {
159
+ const handlerId = `legend-${chartId}`
160
+ mouse.registerMouseOverHandler(handlerId, seriesName => setHoveredSeriesName(seriesName))
161
+ mouse.registerMouseLeaveHandler(handlerId, () => setHoveredSeriesName(null))
162
+ return () => {
163
+ mouse.unregisterMouseOverHandler(handlerId)
164
+ mouse.unregisterMouseLeaveHandler(handlerId)
165
+ }
166
+ }, [chartId, mouse])
167
+
168
+ // Keep a ref so D3 closures in the SVG legend always read current styles
169
+ const seriesStylesRef = useRef<Map<string, S>>(seriesStyles)
170
+ seriesStylesRef.current = seriesStyles
171
+
172
+ const highlightSeriesInPlot = useCallback<(name: string) => void>(name => {
173
+ hoveredSeriesRef.current = name
174
+ if (!container) return
175
+ const {
176
+ highlightColor,
177
+ highlightWidth
178
+ } = (seriesStylesRef.current.get(name) as SeriesLineStyle | undefined) || defaultLineStyle()
179
+ d3.select(container)
180
+ .selectAll<SVGPathElement, unknown>(`path[data-series-name="${name}"], line[data-series-name="${name}"]`)
181
+ .attr('stroke', highlightColor)
182
+ .attr('stroke-width', highlightWidth)
183
+ }, [container, hoveredSeriesRef])
184
+
185
+ const restoreSeriesInPlot = useCallback<(name: string) => void>(name => {
186
+ hoveredSeriesRef.current = null
187
+ if (!container) return
188
+ const {
189
+ color,
190
+ lineWidth
191
+ } = (seriesStylesRef.current.get(name) as SeriesLineStyle | undefined) || defaultLineStyle()
192
+ d3.select(container)
193
+ .selectAll<SVGPathElement, unknown>(`path[data-series-name="${name}"], line[data-series-name="${name}"]`)
194
+ .attr('stroke', color)
195
+ .attr('stroke-width', lineWidth)
196
+ }, [container, hoveredSeriesRef])
197
+
198
+ // Derive the filtered list of series names
199
+ const visibleSeriesNames = useMemo<Array<string>>(
200
+ () => initialData.map(s => s.name).filter(name => seriesFilter.test(name)),
201
+ [initialData, seriesFilter]
202
+ )
203
+
204
+ useEffect(
205
+ () => {
206
+ if (!container) return
207
+
208
+ const legendId = `${LEGEND_CONTAINER_ID_PREFIX}-${chartId}`
209
+ const svg = d3.select<SVGSVGElement, unknown>(container)
210
+ const {transitionDuration} = legendStyle
211
+
212
+ if (externalContainer) {
213
+ svg.select(`#${legendId}`).remove()
214
+ return
215
+ }
216
+
217
+ if (!visible || visibleSeriesNames.length === 0) {
218
+ svg.select(`#${legendId}`).remove()
219
+ return
220
+ }
221
+
222
+ // Remove any existing legend (before we potentially redraw) or just reuse?
223
+ // Usually, redrawing is safer if we want to ensure everything is in the right place.
224
+ // But if we're transitioning from visible: false to true, the old one might be gone.
225
+ // Let's just remove without transition for redrawing, except when explicitly making it invisible.
226
+ svg.select(`#${legendId}`).remove()
227
+
228
+ const {
229
+ fontSize,
230
+ fontFamily,
231
+ fontColor,
232
+ backgroundColor,
233
+ backgroundOpacity,
234
+ borderColor,
235
+ borderWidth,
236
+ borderOpacity,
237
+ borderRadius,
238
+ padding,
239
+ rowGap,
240
+ swatchWidth,
241
+ swatchHeight,
242
+ swatchLabelGap,
243
+ maxHeight,
244
+ } = legendStyle
245
+
246
+ const rowHeight = Math.max(swatchHeight, fontSize)
247
+ const totalRows = visibleSeriesNames.length
248
+ const contentHeight = totalRows * rowHeight + (totalRows - 1) * rowGap
249
+ const totalContentHeight = contentHeight + 2 * padding
250
+ const boxHeight = maxHeight !== undefined ? Math.min(totalContentHeight, maxHeight) : totalContentHeight
251
+
252
+ // Use a temporary hidden SVG text element to measure max label width
253
+ const tempText = svg
254
+ .append<SVGTextElement>("text")
255
+ .style("font-size", `${fontSize}px`)
256
+ .style("font-family", fontFamily)
257
+ .style("visibility", "hidden")
258
+
259
+ let maxLabelWidth = 0
260
+ visibleSeriesNames.forEach(name => {
261
+ tempText.text(name)
262
+ const w = tempText.node()?.getBBox().width ?? name.length * (fontSize * 0.6)
263
+ if (w > maxLabelWidth) maxLabelWidth = w
264
+ })
265
+ tempText.remove()
266
+
267
+ const boxWidth = padding + swatchWidth + swatchLabelGap + maxLabelWidth + padding
268
+
269
+ // Determine the (x, y) position of the legend box within the SVG (plot area coordinates)
270
+ const plotLeft = margin.left
271
+ const plotTop = margin.top
272
+ const plotRight = margin.left + plotDimensions.width
273
+ const plotBottom = margin.top + plotDimensions.height
274
+
275
+ let boxX: number
276
+ let boxY: number
277
+
278
+ switch (location) {
279
+ case LegendLocation.TOP_LEFT:
280
+ boxX = plotLeft + offset.x
281
+ boxY = plotTop + offset.y
282
+ break
283
+ case LegendLocation.TOP_RIGHT:
284
+ boxX = plotRight - boxWidth - offset.x
285
+ boxY = plotTop + offset.y
286
+ break
287
+ case LegendLocation.BOTTOM_LEFT:
288
+ boxX = plotLeft + offset.x
289
+ boxY = plotBottom - boxHeight - offset.y
290
+ break
291
+ case LegendLocation.BOTTOM_RIGHT:
292
+ default:
293
+ boxX = plotRight - boxWidth - offset.x
294
+ boxY = plotBottom - boxHeight - offset.y
295
+ break
296
+ }
297
+
298
+ // Create the legend container group
299
+ const legendG = svg
300
+ .append<SVGGElement>("g")
301
+ .attr("id", legendId)
302
+ .attr("transform", `translate(${boxX}, ${boxY})`)
303
+ .style("opacity", 0)
304
+ .on("mouseover", () => {
305
+ setMouseInLegend(true)
306
+ })
307
+ .on("mouseleave", () => {
308
+ setMouseInLegend(false)
309
+ })
310
+
311
+ // Apply transition for shimmering effect
312
+ legendG
313
+ .style("transition", `opacity ${transitionDuration}ms ease-in-out`)
314
+ .style("opacity", 1)
315
+
316
+ // Background box
317
+ legendG
318
+ .append("rect")
319
+ .attr("x", 0)
320
+ .attr("y", 0)
321
+ .attr("width", boxWidth)
322
+ .attr("height", boxHeight)
323
+ .attr("rx", borderRadius)
324
+ .attr("fill", backgroundColor)
325
+ .attr("fill-opacity", backgroundOpacity)
326
+ .attr("stroke", borderColor)
327
+ .attr("stroke-width", borderWidth)
328
+ .attr("stroke-opacity", borderOpacity)
329
+
330
+ const innerG = legendG
331
+ .append("g")
332
+ .attr("class", "legend-content")
333
+ .attr("transform", `translate(0, ${-scrollYRef.current})`)
334
+
335
+ // If we have a max height and the content is taller, we'd need a scrollbar.
336
+ // In SVG, we can use a clipPath and handle scroll events manually, or use foreignObject.
337
+ // foreignObject is generally better for this if we want real scrollbars.
338
+ const isScrolling = maxHeight !== undefined && totalContentHeight > maxHeight
339
+
340
+ if (isScrolling) {
341
+ const clipId = `legend-clip-${chartId}`
342
+ // Remove existing clipPath for this legend to avoid duplicates
343
+ svg.select(`#${clipId}`).remove()
344
+ //
345
+ svg.append("defs")
346
+ .append("clipPath")
347
+ .attr("id", clipId)
348
+ .attr("clipPathUnits", "userSpaceOnUse")
349
+ .append("rect")
350
+ .attr("x", 0)
351
+ .attr("y", 0)
352
+ .attr("width", boxWidth)
353
+ .attr("height", boxHeight)
354
+
355
+ legendG.attr("clip-path", `url(#${clipId})`)
356
+
357
+ // Simple scroll handling via mouse wheel
358
+ legendG.on("wheel", (event: WheelEvent) => {
359
+ event.preventDefault()
360
+ // scrollBarVisibleRef.current = true
361
+ isWheelingRef.current = true
362
+ const maxScroll = totalContentHeight - boxHeight
363
+ scrollYRef.current = Math.max(0, Math.min(maxScroll, scrollYRef.current + event.deltaY))
364
+ innerG.attr("transform", `translate(0, ${-scrollYRef.current})`)
365
+
366
+ // Clear the existing timer if the user is still wheeling
367
+ clearTimeout(wheelTimeoutRef.current);
368
+
369
+ // Set a new timer to fire after 100-200ms of inactivity
370
+ wheelTimeoutRef.current = setTimeout(() => {
371
+ isWheelingRef.current = false
372
+ // scrollBarVisibleRef.current = false
373
+ console.log(`Wheel movement has ended. ${isWheelingRef.current ? "Still wheeling." : "No longer wheeling."}`);
374
+ }, 150);
375
+ }, {passive: false})
376
+
377
+ // Visual scrollbar (optional but good for visibility)
378
+ const scrollbarWidth = 4
379
+ const scrollbarHeight = (boxHeight / totalContentHeight) * boxHeight - padding
380
+ const scrollbar = legendG.append("rect")
381
+ .attr("class", "legend-scrollbar")
382
+ .attr("x", boxWidth - scrollbarWidth - 2)
383
+ .attr("y", calculateScrollbarY(totalContentHeight, boxHeight, scrollYRef.current, scrollbarHeight, padding))
384
+ .attr("width", scrollbarWidth)
385
+ .attr("height", scrollbarHeight)
386
+ .attr("rx", scrollbarWidth / 2)
387
+ .style("fill-opacity", mouseInLegend ? 0.25 : 0)
388
+ .attr("fill", fontColor)
389
+
390
+ legendG.on("wheel.scrollbar", (_: WheelEvent) => {
391
+ scrollbar.attr("y", calculateScrollbarY(totalContentHeight, boxHeight, scrollYRef.current, scrollbarHeight, padding))
392
+ })
393
+ }
394
+
395
+ // Legend rows
396
+ visibleSeriesNames.forEach((name, i) => {
397
+ const seriesColor = seriesStyles.get(name)?.color ?? color
398
+ const rowY = padding + i * (rowHeight + rowGap)
399
+ const swatchMidY = rowY + rowHeight / 2
400
+
401
+ const rowG = innerG
402
+ .append("g")
403
+ .attr("class", "legend-row")
404
+ .attr("data-series-name", name)
405
+ .style("cursor", "default")
406
+
407
+ // Color swatch — a short horizontal line to mimic series appearance
408
+ rowG
409
+ .append("line")
410
+ .attr("x1", padding)
411
+ .attr("y1", swatchMidY)
412
+ .attr("x2", padding + swatchWidth)
413
+ .attr("y2", swatchMidY)
414
+ .attr("stroke", seriesColor)
415
+ .attr("stroke-width", swatchHeight)
416
+ .attr("stroke-linecap", "round")
417
+
418
+ // Series name label
419
+ rowG
420
+ .append("text")
421
+ .attr("x", padding + swatchWidth + swatchLabelGap)
422
+ .attr("y", swatchMidY)
423
+ .attr("dominant-baseline", "middle")
424
+ .attr("data-series-name", name)
425
+ .style("font-size", `${fontSize}px`)
426
+ .style("font-family", fontFamily)
427
+ .style("fill", fontColor)
428
+ .text(name)
429
+
430
+ // keep this at the end
431
+ rowG
432
+ .append("rect")
433
+ .attr("x", 0)
434
+ .attr("width", boxWidth)
435
+ .attr("y", padding + i * (rowHeight + rowGap) - rowGap)
436
+ .attr("height", rowHeight + rowGap)
437
+ .style("fill", backgroundColor)
438
+ .style("fill-opacity", 0)
439
+ .on("mouseover", () => {
440
+ if (isWheelingRef.current) return
441
+ setHoveredSeriesName(prevName => {
442
+ // restore any previous names in case the events
443
+ // get out of order, this prevents multiple series
444
+ // being highlighted when the mouse moves quickly
445
+ if (prevName && prevName !== name) {
446
+ restoreSeriesInPlot(prevName)
447
+ }
448
+ return name
449
+ })
450
+ highlightSeriesInPlot(name)
451
+ })
452
+ .on("mouseleave", () => {
453
+ setHoveredSeriesName(null)
454
+ restoreSeriesInPlot(name)
455
+ })
456
+
457
+ })
458
+ },
459
+ [
460
+ visible, container, externalContainer, chartId, visibleSeriesNames,
461
+ legendStyle, location, offset, margin, plotDimensions, color,
462
+ seriesStyles, highlightSeriesInPlot, restoreSeriesInPlot, mouseInLegend
463
+ ]
464
+ )
465
+
466
+ // Update SVG row opacity when the hovered series changes
467
+ useEffect(
468
+ () => {
469
+ if (!container || externalContainer) return
470
+ const legendG = d3.select(container).select(`#${LEGEND_CONTAINER_ID_PREFIX}-${chartId}`)
471
+ if (!legendG.empty()) {
472
+ const FADE_BACK_OPACITY = 0.35
473
+ legendG.selectAll<SVGGElement, unknown>("g.legend-row")
474
+ .attr("transition", `opacity ${350}ms ease-in-out`)
475
+ .style("opacity", function (): number {
476
+ const seriesName = d3.select(this).attr("data-series-name")
477
+ if (mouseInLegend) {
478
+ return hoveredSeriesName !== null && seriesName === hoveredSeriesName ? 1 : FADE_BACK_OPACITY
479
+ } else if (hoveredSeriesName !== null && seriesName !== hoveredSeriesName) {
480
+ return FADE_BACK_OPACITY
481
+ } else {
482
+ return 1
483
+ }
484
+ })
485
+ legendG.selectAll<SVGTextElement, unknown>("text[data-series-name]")
486
+ .style("font-weight", function (): string {
487
+ const seriesName: string = d3.select(this).attr("data-series-name")
488
+ return hoveredSeriesName !== null && seriesName === hoveredSeriesName ? "bold" : "normal"
489
+ })
490
+ }
491
+ },
492
+ [hoveredSeriesName, container, externalContainer, chartId, mouseInLegend]
493
+ )
494
+
495
+ // HTML portal legend — rendered outside the SVG into an external container
496
+ if (externalContainerReady && externalContainer?.current && visibleSeriesNames.length > 0) {
497
+ const {
498
+ fontSize,
499
+ fontFamily,
500
+ fontColor,
501
+ backgroundColor,
502
+ backgroundOpacity,
503
+ borderColor,
504
+ borderWidth,
505
+ borderOpacity,
506
+ borderRadius,
507
+ padding,
508
+ rowGap,
509
+ swatchWidth,
510
+ swatchHeight,
511
+ swatchLabelGap,
512
+ maxHeight,
513
+ transitionDuration,
514
+ } = legendStyle
515
+
516
+ const bg = d3.color(backgroundColor) as d3.RGBColor | undefined
517
+ const bgWithOpacity = bg
518
+ ? `rgba(${bg.r},${bg.g},${bg.b},${backgroundOpacity})`
519
+ : backgroundColor
520
+ const bd = d3.color(borderColor) as d3.RGBColor | undefined
521
+ const bdWithOpacity = bd
522
+ ? `rgba(${bd.r},${bd.g},${bd.b},${borderOpacity})`
523
+ : borderColor
524
+
525
+ const boxStyle: React.CSSProperties = {
526
+ display: "inline-flex",
527
+ flexDirection: "column",
528
+ backgroundColor: bgWithOpacity,
529
+ border: `${borderWidth}px solid ${bdWithOpacity}`,
530
+ borderRadius,
531
+ padding,
532
+ maxHeight,
533
+ overflowY: "auto",
534
+ fontFamily,
535
+ fontSize,
536
+ color: fontColor,
537
+ boxSizing: "border-box",
538
+ opacity: visible ? 1 : 0,
539
+ transition: visible ? `opacity ${transitionDuration}ms ease-in-out` : "none",
540
+ pointerEvents: visible ? "auto" : "none",
541
+ }
542
+
543
+ const anyHovered = hoveredSeriesName !== null
544
+ return createPortal(
545
+ <div style={boxStyle}>
546
+ {visibleSeriesNames.map(name => {
547
+ const seriesColor = seriesStyles.get(name)?.color ?? color
548
+ const isHovered = name === hoveredSeriesName
549
+ const rowStyle: React.CSSProperties = {
550
+ display: "flex",
551
+ alignItems: "center",
552
+ gap: swatchLabelGap,
553
+ opacity: anyHovered && !isHovered ? 0.35 : 1,
554
+ fontWeight: isHovered ? "bold" : "normal",
555
+ transition: "opacity 0.15s, font-weight 0s",
556
+ height: rowGap + fontSize,
557
+ }
558
+ return (
559
+ <div
560
+ key={name}
561
+ style={{...rowStyle, cursor: "default"}}
562
+ onMouseEnter={() => {
563
+ setHoveredSeriesName(name)
564
+ highlightSeriesInPlot(name)
565
+ }}
566
+ onMouseLeave={() => {
567
+ setHoveredSeriesName(null)
568
+ restoreSeriesInPlot(name)
569
+ }}
570
+ >
571
+ <span style={{
572
+ display: "inline-block",
573
+ width: swatchWidth,
574
+ height: swatchHeight,
575
+ backgroundColor: seriesColor,
576
+ borderRadius: swatchHeight / 2,
577
+ flexShrink: 0,
578
+ }}/>
579
+ <span style={{
580
+ height: rowGap + fontSize,
581
+ alignItems: "center",
582
+ display: "inline-flex"
583
+ }}>{name}</span>
584
+ </div>
585
+ )
586
+ })}
587
+ </div>,
588
+ externalContainer.current
589
+ )
590
+ }
591
+
592
+ return null
593
+ }
594
+
595
+ function calculateScrollbarY(totalContentHeight: number, boxHeight: number, scrollY: number, scrollbarHeight: number, padding: number): number {
596
+ const maxScroll = totalContentHeight - boxHeight
597
+ const scrollPercent = scrollY / maxScroll
598
+ const scrollbarMaxY = boxHeight - scrollbarHeight - 4 - padding
599
+ return Math.max(padding, 2 + scrollPercent * scrollbarMaxY)
600
+ }
@@ -73,7 +73,7 @@ export const BAR_CHART_TOOLTIP_PROVIDER_IDS: BarChartElementId = {
73
73
  windowedMinMax: TOOLTIP_PROVIDER_ID + '-windowed-mean'
74
74
  }
75
75
 
76
- interface Props {
76
+ export interface Props {
77
77
  /**
78
78
  * Holds the mapping between a series and the axis it uses (is assigned). The
79
79
  * map's key holds the series name, and the value is an {@link AxesAssignment}
@@ -124,22 +124,21 @@ interface Props {
124
124
  * <a href="https://github.com/robphilipp/stream-charts-examples">`StreamingBarChart` example</a>
125
125
  *
126
126
  * @param props The properties associated with the bar plot
127
- * @constructor
128
127
  * @example
129
128
  * ```typescript
130
129
  * <BarPlot
131
130
  * barMargin={1}
132
131
  * dropDataAfter={5000}
133
- * // panEnabled={true}
134
- * // zoomEnabled={true}
135
- * // zoomKeyModifiersRequired={true}
136
- * // withCadenceOf={50}
132
+ * panEnabled={true}
133
+ * zoomEnabled={true}
134
+ * zoomKeyModifiersRequired={true}
135
+ * withCadenceOf={50}
137
136
  *
138
- * showMinMaxBars={showMinMax}
139
- * showValueLines={showValue}
140
- * showMeanValueLines={showMean}
141
- * showWindowedMinMaxBars={showWinMinMax}
142
- * showWindowedMeanValueLines={showWinMean}
137
+ * showMinMaxBars={true}
138
+ * showValueLines={true}
139
+ * showMeanValueLines={true}
140
+ * showWindowedMinMaxBars={true}
141
+ * showWindowedMeanValueLines={true}
143
142
  * />
144
143
  * ```
145
144
  */
@@ -434,7 +433,7 @@ export function BarPlot(props: Props): null {
434
433
  margin,
435
434
  seriesStyles,
436
435
  barSeriesStyle,
437
- allowTooltipRef.current,
436
+ allowTooltipRef.current && showMinMaxBars,
438
437
  mouseOverHandlerFor(`tooltip-${chartId}`, BAR_CHART_TOOLTIP_PROVIDER_IDS.minMax),
439
438
  BAR_CHART_TOOLTIP_PROVIDER_IDS.minMax
440
439
  )
@@ -490,7 +489,7 @@ export function BarPlot(props: Props): null {
490
489
  margin,
491
490
  seriesStyles,
492
491
  barSeriesStyle,
493
- allowTooltipRef.current,
492
+ allowTooltipRef.current && showWindowedMinMaxBars,
494
493
  mouseOverHandlerFor(`tooltip-${chartId}`, BAR_CHART_TOOLTIP_PROVIDER_IDS.windowedMinMax),
495
494
  BAR_CHART_TOOLTIP_PROVIDER_IDS.windowedMinMax
496
495
  )
@@ -545,7 +544,7 @@ export function BarPlot(props: Props): null {
545
544
  margin,
546
545
  seriesStyles,
547
546
  barSeriesStyle,
548
- allowTooltipRef.current,
547
+ allowTooltipRef.current && showMeanValueLines,
549
548
  mouseOverHandlerFor(`tooltip-${chartId}`, BAR_CHART_TOOLTIP_PROVIDER_IDS.meanValue),
550
549
  BAR_CHART_TOOLTIP_PROVIDER_IDS.meanValue
551
550
  )
@@ -598,7 +597,7 @@ export function BarPlot(props: Props): null {
598
597
  margin,
599
598
  seriesStyles,
600
599
  barSeriesStyle,
601
- allowTooltipRef.current,
600
+ allowTooltipRef.current && showWindowedMeanValueLines,
602
601
  mouseOverHandlerFor(`tooltip-${chartId}`, BAR_CHART_TOOLTIP_PROVIDER_IDS.windowedMeanValue),
603
602
  BAR_CHART_TOOLTIP_PROVIDER_IDS.windowedMeanValue
604
603
  )
@@ -653,7 +652,7 @@ export function BarPlot(props: Props): null {
653
652
  margin,
654
653
  seriesStyles,
655
654
  barSeriesStyle,
656
- allowTooltipRef.current,
655
+ allowTooltipRef.current && showValueLines,
657
656
  mouseOverHandlerFor(`tooltip-${chartId}`, BAR_CHART_TOOLTIP_PROVIDER_IDS.currentValue),
658
657
  BAR_CHART_TOOLTIP_PROVIDER_IDS.currentValue
659
658
  )