@gravity-ui/charts 0.5.0 → 0.6.1-beta.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 (216) hide show
  1. package/README.md +2 -2
  2. package/dist/cjs/components/Axis/AxisY.d.ts +1 -0
  3. package/dist/cjs/components/Axis/AxisY.js +55 -13
  4. package/dist/cjs/components/ChartInner/index.d.ts +2 -8
  5. package/dist/cjs/components/ChartInner/index.js +25 -119
  6. package/dist/cjs/components/ChartInner/types.d.ts +6 -0
  7. package/dist/cjs/components/ChartInner/useChartInnerHandlers.d.ts +26 -0
  8. package/dist/cjs/components/ChartInner/useChartInnerHandlers.js +98 -0
  9. package/dist/cjs/components/ChartInner/useChartInnerProps.d.ts +43 -0
  10. package/dist/cjs/components/ChartInner/useChartInnerProps.js +81 -0
  11. package/dist/cjs/components/ChartInner/useChartInnerState.d.ts +13 -0
  12. package/dist/cjs/components/ChartInner/useChartInnerState.js +34 -0
  13. package/dist/cjs/components/Legend/index.d.ts +1 -0
  14. package/dist/cjs/components/Legend/index.js +4 -4
  15. package/dist/cjs/components/PlotTitle/index.js +1 -1
  16. package/dist/cjs/components/PlotTitle/styles.css +1 -1
  17. package/dist/cjs/components/Tooltip/ChartTooltipContent.d.ts +2 -2
  18. package/dist/cjs/components/Tooltip/DefaultContent.js +19 -3
  19. package/dist/cjs/components/Tooltip/index.d.ts +2 -0
  20. package/dist/cjs/components/Tooltip/index.js +10 -4
  21. package/dist/cjs/components/Tooltip/styles.css +13 -8
  22. package/dist/cjs/components/index.d.ts +10 -9
  23. package/dist/cjs/constants/index.d.ts +1 -0
  24. package/dist/cjs/constants/index.js +1 -0
  25. package/dist/cjs/hooks/index.d.ts +2 -1
  26. package/dist/cjs/hooks/index.js +2 -1
  27. package/dist/cjs/hooks/useChartOptions/types.d.ts +11 -1
  28. package/dist/cjs/hooks/useChartOptions/x-axis.js +1 -0
  29. package/dist/cjs/hooks/useChartOptions/y-axis.js +9 -1
  30. package/dist/cjs/hooks/usePrevious/index.d.ts +1 -0
  31. package/dist/cjs/hooks/usePrevious/index.js +8 -0
  32. package/dist/cjs/hooks/useSeries/prepare-area.d.ts +1 -1
  33. package/dist/cjs/hooks/useSeries/prepare-bar-x.d.ts +2 -1
  34. package/dist/cjs/hooks/useSeries/prepare-bar-x.js +2 -1
  35. package/dist/cjs/hooks/useSeries/prepare-bar-y.d.ts +2 -1
  36. package/dist/cjs/hooks/useSeries/prepare-bar-y.js +3 -1
  37. package/dist/cjs/hooks/useSeries/prepare-line.d.ts +1 -1
  38. package/dist/cjs/hooks/useSeries/prepare-pie.js +2 -2
  39. package/dist/cjs/hooks/useSeries/prepare-sankey.d.ts +11 -0
  40. package/dist/cjs/hooks/useSeries/prepare-sankey.js +38 -0
  41. package/dist/cjs/hooks/useSeries/prepareSeries.js +21 -2
  42. package/dist/cjs/hooks/useSeries/types.d.ts +12 -2
  43. package/dist/cjs/hooks/useSeries/utils.js +1 -1
  44. package/dist/cjs/hooks/useShapes/area/index.js +8 -2
  45. package/dist/cjs/hooks/useShapes/area/prepare-data.js +4 -0
  46. package/dist/cjs/hooks/useShapes/bar-x/index.js +24 -4
  47. package/dist/cjs/hooks/useShapes/bar-x/prepare-data.js +3 -1
  48. package/dist/cjs/hooks/useShapes/bar-x/types.d.ts +1 -0
  49. package/dist/cjs/hooks/useShapes/bar-y/index.js +24 -4
  50. package/dist/cjs/hooks/useShapes/bar-y/prepare-data.js +3 -1
  51. package/dist/cjs/hooks/useShapes/bar-y/types.d.ts +1 -0
  52. package/dist/cjs/hooks/useShapes/index.d.ts +2 -1
  53. package/dist/cjs/hooks/useShapes/index.js +19 -0
  54. package/dist/cjs/hooks/useShapes/line/index.js +10 -4
  55. package/dist/cjs/hooks/useShapes/line/prepare-data.js +1 -0
  56. package/dist/cjs/hooks/useShapes/pie/index.js +5 -4
  57. package/dist/cjs/hooks/useShapes/pie/prepare-data.js +168 -118
  58. package/dist/cjs/hooks/useShapes/pie/types.d.ts +2 -2
  59. package/dist/cjs/hooks/useShapes/sankey/index.d.ts +12 -0
  60. package/dist/cjs/hooks/useShapes/sankey/index.js +67 -0
  61. package/dist/cjs/hooks/useShapes/sankey/prepare-data.d.ts +7 -0
  62. package/dist/cjs/hooks/useShapes/sankey/prepare-data.js +72 -0
  63. package/dist/cjs/hooks/useShapes/sankey/types.d.ts +33 -0
  64. package/dist/cjs/hooks/useShapes/scatter/index.js +8 -2
  65. package/dist/cjs/hooks/useShapes/styles.css +2 -2
  66. package/dist/cjs/hooks/useShapes/treemap/index.js +8 -2
  67. package/dist/cjs/hooks/useShapes/treemap/prepare-data.js +1 -0
  68. package/dist/cjs/hooks/useShapes/utils.d.ts +8 -3
  69. package/dist/cjs/hooks/useShapes/utils.js +26 -19
  70. package/dist/cjs/hooks/useShapes/waterfall/index.js +9 -4
  71. package/dist/cjs/hooks/useTooltip/index.d.ts +2 -3
  72. package/dist/cjs/types/chart/area.d.ts +6 -6
  73. package/dist/cjs/types/chart/axis.d.ts +32 -7
  74. package/dist/cjs/types/chart/bar-x.d.ts +9 -4
  75. package/dist/cjs/types/chart/bar-y.d.ts +10 -6
  76. package/dist/cjs/types/chart/base.d.ts +6 -6
  77. package/dist/cjs/types/chart/chart.d.ts +6 -6
  78. package/dist/cjs/types/chart/halo.d.ts +2 -2
  79. package/dist/cjs/types/chart/legend.d.ts +10 -10
  80. package/dist/cjs/types/chart/line.d.ts +4 -4
  81. package/dist/cjs/types/chart/marker.d.ts +2 -2
  82. package/dist/cjs/types/chart/pie.d.ts +6 -4
  83. package/dist/cjs/types/chart/sankey.d.ts +22 -0
  84. package/dist/cjs/types/chart/sankey.js +1 -0
  85. package/dist/cjs/types/chart/scatter.d.ts +4 -4
  86. package/dist/cjs/types/chart/series.d.ts +21 -11
  87. package/dist/cjs/types/chart/split.d.ts +4 -4
  88. package/dist/cjs/types/chart/title.d.ts +2 -2
  89. package/dist/cjs/types/chart/tooltip.d.ts +32 -26
  90. package/dist/cjs/types/chart/treemap.d.ts +4 -4
  91. package/dist/cjs/types/chart/waterfall.d.ts +4 -4
  92. package/dist/cjs/types/chart-ui.d.ts +10 -6
  93. package/dist/cjs/types/formatter.d.ts +4 -4
  94. package/dist/cjs/types/index.d.ts +35 -4
  95. package/dist/cjs/types/index.js +1 -0
  96. package/dist/cjs/types/misc.d.ts +1 -0
  97. package/dist/cjs/utils/chart/get-closest-data.d.ts +2 -0
  98. package/dist/cjs/utils/chart/get-closest-data.js +39 -3
  99. package/dist/cjs/utils/chart/index.js +1 -1
  100. package/dist/cjs/utils/chart/series/index.d.ts +1 -0
  101. package/dist/cjs/utils/chart/series/index.js +1 -0
  102. package/dist/cjs/utils/chart/series/line.d.ts +2 -0
  103. package/dist/cjs/utils/chart/series/line.js +17 -0
  104. package/dist/cjs/utils/misc.d.ts +10 -2
  105. package/dist/cjs/utils/misc.js +15 -3
  106. package/dist/esm/components/Axis/AxisY.d.ts +1 -0
  107. package/dist/esm/components/Axis/AxisY.js +55 -13
  108. package/dist/esm/components/ChartInner/index.d.ts +2 -8
  109. package/dist/esm/components/ChartInner/index.js +25 -119
  110. package/dist/esm/components/ChartInner/types.d.ts +6 -0
  111. package/dist/esm/components/ChartInner/types.js +1 -0
  112. package/dist/esm/components/ChartInner/useChartInnerHandlers.d.ts +26 -0
  113. package/dist/esm/components/ChartInner/useChartInnerHandlers.js +98 -0
  114. package/dist/esm/components/ChartInner/useChartInnerProps.d.ts +43 -0
  115. package/dist/esm/components/ChartInner/useChartInnerProps.js +81 -0
  116. package/dist/esm/components/ChartInner/useChartInnerState.d.ts +13 -0
  117. package/dist/esm/components/ChartInner/useChartInnerState.js +34 -0
  118. package/dist/esm/components/Legend/index.d.ts +1 -0
  119. package/dist/esm/components/Legend/index.js +4 -4
  120. package/dist/esm/components/PlotTitle/index.js +1 -1
  121. package/dist/esm/components/PlotTitle/styles.css +1 -1
  122. package/dist/esm/components/Tooltip/ChartTooltipContent.d.ts +2 -2
  123. package/dist/esm/components/Tooltip/DefaultContent.js +19 -3
  124. package/dist/esm/components/Tooltip/index.d.ts +2 -0
  125. package/dist/esm/components/Tooltip/index.js +10 -4
  126. package/dist/esm/components/Tooltip/styles.css +13 -8
  127. package/dist/esm/components/index.d.ts +10 -9
  128. package/dist/esm/constants/index.d.ts +1 -0
  129. package/dist/esm/constants/index.js +1 -0
  130. package/dist/esm/hooks/index.d.ts +2 -1
  131. package/dist/esm/hooks/index.js +2 -1
  132. package/dist/esm/hooks/useChartOptions/types.d.ts +11 -1
  133. package/dist/esm/hooks/useChartOptions/x-axis.js +1 -0
  134. package/dist/esm/hooks/useChartOptions/y-axis.js +9 -1
  135. package/dist/esm/hooks/usePrevious/index.d.ts +1 -0
  136. package/dist/esm/hooks/usePrevious/index.js +8 -0
  137. package/dist/esm/hooks/useSeries/prepare-area.d.ts +1 -1
  138. package/dist/esm/hooks/useSeries/prepare-bar-x.d.ts +2 -1
  139. package/dist/esm/hooks/useSeries/prepare-bar-x.js +2 -1
  140. package/dist/esm/hooks/useSeries/prepare-bar-y.d.ts +2 -1
  141. package/dist/esm/hooks/useSeries/prepare-bar-y.js +3 -1
  142. package/dist/esm/hooks/useSeries/prepare-line.d.ts +1 -1
  143. package/dist/esm/hooks/useSeries/prepare-pie.js +2 -2
  144. package/dist/esm/hooks/useSeries/prepare-sankey.d.ts +11 -0
  145. package/dist/esm/hooks/useSeries/prepare-sankey.js +38 -0
  146. package/dist/esm/hooks/useSeries/prepareSeries.js +21 -2
  147. package/dist/esm/hooks/useSeries/types.d.ts +12 -2
  148. package/dist/esm/hooks/useSeries/utils.js +1 -1
  149. package/dist/esm/hooks/useShapes/area/index.js +8 -2
  150. package/dist/esm/hooks/useShapes/area/prepare-data.js +4 -0
  151. package/dist/esm/hooks/useShapes/bar-x/index.js +24 -4
  152. package/dist/esm/hooks/useShapes/bar-x/prepare-data.js +3 -1
  153. package/dist/esm/hooks/useShapes/bar-x/types.d.ts +1 -0
  154. package/dist/esm/hooks/useShapes/bar-y/index.js +24 -4
  155. package/dist/esm/hooks/useShapes/bar-y/prepare-data.js +3 -1
  156. package/dist/esm/hooks/useShapes/bar-y/types.d.ts +1 -0
  157. package/dist/esm/hooks/useShapes/index.d.ts +2 -1
  158. package/dist/esm/hooks/useShapes/index.js +19 -0
  159. package/dist/esm/hooks/useShapes/line/index.js +10 -4
  160. package/dist/esm/hooks/useShapes/line/prepare-data.js +1 -0
  161. package/dist/esm/hooks/useShapes/pie/index.js +5 -4
  162. package/dist/esm/hooks/useShapes/pie/prepare-data.js +168 -118
  163. package/dist/esm/hooks/useShapes/pie/types.d.ts +2 -2
  164. package/dist/esm/hooks/useShapes/sankey/index.d.ts +12 -0
  165. package/dist/esm/hooks/useShapes/sankey/index.js +67 -0
  166. package/dist/esm/hooks/useShapes/sankey/prepare-data.d.ts +7 -0
  167. package/dist/esm/hooks/useShapes/sankey/prepare-data.js +72 -0
  168. package/dist/esm/hooks/useShapes/sankey/types.d.ts +33 -0
  169. package/dist/esm/hooks/useShapes/sankey/types.js +1 -0
  170. package/dist/esm/hooks/useShapes/scatter/index.js +8 -2
  171. package/dist/esm/hooks/useShapes/styles.css +2 -2
  172. package/dist/esm/hooks/useShapes/treemap/index.js +8 -2
  173. package/dist/esm/hooks/useShapes/treemap/prepare-data.js +1 -0
  174. package/dist/esm/hooks/useShapes/utils.d.ts +8 -3
  175. package/dist/esm/hooks/useShapes/utils.js +26 -19
  176. package/dist/esm/hooks/useShapes/waterfall/index.js +9 -4
  177. package/dist/esm/hooks/useTooltip/index.d.ts +2 -3
  178. package/dist/esm/types/chart/area.d.ts +6 -6
  179. package/dist/esm/types/chart/axis.d.ts +32 -7
  180. package/dist/esm/types/chart/bar-x.d.ts +9 -4
  181. package/dist/esm/types/chart/bar-y.d.ts +10 -6
  182. package/dist/esm/types/chart/base.d.ts +6 -6
  183. package/dist/esm/types/chart/chart.d.ts +6 -6
  184. package/dist/esm/types/chart/halo.d.ts +2 -2
  185. package/dist/esm/types/chart/legend.d.ts +10 -10
  186. package/dist/esm/types/chart/line.d.ts +4 -4
  187. package/dist/esm/types/chart/marker.d.ts +2 -2
  188. package/dist/esm/types/chart/pie.d.ts +6 -4
  189. package/dist/esm/types/chart/sankey.d.ts +22 -0
  190. package/dist/esm/types/chart/sankey.js +1 -0
  191. package/dist/esm/types/chart/scatter.d.ts +4 -4
  192. package/dist/esm/types/chart/series.d.ts +21 -11
  193. package/dist/esm/types/chart/split.d.ts +4 -4
  194. package/dist/esm/types/chart/title.d.ts +2 -2
  195. package/dist/esm/types/chart/tooltip.d.ts +32 -26
  196. package/dist/esm/types/chart/treemap.d.ts +4 -4
  197. package/dist/esm/types/chart/waterfall.d.ts +4 -4
  198. package/dist/esm/types/chart-ui.d.ts +10 -6
  199. package/dist/esm/types/formatter.d.ts +4 -4
  200. package/dist/esm/types/index.d.ts +35 -4
  201. package/dist/esm/types/index.js +1 -0
  202. package/dist/esm/types/misc.d.ts +1 -0
  203. package/dist/esm/utils/chart/get-closest-data.d.ts +2 -0
  204. package/dist/esm/utils/chart/get-closest-data.js +39 -3
  205. package/dist/esm/utils/chart/index.js +1 -1
  206. package/dist/esm/utils/chart/series/index.d.ts +1 -0
  207. package/dist/esm/utils/chart/series/index.js +1 -0
  208. package/dist/esm/utils/chart/series/line.d.ts +2 -0
  209. package/dist/esm/utils/chart/series/line.js +17 -0
  210. package/dist/esm/utils/misc.d.ts +10 -2
  211. package/dist/esm/utils/misc.js +15 -3
  212. package/package.json +7 -2
  213. package/dist/cjs/hooks/useTooltip/types.d.ts +0 -1
  214. package/dist/esm/hooks/useTooltip/types.d.ts +0 -1
  215. /package/dist/cjs/{hooks/useTooltip → components/ChartInner}/types.js +0 -0
  216. /package/dist/{esm/hooks/useTooltip → cjs/hooks/useShapes/sankey}/types.js +0 -0
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # @gravity-ui/charts · [![npm package](https://img.shields.io/npm/v/@gravity-ui/charts)](https://www.npmjs.com/package/@gravity-ui/charts) [![CI](https://img.shields.io/github/actions/workflow/status/gravity-ui/charts/.github/workflows/ci.yml?label=CI&logo=github)](https://github.com/gravity-ui/charts/actions/workflows/ci.yml?query=branch:main) [![storybook](https://img.shields.io/badge/Storybook-deployed-ff4685)](https://preview.gravity-ui.com/charts/)
1
+ # Gravity Charts · [![npm package](https://img.shields.io/npm/v/@gravity-ui/charts)](https://www.npmjs.com/package/@gravity-ui/charts) [![CI](https://img.shields.io/github/actions/workflow/status/gravity-ui/charts/.github/workflows/ci.yml?label=CI&logo=github)](https://github.com/gravity-ui/charts/actions/workflows/ci.yml?query=branch:main) [![storybook](https://img.shields.io/badge/Storybook-deployed-ff4685)](https://preview.gravity-ui.com/charts/)
2
2
 
3
3
  > [!WARNING]
4
4
  > The library may have major changes in minor releases while it is on version `0.*.*`.
@@ -6,7 +6,7 @@
6
6
  ## Install
7
7
 
8
8
  ```shell
9
- npm install --save-dev @gravity-ui/uikit @gravity-ui/charts
9
+ npm install @gravity-ui/uikit @gravity-ui/charts
10
10
  ```
11
11
 
12
12
  ## Development
@@ -7,6 +7,7 @@ type Props = {
7
7
  width: number;
8
8
  height: number;
9
9
  split: PreparedSplit;
10
+ plotRef?: React.MutableRefObject<SVGGElement | null>;
10
11
  };
11
12
  export declare const AxisY: (props: Props) => React.JSX.Element;
12
13
  export {};
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import { axisLeft, axisRight, line, select } from 'd3';
3
- import { block, calculateCos, calculateSin, formatAxisTickLabel, getAxisHeight, getAxisTitleRows, getClosestPointsRange, getScaleTicks, getTicksCount, handleOverflowingText, parseTransformStyle, setEllipsisForOverflowTexts, wrapText, } from '../../utils';
3
+ import { block, calculateCos, calculateSin, formatAxisTickLabel, getAxisHeight, getAxisTitleRows, getClosestPointsRange, getLineDashArray, getScaleTicks, getTicksCount, handleOverflowingText, parseTransformStyle, setEllipsisForOverflowTexts, wrapText, } from '../../utils';
4
4
  import './styles.css';
5
5
  const b = block('d3-axis');
6
6
  function transformLabel(args) {
@@ -79,7 +79,7 @@ function getTitlePosition(args) {
79
79
  return { x, y };
80
80
  }
81
81
  export const AxisY = (props) => {
82
- const { axes, width, height: totalHeight, scale, split } = props;
82
+ const { axes, width, height: totalHeight, scale, split, plotRef } = props;
83
83
  const height = getAxisHeight({ split, boundsHeight: totalHeight });
84
84
  const ref = React.useRef(null);
85
85
  React.useEffect(() => {
@@ -88,26 +88,34 @@ export const AxisY = (props) => {
88
88
  }
89
89
  const svgElement = select(ref.current);
90
90
  svgElement.selectAll('*').remove();
91
+ const getAxisPosition = (axis) => {
92
+ var _a;
93
+ const top = ((_a = split.plots[axis.plotIndex]) === null || _a === void 0 ? void 0 : _a.top) || 0;
94
+ if (axis.position === 'left') {
95
+ return `translate(0, ${top}px)`;
96
+ }
97
+ return `translate(${width}px, 0)`;
98
+ };
99
+ const plotLines = axes.reduce((acc, axis) => {
100
+ if (axis.plotLines.length) {
101
+ acc.push(...axis.plotLines.map((plotLine) => {
102
+ return Object.assign(Object.assign({}, plotLine), { transform: getAxisPosition(axis) });
103
+ }));
104
+ }
105
+ return acc;
106
+ }, []);
91
107
  const axisSelection = svgElement
92
108
  .selectAll('axis')
93
109
  .data(axes)
94
110
  .join('g')
95
111
  .attr('class', b())
96
- .style('transform', (d) => {
97
- var _a;
98
- const top = ((_a = split.plots[d.plotIndex]) === null || _a === void 0 ? void 0 : _a.top) || 0;
99
- if (d.position === 'left') {
100
- return `translate(0, ${top}px)`;
101
- }
102
- return `translate(${width}px, 0)`;
103
- });
112
+ .style('transform', (d) => getAxisPosition(d));
104
113
  axisSelection.each((d, index, node) => {
105
114
  const seriesScale = scale[index];
106
115
  const axisItem = select(node[index]);
116
+ const axisScale = seriesScale;
107
117
  const yAxisGenerator = getAxisGenerator({
108
- axisGenerator: d.position === 'left'
109
- ? axisLeft(seriesScale)
110
- : axisRight(seriesScale),
118
+ axisGenerator: d.position === 'left' ? axisLeft(axisScale) : axisRight(axisScale),
111
119
  preparedAxis: d,
112
120
  height,
113
121
  width,
@@ -148,6 +156,40 @@ export const AxisY = (props) => {
148
156
  })
149
157
  .remove();
150
158
  }
159
+ if (plotRef && d.plotLines.length > 0) {
160
+ const plotLineClassName = b('plotLine');
161
+ const plotLineContainer = select(plotRef.current);
162
+ plotLineContainer.selectAll(`.${plotLineClassName}`).remove();
163
+ const plotLinesSelection = plotLineContainer
164
+ .selectAll(`.${plotLineClassName}`)
165
+ .data(plotLines)
166
+ .join('g')
167
+ .attr('class', plotLineClassName)
168
+ .style('transform', (plotLine) => plotLine.transform);
169
+ plotLinesSelection
170
+ .append('path')
171
+ .attr('d', (plotLine) => {
172
+ const plotLineValue = Number(axisScale(plotLine.value));
173
+ const points = [
174
+ [0, plotLineValue],
175
+ [width, plotLineValue],
176
+ ];
177
+ return line()(points);
178
+ })
179
+ .attr('stroke', (plotLine) => plotLine.color)
180
+ .attr('stroke-width', (plotLine) => plotLine.width)
181
+ .attr('stroke-dasharray', (plotLine) => getLineDashArray(plotLine.dashStyle, plotLine.width))
182
+ .attr('opacity', (plotLine) => plotLine.opacity);
183
+ plotLinesSelection.each((plotLineData, i, nodes) => {
184
+ const plotLineSelection = select(nodes[i]);
185
+ if (plotLineData.layerPlacement === 'before') {
186
+ plotLineSelection.lower();
187
+ }
188
+ else {
189
+ plotLineSelection.raise();
190
+ }
191
+ });
192
+ }
151
193
  return axisItem;
152
194
  });
153
195
  axisSelection
@@ -1,10 +1,4 @@
1
1
  import React from 'react';
2
- import type { ChartData } from '../../types';
2
+ import type { ChartInnerProps } from './types';
3
3
  import './styles.css';
4
- type Props = {
5
- width: number;
6
- height: number;
7
- data: ChartData;
8
- };
9
- export declare const ChartInner: (props: Props) => React.JSX.Element;
10
- export {};
4
+ export declare const ChartInner: (props: ChartInnerProps) => React.JSX.Element;
@@ -1,77 +1,40 @@
1
1
  import React from 'react';
2
- import { pointer } from 'd3';
3
- import throttle from 'lodash/throttle';
4
- import { IS_TOUCH_ENABLED } from '../../constants';
5
- import { useAxisScales, useChartDimensions, useChartOptions, useSeries, useShapes, } from '../../hooks';
6
- import { getYAxisWidth } from '../../hooks/useChartDimensions/utils';
7
- import { getPreparedXAxis } from '../../hooks/useChartOptions/x-axis';
8
- import { getPreparedYAxis } from '../../hooks/useChartOptions/y-axis';
9
- import { useSplit } from '../../hooks/useSplit';
10
2
  import { EventType, block, getD3Dispatcher } from '../../utils';
11
- import { getClosestPoints } from '../../utils/chart/get-closest-data';
12
3
  import { AxisX, AxisY } from '../Axis';
13
4
  import { Legend } from '../Legend';
14
5
  import { PlotTitle } from '../PlotTitle';
15
6
  import { Title } from '../Title';
16
7
  import { Tooltip } from '../Tooltip';
8
+ import { useChartInnerHandlers } from './useChartInnerHandlers';
9
+ import { useChartInnerProps } from './useChartInnerProps';
10
+ import { useChartInnerState } from './useChartInnerState';
17
11
  import './styles.css';
18
12
  const b = block('d3');
19
- const THROTTLE_DELAY = 50;
20
13
  export const ChartInner = (props) => {
21
14
  var _a, _b, _c, _d;
22
15
  const { width, height, data } = props;
23
16
  const svgRef = React.useRef(null);
24
17
  const htmlLayerRef = React.useRef(null);
25
- const dispatcher = React.useMemo(() => {
26
- return getD3Dispatcher();
27
- }, []);
28
- const { chart, title, tooltip } = useChartOptions({
29
- data,
30
- });
31
- const xAxis = React.useMemo(() => getPreparedXAxis({ xAxis: data.xAxis, width, series: data.series.data }), [data, width]);
32
- const yAxis = React.useMemo(() => getPreparedYAxis({
33
- series: data.series.data,
34
- yAxis: data.yAxis,
35
- height,
36
- }), [data, height]);
37
- const { legendItems, legendConfig, preparedSeries, preparedSeriesOptions, preparedLegend, handleLegendItemClick, } = useSeries({
38
- chartWidth: width,
39
- chartHeight: height,
40
- chartMargin: chart.margin,
41
- series: data.series,
42
- legend: data.legend,
43
- preparedYAxis: yAxis,
44
- });
45
- const { boundsWidth, boundsHeight } = useChartDimensions({
46
- width,
47
- height,
48
- margin: chart.margin,
49
- preparedLegend,
50
- preparedXAxis: xAxis,
51
- preparedYAxis: yAxis,
52
- preparedSeries: preparedSeries,
18
+ const plotRef = React.useRef(null);
19
+ const dispatcher = React.useMemo(() => getD3Dispatcher(), []);
20
+ const { boundsHeight, boundsOffsetLeft, boundsOffsetTop, boundsWidth, handleLegendItemClick, legendConfig, legendItems, preparedSeries, preparedSplit, preparedLegend, prevHeight, prevWidth, shapes, shapesData, title, tooltip, xAxis, xScale, yAxis, yScale, } = useChartInnerProps(Object.assign(Object.assign({}, props), { dispatcher, htmlLayout: htmlLayerRef.current }));
21
+ const { tooltipPinned, togglePinTooltip, unpinTooltip } = useChartInnerState({
22
+ dispatcher,
23
+ tooltip,
53
24
  });
54
- const preparedSplit = useSplit({ split: data.split, boundsHeight, chartWidth: width });
55
- const { xScale, yScale } = useAxisScales({
56
- boundsWidth,
25
+ const { handleChartClick, handleMouseLeave, throttledHandleMouseMove, throttledHandleTouchMove } = useChartInnerHandlers({
57
26
  boundsHeight,
58
- series: preparedSeries,
59
- xAxis,
60
- yAxis,
61
- split: preparedSplit,
62
- });
63
- const { shapes, shapesData } = useShapes({
27
+ boundsOffsetLeft,
28
+ boundsOffsetTop,
64
29
  boundsWidth,
65
- boundsHeight,
66
30
  dispatcher,
67
- series: preparedSeries,
68
- seriesOptions: preparedSeriesOptions,
31
+ shapesData,
32
+ svgContainer: svgRef.current,
33
+ togglePinTooltip,
34
+ tooltipPinned,
35
+ unpinTooltip,
69
36
  xAxis,
70
- xScale,
71
37
  yAxis,
72
- yScale,
73
- split: preparedSplit,
74
- htmlLayout: htmlLayerRef.current,
75
38
  });
76
39
  const clickHandler = (_b = (_a = data.chart) === null || _a === void 0 ? void 0 : _a.events) === null || _b === void 0 ? void 0 : _b.click;
77
40
  const pointerMoveHandler = (_d = (_c = data.chart) === null || _c === void 0 ? void 0 : _c.events) === null || _d === void 0 ? void 0 : _d.pointermove;
@@ -90,83 +53,26 @@ export const ChartInner = (props) => {
90
53
  dispatcher.on(EventType.POINTERMOVE_CHART, null);
91
54
  };
92
55
  }, [dispatcher, clickHandler, pointerMoveHandler]);
93
- const boundsOffsetTop = chart.margin.top;
94
- // We only need to consider the width of the first left axis
95
- const boundsOffsetLeft = chart.margin.left + getYAxisWidth(yAxis[0]);
96
- const isOutsideBounds = React.useCallback((x, y) => {
97
- return x < 0 || x > boundsWidth || y < 0 || y > boundsHeight;
98
- }, [boundsHeight, boundsWidth]);
99
- const handleMove = ([pointerX, pointerY], event) => {
100
- const x = pointerX - boundsOffsetLeft;
101
- const y = pointerY - boundsOffsetTop;
102
- if (isOutsideBounds(x, y)) {
103
- dispatcher.call(EventType.HOVER_SHAPE, {}, undefined);
104
- dispatcher.call(EventType.POINTERMOVE_CHART, {}, undefined, event);
105
- return;
106
- }
107
- const closest = getClosestPoints({
108
- position: [x, y],
109
- shapesData,
110
- });
111
- dispatcher.call(EventType.HOVER_SHAPE, event.target, closest, [pointerX, pointerY]);
112
- dispatcher.call(EventType.POINTERMOVE_CHART, {}, {
113
- hovered: closest,
114
- xAxis,
115
- yAxis: yAxis[0],
116
- }, event);
117
- };
118
- const handleMouseMove = (event) => {
119
- const [pointerX, pointerY] = pointer(event, svgRef.current);
120
- handleMove([pointerX, pointerY], event);
121
- };
122
- const throttledHandleMouseMove = IS_TOUCH_ENABLED
123
- ? undefined
124
- : throttle(handleMouseMove, THROTTLE_DELAY);
125
- const handleMouseLeave = (event) => {
126
- throttledHandleMouseMove === null || throttledHandleMouseMove === void 0 ? void 0 : throttledHandleMouseMove.cancel();
127
- dispatcher.call(EventType.HOVER_SHAPE, {}, undefined);
128
- dispatcher.call(EventType.POINTERMOVE_CHART, {}, undefined, event);
129
- };
130
- const handleTouchMove = (event) => {
131
- const touch = event.touches[0];
132
- const [pointerX, pointerY] = pointer(touch, svgRef.current);
133
- handleMove([pointerX, pointerY], event);
134
- };
135
- const throttledHandleTouchMove = IS_TOUCH_ENABLED
136
- ? throttle(handleTouchMove, THROTTLE_DELAY)
137
- : undefined;
138
- const handleChartClick = React.useCallback((event) => {
139
- const [pointerX, pointerY] = pointer(event, svgRef.current);
140
- const x = pointerX - boundsOffsetLeft;
141
- const y = pointerY - boundsOffsetTop;
142
- if (isOutsideBounds(x, y)) {
143
- return;
144
- }
145
- const items = getClosestPoints({
146
- position: [x, y],
147
- shapesData,
148
- });
149
- const selected = items === null || items === void 0 ? void 0 : items.find((item) => item.closest);
150
- if (!selected) {
151
- return;
56
+ React.useEffect(() => {
57
+ if ((prevWidth !== width || prevHeight !== height) && tooltipPinned) {
58
+ unpinTooltip === null || unpinTooltip === void 0 ? void 0 : unpinTooltip();
152
59
  }
153
- dispatcher.call('click-chart', undefined, { point: selected.data, series: selected.series }, event);
154
- }, [boundsOffsetLeft, boundsOffsetTop, dispatcher, isOutsideBounds, shapesData]);
60
+ }, [prevWidth, width, prevHeight, height, tooltipPinned, unpinTooltip]);
155
61
  return (React.createElement(React.Fragment, null,
156
62
  React.createElement("svg", { ref: svgRef, className: b(), width: width, height: height, onMouseMove: throttledHandleMouseMove, onMouseLeave: handleMouseLeave, onTouchStart: throttledHandleTouchMove, onTouchMove: throttledHandleTouchMove, onClick: handleChartClick },
157
63
  title && React.createElement(Title, Object.assign({}, title, { chartWidth: width })),
158
64
  React.createElement("g", { transform: `translate(0, ${boundsOffsetTop})` }, preparedSplit.plots.map((plot, index) => {
159
65
  return React.createElement(PlotTitle, { key: `plot-${index}`, title: plot.title });
160
66
  })),
161
- React.createElement("g", { width: boundsWidth, height: boundsHeight, transform: `translate(${[boundsOffsetLeft, boundsOffsetTop].join(',')})` },
67
+ React.createElement("g", { width: boundsWidth, height: boundsHeight, transform: `translate(${[boundsOffsetLeft, boundsOffsetTop].join(',')})`, ref: plotRef },
162
68
  xScale && (yScale === null || yScale === void 0 ? void 0 : yScale.length) && (React.createElement(React.Fragment, null,
163
- React.createElement(AxisY, { axes: yAxis, width: boundsWidth, height: boundsHeight, scale: yScale, split: preparedSplit }),
69
+ React.createElement(AxisY, { axes: yAxis, width: boundsWidth, height: boundsHeight, scale: yScale, split: preparedSplit, plotRef: plotRef }),
164
70
  React.createElement("g", { transform: `translate(0, ${boundsHeight})` },
165
71
  React.createElement(AxisX, { axis: xAxis, width: boundsWidth, height: boundsHeight, scale: xScale, split: preparedSplit })))),
166
72
  shapes),
167
- preparedLegend.enabled && (React.createElement(Legend, { chartSeries: preparedSeries, boundsWidth: boundsWidth, legend: preparedLegend, items: legendItems, config: legendConfig, onItemClick: handleLegendItemClick }))),
73
+ preparedLegend.enabled && (React.createElement(Legend, { chartSeries: preparedSeries, boundsWidth: boundsWidth, legend: preparedLegend, items: legendItems, config: legendConfig, onItemClick: handleLegendItemClick, onUpdate: unpinTooltip }))),
168
74
  React.createElement("div", { className: b('html-layer'), ref: htmlLayerRef, style: {
169
75
  transform: `translate(${boundsOffsetLeft}px, ${boundsOffsetTop}px)`,
170
76
  } }),
171
- React.createElement(Tooltip, { dispatcher: dispatcher, tooltip: tooltip, svgContainer: svgRef.current, xAxis: xAxis, yAxis: yAxis[0] })));
77
+ React.createElement(Tooltip, { dispatcher: dispatcher, tooltip: tooltip, svgContainer: svgRef.current, xAxis: xAxis, yAxis: yAxis[0], onOutsideClick: unpinTooltip, tooltipPinned: tooltipPinned })));
172
78
  };
@@ -0,0 +1,6 @@
1
+ import type { ChartData } from '../../types';
2
+ export type ChartInnerProps = {
3
+ width: number;
4
+ height: number;
5
+ data: ChartData;
6
+ };
@@ -0,0 +1,26 @@
1
+ import React from 'react';
2
+ import type { Dispatch } from 'd3';
3
+ import type { PreparedAxis, ShapeData } from '../../hooks';
4
+ import type { useChartInnerState } from './useChartInnerState';
5
+ type ChartInnerState = ReturnType<typeof useChartInnerState>;
6
+ type Props = {
7
+ boundsHeight: number;
8
+ boundsOffsetLeft: number;
9
+ boundsOffsetTop: number;
10
+ boundsWidth: number;
11
+ dispatcher: Dispatch<object>;
12
+ shapesData: ShapeData[];
13
+ svgContainer: SVGSVGElement | null;
14
+ togglePinTooltip: ChartInnerState['togglePinTooltip'];
15
+ tooltipPinned: boolean;
16
+ unpinTooltip: ChartInnerState['unpinTooltip'];
17
+ xAxis: PreparedAxis;
18
+ yAxis: PreparedAxis[];
19
+ };
20
+ export declare function useChartInnerHandlers(props: Props): {
21
+ handleChartClick: (event: React.MouseEvent<SVGSVGElement>) => void;
22
+ handleMouseLeave: React.MouseEventHandler<SVGSVGElement>;
23
+ throttledHandleMouseMove: import("lodash").DebouncedFuncLeading<React.MouseEventHandler<SVGSVGElement>> | undefined;
24
+ throttledHandleTouchMove: import("lodash").DebouncedFuncLeading<React.TouchEventHandler<SVGSVGElement>> | undefined;
25
+ };
26
+ export {};
@@ -0,0 +1,98 @@
1
+ import React from 'react';
2
+ import { pointer } from 'd3';
3
+ import throttle from 'lodash/throttle';
4
+ import { IS_TOUCH_ENABLED } from '../../constants';
5
+ import { EventType } from '../../utils';
6
+ import { getClosestPoints } from '../../utils/chart/get-closest-data';
7
+ const THROTTLE_DELAY = 50;
8
+ export function useChartInnerHandlers(props) {
9
+ const { boundsHeight, boundsOffsetLeft, boundsOffsetTop, boundsWidth, dispatcher, shapesData, svgContainer, togglePinTooltip, tooltipPinned, unpinTooltip, xAxis, yAxis, } = props;
10
+ const isOutsideBounds = React.useCallback((x, y) => {
11
+ return x < 0 || x > boundsWidth || y < 0 || y > boundsHeight;
12
+ }, [boundsHeight, boundsWidth]);
13
+ const handleMove = ([pointerX, pointerY], event) => {
14
+ if (tooltipPinned) {
15
+ return;
16
+ }
17
+ const x = pointerX - boundsOffsetLeft;
18
+ const y = pointerY - boundsOffsetTop;
19
+ if (isOutsideBounds(x, y)) {
20
+ dispatcher.call(EventType.HOVER_SHAPE, {}, undefined);
21
+ dispatcher.call(EventType.POINTERMOVE_CHART, {}, undefined, event);
22
+ return;
23
+ }
24
+ const closest = getClosestPoints({
25
+ position: [x, y],
26
+ shapesData,
27
+ boundsHeight,
28
+ boundsWidth,
29
+ });
30
+ dispatcher.call(EventType.HOVER_SHAPE, event.target, closest, [pointerX, pointerY]);
31
+ dispatcher.call(EventType.POINTERMOVE_CHART, {}, {
32
+ hovered: closest,
33
+ xAxis,
34
+ yAxis: yAxis[0],
35
+ }, event);
36
+ };
37
+ const handleMouseMove = (event) => {
38
+ const [pointerX, pointerY] = pointer(event, svgContainer);
39
+ handleMove([pointerX, pointerY], event);
40
+ };
41
+ const throttledHandleMouseMove = IS_TOUCH_ENABLED
42
+ ? undefined
43
+ : throttle(handleMouseMove, THROTTLE_DELAY);
44
+ const handleMouseLeave = (event) => {
45
+ if (tooltipPinned) {
46
+ return;
47
+ }
48
+ throttledHandleMouseMove === null || throttledHandleMouseMove === void 0 ? void 0 : throttledHandleMouseMove.cancel();
49
+ dispatcher.call(EventType.HOVER_SHAPE, {}, undefined);
50
+ dispatcher.call(EventType.POINTERMOVE_CHART, {}, undefined, event);
51
+ };
52
+ const handleTouchMove = (event) => {
53
+ const touch = event.touches[0];
54
+ const [pointerX, pointerY] = pointer(touch, svgContainer);
55
+ handleMove([pointerX, pointerY], event);
56
+ };
57
+ const throttledHandleTouchMove = IS_TOUCH_ENABLED
58
+ ? throttle(handleTouchMove, THROTTLE_DELAY)
59
+ : undefined;
60
+ const handleChartClick = (event) => {
61
+ const [pointerX, pointerY] = pointer(event, svgContainer);
62
+ const x = pointerX - boundsOffsetLeft;
63
+ const y = pointerY - boundsOffsetTop;
64
+ if (isOutsideBounds(x, y)) {
65
+ return;
66
+ }
67
+ const items = getClosestPoints({
68
+ position: [x, y],
69
+ shapesData,
70
+ boundsHeight,
71
+ boundsWidth,
72
+ });
73
+ const selected = items === null || items === void 0 ? void 0 : items.find((item) => item.closest);
74
+ if (!selected) {
75
+ if (tooltipPinned) {
76
+ unpinTooltip === null || unpinTooltip === void 0 ? void 0 : unpinTooltip();
77
+ }
78
+ return;
79
+ }
80
+ dispatcher.call(EventType.CLICK_CHART, undefined, { point: selected.data, series: selected.series }, event);
81
+ const nextTooltipFixed = !tooltipPinned;
82
+ if (!nextTooltipFixed) {
83
+ dispatcher.call(EventType.HOVER_SHAPE, event.target, items, [pointerX, pointerY]);
84
+ dispatcher.call(EventType.POINTERMOVE_CHART, {}, {
85
+ hovered: items,
86
+ xAxis,
87
+ yAxis: yAxis[0],
88
+ }, event);
89
+ }
90
+ togglePinTooltip === null || togglePinTooltip === void 0 ? void 0 : togglePinTooltip(nextTooltipFixed, event);
91
+ };
92
+ return {
93
+ handleChartClick,
94
+ handleMouseLeave,
95
+ throttledHandleMouseMove,
96
+ throttledHandleTouchMove,
97
+ };
98
+ }
@@ -0,0 +1,43 @@
1
+ import React from 'react';
2
+ import type { Dispatch } from 'd3';
3
+ import type { ChartInnerProps } from './types';
4
+ type Props = ChartInnerProps & {
5
+ dispatcher: Dispatch<object>;
6
+ htmlLayout: HTMLElement | null;
7
+ };
8
+ export declare function useChartInnerProps(props: Props): {
9
+ boundsHeight: number;
10
+ boundsOffsetLeft: number;
11
+ boundsOffsetTop: number;
12
+ boundsWidth: number;
13
+ handleLegendItemClick: import("../../hooks").OnLegendItemClick;
14
+ legendConfig: {
15
+ offset: {
16
+ left: number;
17
+ top: number;
18
+ };
19
+ pagination: {
20
+ limit: number;
21
+ maxPage: number;
22
+ } | undefined;
23
+ };
24
+ legendItems: import("../../hooks").LegendItem[][];
25
+ preparedLegend: import("../../hooks").PreparedLegend;
26
+ preparedSeries: import("../../hooks").PreparedSeries[];
27
+ preparedSplit: import("../../hooks").PreparedSplit;
28
+ prevHeight: number | undefined;
29
+ prevWidth: number | undefined;
30
+ shapes: React.ReactElement<any, string | React.JSXElementConstructor<any>>[];
31
+ shapesData: import("../../hooks").ShapeData[];
32
+ title: (import("../../types").ChartTitle & {
33
+ height: number;
34
+ }) | undefined;
35
+ tooltip: import("../../types").ChartTooltip<any> & {
36
+ enabled: boolean;
37
+ };
38
+ xAxis: import("../../hooks").PreparedAxis;
39
+ xScale: import("../../hooks").ChartScale | undefined;
40
+ yAxis: import("../../hooks").PreparedAxis[];
41
+ yScale: import("../../hooks").ChartScale[] | undefined;
42
+ };
43
+ export {};
@@ -0,0 +1,81 @@
1
+ import React from 'react';
2
+ import { useAxisScales, useChartDimensions, useChartOptions, usePrevious, useSeries, useShapes, useSplit, } from '../../hooks';
3
+ import { getYAxisWidth } from '../../hooks/useChartDimensions/utils';
4
+ import { getPreparedXAxis } from '../../hooks/useChartOptions/x-axis';
5
+ import { getPreparedYAxis } from '../../hooks/useChartOptions/y-axis';
6
+ export function useChartInnerProps(props) {
7
+ const { width, height, data, dispatcher, htmlLayout } = props;
8
+ const prevWidth = usePrevious(width);
9
+ const prevHeight = usePrevious(height);
10
+ const { chart, title, tooltip } = useChartOptions({ data });
11
+ const xAxis = React.useMemo(() => getPreparedXAxis({ xAxis: data.xAxis, width, series: data.series.data }), [data, width]);
12
+ const yAxis = React.useMemo(() => getPreparedYAxis({
13
+ series: data.series.data,
14
+ yAxis: data.yAxis,
15
+ height,
16
+ }), [data, height]);
17
+ const { legendItems, legendConfig, preparedSeries, preparedSeriesOptions, preparedLegend, handleLegendItemClick, } = useSeries({
18
+ chartWidth: width,
19
+ chartHeight: height,
20
+ chartMargin: chart.margin,
21
+ series: data.series,
22
+ legend: data.legend,
23
+ preparedYAxis: yAxis,
24
+ });
25
+ const { boundsWidth, boundsHeight } = useChartDimensions({
26
+ width,
27
+ height,
28
+ margin: chart.margin,
29
+ preparedLegend,
30
+ preparedXAxis: xAxis,
31
+ preparedYAxis: yAxis,
32
+ preparedSeries: preparedSeries,
33
+ });
34
+ const preparedSplit = useSplit({ split: data.split, boundsHeight, chartWidth: width });
35
+ const { xScale, yScale } = useAxisScales({
36
+ boundsWidth,
37
+ boundsHeight,
38
+ series: preparedSeries,
39
+ xAxis,
40
+ yAxis,
41
+ split: preparedSplit,
42
+ });
43
+ const { shapes, shapesData } = useShapes({
44
+ boundsWidth,
45
+ boundsHeight,
46
+ dispatcher,
47
+ series: preparedSeries,
48
+ seriesOptions: preparedSeriesOptions,
49
+ xAxis,
50
+ xScale,
51
+ yAxis,
52
+ yScale,
53
+ split: preparedSplit,
54
+ htmlLayout,
55
+ });
56
+ const boundsOffsetTop = chart.margin.top;
57
+ // We only need to consider the width of the first left axis
58
+ const boundsOffsetLeft = chart.margin.left + getYAxisWidth(yAxis[0]);
59
+ return {
60
+ boundsHeight,
61
+ boundsOffsetLeft,
62
+ boundsOffsetTop,
63
+ boundsWidth,
64
+ handleLegendItemClick,
65
+ legendConfig,
66
+ legendItems,
67
+ preparedLegend,
68
+ preparedSeries,
69
+ preparedSplit,
70
+ prevHeight,
71
+ prevWidth,
72
+ shapes,
73
+ shapesData,
74
+ title,
75
+ tooltip,
76
+ xAxis,
77
+ xScale,
78
+ yAxis,
79
+ yScale,
80
+ };
81
+ }
@@ -0,0 +1,13 @@
1
+ import React from 'react';
2
+ import type { Dispatch } from 'd3';
3
+ import type { ChartTooltip } from '../../types';
4
+ type Props = {
5
+ dispatcher: Dispatch<object>;
6
+ tooltip?: ChartTooltip;
7
+ };
8
+ export declare function useChartInnerState(props: Props): {
9
+ tooltipPinned: boolean;
10
+ togglePinTooltip: ((value: boolean, event: React.MouseEvent) => void) | undefined;
11
+ unpinTooltip: (() => void) | undefined;
12
+ };
13
+ export {};
@@ -0,0 +1,34 @@
1
+ import React from 'react';
2
+ import { EventType, isMacintosh } from '../../utils';
3
+ export function useChartInnerState(props) {
4
+ var _a, _b;
5
+ const { dispatcher, tooltip } = props;
6
+ const [tooltipPinned, setTooltipPinned] = React.useState(false);
7
+ const tooltipEnabled = tooltip === null || tooltip === void 0 ? void 0 : tooltip.enabled;
8
+ const tooltipPinEnabled = (_a = tooltip === null || tooltip === void 0 ? void 0 : tooltip.pin) === null || _a === void 0 ? void 0 : _a.enabled;
9
+ const modifierKey = (_b = tooltip === null || tooltip === void 0 ? void 0 : tooltip.pin) === null || _b === void 0 ? void 0 : _b.modifierKey;
10
+ const togglePinTooltip = React.useCallback((value, event) => {
11
+ let resultValue = value;
12
+ if (value && modifierKey) {
13
+ switch (modifierKey) {
14
+ case 'altKey': {
15
+ resultValue = event.altKey;
16
+ break;
17
+ }
18
+ case 'metaKey': {
19
+ resultValue = isMacintosh() ? event.metaKey : event.ctrlKey;
20
+ }
21
+ }
22
+ }
23
+ setTooltipPinned(resultValue);
24
+ }, [modifierKey]);
25
+ const unpinTooltip = React.useCallback(() => {
26
+ setTooltipPinned(false);
27
+ dispatcher.call(EventType.HOVER_SHAPE, {}, undefined);
28
+ }, [dispatcher]);
29
+ return {
30
+ tooltipPinned,
31
+ togglePinTooltip: tooltipEnabled && tooltipPinEnabled ? togglePinTooltip : undefined,
32
+ unpinTooltip: tooltipEnabled && tooltipPinEnabled ? unpinTooltip : undefined,
33
+ };
34
+ }
@@ -8,6 +8,7 @@ type Props = {
8
8
  items: LegendItem[][];
9
9
  config: LegendConfig;
10
10
  onItemClick: OnLegendItemClick;
11
+ onUpdate?: () => void;
11
12
  };
12
13
  export declare const Legend: (props: Props) => React.JSX.Element;
13
14
  export {};