@gravity-ui/charts 1.38.2 → 1.38.4
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.
- package/dist/cjs/components/Tooltip/DefaultTooltipContent/index.js +10 -23
- package/dist/cjs/hooks/useAxis/index.js +11 -3
- package/dist/cjs/hooks/useChartDimensions/index.js +3 -0
- package/dist/cjs/hooks/useShapes/index.js +3 -0
- package/dist/cjs/hooks/useYAxisLabelWidth/index.js +2 -2
- package/dist/cjs/utils/misc.d.ts +0 -1
- package/dist/cjs/utils/misc.js +0 -6
- package/dist/esm/components/Tooltip/DefaultTooltipContent/index.js +10 -23
- package/dist/esm/hooks/useAxis/index.js +11 -3
- package/dist/esm/hooks/useChartDimensions/index.js +3 -0
- package/dist/esm/hooks/useShapes/index.js +3 -0
- package/dist/esm/hooks/useYAxisLabelWidth/index.js +2 -2
- package/dist/esm/utils/misc.d.ts +0 -1
- package/dist/esm/utils/misc.js +0 -6
- package/package.json +1 -1
|
@@ -4,7 +4,7 @@ import get from 'lodash/get';
|
|
|
4
4
|
import isEqual from 'lodash/isEqual';
|
|
5
5
|
import { usePrevious } from '../../../hooks';
|
|
6
6
|
import { i18n } from '../../../i18n';
|
|
7
|
-
import { block
|
|
7
|
+
import { block } from '../../../utils';
|
|
8
8
|
import { getFormattedValue } from '../../../utils/chart/format';
|
|
9
9
|
import { Row } from './Row';
|
|
10
10
|
import { RowWithAggregation } from './RowWithAggregation';
|
|
@@ -52,30 +52,17 @@ export const DefaultTooltipContent = ({ hovered, pinned, rowRenderer, totals, va
|
|
|
52
52
|
if (!contentRowsRef.current) {
|
|
53
53
|
return;
|
|
54
54
|
}
|
|
55
|
-
if (
|
|
55
|
+
if (isEqual(hoveredValues, prevHoveredValues)) {
|
|
56
56
|
return;
|
|
57
57
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
const rows = contentRowsRef.current.querySelectorAll(`.${b('content-row')}`);
|
|
62
|
-
let nextVisibleRows = 0;
|
|
63
|
-
let nextMaxContentRowsHeight = 0;
|
|
64
|
-
for (let i = 0; i < rows.length; i++) {
|
|
65
|
-
const row = rows[i];
|
|
66
|
-
const { top, height } = row.getBoundingClientRect();
|
|
67
|
-
if (top - containerTop + height <= clientHeight) {
|
|
68
|
-
nextVisibleRows += 1;
|
|
69
|
-
nextMaxContentRowsHeight += height;
|
|
70
|
-
}
|
|
71
|
-
else {
|
|
72
|
-
break;
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
setVisibleRows(nextVisibleRows - 1);
|
|
76
|
-
setMaxContentRowsHeight(nextMaxContentRowsHeight);
|
|
58
|
+
const { scrollHeight, clientHeight } = contentRowsRef.current;
|
|
59
|
+
if (scrollHeight <= clientHeight) {
|
|
60
|
+
return;
|
|
77
61
|
}
|
|
78
|
-
|
|
62
|
+
const nextVisibleRows = Math.floor(hovered.length * (clientHeight / scrollHeight));
|
|
63
|
+
setVisibleRows(Math.max(nextVisibleRows - 1, 1));
|
|
64
|
+
setMaxContentRowsHeight((scrollHeight / hovered.length) * nextVisibleRows);
|
|
65
|
+
}, [hovered.length, hoveredValues, prevHoveredValues]);
|
|
79
66
|
React.useEffect(() => {
|
|
80
67
|
if (!contentRowsRef.current) {
|
|
81
68
|
return;
|
|
@@ -91,7 +78,7 @@ export const DefaultTooltipContent = ({ hovered, pinned, rowRenderer, totals, va
|
|
|
91
78
|
return (React.createElement("div", { className: b('content'), "data-qa": qa },
|
|
92
79
|
formattedHeadValue && (React.createElement("div", { className: b('series-name') },
|
|
93
80
|
React.createElement("div", { className: b('series-name-text'), dangerouslySetInnerHTML: { __html: formattedHeadValue } }))),
|
|
94
|
-
React.createElement("div", { className: b('content-rows', { pinned }), ref: contentRowsRef, style: { maxHeight: maxContentRowsHeight } },
|
|
81
|
+
React.createElement("div", { className: b('content-rows', { pinned }), ref: contentRowsRef, style: pinned ? { maxHeight: maxContentRowsHeight } : undefined },
|
|
95
82
|
visibleHovered.map((seriesItem, i) => {
|
|
96
83
|
var _a;
|
|
97
84
|
const { data, series, closest } = seriesItem;
|
|
@@ -10,12 +10,12 @@ export function useAxis(props) {
|
|
|
10
10
|
const prevAxesStateValue = React.useRef(axesState);
|
|
11
11
|
const axesStateReady = React.useRef(false);
|
|
12
12
|
React.useEffect(() => {
|
|
13
|
+
axesStateRunRef.current++;
|
|
14
|
+
axesStateReady.current = false;
|
|
13
15
|
const shouldWaitForLegendReady = !preparedLegend || ((preparedLegend === null || preparedLegend === void 0 ? void 0 : preparedLegend.enabled) && !legendConfig);
|
|
14
16
|
if (shouldWaitForLegendReady) {
|
|
15
17
|
return;
|
|
16
18
|
}
|
|
17
|
-
axesStateRunRef.current++;
|
|
18
|
-
axesStateReady.current = false;
|
|
19
19
|
(async function () {
|
|
20
20
|
var _a, _b;
|
|
21
21
|
const currentRun = axesStateRunRef.current;
|
|
@@ -79,5 +79,13 @@ export function useAxis(props) {
|
|
|
79
79
|
xAxis,
|
|
80
80
|
yAxis,
|
|
81
81
|
]);
|
|
82
|
-
|
|
82
|
+
const isAxesReady = axesStateReady.current;
|
|
83
|
+
const result = React.useMemo(() => {
|
|
84
|
+
if (isAxesReady) {
|
|
85
|
+
return Object.assign(Object.assign({}, axesState), { setAxes });
|
|
86
|
+
}
|
|
87
|
+
prevAxesStateValue.current = { xAxis: null, yAxis: [] };
|
|
88
|
+
return Object.assign(Object.assign({}, prevAxesStateValue.current), { setAxes });
|
|
89
|
+
}, [isAxesReady, axesState]);
|
|
90
|
+
return result;
|
|
83
91
|
}
|
|
@@ -49,6 +49,9 @@ const getLeftOffset = ({ preparedLegend, legendConfig, }) => {
|
|
|
49
49
|
export const useChartDimensions = (args) => {
|
|
50
50
|
const { height, margin, preparedLegend, preparedSeries, preparedXAxis, preparedYAxis, width, legendConfig, } = args;
|
|
51
51
|
return React.useMemo(() => {
|
|
52
|
+
if (!preparedLegend || !legendConfig) {
|
|
53
|
+
return { boundsWidth: 0, boundsHeight: 0 };
|
|
54
|
+
}
|
|
52
55
|
const hasAxisRelatedSeries = preparedSeries.some(isAxisRelatedSeries);
|
|
53
56
|
const boundsWidth = getBoundsWidth({ chartWidth: width, chartMargin: margin, preparedYAxis });
|
|
54
57
|
const bottomOffset = getBottomOffset({
|
|
@@ -38,6 +38,9 @@ export const useShapes = (args) => {
|
|
|
38
38
|
const countedRef = React.useRef(0);
|
|
39
39
|
React.useEffect(() => {
|
|
40
40
|
countedRef.current++;
|
|
41
|
+
if (!boundsHeight || !boundsWidth) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
41
44
|
(async () => {
|
|
42
45
|
const currentRun = countedRef.current;
|
|
43
46
|
const visibleSeries = getOnlyVisibleSeries(series);
|
|
@@ -32,7 +32,7 @@ export function useYAxisLabelWidth(props) {
|
|
|
32
32
|
}
|
|
33
33
|
if (runRef.current === currentRun && axisIndexesToRecalculateMap.size > 0) {
|
|
34
34
|
setAxes((prevState) => {
|
|
35
|
-
|
|
35
|
+
const newYAxis = prevState.yAxis.map((axis, i) => {
|
|
36
36
|
const width = axisIndexesToRecalculateMap.get(i);
|
|
37
37
|
if (width) {
|
|
38
38
|
const axisWithRecalculatedLabels = Object.assign(Object.assign({}, axis), { labels: Object.assign(Object.assign({}, axis.labels), { width }) });
|
|
@@ -40,7 +40,7 @@ export function useYAxisLabelWidth(props) {
|
|
|
40
40
|
}
|
|
41
41
|
return axis;
|
|
42
42
|
});
|
|
43
|
-
return prevState;
|
|
43
|
+
return Object.assign(Object.assign({}, prevState), { yAxis: newYAxis });
|
|
44
44
|
});
|
|
45
45
|
}
|
|
46
46
|
})();
|
package/dist/cjs/utils/misc.d.ts
CHANGED
package/dist/cjs/utils/misc.js
CHANGED
|
@@ -4,7 +4,7 @@ import get from 'lodash/get';
|
|
|
4
4
|
import isEqual from 'lodash/isEqual';
|
|
5
5
|
import { usePrevious } from '../../../hooks';
|
|
6
6
|
import { i18n } from '../../../i18n';
|
|
7
|
-
import { block
|
|
7
|
+
import { block } from '../../../utils';
|
|
8
8
|
import { getFormattedValue } from '../../../utils/chart/format';
|
|
9
9
|
import { Row } from './Row';
|
|
10
10
|
import { RowWithAggregation } from './RowWithAggregation';
|
|
@@ -52,30 +52,17 @@ export const DefaultTooltipContent = ({ hovered, pinned, rowRenderer, totals, va
|
|
|
52
52
|
if (!contentRowsRef.current) {
|
|
53
53
|
return;
|
|
54
54
|
}
|
|
55
|
-
if (
|
|
55
|
+
if (isEqual(hoveredValues, prevHoveredValues)) {
|
|
56
56
|
return;
|
|
57
57
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
const rows = contentRowsRef.current.querySelectorAll(`.${b('content-row')}`);
|
|
62
|
-
let nextVisibleRows = 0;
|
|
63
|
-
let nextMaxContentRowsHeight = 0;
|
|
64
|
-
for (let i = 0; i < rows.length; i++) {
|
|
65
|
-
const row = rows[i];
|
|
66
|
-
const { top, height } = row.getBoundingClientRect();
|
|
67
|
-
if (top - containerTop + height <= clientHeight) {
|
|
68
|
-
nextVisibleRows += 1;
|
|
69
|
-
nextMaxContentRowsHeight += height;
|
|
70
|
-
}
|
|
71
|
-
else {
|
|
72
|
-
break;
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
setVisibleRows(nextVisibleRows - 1);
|
|
76
|
-
setMaxContentRowsHeight(nextMaxContentRowsHeight);
|
|
58
|
+
const { scrollHeight, clientHeight } = contentRowsRef.current;
|
|
59
|
+
if (scrollHeight <= clientHeight) {
|
|
60
|
+
return;
|
|
77
61
|
}
|
|
78
|
-
|
|
62
|
+
const nextVisibleRows = Math.floor(hovered.length * (clientHeight / scrollHeight));
|
|
63
|
+
setVisibleRows(Math.max(nextVisibleRows - 1, 1));
|
|
64
|
+
setMaxContentRowsHeight((scrollHeight / hovered.length) * nextVisibleRows);
|
|
65
|
+
}, [hovered.length, hoveredValues, prevHoveredValues]);
|
|
79
66
|
React.useEffect(() => {
|
|
80
67
|
if (!contentRowsRef.current) {
|
|
81
68
|
return;
|
|
@@ -91,7 +78,7 @@ export const DefaultTooltipContent = ({ hovered, pinned, rowRenderer, totals, va
|
|
|
91
78
|
return (React.createElement("div", { className: b('content'), "data-qa": qa },
|
|
92
79
|
formattedHeadValue && (React.createElement("div", { className: b('series-name') },
|
|
93
80
|
React.createElement("div", { className: b('series-name-text'), dangerouslySetInnerHTML: { __html: formattedHeadValue } }))),
|
|
94
|
-
React.createElement("div", { className: b('content-rows', { pinned }), ref: contentRowsRef, style: { maxHeight: maxContentRowsHeight } },
|
|
81
|
+
React.createElement("div", { className: b('content-rows', { pinned }), ref: contentRowsRef, style: pinned ? { maxHeight: maxContentRowsHeight } : undefined },
|
|
95
82
|
visibleHovered.map((seriesItem, i) => {
|
|
96
83
|
var _a;
|
|
97
84
|
const { data, series, closest } = seriesItem;
|
|
@@ -10,12 +10,12 @@ export function useAxis(props) {
|
|
|
10
10
|
const prevAxesStateValue = React.useRef(axesState);
|
|
11
11
|
const axesStateReady = React.useRef(false);
|
|
12
12
|
React.useEffect(() => {
|
|
13
|
+
axesStateRunRef.current++;
|
|
14
|
+
axesStateReady.current = false;
|
|
13
15
|
const shouldWaitForLegendReady = !preparedLegend || ((preparedLegend === null || preparedLegend === void 0 ? void 0 : preparedLegend.enabled) && !legendConfig);
|
|
14
16
|
if (shouldWaitForLegendReady) {
|
|
15
17
|
return;
|
|
16
18
|
}
|
|
17
|
-
axesStateRunRef.current++;
|
|
18
|
-
axesStateReady.current = false;
|
|
19
19
|
(async function () {
|
|
20
20
|
var _a, _b;
|
|
21
21
|
const currentRun = axesStateRunRef.current;
|
|
@@ -79,5 +79,13 @@ export function useAxis(props) {
|
|
|
79
79
|
xAxis,
|
|
80
80
|
yAxis,
|
|
81
81
|
]);
|
|
82
|
-
|
|
82
|
+
const isAxesReady = axesStateReady.current;
|
|
83
|
+
const result = React.useMemo(() => {
|
|
84
|
+
if (isAxesReady) {
|
|
85
|
+
return Object.assign(Object.assign({}, axesState), { setAxes });
|
|
86
|
+
}
|
|
87
|
+
prevAxesStateValue.current = { xAxis: null, yAxis: [] };
|
|
88
|
+
return Object.assign(Object.assign({}, prevAxesStateValue.current), { setAxes });
|
|
89
|
+
}, [isAxesReady, axesState]);
|
|
90
|
+
return result;
|
|
83
91
|
}
|
|
@@ -49,6 +49,9 @@ const getLeftOffset = ({ preparedLegend, legendConfig, }) => {
|
|
|
49
49
|
export const useChartDimensions = (args) => {
|
|
50
50
|
const { height, margin, preparedLegend, preparedSeries, preparedXAxis, preparedYAxis, width, legendConfig, } = args;
|
|
51
51
|
return React.useMemo(() => {
|
|
52
|
+
if (!preparedLegend || !legendConfig) {
|
|
53
|
+
return { boundsWidth: 0, boundsHeight: 0 };
|
|
54
|
+
}
|
|
52
55
|
const hasAxisRelatedSeries = preparedSeries.some(isAxisRelatedSeries);
|
|
53
56
|
const boundsWidth = getBoundsWidth({ chartWidth: width, chartMargin: margin, preparedYAxis });
|
|
54
57
|
const bottomOffset = getBottomOffset({
|
|
@@ -38,6 +38,9 @@ export const useShapes = (args) => {
|
|
|
38
38
|
const countedRef = React.useRef(0);
|
|
39
39
|
React.useEffect(() => {
|
|
40
40
|
countedRef.current++;
|
|
41
|
+
if (!boundsHeight || !boundsWidth) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
41
44
|
(async () => {
|
|
42
45
|
const currentRun = countedRef.current;
|
|
43
46
|
const visibleSeries = getOnlyVisibleSeries(series);
|
|
@@ -32,7 +32,7 @@ export function useYAxisLabelWidth(props) {
|
|
|
32
32
|
}
|
|
33
33
|
if (runRef.current === currentRun && axisIndexesToRecalculateMap.size > 0) {
|
|
34
34
|
setAxes((prevState) => {
|
|
35
|
-
|
|
35
|
+
const newYAxis = prevState.yAxis.map((axis, i) => {
|
|
36
36
|
const width = axisIndexesToRecalculateMap.get(i);
|
|
37
37
|
if (width) {
|
|
38
38
|
const axisWithRecalculatedLabels = Object.assign(Object.assign({}, axis), { labels: Object.assign(Object.assign({}, axis.labels), { width }) });
|
|
@@ -40,7 +40,7 @@ export function useYAxisLabelWidth(props) {
|
|
|
40
40
|
}
|
|
41
41
|
return axis;
|
|
42
42
|
});
|
|
43
|
-
return prevState;
|
|
43
|
+
return Object.assign(Object.assign({}, prevState), { yAxis: newYAxis });
|
|
44
44
|
});
|
|
45
45
|
}
|
|
46
46
|
})();
|
package/dist/esm/utils/misc.d.ts
CHANGED
package/dist/esm/utils/misc.js
CHANGED