@gravity-ui/charts 1.36.0 → 1.37.2
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/ChartInner/index.js +1 -1
- package/dist/cjs/components/ChartInner/useChartInnerProps.d.ts +24 -24
- package/dist/cjs/components/ChartInner/useChartInnerProps.js +57 -17
- package/dist/cjs/components/Legend/index.d.ts +2 -1
- package/dist/cjs/components/Legend/index.js +17 -16
- package/dist/cjs/components/Tooltip/ChartTooltipContent.js +8 -1
- package/dist/cjs/components/Tooltip/styles.css +1 -1
- package/dist/cjs/hooks/useAxis/index.d.ts +2 -1
- package/dist/cjs/hooks/useAxis/index.js +9 -2
- package/dist/cjs/hooks/useChartDimensions/index.d.ts +2 -1
- package/dist/cjs/hooks/useChartDimensions/index.js +27 -13
- package/dist/cjs/hooks/useRangeSlider/index.js +2 -1
- package/dist/cjs/hooks/useRangeSlider/types.d.ts +2 -1
- package/dist/cjs/hooks/useSeries/prepare-legend.d.ts +4 -2
- package/dist/cjs/hooks/useSeries/prepare-legend.js +76 -55
- package/dist/cjs/hooks/useSeries/types.d.ts +1 -13
- package/dist/cjs/types/chart/tooltip.d.ts +2 -0
- package/dist/cjs/types/chart-ui.d.ts +15 -0
- package/dist/cjs/utils/chart/index.js +4 -2
- package/dist/esm/components/ChartInner/index.js +1 -1
- package/dist/esm/components/ChartInner/useChartInnerProps.d.ts +17 -17
- package/dist/esm/components/ChartInner/useChartInnerProps.js +57 -17
- package/dist/esm/components/Legend/index.d.ts +2 -1
- package/dist/esm/components/Legend/index.js +17 -16
- package/dist/esm/components/Tooltip/ChartTooltipContent.js +8 -1
- package/dist/esm/components/Tooltip/styles.css +1 -1
- package/dist/esm/hooks/useAxis/index.d.ts +2 -1
- package/dist/esm/hooks/useAxis/index.js +9 -2
- package/dist/esm/hooks/useChartDimensions/index.d.ts +2 -1
- package/dist/esm/hooks/useChartDimensions/index.js +27 -13
- package/dist/esm/hooks/useRangeSlider/index.js +2 -1
- package/dist/esm/hooks/useRangeSlider/types.d.ts +2 -1
- package/dist/esm/hooks/useSeries/prepare-legend.d.ts +4 -2
- package/dist/esm/hooks/useSeries/prepare-legend.js +76 -55
- package/dist/esm/hooks/useSeries/types.d.ts +1 -13
- package/dist/esm/types/chart/tooltip.d.ts +2 -0
- package/dist/esm/types/chart-ui.d.ts +15 -0
- package/dist/esm/utils/chart/index.js +4 -2
- package/package.json +1 -1
|
@@ -248,7 +248,7 @@ export const ChartInner = (props) => {
|
|
|
248
248
|
React.createElement("g", { ref: plotBeforeRef }),
|
|
249
249
|
shapes,
|
|
250
250
|
React.createElement("g", { ref: plotAfterRef })),
|
|
251
|
-
((_e = xAxis === null || xAxis === void 0 ? void 0 : xAxis.rangeSlider) === null || _e === void 0 ? void 0 : _e.enabled) && (React.createElement(RangeSlider, { boundsOffsetLeft: debouncedOffsetLeft, boundsWidth: debouncedBoundsWidth, height: height, htmlLayout: htmlLayout, onUpdate: updateRangeSliderState, preparedChart: preparedChart, preparedLegend: preparedLegend, preparedSeries: debouncedAllPreparedSeries, preparedSeriesOptions: preparedSeriesOptions, preparedRangeSlider: xAxis.rangeSlider, rangeSliderState: rangeSliderState, ref: rangeSliderRef, width: width, xAxis: data.xAxis, yAxis: data.yAxis })),
|
|
251
|
+
((_e = xAxis === null || xAxis === void 0 ? void 0 : xAxis.rangeSlider) === null || _e === void 0 ? void 0 : _e.enabled) && (React.createElement(RangeSlider, { boundsOffsetLeft: debouncedOffsetLeft, boundsWidth: debouncedBoundsWidth, height: height, htmlLayout: htmlLayout, onUpdate: updateRangeSliderState, preparedChart: preparedChart, preparedLegend: preparedLegend, preparedSeries: debouncedAllPreparedSeries, preparedSeriesOptions: preparedSeriesOptions, preparedRangeSlider: xAxis.rangeSlider, rangeSliderState: rangeSliderState, ref: rangeSliderRef, width: width, xAxis: data.xAxis, yAxis: data.yAxis, legendConfig: legendConfig })),
|
|
252
252
|
(preparedLegend === null || preparedLegend === void 0 ? void 0 : preparedLegend.enabled) && legendConfig && (React.createElement(Legend, { chartSeries: preparedSeries, legend: preparedLegend, items: legendItems, config: legendConfig, onItemClick: handleLegendItemClick, onUpdate: unpinTooltip, htmlLayout: htmlLayout }))));
|
|
253
253
|
return (React.createElement("div", { className: b() },
|
|
254
254
|
React.createElement("svg", { ref: svgRef, width: width, height: height,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { Dispatch } from 'd3';
|
|
3
|
-
import type { PreparedChart, PreparedLegend, RangeSliderState, ZoomState } from '../../hooks';
|
|
3
|
+
import type { LegendItem, PreparedChart, PreparedLegend, PreparedSeries, RangeSliderState, ZoomState } from '../../hooks';
|
|
4
|
+
import type { LegendConfig } from '../../types';
|
|
4
5
|
import type { ChartInnerProps } from './types';
|
|
5
6
|
type Props = ChartInnerProps & {
|
|
6
7
|
clipPathId: string;
|
|
@@ -13,30 +14,29 @@ type Props = ChartInnerProps & {
|
|
|
13
14
|
zoomState: Partial<ZoomState>;
|
|
14
15
|
rangeSliderState?: RangeSliderState;
|
|
15
16
|
};
|
|
17
|
+
type LegendState = {
|
|
18
|
+
legendConfig?: LegendConfig;
|
|
19
|
+
legendItems: LegendItem[][];
|
|
20
|
+
};
|
|
21
|
+
export declare function useLegend({ preparedLegend, preparedChart, preparedSeries, width, height, }: {
|
|
22
|
+
preparedLegend: PreparedLegend | null;
|
|
23
|
+
preparedChart: PreparedChart;
|
|
24
|
+
preparedSeries: PreparedSeries[];
|
|
25
|
+
width: number;
|
|
26
|
+
height: number;
|
|
27
|
+
}): LegendState;
|
|
16
28
|
export declare function useChartInnerProps(props: Props): {
|
|
17
|
-
allPreparedSeries:
|
|
29
|
+
allPreparedSeries: PreparedSeries[];
|
|
18
30
|
boundsHeight: number;
|
|
19
31
|
boundsOffsetLeft: number;
|
|
20
32
|
boundsOffsetTop: number;
|
|
21
33
|
boundsWidth: number;
|
|
22
34
|
handleLegendItemClick: import("../../hooks").OnLegendItemClick;
|
|
23
35
|
isOutsideBounds: (x: number, y: number) => boolean;
|
|
24
|
-
legendConfig:
|
|
25
|
-
|
|
26
|
-
left: number;
|
|
27
|
-
top: number;
|
|
28
|
-
};
|
|
29
|
-
pagination: {
|
|
30
|
-
pages: {
|
|
31
|
-
start: number;
|
|
32
|
-
end: number;
|
|
33
|
-
}[];
|
|
34
|
-
} | undefined;
|
|
35
|
-
maxWidth: number;
|
|
36
|
-
} | undefined;
|
|
37
|
-
legendItems: never[] | import("../../hooks").LegendItem[][];
|
|
36
|
+
legendConfig: LegendConfig | undefined;
|
|
37
|
+
legendItems: LegendItem[][];
|
|
38
38
|
preparedLegend: PreparedLegend | null;
|
|
39
|
-
preparedSeries:
|
|
39
|
+
preparedSeries: PreparedSeries[];
|
|
40
40
|
preparedSeriesOptions: import("../../constants").SeriesOptionsDefaults;
|
|
41
41
|
preparedSplit: import("../../hooks").PreparedSplit;
|
|
42
42
|
prevHeight: number | undefined;
|
|
@@ -47,10 +47,10 @@ export declare function useChartInnerProps(props: Props): {
|
|
|
47
47
|
svgXPos: number | undefined;
|
|
48
48
|
xAxis: import("../../hooks").PreparedXAxis | null;
|
|
49
49
|
xScale: import("../../hooks").ChartScale | undefined;
|
|
50
|
-
yAxis: (Omit<import("
|
|
51
|
-
type: import("
|
|
52
|
-
labels: Omit<import("
|
|
53
|
-
style: import("
|
|
50
|
+
yAxis: (Omit<import("../../types").ChartAxis, "type" | "labels" | "plotLines" | "plotBands"> & {
|
|
51
|
+
type: import("../../types").ChartAxisType;
|
|
52
|
+
labels: Omit<import("../../types").ChartAxisLabels, "enabled" | "style" | "padding" | "autoRotation"> & Required<Pick<import("../../types").ChartAxisLabels, "margin" | "html" | "enabled" | "rotation" | "padding">> & {
|
|
53
|
+
style: import("../../types").BaseTextStyle;
|
|
54
54
|
rotation: number;
|
|
55
55
|
height: number;
|
|
56
56
|
width: number;
|
|
@@ -62,8 +62,8 @@ export declare function useChartInnerProps(props: Props): {
|
|
|
62
62
|
width: number;
|
|
63
63
|
text: string;
|
|
64
64
|
margin: number;
|
|
65
|
-
style: import("
|
|
66
|
-
align: import("
|
|
65
|
+
style: import("../../types").BaseTextStyle;
|
|
66
|
+
align: import("../../types").ChartAxisTitleAlignment;
|
|
67
67
|
maxRowCount: number;
|
|
68
68
|
rotation: number;
|
|
69
69
|
maxWidth: number;
|
|
@@ -82,7 +82,7 @@ export declare function useChartInnerProps(props: Props): {
|
|
|
82
82
|
plotIndex: number;
|
|
83
83
|
plotLines: import("../../hooks").PreparedAxisPlotLine[];
|
|
84
84
|
plotBands: import("../../hooks").PreparedAxisPlotBand[];
|
|
85
|
-
crosshair: Required<import("
|
|
85
|
+
crosshair: Required<import("../../types").AxisCrosshair>;
|
|
86
86
|
})[];
|
|
87
87
|
yScale: (import("../../hooks").ChartScale | undefined)[] | undefined;
|
|
88
88
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import isEqual from 'lodash/isEqual';
|
|
2
3
|
import { DEFAULT_PALETTE, SERIES_TYPE } from '../../constants';
|
|
3
4
|
import { useAxis, useAxisScales, useChartDimensions, useNormalizedOriginalData, usePrevious, useSeries, useShapes, useSplit, useYAxisLabelWidth, useZoom, } from '../../hooks';
|
|
4
5
|
import { getYAxisWidth } from '../../hooks/useChartDimensions/utils';
|
|
@@ -9,17 +10,18 @@ import { hasAtLeastOneSeriesDataPerPlot } from './utils';
|
|
|
9
10
|
const CLIP_PATH_BY_SERIES_TYPE = {
|
|
10
11
|
[SERIES_TYPE.Scatter]: false,
|
|
11
12
|
};
|
|
12
|
-
function getBoundsOffsetTop(
|
|
13
|
-
|
|
13
|
+
function getBoundsOffsetTop({ chartMarginTop, preparedLegend, legendConfig, }) {
|
|
14
|
+
var _a;
|
|
14
15
|
return (chartMarginTop +
|
|
15
16
|
((preparedLegend === null || preparedLegend === void 0 ? void 0 : preparedLegend.enabled) && preparedLegend.position === 'top'
|
|
16
|
-
?
|
|
17
|
+
? ((_a = legendConfig === null || legendConfig === void 0 ? void 0 : legendConfig.height) !== null && _a !== void 0 ? _a : 0) + preparedLegend.margin
|
|
17
18
|
: 0));
|
|
18
19
|
}
|
|
19
20
|
function getBoundsOffsetLeft(args) {
|
|
20
|
-
|
|
21
|
+
var _a;
|
|
22
|
+
const { chartMarginLeft, preparedLegend, yAxis, getYAxisWidth: getAxisWidth, legendConfig, } = args;
|
|
21
23
|
const legendOffset = (preparedLegend === null || preparedLegend === void 0 ? void 0 : preparedLegend.enabled) && preparedLegend.position === 'left'
|
|
22
|
-
?
|
|
24
|
+
? ((_a = legendConfig === null || legendConfig === void 0 ? void 0 : legendConfig.width) !== null && _a !== void 0 ? _a : 0) + preparedLegend.margin
|
|
23
25
|
: 0;
|
|
24
26
|
const leftAxisWidth = yAxis.reduce((acc, axis) => {
|
|
25
27
|
if (axis.position !== 'left') {
|
|
@@ -33,6 +35,45 @@ function getBoundsOffsetLeft(args) {
|
|
|
33
35
|
}, 0);
|
|
34
36
|
return chartMarginLeft + legendOffset + leftAxisWidth;
|
|
35
37
|
}
|
|
38
|
+
export function useLegend({ preparedLegend, preparedChart, preparedSeries, width, height, }) {
|
|
39
|
+
const [legendState, setLegend] = React.useState({
|
|
40
|
+
legendConfig: undefined,
|
|
41
|
+
legendItems: [],
|
|
42
|
+
});
|
|
43
|
+
const legendStateRunRef = React.useRef(0);
|
|
44
|
+
const prevLegendStateValue = React.useRef(legendState);
|
|
45
|
+
const legendStateReady = React.useRef(false);
|
|
46
|
+
React.useEffect(() => {
|
|
47
|
+
legendStateRunRef.current++;
|
|
48
|
+
legendStateReady.current = false;
|
|
49
|
+
(async function () {
|
|
50
|
+
const currentRun = legendStateRunRef.current;
|
|
51
|
+
if (!preparedLegend) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
const newStateValue = await getLegendComponents({
|
|
55
|
+
chartWidth: width,
|
|
56
|
+
chartHeight: height,
|
|
57
|
+
chartMargin: preparedChart.margin,
|
|
58
|
+
series: preparedSeries,
|
|
59
|
+
preparedLegend,
|
|
60
|
+
});
|
|
61
|
+
if (legendStateRunRef.current === currentRun) {
|
|
62
|
+
if (!isEqual(prevLegendStateValue.current, newStateValue)) {
|
|
63
|
+
setLegend(newStateValue);
|
|
64
|
+
prevLegendStateValue.current = newStateValue;
|
|
65
|
+
}
|
|
66
|
+
legendStateReady.current = true;
|
|
67
|
+
}
|
|
68
|
+
})();
|
|
69
|
+
}, [height, preparedChart.margin, preparedLegend, preparedSeries, width]);
|
|
70
|
+
return legendStateReady.current
|
|
71
|
+
? legendState
|
|
72
|
+
: {
|
|
73
|
+
legendConfig: undefined,
|
|
74
|
+
legendItems: [],
|
|
75
|
+
};
|
|
76
|
+
}
|
|
36
77
|
export function useChartInnerProps(props) {
|
|
37
78
|
var _a;
|
|
38
79
|
const { clipPathId, data, dispatcher, height, htmlLayout, plotNode, preparedChart, rangeSliderState, svgContainer, width, updateZoomState, zoomState, } = props;
|
|
@@ -76,21 +117,17 @@ export function useChartInnerProps(props) {
|
|
|
76
117
|
zoomState: effectiveZoomState,
|
|
77
118
|
});
|
|
78
119
|
}, [allPreparedSeries, normalizedXAxis, normalizedYAxis, effectiveZoomState]);
|
|
79
|
-
const { legendConfig, legendItems } =
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
chartMargin: preparedChart.margin,
|
|
87
|
-
series: preparedSeries,
|
|
88
|
-
preparedLegend,
|
|
89
|
-
});
|
|
90
|
-
}, [width, height, preparedChart.margin, preparedSeries, preparedLegend]);
|
|
120
|
+
const { legendConfig, legendItems } = useLegend({
|
|
121
|
+
width,
|
|
122
|
+
height,
|
|
123
|
+
preparedChart,
|
|
124
|
+
preparedSeries,
|
|
125
|
+
preparedLegend,
|
|
126
|
+
});
|
|
91
127
|
const { xAxis, yAxis, setAxes } = useAxis({
|
|
92
128
|
height,
|
|
93
129
|
preparedChart,
|
|
130
|
+
legendConfig,
|
|
94
131
|
preparedLegend,
|
|
95
132
|
preparedSeries,
|
|
96
133
|
preparedSeriesOptions,
|
|
@@ -106,6 +143,7 @@ export function useChartInnerProps(props) {
|
|
|
106
143
|
preparedYAxis: yAxis,
|
|
107
144
|
preparedXAxis: xAxis,
|
|
108
145
|
width,
|
|
146
|
+
legendConfig,
|
|
109
147
|
});
|
|
110
148
|
const preparedSplit = useSplit({ split: data.split, boundsHeight, chartWidth: width });
|
|
111
149
|
const { xScale, yScale } = useAxisScales({
|
|
@@ -166,6 +204,7 @@ export function useChartInnerProps(props) {
|
|
|
166
204
|
const boundsOffsetTop = getBoundsOffsetTop({
|
|
167
205
|
chartMarginTop: preparedChart.margin.top,
|
|
168
206
|
preparedLegend,
|
|
207
|
+
legendConfig,
|
|
169
208
|
});
|
|
170
209
|
// We need to calculate the width of each left axis because the first axis can be hidden
|
|
171
210
|
const boundsOffsetLeft = getBoundsOffsetLeft({
|
|
@@ -173,6 +212,7 @@ export function useChartInnerProps(props) {
|
|
|
173
212
|
preparedLegend,
|
|
174
213
|
yAxis,
|
|
175
214
|
getYAxisWidth,
|
|
215
|
+
legendConfig,
|
|
176
216
|
});
|
|
177
217
|
const { x } = (_a = svgContainer === null || svgContainer === void 0 ? void 0 : svgContainer.getBoundingClientRect()) !== null && _a !== void 0 ? _a : {};
|
|
178
218
|
return {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import type {
|
|
2
|
+
import type { LegendItem, OnLegendItemClick, PreparedLegend, PreparedSeries } from '../../hooks';
|
|
3
|
+
import type { LegendConfig } from '../../types';
|
|
3
4
|
import './styles.css';
|
|
4
5
|
type Props = {
|
|
5
6
|
chartSeries: PreparedSeries[];
|
|
@@ -2,7 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import { scaleLinear, select, symbol } from 'd3';
|
|
3
3
|
import { CONTINUOUS_LEGEND_SIZE } from '../../constants';
|
|
4
4
|
import { formatNumber } from '../../libs';
|
|
5
|
-
import { block, createGradientRect, getContinuesColorFn, getLabelsSize, getSymbol, getUniqId,
|
|
5
|
+
import { block, createGradientRect, getContinuesColorFn, getLabelsSize, getSymbol, getUniqId, } from '../../utils';
|
|
6
6
|
import { axisBottom } from '../../utils/chart/axis-generators';
|
|
7
7
|
import { appendLinePathElement } from '../utils';
|
|
8
8
|
import './styles.css';
|
|
@@ -163,7 +163,6 @@ export const Legend = (props) => {
|
|
|
163
163
|
: items;
|
|
164
164
|
const legendLineHeights = [];
|
|
165
165
|
pageItems.forEach((line) => {
|
|
166
|
-
var _a;
|
|
167
166
|
const legendLine = svgElement.append('g').attr('class', b('line'));
|
|
168
167
|
const htmlLegendLine = htmlContainer === null || htmlContainer === void 0 ? void 0 : htmlContainer.append('div').style('position', 'absolute');
|
|
169
168
|
const legendItemTemplate = legendLine
|
|
@@ -214,9 +213,8 @@ export const Legend = (props) => {
|
|
|
214
213
|
.on('click', function (e, d) {
|
|
215
214
|
onItemClick({ id: d.id, name: d.name, metaKey: e.metaKey });
|
|
216
215
|
onUpdate === null || onUpdate === void 0 ? void 0 : onUpdate();
|
|
217
|
-
})
|
|
218
|
-
|
|
219
|
-
});
|
|
216
|
+
})
|
|
217
|
+
.html((d) => d.text);
|
|
220
218
|
}
|
|
221
219
|
else {
|
|
222
220
|
legendItemTemplate
|
|
@@ -231,19 +229,22 @@ export const Legend = (props) => {
|
|
|
231
229
|
const mods = { selected: d.visible, unselected: !d.visible };
|
|
232
230
|
return b('item-text', mods);
|
|
233
231
|
})
|
|
234
|
-
.html(
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
232
|
+
.html((d) => d.text)
|
|
233
|
+
.style('font-size', legend.itemStyle.fontSize);
|
|
234
|
+
}
|
|
235
|
+
let contentWidth = 0;
|
|
236
|
+
if (legend.html) {
|
|
237
|
+
contentWidth = getXPosition(line.length) - legend.itemDistance;
|
|
238
|
+
}
|
|
239
|
+
else {
|
|
240
|
+
contentWidth = line.reduce((sum, l, index) => {
|
|
241
|
+
sum += l.textWidth + l.symbol.width + l.symbol.padding;
|
|
242
|
+
if (index > 0) {
|
|
243
|
+
sum += legend.itemDistance;
|
|
241
244
|
}
|
|
242
|
-
|
|
245
|
+
return sum;
|
|
246
|
+
}, 0);
|
|
243
247
|
}
|
|
244
|
-
const contentWidth = (legend.html
|
|
245
|
-
? getXPosition(line.length) - legend.itemDistance
|
|
246
|
-
: (_a = legendLine.node()) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect().width) || 0;
|
|
247
248
|
let left = 0;
|
|
248
249
|
switch (legend.justifyContent) {
|
|
249
250
|
case 'center': {
|
|
@@ -6,7 +6,14 @@ export const ChartTooltipContent = React.memo((props) => {
|
|
|
6
6
|
if (!hovered) {
|
|
7
7
|
return null;
|
|
8
8
|
}
|
|
9
|
-
const customTooltip = renderer === null || renderer === void 0 ? void 0 : renderer({
|
|
9
|
+
const customTooltip = renderer === null || renderer === void 0 ? void 0 : renderer({
|
|
10
|
+
headerFormat,
|
|
11
|
+
hovered,
|
|
12
|
+
hoveredPlotLines,
|
|
13
|
+
hoveredPlotBands,
|
|
14
|
+
xAxis,
|
|
15
|
+
yAxis,
|
|
16
|
+
});
|
|
10
17
|
return isNil(customTooltip) ? (React.createElement(DefaultTooltipContent, { hovered: hovered, pinned: pinned, rowRenderer: rowRenderer, totals: totals, valueFormat: valueFormat, headerFormat: headerFormat, xAxis: xAxis, yAxis: yAxis, qa: qa })) : (customTooltip);
|
|
11
18
|
});
|
|
12
19
|
ChartTooltipContent.displayName = 'ChartTooltipContent';
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
.gcharts-tooltip {
|
|
2
2
|
padding: var(--gcharts-tooltip-content-padding, 8px 0);
|
|
3
|
+
background-color: var(--g-color-infographics-tooltip-bg);
|
|
3
4
|
box-shadow: 0 2px 12px var(--g-color-sfx-shadow);
|
|
4
5
|
}
|
|
5
6
|
.gcharts-tooltip__popup-content {
|
|
6
7
|
max-width: 450px;
|
|
7
8
|
text-wrap: nowrap;
|
|
8
9
|
border-radius: 4px;
|
|
9
|
-
background-color: var(--g-color-infographics-tooltip-bg);
|
|
10
10
|
}
|
|
11
11
|
.gcharts-tooltip__content {
|
|
12
12
|
display: flex;
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import type { ChartXAxis, ChartYAxis } from '../../types';
|
|
2
|
+
import type { ChartXAxis, ChartYAxis, LegendConfig } from '../../types';
|
|
3
3
|
import type { PreparedChart } from '../useChartOptions/types';
|
|
4
4
|
import type { PreparedLegend, PreparedSeries, PreparedSeriesOptions } from '../useSeries/types';
|
|
5
5
|
import type { AxesState } from './types';
|
|
6
6
|
interface UseAxesProps {
|
|
7
7
|
height: number;
|
|
8
8
|
preparedChart: PreparedChart;
|
|
9
|
+
legendConfig: LegendConfig | undefined;
|
|
9
10
|
preparedLegend: PreparedLegend | null;
|
|
10
11
|
preparedSeries: PreparedSeries[];
|
|
11
12
|
preparedSeriesOptions: PreparedSeriesOptions;
|
|
@@ -4,15 +4,20 @@ import { getWidthOccupiedByYAxis } from '../useChartDimensions/utils';
|
|
|
4
4
|
import { getPreparedXAxis } from './x-axis';
|
|
5
5
|
import { getPreparedYAxis } from './y-axis';
|
|
6
6
|
export function useAxis(props) {
|
|
7
|
-
const { boundsHeight, height, preparedChart, preparedLegend, preparedSeries, preparedSeriesOptions, width, xAxis, yAxis, } = props;
|
|
7
|
+
const { boundsHeight, height, preparedChart, legendConfig, preparedLegend, preparedSeries, preparedSeriesOptions, width, xAxis, yAxis, } = props;
|
|
8
8
|
const [axesState, setAxes] = React.useState({ xAxis: null, yAxis: [] });
|
|
9
9
|
const axesStateRunRef = React.useRef(0);
|
|
10
10
|
const prevAxesStateValue = React.useRef(axesState);
|
|
11
11
|
const axesStateReady = React.useRef(false);
|
|
12
12
|
React.useEffect(() => {
|
|
13
|
+
const shouldWaitForLegendReady = !preparedLegend || ((preparedLegend === null || preparedLegend === void 0 ? void 0 : preparedLegend.enabled) && !legendConfig);
|
|
14
|
+
if (shouldWaitForLegendReady) {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
13
17
|
axesStateRunRef.current++;
|
|
14
18
|
axesStateReady.current = false;
|
|
15
19
|
(async function () {
|
|
20
|
+
var _a, _b;
|
|
16
21
|
const currentRun = axesStateRunRef.current;
|
|
17
22
|
const seriesData = preparedSeries.filter((s) => s.visible);
|
|
18
23
|
const estimatedPreparedYAxis = await getPreparedYAxis({
|
|
@@ -41,7 +46,8 @@ export function useAxis(props) {
|
|
|
41
46
|
(preparedXAxis.rangeSlider.enabled
|
|
42
47
|
? preparedXAxis.rangeSlider.height + preparedXAxis.rangeSlider.margin
|
|
43
48
|
: 0) +
|
|
44
|
-
(
|
|
49
|
+
((_a = legendConfig === null || legendConfig === void 0 ? void 0 : legendConfig.height) !== null && _a !== void 0 ? _a : 0) +
|
|
50
|
+
((_b = preparedLegend === null || preparedLegend === void 0 ? void 0 : preparedLegend.margin) !== null && _b !== void 0 ? _b : 0) +
|
|
45
51
|
preparedChart.margin.top +
|
|
46
52
|
preparedChart.margin.bottom);
|
|
47
53
|
}
|
|
@@ -65,6 +71,7 @@ export function useAxis(props) {
|
|
|
65
71
|
boundsHeight,
|
|
66
72
|
height,
|
|
67
73
|
preparedChart.margin,
|
|
74
|
+
legendConfig,
|
|
68
75
|
preparedLegend,
|
|
69
76
|
preparedSeries,
|
|
70
77
|
preparedSeriesOptions,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { PreparedLegend, PreparedSeries, PreparedXAxis, PreparedYAxis } from '../../hooks';
|
|
2
|
-
import type { ChartMargin } from '../../types';
|
|
2
|
+
import type { ChartMargin, LegendConfig } from '../../types';
|
|
3
3
|
export { getBoundsWidth } from './utils';
|
|
4
4
|
type Args = {
|
|
5
5
|
height: number;
|
|
@@ -9,6 +9,7 @@ type Args = {
|
|
|
9
9
|
preparedXAxis: PreparedXAxis | null;
|
|
10
10
|
preparedYAxis: PreparedYAxis[] | null;
|
|
11
11
|
width: number;
|
|
12
|
+
legendConfig: LegendConfig | undefined;
|
|
12
13
|
};
|
|
13
14
|
export declare const useChartDimensions: (args: Args) => {
|
|
14
15
|
boundsWidth: number;
|
|
@@ -3,10 +3,11 @@ import { isAxisRelatedSeries } from '../../utils';
|
|
|
3
3
|
import { getBoundsWidth } from './utils';
|
|
4
4
|
export { getBoundsWidth } from './utils';
|
|
5
5
|
const getBottomOffset = (args) => {
|
|
6
|
-
|
|
6
|
+
var _a;
|
|
7
|
+
const { hasAxisRelatedSeries, preparedLegend, legendConfig, preparedXAxis } = args;
|
|
7
8
|
let result = 0;
|
|
8
9
|
if ((preparedLegend === null || preparedLegend === void 0 ? void 0 : preparedLegend.enabled) && preparedLegend.position === 'bottom') {
|
|
9
|
-
result +=
|
|
10
|
+
result += ((_a = legendConfig === null || legendConfig === void 0 ? void 0 : legendConfig.height) !== null && _a !== void 0 ? _a : 0) + preparedLegend.margin;
|
|
10
11
|
}
|
|
11
12
|
if (!(preparedXAxis === null || preparedXAxis === void 0 ? void 0 : preparedXAxis.visible)) {
|
|
12
13
|
return result;
|
|
@@ -24,26 +25,29 @@ const getBottomOffset = (args) => {
|
|
|
24
25
|
}
|
|
25
26
|
return result;
|
|
26
27
|
};
|
|
27
|
-
const getTopOffset = ({ preparedLegend }) => {
|
|
28
|
+
const getTopOffset = ({ preparedLegend, legendConfig, }) => {
|
|
29
|
+
var _a;
|
|
28
30
|
if ((preparedLegend === null || preparedLegend === void 0 ? void 0 : preparedLegend.enabled) && preparedLegend.position === 'top') {
|
|
29
|
-
return
|
|
31
|
+
return ((_a = legendConfig === null || legendConfig === void 0 ? void 0 : legendConfig.height) !== null && _a !== void 0 ? _a : 0) + preparedLegend.margin;
|
|
30
32
|
}
|
|
31
33
|
return 0;
|
|
32
34
|
};
|
|
33
|
-
const getRightOffset = ({ preparedLegend }) => {
|
|
35
|
+
const getRightOffset = ({ preparedLegend, legendConfig, }) => {
|
|
36
|
+
var _a;
|
|
34
37
|
if ((preparedLegend === null || preparedLegend === void 0 ? void 0 : preparedLegend.enabled) && preparedLegend.position === 'right') {
|
|
35
|
-
return
|
|
38
|
+
return ((_a = legendConfig === null || legendConfig === void 0 ? void 0 : legendConfig.width) !== null && _a !== void 0 ? _a : 0) + preparedLegend.margin;
|
|
36
39
|
}
|
|
37
40
|
return 0;
|
|
38
41
|
};
|
|
39
|
-
const getLeftOffset = ({ preparedLegend }) => {
|
|
42
|
+
const getLeftOffset = ({ preparedLegend, legendConfig, }) => {
|
|
43
|
+
var _a;
|
|
40
44
|
if ((preparedLegend === null || preparedLegend === void 0 ? void 0 : preparedLegend.enabled) && preparedLegend.position === 'left') {
|
|
41
|
-
return
|
|
45
|
+
return ((_a = legendConfig === null || legendConfig === void 0 ? void 0 : legendConfig.width) !== null && _a !== void 0 ? _a : 0) + preparedLegend.margin;
|
|
42
46
|
}
|
|
43
47
|
return 0;
|
|
44
48
|
};
|
|
45
49
|
export const useChartDimensions = (args) => {
|
|
46
|
-
const { height, margin, preparedLegend, preparedSeries, preparedXAxis, preparedYAxis, width } = args;
|
|
50
|
+
const { height, margin, preparedLegend, preparedSeries, preparedXAxis, preparedYAxis, width, legendConfig, } = args;
|
|
47
51
|
return React.useMemo(() => {
|
|
48
52
|
const hasAxisRelatedSeries = preparedSeries.some(isAxisRelatedSeries);
|
|
49
53
|
const boundsWidth = getBoundsWidth({ chartWidth: width, chartMargin: margin, preparedYAxis });
|
|
@@ -51,12 +55,22 @@ export const useChartDimensions = (args) => {
|
|
|
51
55
|
hasAxisRelatedSeries,
|
|
52
56
|
preparedLegend,
|
|
53
57
|
preparedXAxis,
|
|
58
|
+
legendConfig,
|
|
54
59
|
});
|
|
55
|
-
const topOffset = getTopOffset({ preparedLegend });
|
|
56
|
-
const rightOffset = getRightOffset({ preparedLegend });
|
|
57
|
-
const leftOffset = getLeftOffset({ preparedLegend });
|
|
60
|
+
const topOffset = getTopOffset({ preparedLegend, legendConfig });
|
|
61
|
+
const rightOffset = getRightOffset({ preparedLegend, legendConfig });
|
|
62
|
+
const leftOffset = getLeftOffset({ preparedLegend, legendConfig });
|
|
58
63
|
const boundsHeight = height - margin.top - margin.bottom - bottomOffset - topOffset;
|
|
59
64
|
const adjustedBoundsWidth = boundsWidth - rightOffset - leftOffset;
|
|
60
65
|
return { boundsWidth: adjustedBoundsWidth, boundsHeight };
|
|
61
|
-
}, [
|
|
66
|
+
}, [
|
|
67
|
+
height,
|
|
68
|
+
margin,
|
|
69
|
+
preparedLegend,
|
|
70
|
+
legendConfig,
|
|
71
|
+
preparedSeries,
|
|
72
|
+
preparedXAxis,
|
|
73
|
+
preparedYAxis,
|
|
74
|
+
width,
|
|
75
|
+
]);
|
|
62
76
|
};
|
|
@@ -17,7 +17,7 @@ const CLIP_PATH_BY_SERIES_TYPE = {
|
|
|
17
17
|
[SERIES_TYPE.Scatter]: true,
|
|
18
18
|
};
|
|
19
19
|
export function useRangeSlider(props) {
|
|
20
|
-
const { boundsWidth, boundsOffsetLeft, clipPathId, height, htmlLayout, onUpdate, preparedChart, preparedLegend, preparedSeries, preparedSeriesOptions, preparedRangeSlider, rangeSliderState, width, xAxis, yAxis, } = props;
|
|
20
|
+
const { boundsWidth, boundsOffsetLeft, clipPathId, height, htmlLayout, onUpdate, preparedChart, preparedLegend, legendConfig, preparedSeries, preparedSeriesOptions, preparedRangeSlider, rangeSliderState, width, xAxis, yAxis, } = props;
|
|
21
21
|
const filteredPreparedSeries = React.useMemo(() => {
|
|
22
22
|
return preparedSeries.filter((s) => {
|
|
23
23
|
if ('rangeSlider' in s && !s.rangeSlider.visible) {
|
|
@@ -31,6 +31,7 @@ export function useRangeSlider(props) {
|
|
|
31
31
|
height,
|
|
32
32
|
preparedChart,
|
|
33
33
|
preparedLegend,
|
|
34
|
+
legendConfig,
|
|
34
35
|
preparedSeries,
|
|
35
36
|
preparedSeriesOptions,
|
|
36
37
|
width,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ChartXAxis, ChartYAxis } from '../../types';
|
|
1
|
+
import type { ChartXAxis, ChartYAxis, LegendConfig } from '../../types';
|
|
2
2
|
import type { PreparedRangeSlider, PreparedXAxis, PreparedYAxis } from '../useAxis/types';
|
|
3
3
|
import type { ChartScale } from '../useAxisScales/types';
|
|
4
4
|
import type { BrushSelection, UseBrushProps } from '../useBrush/types';
|
|
@@ -16,6 +16,7 @@ export interface RangeSliderProps {
|
|
|
16
16
|
onUpdate: (nextRangeSliderState?: RangeSliderState) => void;
|
|
17
17
|
preparedChart: PreparedChart;
|
|
18
18
|
preparedLegend: PreparedLegend | null;
|
|
19
|
+
legendConfig: LegendConfig | undefined;
|
|
19
20
|
preparedRangeSlider: PreparedRangeSlider;
|
|
20
21
|
preparedSeries: PreparedSeries[];
|
|
21
22
|
preparedSeriesOptions: PreparedSeriesOptions;
|
|
@@ -11,7 +11,7 @@ export declare function getLegendComponents(args: {
|
|
|
11
11
|
chartMargin: PreparedChart['margin'];
|
|
12
12
|
series: PreparedSeries[];
|
|
13
13
|
preparedLegend: PreparedLegend;
|
|
14
|
-
}): {
|
|
14
|
+
}): Promise<{
|
|
15
15
|
legendConfig: {
|
|
16
16
|
offset: {
|
|
17
17
|
left: number;
|
|
@@ -24,6 +24,8 @@ export declare function getLegendComponents(args: {
|
|
|
24
24
|
}[];
|
|
25
25
|
} | undefined;
|
|
26
26
|
maxWidth: number;
|
|
27
|
+
height: number;
|
|
28
|
+
width: number;
|
|
27
29
|
};
|
|
28
30
|
legendItems: LegendItem[][];
|
|
29
|
-
}
|
|
31
|
+
}>;
|