@gravity-ui/charts 1.38.6 → 1.39.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 (169) hide show
  1. package/dist/cjs/components/AxisX/prepare-axis-data.d.ts +1 -1
  2. package/dist/cjs/components/AxisX/prepare-axis-data.js +10 -10
  3. package/dist/cjs/components/AxisY/prepare-axis-data.d.ts +1 -1
  4. package/dist/cjs/components/AxisY/prepare-axis-data.js +2 -2
  5. package/dist/cjs/components/ChartInner/index.js +25 -8
  6. package/dist/cjs/components/ChartInner/useChartInnerHandlers.d.ts +1 -2
  7. package/dist/cjs/components/ChartInner/useChartInnerHandlers.js +5 -1
  8. package/dist/cjs/components/ChartInner/useChartInnerProps.d.ts +19 -20
  9. package/dist/cjs/components/ChartInner/useChartInnerProps.js +230 -139
  10. package/dist/cjs/components/ChartInner/useChartInnerState.js +2 -1
  11. package/dist/cjs/components/ChartInner/useDefaultState.d.ts +26 -0
  12. package/dist/cjs/components/ChartInner/useDefaultState.js +74 -0
  13. package/dist/cjs/components/ChartInner/utils/axis.d.ts +44 -0
  14. package/dist/cjs/components/ChartInner/utils/axis.js +35 -0
  15. package/dist/cjs/{hooks/useChartOptions → components/ChartInner/utils}/chart.d.ts +2 -2
  16. package/dist/{esm/components/ChartInner/utils.d.ts → cjs/components/ChartInner/utils/common.d.ts} +2 -1
  17. package/dist/cjs/components/ChartInner/utils/index.d.ts +7 -0
  18. package/dist/cjs/components/ChartInner/utils/index.js +7 -0
  19. package/dist/cjs/components/ChartInner/utils/normalized-original-data.d.ts +33 -0
  20. package/dist/cjs/components/ChartInner/utils/normalized-original-data.js +21 -0
  21. package/dist/cjs/{hooks/useChartOptions → components/ChartInner/utils}/title.d.ts +2 -2
  22. package/dist/{esm/hooks/useChartOptions → cjs/components/ChartInner/utils}/title.js +1 -1
  23. package/dist/cjs/components/ChartInner/utils/tooltip.d.ts +8 -0
  24. package/dist/cjs/components/ChartInner/utils/tooltip.js +7 -0
  25. package/dist/cjs/{hooks/useChartOptions → components/ChartInner/utils}/zoom.d.ts +3 -3
  26. package/dist/{esm/hooks/useChartOptions → cjs/components/ChartInner/utils}/zoom.js +1 -1
  27. package/dist/cjs/components/Legend/index.d.ts +1 -1
  28. package/dist/cjs/components/Legend/index.js +1 -1
  29. package/dist/cjs/hooks/index.d.ts +1 -4
  30. package/dist/cjs/hooks/index.js +1 -4
  31. package/dist/cjs/hooks/{useChartOptions/types.d.ts → types.d.ts} +1 -1
  32. package/dist/cjs/hooks/useAxis/index.d.ts +41 -6
  33. package/dist/cjs/hooks/useAxis/index.js +55 -40
  34. package/dist/cjs/hooks/useAxis/types.d.ts +0 -2
  35. package/dist/cjs/hooks/useAxis/y-axis.js +1 -3
  36. package/dist/cjs/hooks/useAxisScales/index.d.ts +4 -0
  37. package/dist/cjs/hooks/useAxisScales/index.js +1 -1
  38. package/dist/cjs/hooks/useAxisScales/x-scale.js +0 -1
  39. package/dist/cjs/hooks/useAxisScales/y-scale.js +0 -1
  40. package/dist/cjs/hooks/useCrosshair/index.d.ts +1 -1
  41. package/dist/cjs/hooks/useRangeSlider/types.d.ts +1 -1
  42. package/dist/cjs/hooks/useRangeSlider/utils.d.ts +1 -1
  43. package/dist/cjs/hooks/useSeries/index.d.ts +10 -14
  44. package/dist/cjs/hooks/useSeries/index.js +8 -80
  45. package/dist/cjs/hooks/useSeries/prepare-area.d.ts +2 -2
  46. package/dist/cjs/hooks/useSeries/prepare-legend.d.ts +1 -1
  47. package/dist/cjs/hooks/useSeries/prepare-line.d.ts +2 -2
  48. package/dist/cjs/hooks/useSeries/prepare-radar.d.ts +1 -1
  49. package/dist/cjs/hooks/useShapes/index.d.ts +4 -0
  50. package/dist/cjs/hooks/useShapes/index.js +209 -189
  51. package/dist/cjs/hooks/useShapes/pie/prepare-data.js +0 -1
  52. package/dist/cjs/hooks/useSplit/index.d.ts +5 -2
  53. package/dist/cjs/hooks/useSplit/index.js +27 -30
  54. package/dist/cjs/hooks/useTooltip/index.d.ts +1 -1
  55. package/dist/cjs/hooks/useZoom/index.d.ts +2 -2
  56. package/dist/cjs/hooks/useZoom/index.js +2 -2
  57. package/dist/cjs/index.d.ts +1 -1
  58. package/dist/cjs/index.js +1 -1
  59. package/dist/cjs/types/index.d.ts +24 -11
  60. package/dist/cjs/utils/chart/axis/common.d.ts +2 -2
  61. package/dist/cjs/utils/chart/axis/common.js +1 -1
  62. package/dist/cjs/utils/chart/chart-dimensions.d.ts +24 -0
  63. package/dist/cjs/{hooks/useChartDimensions/index.js → utils/chart/chart-dimensions.js} +56 -33
  64. package/dist/cjs/utils/chart/common.d.ts +28 -0
  65. package/dist/cjs/utils/chart/common.js +192 -0
  66. package/dist/cjs/utils/chart/get-closest-data.js +0 -1
  67. package/dist/cjs/utils/chart/index.d.ts +2 -28
  68. package/dist/cjs/utils/chart/index.js +2 -192
  69. package/dist/cjs/utils/chart/tooltip.d.ts +6 -0
  70. package/dist/cjs/{hooks/useChartOptions → utils/chart}/tooltip.js +2 -7
  71. package/dist/cjs/utils/chart/zoom.js +0 -2
  72. package/dist/esm/components/AxisX/prepare-axis-data.d.ts +1 -1
  73. package/dist/esm/components/AxisX/prepare-axis-data.js +10 -10
  74. package/dist/esm/components/AxisY/prepare-axis-data.d.ts +1 -1
  75. package/dist/esm/components/AxisY/prepare-axis-data.js +2 -2
  76. package/dist/esm/components/ChartInner/index.js +25 -8
  77. package/dist/esm/components/ChartInner/useChartInnerHandlers.d.ts +1 -2
  78. package/dist/esm/components/ChartInner/useChartInnerHandlers.js +5 -1
  79. package/dist/esm/components/ChartInner/useChartInnerProps.d.ts +19 -20
  80. package/dist/esm/components/ChartInner/useChartInnerProps.js +230 -139
  81. package/dist/esm/components/ChartInner/useChartInnerState.js +2 -1
  82. package/dist/esm/components/ChartInner/useDefaultState.d.ts +26 -0
  83. package/dist/esm/components/ChartInner/useDefaultState.js +74 -0
  84. package/dist/esm/components/ChartInner/utils/axis.d.ts +44 -0
  85. package/dist/esm/components/ChartInner/utils/axis.js +35 -0
  86. package/dist/esm/{hooks/useChartOptions → components/ChartInner/utils}/chart.d.ts +2 -2
  87. package/dist/{cjs/components/ChartInner/utils.d.ts → esm/components/ChartInner/utils/common.d.ts} +2 -1
  88. package/dist/esm/components/ChartInner/utils/index.d.ts +7 -0
  89. package/dist/esm/components/ChartInner/utils/index.js +7 -0
  90. package/dist/esm/components/ChartInner/utils/normalized-original-data.d.ts +33 -0
  91. package/dist/esm/components/ChartInner/utils/normalized-original-data.js +21 -0
  92. package/dist/esm/{hooks/useChartOptions → components/ChartInner/utils}/title.d.ts +2 -2
  93. package/dist/{cjs/hooks/useChartOptions → esm/components/ChartInner/utils}/title.js +1 -1
  94. package/dist/esm/components/ChartInner/utils/tooltip.d.ts +8 -0
  95. package/dist/esm/components/ChartInner/utils/tooltip.js +7 -0
  96. package/dist/esm/{hooks/useChartOptions → components/ChartInner/utils}/zoom.d.ts +3 -3
  97. package/dist/{cjs/hooks/useChartOptions → esm/components/ChartInner/utils}/zoom.js +1 -1
  98. package/dist/esm/components/Legend/index.d.ts +1 -1
  99. package/dist/esm/components/Legend/index.js +1 -1
  100. package/dist/esm/hooks/index.d.ts +1 -4
  101. package/dist/esm/hooks/index.js +1 -4
  102. package/dist/esm/hooks/{useChartOptions/types.d.ts → types.d.ts} +1 -1
  103. package/dist/esm/hooks/useAxis/index.d.ts +41 -6
  104. package/dist/esm/hooks/useAxis/index.js +55 -40
  105. package/dist/esm/hooks/useAxis/types.d.ts +0 -2
  106. package/dist/esm/hooks/useAxis/y-axis.js +1 -3
  107. package/dist/esm/hooks/useAxisScales/index.d.ts +4 -0
  108. package/dist/esm/hooks/useAxisScales/index.js +1 -1
  109. package/dist/esm/hooks/useAxisScales/x-scale.js +0 -1
  110. package/dist/esm/hooks/useAxisScales/y-scale.js +0 -1
  111. package/dist/esm/hooks/useCrosshair/index.d.ts +1 -1
  112. package/dist/esm/hooks/useRangeSlider/types.d.ts +1 -1
  113. package/dist/esm/hooks/useRangeSlider/utils.d.ts +1 -1
  114. package/dist/esm/hooks/useSeries/index.d.ts +10 -14
  115. package/dist/esm/hooks/useSeries/index.js +8 -80
  116. package/dist/esm/hooks/useSeries/prepare-area.d.ts +2 -2
  117. package/dist/esm/hooks/useSeries/prepare-legend.d.ts +1 -1
  118. package/dist/esm/hooks/useSeries/prepare-line.d.ts +2 -2
  119. package/dist/esm/hooks/useSeries/prepare-radar.d.ts +1 -1
  120. package/dist/esm/hooks/useShapes/index.d.ts +4 -0
  121. package/dist/esm/hooks/useShapes/index.js +209 -189
  122. package/dist/esm/hooks/useShapes/pie/prepare-data.js +0 -1
  123. package/dist/esm/hooks/useSplit/index.d.ts +5 -2
  124. package/dist/esm/hooks/useSplit/index.js +27 -30
  125. package/dist/esm/hooks/useTooltip/index.d.ts +1 -1
  126. package/dist/esm/hooks/useZoom/index.d.ts +2 -2
  127. package/dist/esm/hooks/useZoom/index.js +2 -2
  128. package/dist/esm/index.d.ts +1 -1
  129. package/dist/esm/index.js +1 -1
  130. package/dist/esm/types/index.d.ts +24 -11
  131. package/dist/esm/utils/chart/axis/common.d.ts +2 -2
  132. package/dist/esm/utils/chart/axis/common.js +1 -1
  133. package/dist/esm/utils/chart/chart-dimensions.d.ts +24 -0
  134. package/dist/esm/{hooks/useChartDimensions/index.js → utils/chart/chart-dimensions.js} +56 -33
  135. package/dist/esm/utils/chart/common.d.ts +28 -0
  136. package/dist/esm/utils/chart/common.js +192 -0
  137. package/dist/esm/utils/chart/get-closest-data.js +0 -1
  138. package/dist/esm/utils/chart/index.d.ts +2 -28
  139. package/dist/esm/utils/chart/index.js +2 -192
  140. package/dist/esm/utils/chart/tooltip.d.ts +6 -0
  141. package/dist/esm/{hooks/useChartOptions → utils/chart}/tooltip.js +2 -7
  142. package/dist/esm/utils/chart/zoom.js +0 -2
  143. package/package.json +3 -1
  144. package/dist/cjs/components/ChartInner/useLegend.d.ts +0 -14
  145. package/dist/cjs/components/ChartInner/useLegend.js +0 -34
  146. package/dist/cjs/hooks/useChartDimensions/index.d.ts +0 -17
  147. package/dist/cjs/hooks/useChartDimensions/utils.d.ts +0 -10
  148. package/dist/cjs/hooks/useChartDimensions/utils.js +0 -41
  149. package/dist/cjs/hooks/useChartOptions/tooltip.d.ts +0 -13
  150. package/dist/cjs/hooks/useNormalizedOriginalData/index.d.ts +0 -38
  151. package/dist/cjs/hooks/useNormalizedOriginalData/index.js +0 -32
  152. package/dist/cjs/hooks/useYAxisLabelWidth/index.d.ts +0 -11
  153. package/dist/cjs/hooks/useYAxisLabelWidth/index.js +0 -48
  154. package/dist/esm/components/ChartInner/useLegend.d.ts +0 -14
  155. package/dist/esm/components/ChartInner/useLegend.js +0 -34
  156. package/dist/esm/hooks/useChartDimensions/index.d.ts +0 -17
  157. package/dist/esm/hooks/useChartDimensions/utils.d.ts +0 -10
  158. package/dist/esm/hooks/useChartDimensions/utils.js +0 -41
  159. package/dist/esm/hooks/useChartOptions/tooltip.d.ts +0 -13
  160. package/dist/esm/hooks/useNormalizedOriginalData/index.d.ts +0 -38
  161. package/dist/esm/hooks/useNormalizedOriginalData/index.js +0 -32
  162. package/dist/esm/hooks/useYAxisLabelWidth/index.d.ts +0 -11
  163. package/dist/esm/hooks/useYAxisLabelWidth/index.js +0 -48
  164. /package/dist/cjs/{hooks/useChartOptions → components/ChartInner/utils}/chart.js +0 -0
  165. /package/dist/cjs/components/ChartInner/{utils.js → utils/common.js} +0 -0
  166. /package/dist/cjs/hooks/{useChartOptions/types.js → types.js} +0 -0
  167. /package/dist/esm/{hooks/useChartOptions → components/ChartInner/utils}/chart.js +0 -0
  168. /package/dist/esm/components/ChartInner/{utils.js → utils/common.js} +0 -0
  169. /package/dist/esm/hooks/{useChartOptions/types.js → types.js} +0 -0
@@ -1,11 +1,13 @@
1
1
  import React from 'react';
2
+ import isEqual from 'lodash/isEqual';
2
3
  import { DEFAULT_PALETTE, SERIES_TYPE } from '../../constants';
3
- import { useAxis, useAxisScales, useChartDimensions, useNormalizedOriginalData, usePrevious, useSeries, useShapes, useSplit, useYAxisLabelWidth, useZoom, } from '../../hooks';
4
- import { getYAxisWidth } from '../../hooks/useChartDimensions/utils';
4
+ import { createScales, getAxes, getPreparedSeries, getShapes, getSplit, getVisibleSeries, useZoom, } from '../../hooks';
5
+ import { getLegendComponents, getPreparedLegend } from '../../hooks/useSeries/prepare-legend';
5
6
  import { getPreparedOptions } from '../../hooks/useSeries/prepare-options';
6
- import { getEffectiveXRange, getZoomedSeriesData } from '../../utils';
7
- import { useLegend } from './useLegend';
8
- import { hasAtLeastOneSeriesDataPerPlot } from './utils';
7
+ import { getActiveLegendItems, getAllLegendItems } from '../../hooks/useSeries/utils';
8
+ import { getChartDimensions, getEffectiveXRange, getSortedSeriesData, getYAxisWidth, getZoomedSeriesData, isAxisRelatedSeries, } from '../../utils';
9
+ import { getNormalizedXAxis, getNormalizedYAxis, recalculateYAxisLabelsWidth } from './utils';
10
+ import { hasAtLeastOneSeriesDataPerPlot } from './utils/common';
9
11
  const CLIP_PATH_BY_SERIES_TYPE = {
10
12
  [SERIES_TYPE.Scatter]: false,
11
13
  };
@@ -35,110 +37,231 @@ function getBoundsOffsetLeft(args) {
35
37
  return chartMarginLeft + legendOffset + leftAxisWidth;
36
38
  }
37
39
  export function useChartInnerProps(props) {
40
+ var _a, _b, _c, _d, _e, _f;
38
41
  const { clipPathId, data, dispatcher, height, htmlLayout, plotNode, preparedChart, rangeSliderState, width, updateZoomState, zoomState, } = props;
39
- const prevWidth = usePrevious(width);
40
- const prevHeight = usePrevious(height);
41
- const colors = React.useMemo(() => {
42
- var _a;
43
- return (_a = data.colors) !== null && _a !== void 0 ? _a : DEFAULT_PALETTE;
44
- }, [data.colors]);
45
- const { normalizedSeriesData, normalizedXAxis, normalizedYAxis } = useNormalizedOriginalData({
46
- seriesData: data.series.data,
47
- xAxis: data.xAxis,
48
- yAxis: data.yAxis,
49
- });
50
- const preparedSeriesOptions = React.useMemo(() => {
51
- return getPreparedOptions(data.series.options);
52
- }, [data.series.options]);
53
- const { preparedSeries: allPreparedSeries, preparedLegend, handleLegendItemClick, } = useSeries({
54
- colors,
55
- legend: data.legend,
56
- originalSeriesData: normalizedSeriesData,
57
- seriesData: normalizedSeriesData,
58
- seriesOptions: data.series.options,
59
- });
60
- const effectiveZoomState = React.useMemo(() => {
61
- const result = {};
62
- const effectiveX = getEffectiveXRange(zoomState.x, rangeSliderState);
63
- if (effectiveX !== undefined) {
64
- result.x = effectiveX;
65
- }
66
- if (zoomState.y !== undefined) {
67
- result.y = zoomState.y;
68
- }
69
- return result;
70
- }, [zoomState, rangeSliderState]);
71
- const { preparedSeries, preparedShapesSeries } = React.useMemo(() => {
72
- return getZoomedSeriesData({
73
- seriesData: allPreparedSeries,
74
- xAxis: normalizedXAxis,
75
- yAxis: normalizedYAxis,
76
- zoomState: effectiveZoomState,
77
- });
78
- }, [allPreparedSeries, normalizedXAxis, normalizedYAxis, effectiveZoomState]);
79
- const { legendConfig, legendItems } = useLegend({
80
- width,
81
- height,
82
- preparedChart,
83
- preparedSeries,
84
- preparedLegend,
85
- });
86
- const { xAxis, yAxis, setAxes } = useAxis({
87
- height,
88
- preparedChart,
89
- legendConfig,
90
- preparedLegend,
91
- preparedSeries,
92
- preparedSeriesOptions,
93
- width,
94
- xAxis: normalizedXAxis,
95
- yAxis: normalizedYAxis,
96
- });
97
- const { boundsWidth, boundsHeight } = useChartDimensions({
42
+ const [selectedLegendItems, setSelectedLegendItems] = React.useState(null);
43
+ const [chartState, setState] = React.useState(null);
44
+ const prevStateValue = React.useRef(chartState);
45
+ const previousChartData = React.useRef(null);
46
+ const currentRunRef = React.useRef(0);
47
+ React.useEffect(() => {
48
+ currentRunRef.current++;
49
+ const currentRun = currentRunRef.current;
50
+ (async function () {
51
+ var _a, _b, _c;
52
+ const chartDataChanged = !(previousChartData.current && isEqual(previousChartData.current, data));
53
+ const colors = (_a = data.colors) !== null && _a !== void 0 ? _a : DEFAULT_PALETTE;
54
+ const normalizedSeriesData = getSortedSeriesData({
55
+ seriesData: data.series.data,
56
+ xAxis: data.xAxis,
57
+ yAxis: data.yAxis,
58
+ });
59
+ const normalizedXAxis = getNormalizedXAxis({ xAxis: data.xAxis });
60
+ const normalizedYAxis = getNormalizedYAxis({ yAxis: data.yAxis });
61
+ const preparedSeriesOptions = getPreparedOptions(data.series.options);
62
+ const preparedLegend = await getPreparedLegend({
63
+ legend: data.legend,
64
+ series: normalizedSeriesData,
65
+ });
66
+ let allPreparedSeries;
67
+ if (chartDataChanged) {
68
+ allPreparedSeries = await getPreparedSeries({
69
+ seriesData: normalizedSeriesData,
70
+ seriesOptions: data.series.options,
71
+ preparedLegend,
72
+ colors,
73
+ });
74
+ }
75
+ else {
76
+ allPreparedSeries = (_c = (_b = prevStateValue.current) === null || _b === void 0 ? void 0 : _b.allPreparedSeries) !== null && _c !== void 0 ? _c : [];
77
+ }
78
+ const activeLegendItems = selectedLegendItems !== null && selectedLegendItems !== void 0 ? selectedLegendItems : getActiveLegendItems(allPreparedSeries);
79
+ const visiblePreparedSeries = getVisibleSeries({
80
+ preparedSeries: allPreparedSeries,
81
+ activeLegendItems,
82
+ });
83
+ const effectiveZoomState = {};
84
+ const effectiveX = getEffectiveXRange(zoomState.x, rangeSliderState);
85
+ if (effectiveX !== undefined) {
86
+ effectiveZoomState.x = effectiveX;
87
+ }
88
+ if (zoomState.y !== undefined) {
89
+ effectiveZoomState.y = zoomState.y;
90
+ }
91
+ const { preparedSeries, preparedShapesSeries } = getZoomedSeriesData({
92
+ seriesData: visiblePreparedSeries,
93
+ xAxis: normalizedXAxis,
94
+ yAxis: normalizedYAxis,
95
+ zoomState: effectiveZoomState,
96
+ });
97
+ const { legendConfig, legendItems } = await getLegendComponents({
98
+ chartWidth: width,
99
+ chartHeight: height,
100
+ chartMargin: preparedChart.margin,
101
+ series: preparedSeries,
102
+ preparedLegend,
103
+ });
104
+ const axes = await getAxes({
105
+ height,
106
+ preparedChart,
107
+ legendConfig,
108
+ preparedLegend,
109
+ preparedSeries,
110
+ preparedSeriesOptions,
111
+ width,
112
+ xAxis: normalizedXAxis,
113
+ yAxis: normalizedYAxis,
114
+ });
115
+ const xAxis = axes.xAxis;
116
+ let yAxis = axes.yAxis;
117
+ let preparedSplit = { plots: [], gap: 0 };
118
+ let xScale;
119
+ let yScale;
120
+ let boundsWidth = 0;
121
+ let boundsHeight = 0;
122
+ const calculateAxisBasedProps = () => {
123
+ const chartDimensions = getChartDimensions({
124
+ height,
125
+ margin: preparedChart.margin,
126
+ preparedLegend,
127
+ preparedSeries: preparedSeries,
128
+ preparedYAxis: yAxis,
129
+ preparedXAxis: xAxis,
130
+ width,
131
+ legendConfig,
132
+ });
133
+ boundsHeight = chartDimensions.boundsHeight;
134
+ boundsWidth = chartDimensions.boundsWidth;
135
+ preparedSplit = getSplit({ split: data.split, boundsHeight, chartWidth: width });
136
+ if (preparedSeries.some(isAxisRelatedSeries)) {
137
+ ({ xScale, yScale } = createScales({
138
+ boundsWidth,
139
+ boundsHeight,
140
+ isRangeSlider: false,
141
+ rangeSliderState,
142
+ series: preparedSeries,
143
+ split: preparedSplit,
144
+ xAxis,
145
+ yAxis,
146
+ zoomState,
147
+ }));
148
+ }
149
+ };
150
+ calculateAxisBasedProps();
151
+ const newYAxis = await recalculateYAxisLabelsWidth({
152
+ seriesData: preparedSeries,
153
+ yAxis,
154
+ yScale,
155
+ });
156
+ if (!isEqual(yAxis, newYAxis)) {
157
+ yAxis = newYAxis;
158
+ calculateAxisBasedProps();
159
+ }
160
+ const { shapes, shapesData } = await getShapes({
161
+ boundsWidth,
162
+ boundsHeight,
163
+ clipPathBySeriesType: CLIP_PATH_BY_SERIES_TYPE,
164
+ dispatcher,
165
+ series: preparedShapesSeries,
166
+ seriesOptions: preparedSeriesOptions,
167
+ xAxis,
168
+ xScale,
169
+ yAxis,
170
+ yScale,
171
+ split: preparedSplit,
172
+ htmlLayout,
173
+ clipPathId,
174
+ isOutsideBounds: (x, y) => {
175
+ return x < 0 || x > boundsWidth || y < 0 || y > boundsHeight;
176
+ },
177
+ zoomState: effectiveZoomState,
178
+ });
179
+ const boundsOffsetTop = getBoundsOffsetTop({
180
+ chartMarginTop: preparedChart.margin.top,
181
+ preparedLegend,
182
+ legendConfig,
183
+ });
184
+ // We need to calculate the width of each left axis because the first axis can be hidden
185
+ const boundsOffsetLeft = getBoundsOffsetLeft({
186
+ chartMarginLeft: preparedChart.margin.left,
187
+ preparedLegend,
188
+ yAxis,
189
+ getYAxisWidth,
190
+ legendConfig,
191
+ });
192
+ //end
193
+ const newStateValue = {
194
+ allPreparedSeries,
195
+ boundsHeight,
196
+ boundsOffsetLeft,
197
+ boundsOffsetTop,
198
+ boundsWidth,
199
+ legendConfig,
200
+ legendItems,
201
+ preparedLegend,
202
+ preparedSeries,
203
+ preparedSeriesOptions,
204
+ preparedSplit,
205
+ shapes,
206
+ shapesData,
207
+ xAxis,
208
+ xScale,
209
+ yAxis,
210
+ yScale,
211
+ activeLegendItems,
212
+ };
213
+ if (currentRunRef.current === currentRun) {
214
+ if (!isEqual(prevStateValue.current, newStateValue)) {
215
+ setState(newStateValue);
216
+ prevStateValue.current = newStateValue;
217
+ }
218
+ previousChartData.current = data;
219
+ }
220
+ })();
221
+ }, [
98
222
  height,
99
- margin: preparedChart.margin,
100
- preparedLegend,
101
- preparedSeries: preparedSeries,
102
- preparedYAxis: yAxis,
103
- preparedXAxis: xAxis,
104
223
  width,
105
- legendConfig,
106
- });
107
- const preparedSplit = useSplit({ split: data.split, boundsHeight, chartWidth: width });
108
- const { xScale, yScale } = useAxisScales({
109
- boundsWidth,
110
- boundsHeight,
111
- rangeSliderState,
112
- series: preparedSeries,
113
- split: preparedSplit,
114
- xAxis,
115
- yAxis,
224
+ data,
225
+ selectedLegendItems,
116
226
  zoomState,
117
- });
118
- useYAxisLabelWidth({ seriesData: preparedSeries, setAxes, yAxis, yScale });
119
- const isOutsideBounds = React.useCallback((x, y) => {
120
- return x < 0 || x > boundsWidth || y < 0 || y > boundsHeight;
121
- }, [boundsHeight, boundsWidth]);
122
- const { shapes, shapesData, shapesReady } = useShapes({
123
- boundsWidth,
124
- boundsHeight,
125
- clipPathBySeriesType: CLIP_PATH_BY_SERIES_TYPE,
227
+ rangeSliderState,
228
+ preparedChart,
126
229
  dispatcher,
127
- series: preparedShapesSeries,
128
- seriesOptions: preparedSeriesOptions,
129
- xAxis,
130
- xScale,
131
- yAxis,
132
- yScale,
133
- split: preparedSplit,
134
230
  htmlLayout,
135
231
  clipPathId,
136
- isOutsideBounds,
137
- zoomState: effectiveZoomState,
138
- });
232
+ ]);
233
+ // additional start
234
+ const preparedSeries = React.useMemo(() => { var _a; return (_a = chartState === null || chartState === void 0 ? void 0 : chartState.preparedSeries) !== null && _a !== void 0 ? _a : []; }, [chartState === null || chartState === void 0 ? void 0 : chartState.preparedSeries]);
235
+ const activeLegendItems = React.useMemo(() => { var _a; return (_a = chartState === null || chartState === void 0 ? void 0 : chartState.activeLegendItems) !== null && _a !== void 0 ? _a : []; }, [chartState === null || chartState === void 0 ? void 0 : chartState.activeLegendItems]);
236
+ const boundsHeight = (_a = chartState === null || chartState === void 0 ? void 0 : chartState.boundsHeight) !== null && _a !== void 0 ? _a : 0;
237
+ const boundsWidth = (_b = chartState === null || chartState === void 0 ? void 0 : chartState.boundsWidth) !== null && _b !== void 0 ? _b : 0;
238
+ const xAxis = (_c = chartState === null || chartState === void 0 ? void 0 : chartState.xAxis) !== null && _c !== void 0 ? _c : null;
239
+ const yAxis = React.useMemo(() => { var _a; return (_a = chartState === null || chartState === void 0 ? void 0 : chartState.yAxis) !== null && _a !== void 0 ? _a : []; }, [chartState === null || chartState === void 0 ? void 0 : chartState.yAxis]);
240
+ const handleLegendItemClick = React.useCallback(({ id, metaKey }) => {
241
+ const allItems = getAllLegendItems(preparedSeries);
242
+ const onlyItemSelected = (selectedLegendItems !== null && selectedLegendItems !== void 0 ? selectedLegendItems : []).length === 1 && activeLegendItems.includes(id);
243
+ let nextActiveLegendItems;
244
+ if (metaKey && activeLegendItems.includes(id)) {
245
+ nextActiveLegendItems = activeLegendItems.filter((item) => item !== id);
246
+ }
247
+ else if (metaKey && !activeLegendItems.includes(id)) {
248
+ nextActiveLegendItems = activeLegendItems.concat(id);
249
+ }
250
+ else if (onlyItemSelected && allItems.length === 1) {
251
+ nextActiveLegendItems = [];
252
+ }
253
+ else if (onlyItemSelected) {
254
+ nextActiveLegendItems = allItems;
255
+ }
256
+ else {
257
+ nextActiveLegendItems = [id];
258
+ }
259
+ setSelectedLegendItems(nextActiveLegendItems);
260
+ }, [preparedSeries, selectedLegendItems, activeLegendItems]);
139
261
  const handleAttemptToSetZoomState = React.useCallback((nextZoomState) => {
262
+ var _a;
140
263
  const { preparedSeries: nextZoomedSeriesData } = getZoomedSeriesData({
141
- seriesData: preparedSeries,
264
+ seriesData: (_a = chartState === null || chartState === void 0 ? void 0 : chartState.preparedSeries) !== null && _a !== void 0 ? _a : [],
142
265
  xAxis,
143
266
  yAxis,
144
267
  zoomState: nextZoomState,
@@ -147,54 +270,22 @@ export function useChartInnerProps(props) {
147
270
  if (hasData) {
148
271
  updateZoomState(nextZoomState);
149
272
  }
150
- }, [xAxis, yAxis, preparedSeries, updateZoomState]);
273
+ }, [chartState === null || chartState === void 0 ? void 0 : chartState.preparedSeries, updateZoomState, xAxis, yAxis]);
151
274
  useZoom({
152
275
  node: plotNode,
153
276
  onUpdate: handleAttemptToSetZoomState,
154
277
  plotContainerHeight: boundsHeight,
155
278
  plotContainerWidth: boundsWidth,
156
- preparedSplit,
279
+ preparedSplit: chartState === null || chartState === void 0 ? void 0 : chartState.preparedSplit,
157
280
  preparedZoom: preparedChart.zoom,
158
281
  xAxis,
159
- xScale,
282
+ xScale: chartState === null || chartState === void 0 ? void 0 : chartState.xScale,
160
283
  yAxis,
161
- yScale,
284
+ yScale: chartState === null || chartState === void 0 ? void 0 : chartState.yScale,
162
285
  });
163
- const boundsOffsetTop = getBoundsOffsetTop({
164
- chartMarginTop: preparedChart.margin.top,
165
- preparedLegend,
166
- legendConfig,
167
- });
168
- // We need to calculate the width of each left axis because the first axis can be hidden
169
- const boundsOffsetLeft = getBoundsOffsetLeft({
170
- chartMarginLeft: preparedChart.margin.left,
171
- preparedLegend,
172
- yAxis,
173
- getYAxisWidth,
174
- legendConfig,
175
- });
176
- return {
177
- allPreparedSeries,
178
- boundsHeight,
179
- boundsOffsetLeft,
180
- boundsOffsetTop,
286
+ // additional end
287
+ return Object.assign(Object.assign({}, chartState), { preparedSeries, boundsOffsetLeft: (_d = chartState === null || chartState === void 0 ? void 0 : chartState.boundsOffsetLeft) !== null && _d !== void 0 ? _d : 0, boundsOffsetTop: (_e = chartState === null || chartState === void 0 ? void 0 : chartState.boundsOffsetTop) !== null && _e !== void 0 ? _e : 0, boundsHeight,
181
288
  boundsWidth,
182
- handleLegendItemClick,
183
- isOutsideBounds,
184
- legendConfig,
185
- legendItems,
186
- preparedLegend,
187
- preparedSeries,
188
- preparedSeriesOptions,
189
- preparedSplit,
190
- prevHeight,
191
- prevWidth,
192
- shapes,
193
- shapesData,
194
- shapesReady,
195
289
  xAxis,
196
- xScale,
197
- yAxis,
198
- yScale,
199
- };
290
+ yAxis, shapesData: (_f = chartState === null || chartState === void 0 ? void 0 : chartState.shapesData) !== null && _f !== void 0 ? _f : [], shapesReady: Boolean(chartState), handleLegendItemClick });
200
291
  }
@@ -41,8 +41,9 @@ export function useChartInnerState(props) {
41
41
  else if (nextZoomState.x !== undefined) {
42
42
  setRangeSliderState({ min: nextZoomState.x[0], max: nextZoomState.x[1] });
43
43
  }
44
+ dispatcher.call(EventType.HOVER_SHAPE, {}, undefined);
44
45
  }
45
- }, [zoomState]);
46
+ }, [dispatcher, zoomState]);
46
47
  const updateRangeSliderState = React.useCallback((nextRangeSliderState) => {
47
48
  if (!isEqual(rangeSliderState, nextRangeSliderState)) {
48
49
  setRangeSliderState(nextRangeSliderState
@@ -0,0 +1,26 @@
1
+ import React from 'react';
2
+ import type { Dispatch } from 'd3';
3
+ import type { PreparedXAxis, PreparedYAxis, ShapeData } from '../../hooks';
4
+ import type { ChartScale } from '../../hooks/useAxisScales/types';
5
+ type Props = {
6
+ boundsHeight: number;
7
+ boundsOffsetLeft: number;
8
+ boundsOffsetTop: number;
9
+ boundsWidth: number;
10
+ defaultState?: {
11
+ hoveredPosition?: {
12
+ x: number | string;
13
+ y: number | string;
14
+ };
15
+ };
16
+ dispatcher: Dispatch<object>;
17
+ shapesData: ShapeData[];
18
+ shapesReady: boolean;
19
+ svgRef: React.RefObject<SVGSVGElement | null>;
20
+ xAxis: PreparedXAxis | null;
21
+ yAxis: PreparedYAxis[];
22
+ xScale?: ChartScale;
23
+ yScale?: (ChartScale | undefined)[];
24
+ };
25
+ export declare function useDefaultState(props: Props): void;
26
+ export {};
@@ -0,0 +1,74 @@
1
+ import React from 'react';
2
+ import get from 'lodash/get';
3
+ import { EventType } from '../../utils';
4
+ import { getClosestPoints } from '../../utils/chart/get-closest-data';
5
+ import { getHoveredPlots } from '../../utils/chart/get-hovered-plots';
6
+ import { calculateNumericProperty } from '../../utils/chart/math';
7
+ export function useDefaultState(props) {
8
+ const { boundsHeight, boundsOffsetLeft, boundsOffsetTop, boundsWidth, defaultState, dispatcher, shapesData, shapesReady, svgRef, xAxis, yAxis, xScale, yScale, } = props;
9
+ const appliedRef = React.useRef(false);
10
+ React.useEffect(() => {
11
+ const hoveredPosition = defaultState === null || defaultState === void 0 ? void 0 : defaultState.hoveredPosition;
12
+ if (appliedRef.current || !shapesReady || !hoveredPosition) {
13
+ return;
14
+ }
15
+ appliedRef.current = true;
16
+ // Defer dispatch so shape components (Area, Line, etc.) register their hover-shape.*
17
+ // listeners first; parent effects run before child effects in React.
18
+ queueMicrotask(() => {
19
+ var _a;
20
+ const x = calculateNumericProperty({ value: hoveredPosition.x, base: boundsWidth });
21
+ const y = calculateNumericProperty({ value: hoveredPosition.y, base: boundsHeight });
22
+ if (x === undefined || y === undefined) {
23
+ return;
24
+ }
25
+ const shapesDataWithTooltipEnabled = shapesData.filter((d) => get(d, 'series.tooltip.enabled', true));
26
+ const closest = getClosestPoints({
27
+ position: [x, y],
28
+ shapesData: shapesDataWithTooltipEnabled,
29
+ boundsHeight,
30
+ boundsWidth,
31
+ });
32
+ const { plotLines, plotBands } = getHoveredPlots({
33
+ pointerX: x,
34
+ pointerY: y,
35
+ xAxis,
36
+ yAxis,
37
+ xScale,
38
+ yScale,
39
+ });
40
+ const hoveredPlotsArg = { lines: plotLines, bands: plotBands };
41
+ const svgPointerX = x + boundsOffsetLeft;
42
+ const svgPointerY = y + boundsOffsetTop;
43
+ dispatcher.call(EventType.HOVER_SHAPE, undefined, closest, [svgPointerX, svgPointerY], hoveredPlotsArg);
44
+ const rect = (_a = svgRef.current) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect();
45
+ const syntheticEvent = rect &&
46
+ new PointerEvent('pointermove', {
47
+ bubbles: true,
48
+ clientX: rect.left + svgPointerX,
49
+ clientY: rect.top + svgPointerY,
50
+ });
51
+ dispatcher.call(EventType.POINTERMOVE_CHART, {}, {
52
+ hovered: closest,
53
+ xAxis,
54
+ yAxis: yAxis[0],
55
+ hoveredPlotLines: plotLines,
56
+ hoveredPlotBands: plotBands,
57
+ }, syntheticEvent);
58
+ });
59
+ }, [
60
+ boundsHeight,
61
+ boundsOffsetLeft,
62
+ boundsOffsetTop,
63
+ boundsWidth,
64
+ defaultState,
65
+ dispatcher,
66
+ shapesData,
67
+ shapesReady,
68
+ svgRef,
69
+ xAxis,
70
+ xScale,
71
+ yAxis,
72
+ yScale,
73
+ ]);
74
+ }
@@ -0,0 +1,44 @@
1
+ import type { PreparedYAxis } from '../../../hooks';
2
+ import type { ChartScale } from '../../../hooks/useAxisScales/types';
3
+ import type { PreparedSeries } from '../../../hooks/useSeries/types';
4
+ export declare function recalculateYAxisLabelsWidth(props: {
5
+ seriesData: PreparedSeries[];
6
+ yAxis: PreparedYAxis[];
7
+ yScale?: (ChartScale | undefined)[];
8
+ }): Promise<(Omit<import("../../..").ChartAxis, "type" | "labels" | "plotLines" | "plotBands"> & {
9
+ type: import("../../..").ChartAxisType;
10
+ labels: Omit<import("../../..").ChartAxisLabels, "style" | "enabled" | "padding" | "autoRotation"> & Required<Pick<import("../../..").ChartAxisLabels, "margin" | "enabled" | "html" | "rotation" | "padding">> & {
11
+ style: import("../../..").BaseTextStyle;
12
+ rotation: number;
13
+ height: number;
14
+ width: number;
15
+ lineHeight: number;
16
+ maxWidth: number;
17
+ };
18
+ title: {
19
+ height: number;
20
+ width: number;
21
+ text: string;
22
+ margin: number;
23
+ style: import("../../..").BaseTextStyle;
24
+ align: import("../../..").ChartAxisTitleAlignment;
25
+ maxRowCount: number;
26
+ rotation: number;
27
+ maxWidth: number;
28
+ html: boolean;
29
+ };
30
+ min?: number;
31
+ grid: {
32
+ enabled: boolean;
33
+ };
34
+ maxPadding: number;
35
+ ticks: {
36
+ pixelInterval?: number;
37
+ };
38
+ tickMarks: import("../../../hooks").PreparedAxisTickMarks;
39
+ position: "left" | "right" | "top" | "bottom";
40
+ plotIndex: number;
41
+ plotLines: import("../../../hooks").PreparedAxisPlotLine[];
42
+ plotBands: import("../../../hooks").PreparedAxisPlotBand[];
43
+ crosshair: Required<import("../../..").AxisCrosshair>;
44
+ })[]>;
@@ -0,0 +1,35 @@
1
+ import get from 'lodash/get';
2
+ import { getYAxisLabelMaxWidth } from '../../../hooks/useAxis/y-axis';
3
+ export async function recalculateYAxisLabelsWidth(props) {
4
+ const { seriesData, yAxis, yScale } = props;
5
+ const axisIndexesToRecalculateMap = new Map();
6
+ for (let i = 0; i < yAxis.length; i++) {
7
+ const axis = yAxis[i];
8
+ const scale = yScale === null || yScale === void 0 ? void 0 : yScale[i];
9
+ if (!scale) {
10
+ continue;
11
+ }
12
+ if (axis.startOnTick || axis.endOnTick) {
13
+ const axisSeriesData = seriesData.filter((s) => get(s, 'yAxis', 0) === i && s.visible);
14
+ if (axisSeriesData.length === 0) {
15
+ continue;
16
+ }
17
+ const res = await getYAxisLabelMaxWidth({
18
+ axis,
19
+ seriesData: axisSeriesData,
20
+ scale,
21
+ });
22
+ if (res.width > axis.labels.width) {
23
+ axisIndexesToRecalculateMap.set(i, res.width);
24
+ }
25
+ }
26
+ }
27
+ return yAxis.map((axis, i) => {
28
+ const width = axisIndexesToRecalculateMap.get(i);
29
+ if (width) {
30
+ const axisWithRecalculatedLabels = Object.assign(Object.assign({}, axis), { labels: Object.assign(Object.assign({}, axis.labels), { width }) });
31
+ return axisWithRecalculatedLabels;
32
+ }
33
+ return axis;
34
+ });
35
+ }
@@ -1,5 +1,5 @@
1
- import type { ChartData, ChartSeries } from '../../types';
2
- import type { PreparedChart, PreparedTitle } from './types';
1
+ import type { PreparedChart, PreparedTitle } from '../../../hooks/types';
2
+ import type { ChartData, ChartSeries } from '../../../types';
3
3
  export declare const getPreparedChart: (args: {
4
4
  chart: ChartData["chart"];
5
5
  seriesData: ChartSeries[];
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
- import type { PreparedAxis, PreparedSeries, PreparedZoom } from '../../hooks';
2
+ import type { PreparedAxis, PreparedSeries } from '../../../hooks';
3
+ import type { PreparedZoom } from '../../../hooks/types';
3
4
  export declare function hasAtLeastOneSeriesDataPerPlot(seriesData: PreparedSeries[], yAxes?: PreparedAxis[]): boolean;
4
5
  export declare function useAsyncState<T>(value: T, setState: () => Promise<T>, isReady?: boolean): T;
5
6
  export declare function getResetZoomButtonStyle(args: {
@@ -0,0 +1,7 @@
1
+ export * from './axis';
2
+ export * from './common';
3
+ export * from './tooltip';
4
+ export * from './chart';
5
+ export * from './zoom';
6
+ export * from './title';
7
+ export * from './normalized-original-data';
@@ -0,0 +1,7 @@
1
+ export * from './axis';
2
+ export * from './common';
3
+ export * from './tooltip';
4
+ export * from './chart';
5
+ export * from './zoom';
6
+ export * from './title';
7
+ export * from './normalized-original-data';