@gravity-ui/charts 1.42.3 → 1.42.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/AxisX/AxisX.js +4 -4
- package/dist/cjs/components/AxisX/prepare-axis-data.js +17 -13
- package/dist/cjs/components/AxisY/AxisY.js +4 -4
- package/dist/cjs/components/AxisY/prepare-axis-data.js +27 -21
- package/dist/cjs/components/AxisY/prepare-axis-title.js +8 -3
- package/dist/cjs/components/AxisY/styles.css +1 -1
- package/dist/cjs/components/ChartInner/index.js +5 -15
- package/dist/cjs/components/ChartInner/useChartInnerProps.d.ts +4 -1
- package/dist/cjs/components/ChartInner/useChartInnerProps.js +22 -11
- package/dist/cjs/components/ChartInner/utils/title.d.ts +1 -1
- package/dist/cjs/components/ChartInner/utils/title.js +3 -3
- package/dist/cjs/components/Legend/index.js +8 -11
- package/dist/cjs/components/Legend/styles.css +1 -1
- package/dist/cjs/components/utils/axis-title.js +1 -1
- package/dist/cjs/core/axes/x-axis.js +2 -2
- package/dist/cjs/core/axes/y-axis.js +2 -2
- package/dist/cjs/core/layout/split.d.ts +2 -2
- package/dist/cjs/core/layout/split.js +22 -19
- package/dist/cjs/core/series/prepare-legend.js +7 -7
- package/dist/cjs/core/series/types.d.ts +2 -0
- package/dist/cjs/core/utils/axis-generators/bottom.js +6 -16
- package/dist/cjs/core/utils/common.d.ts +0 -4
- package/dist/cjs/core/utils/common.js +0 -13
- package/dist/cjs/core/utils/labels.d.ts +1 -0
- package/dist/cjs/core/utils/labels.js +5 -5
- package/dist/cjs/core/utils/text.d.ts +1 -0
- package/dist/cjs/core/utils/text.js +4 -0
- package/dist/cjs/hooks/useShapes/area/prepare-data.js +1 -1
- package/dist/cjs/hooks/useShapes/bar-y/prepare-data.js +3 -2
- package/dist/cjs/hooks/useShapes/funnel/prepare-data.js +4 -1
- package/dist/cjs/hooks/useShapes/heatmap/prepare-data.js +1 -1
- package/dist/cjs/hooks/useShapes/line/prepare-data.js +4 -1
- package/dist/cjs/hooks/useShapes/pie/prepare-data.js +9 -2
- package/dist/cjs/hooks/useShapes/radar/prepare-data.js +17 -7
- package/dist/cjs/hooks/useShapes/sankey/prepare-data.js +1 -1
- package/dist/cjs/hooks/useShapes/sankey/sankey-layout.d.ts +49 -0
- package/dist/cjs/hooks/useShapes/sankey/sankey-layout.js +362 -0
- package/dist/cjs/hooks/useShapes/styles.css +4 -4
- package/dist/cjs/hooks/useShapes/treemap/prepare-data.js +3 -1
- package/dist/cjs/types/chart-ui.d.ts +1 -0
- package/dist/esm/components/AxisX/AxisX.js +4 -4
- package/dist/esm/components/AxisX/prepare-axis-data.js +17 -13
- package/dist/esm/components/AxisY/AxisY.js +4 -4
- package/dist/esm/components/AxisY/prepare-axis-data.js +27 -21
- package/dist/esm/components/AxisY/prepare-axis-title.js +8 -3
- package/dist/esm/components/AxisY/styles.css +1 -1
- package/dist/esm/components/ChartInner/index.js +5 -15
- package/dist/esm/components/ChartInner/useChartInnerProps.d.ts +4 -1
- package/dist/esm/components/ChartInner/useChartInnerProps.js +22 -11
- package/dist/esm/components/ChartInner/utils/title.d.ts +1 -1
- package/dist/esm/components/ChartInner/utils/title.js +3 -3
- package/dist/esm/components/Legend/index.js +8 -11
- package/dist/esm/components/Legend/styles.css +1 -1
- package/dist/esm/components/utils/axis-title.js +1 -1
- package/dist/esm/core/axes/x-axis.js +2 -2
- package/dist/esm/core/axes/y-axis.js +2 -2
- package/dist/esm/core/layout/split.d.ts +2 -2
- package/dist/esm/core/layout/split.js +22 -19
- package/dist/esm/core/series/prepare-legend.js +7 -7
- package/dist/esm/core/series/types.d.ts +2 -0
- package/dist/esm/core/utils/axis-generators/bottom.js +6 -16
- package/dist/esm/core/utils/common.d.ts +0 -4
- package/dist/esm/core/utils/common.js +0 -13
- package/dist/esm/core/utils/labels.d.ts +1 -0
- package/dist/esm/core/utils/labels.js +5 -5
- package/dist/esm/core/utils/text.d.ts +1 -0
- package/dist/esm/core/utils/text.js +4 -0
- package/dist/esm/hooks/useShapes/area/prepare-data.js +1 -1
- package/dist/esm/hooks/useShapes/bar-y/prepare-data.js +3 -2
- package/dist/esm/hooks/useShapes/funnel/prepare-data.js +4 -1
- package/dist/esm/hooks/useShapes/heatmap/prepare-data.js +1 -1
- package/dist/esm/hooks/useShapes/line/prepare-data.js +4 -1
- package/dist/esm/hooks/useShapes/pie/prepare-data.js +9 -2
- package/dist/esm/hooks/useShapes/radar/prepare-data.js +17 -7
- package/dist/esm/hooks/useShapes/sankey/prepare-data.js +1 -1
- package/dist/esm/hooks/useShapes/sankey/sankey-layout.d.ts +49 -0
- package/dist/esm/hooks/useShapes/sankey/sankey-layout.js +362 -0
- package/dist/esm/hooks/useShapes/styles.css +4 -4
- package/dist/esm/hooks/useShapes/treemap/prepare-data.js +3 -1
- package/dist/esm/types/chart-ui.d.ts +1 -0
- package/package.json +1 -3
|
@@ -3,7 +3,7 @@ import { calculateCos, calculateSin, formatAxisTickLabel, getBandsPosition, getL
|
|
|
3
3
|
import { prepareHtmlYAxisTitle, prepareSvgYAxisTitle } from './prepare-axis-title';
|
|
4
4
|
import { getTickValues } from './utils';
|
|
5
5
|
async function getSvgAxisLabel({ getTextSize, text, axis, top, left, labelMaxHeight, topOffset, }) {
|
|
6
|
-
var _a;
|
|
6
|
+
var _a, _b;
|
|
7
7
|
const originalTextSize = await getTextSize(text);
|
|
8
8
|
// Currently, a preliminary label calculation is used to build the chart - we cannot exceed it here.
|
|
9
9
|
// Therefore, we rely on a pre-calculated number instead of the current maximum label width.
|
|
@@ -59,7 +59,9 @@ async function getSvgAxisLabel({ getTextSize, text, axis, top, left, labelMaxHei
|
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
61
|
content.forEach((row) => {
|
|
62
|
+
var _a;
|
|
62
63
|
row.y -= newLabelHeight / 2;
|
|
64
|
+
row.y += (_a = originalTextSize.hangingOffset) !== null && _a !== void 0 ? _a : 0;
|
|
63
65
|
});
|
|
64
66
|
size.width = newLabelWidth;
|
|
65
67
|
size.height = newLabelHeight;
|
|
@@ -87,7 +89,8 @@ async function getSvgAxisLabel({ getTextSize, text, axis, top, left, labelMaxHei
|
|
|
87
89
|
? textSize.height / calculateSin(axis.labels.rotation)
|
|
88
90
|
: textSize.height;
|
|
89
91
|
const x = axis.position === 'left' ? -textSize.width : 0;
|
|
90
|
-
const y = Math.max(-topOffset - top, -actualTextHeight / 2)
|
|
92
|
+
const y = Math.max(-topOffset - top, -actualTextHeight / 2) +
|
|
93
|
+
((_a = originalTextSize.hangingOffset) !== null && _a !== void 0 ? _a : 0);
|
|
91
94
|
content.push({
|
|
92
95
|
text: rowText,
|
|
93
96
|
x,
|
|
@@ -98,7 +101,7 @@ async function getSvgAxisLabel({ getTextSize, text, axis, top, left, labelMaxHei
|
|
|
98
101
|
const x = axis.position === 'left' ? left - axis.labels.margin : left + axis.labels.margin;
|
|
99
102
|
const y = top;
|
|
100
103
|
const svgLabel = {
|
|
101
|
-
title: content.length > 1 || ((
|
|
104
|
+
title: content.length > 1 || ((_b = content[0]) === null || _b === void 0 ? void 0 : _b.text) !== text ? text : undefined,
|
|
102
105
|
content: content,
|
|
103
106
|
style: axis.labels.style,
|
|
104
107
|
size: size,
|
|
@@ -109,7 +112,7 @@ async function getSvgAxisLabel({ getTextSize, text, axis, top, left, labelMaxHei
|
|
|
109
112
|
return svgLabel;
|
|
110
113
|
}
|
|
111
114
|
export async function prepareYAxisData({ axis, split, scale, top: topOffset, width, height, series, }) {
|
|
112
|
-
var _a, _b, _c;
|
|
115
|
+
var _a, _b, _c, _d, _e;
|
|
113
116
|
const axisPlotTopPosition = ((_a = split === null || split === void 0 ? void 0 : split.plots[axis.plotIndex]) === null || _a === void 0 ? void 0 : _a.top) || 0;
|
|
114
117
|
const axisHeight = ((_b = split === null || split === void 0 ? void 0 : split.plots[axis.plotIndex]) === null || _b === void 0 ? void 0 : _b.height) || height;
|
|
115
118
|
const domainX = axis.position === 'left' ? 0 : width;
|
|
@@ -212,23 +215,22 @@ export async function prepareYAxisData({ axis, split, scale, top: topOffset, wid
|
|
|
212
215
|
axisLabelsWidth: labelsWidth,
|
|
213
216
|
});
|
|
214
217
|
const plotBands = [];
|
|
215
|
-
axis.plotBands
|
|
216
|
-
var _a, _b;
|
|
218
|
+
for (const plotBand of axis.plotBands) {
|
|
217
219
|
const axisScale = scale;
|
|
218
220
|
const { from, to } = getBandsPosition({
|
|
219
221
|
band: plotBand,
|
|
220
222
|
axisScale,
|
|
221
223
|
axis: 'y',
|
|
222
224
|
});
|
|
223
|
-
const halfBandwidth = ((
|
|
225
|
+
const halfBandwidth = ((_e = (_d = axisScale.bandwidth) === null || _d === void 0 ? void 0 : _d.call(axisScale)) !== null && _e !== void 0 ? _e : 0) / 2;
|
|
224
226
|
const startPos = halfBandwidth + Math.min(from, to);
|
|
225
227
|
const endPos = Math.min(Math.abs(to - from), axisHeight - Math.min(from, to));
|
|
226
228
|
const top = Math.max(0, startPos);
|
|
227
229
|
const plotBandHeight = Math.min(endPos, axisHeight);
|
|
228
230
|
if (plotBandHeight < 0) {
|
|
229
|
-
|
|
231
|
+
continue;
|
|
230
232
|
}
|
|
231
|
-
|
|
233
|
+
const plotBandItem = {
|
|
232
234
|
layerPlacement: plotBand.layerPlacement,
|
|
233
235
|
x: 0,
|
|
234
236
|
y: axisPlotTopPosition + top,
|
|
@@ -236,17 +238,21 @@ export async function prepareYAxisData({ axis, split, scale, top: topOffset, wid
|
|
|
236
238
|
height: plotBandHeight,
|
|
237
239
|
color: plotBand.color,
|
|
238
240
|
opacity: plotBand.opacity,
|
|
239
|
-
label:
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
:
|
|
248
|
-
|
|
249
|
-
|
|
241
|
+
label: null,
|
|
242
|
+
};
|
|
243
|
+
if (plotBand.label.text) {
|
|
244
|
+
const getPlotLabelSize = getTextSizeFn({ style: plotBand.label.style });
|
|
245
|
+
const labelSize = await getPlotLabelSize(plotBand.label.text);
|
|
246
|
+
plotBandItem.label = {
|
|
247
|
+
text: plotBand.label.text,
|
|
248
|
+
style: plotBand.label.style,
|
|
249
|
+
x: plotBand.label.padding,
|
|
250
|
+
y: plotBand.label.padding + labelSize.hangingOffset,
|
|
251
|
+
qa: plotBand.label.qa,
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
plotBands.push(plotBandItem);
|
|
255
|
+
}
|
|
250
256
|
const plotLines = [];
|
|
251
257
|
for (let i = 0; i < axis.plotLines.length; i++) {
|
|
252
258
|
const plotLine = axis.plotLines[i];
|
|
@@ -267,7 +273,7 @@ export async function prepareYAxisData({ axis, split, scale, top: topOffset, wid
|
|
|
267
273
|
text: plotLine.label.text,
|
|
268
274
|
style: plotLine.label.style,
|
|
269
275
|
x: plotLine.label.padding,
|
|
270
|
-
y: Math.max(0, plotLineValue - size.height - plotLine.label.padding),
|
|
276
|
+
y: Math.max(0, plotLineValue - size.height - plotLine.label.padding + size.hangingOffset),
|
|
271
277
|
qa: plotLine.label.qa,
|
|
272
278
|
};
|
|
273
279
|
}
|
|
@@ -11,7 +11,11 @@ export async function prepareSvgYAxisTitle({ axis, axisTop, axisHeight, axisWidt
|
|
|
11
11
|
const titleContent = [];
|
|
12
12
|
const titleMaxWidth = rotateAngle === 0 ? axis.title.maxWidth : sin * axisHeight;
|
|
13
13
|
if (axis.title.maxRowCount > 1) {
|
|
14
|
-
|
|
14
|
+
const rows = await getMultilineTitleContentRows({ axis, titleMaxWidth });
|
|
15
|
+
rows.forEach((r) => {
|
|
16
|
+
r.y -= r.size.height;
|
|
17
|
+
});
|
|
18
|
+
titleContent.push(...rows);
|
|
15
19
|
}
|
|
16
20
|
else {
|
|
17
21
|
const text = await getTextWithElipsis({
|
|
@@ -19,11 +23,12 @@ export async function prepareSvgYAxisTitle({ axis, axisTop, axisHeight, axisWidt
|
|
|
19
23
|
maxWidth: titleMaxWidth,
|
|
20
24
|
getTextWidth: async (s) => (await getTitleTextSize(s)).width,
|
|
21
25
|
});
|
|
26
|
+
const titleSize = await getTitleTextSize(text);
|
|
22
27
|
titleContent.push({
|
|
23
28
|
text,
|
|
24
29
|
x: 0,
|
|
25
|
-
y:
|
|
26
|
-
size:
|
|
30
|
+
y: titleSize.hangingOffset - titleSize.height,
|
|
31
|
+
size: titleSize,
|
|
27
32
|
});
|
|
28
33
|
}
|
|
29
34
|
const originalTextSize = titleContent.reduce((acc, item) => {
|
|
@@ -20,7 +20,7 @@ import { useChartInnerHandlers } from './useChartInnerHandlers';
|
|
|
20
20
|
import { useChartInnerProps } from './useChartInnerProps';
|
|
21
21
|
import { useChartInnerState } from './useChartInnerState';
|
|
22
22
|
import { useDefaultState } from './useDefaultState';
|
|
23
|
-
import {
|
|
23
|
+
import { getPreparedTooltip, getResetZoomButtonStyle, useAsyncState, useDebouncedValue, } from './utils';
|
|
24
24
|
import './styles.css';
|
|
25
25
|
const b = block('chart');
|
|
26
26
|
const DEBOUNCED_VALUE_DELAY = 10;
|
|
@@ -36,16 +36,6 @@ export const ChartInner = (props) => {
|
|
|
36
36
|
const rangeSliderRef = React.useRef(null);
|
|
37
37
|
const dispatcher = React.useMemo(() => getDispatcher(), []);
|
|
38
38
|
const clipPathId = useUniqId();
|
|
39
|
-
const preparedTitle = React.useMemo(() => {
|
|
40
|
-
return getPreparedTitle({ title: data.title });
|
|
41
|
-
}, [data.title]);
|
|
42
|
-
const preparedChart = React.useMemo(() => {
|
|
43
|
-
return getPreparedChart({
|
|
44
|
-
chart: data.chart,
|
|
45
|
-
seriesData: data.series.data,
|
|
46
|
-
preparedTitle,
|
|
47
|
-
});
|
|
48
|
-
}, [data.chart, data.series.data, preparedTitle]);
|
|
49
39
|
const preparedTooltip = React.useMemo(() => {
|
|
50
40
|
return getPreparedTooltip({
|
|
51
41
|
tooltip: data.tooltip,
|
|
@@ -62,10 +52,9 @@ export const ChartInner = (props) => {
|
|
|
62
52
|
preparedRangeSlider,
|
|
63
53
|
tooltip: preparedTooltip,
|
|
64
54
|
});
|
|
65
|
-
const { activeLegendItems, allPreparedSeries, boundsHeight, boundsOffsetLeft, boundsOffsetTop, boundsWidth, handleLegendItemClick, legendConfig, legendItems, preparedLegend, preparedSeries, preparedSeriesOptions, preparedSplit, shapes, shapesData, shapesReady, xAxis, xScale, yAxis, yScale, } = useChartInnerProps(Object.assign(Object.assign({}, props), { clipPathId,
|
|
55
|
+
const { activeLegendItems, allPreparedSeries, boundsHeight, boundsOffsetLeft, boundsOffsetTop, boundsWidth, handleLegendItemClick, legendConfig, legendItems, preparedLegend, preparedSeries, preparedSeriesOptions, preparedSplit, shapes, shapesData, shapesReady, xAxis, xScale, yAxis, yScale, preparedTitle, preparedChart, } = useChartInnerProps(Object.assign(Object.assign({}, props), { clipPathId,
|
|
66
56
|
dispatcher,
|
|
67
|
-
htmlLayout, plotNode: plotRef.current,
|
|
68
|
-
rangeSliderState,
|
|
57
|
+
htmlLayout, plotNode: plotRef.current, rangeSliderState,
|
|
69
58
|
updateZoomState,
|
|
70
59
|
zoomState }));
|
|
71
60
|
const prevWidth = usePrevious(width);
|
|
@@ -269,6 +258,7 @@ export const ChartInner = (props) => {
|
|
|
269
258
|
shapes,
|
|
270
259
|
React.createElement("g", { ref: plotAfterRef })),
|
|
271
260
|
((_e = xAxis === null || xAxis === void 0 ? void 0 : xAxis.rangeSlider) === null || _e === void 0 ? void 0 : _e.enabled) &&
|
|
261
|
+
preparedChart &&
|
|
272
262
|
preparedLegend &&
|
|
273
263
|
debouncedAllPreparedSeries &&
|
|
274
264
|
preparedSeriesOptions && (React.createElement(RangeSlider, { activeLegendItems: activeLegendItems !== null && activeLegendItems !== void 0 ? activeLegendItems : [], 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 })),
|
|
@@ -281,7 +271,7 @@ export const ChartInner = (props) => {
|
|
|
281
271
|
React.createElement("div", { className: b('html-layer'), ref: setHtmlLayout, style: {
|
|
282
272
|
'--g-html-layout-transform': `translate(${boundsOffsetLeft}px, ${boundsOffsetTop}px)`,
|
|
283
273
|
} }),
|
|
284
|
-
Object.keys(zoomState).length > 0 && preparedChart.zoom && (React.createElement(Button, { className: b('reset-zoom-button'), onClick: () => {
|
|
274
|
+
Object.keys(zoomState).length > 0 && (preparedChart === null || preparedChart === void 0 ? void 0 : preparedChart.zoom) && (React.createElement(Button, { className: b('reset-zoom-button'), onClick: () => {
|
|
285
275
|
var _a;
|
|
286
276
|
updateZoomState({});
|
|
287
277
|
(_a = rangeSliderRef.current) === null || _a === void 0 ? void 0 : _a.resetState();
|
|
@@ -9,7 +9,6 @@ type Props = ChartInnerProps & {
|
|
|
9
9
|
dispatcher: Dispatch<object>;
|
|
10
10
|
htmlLayout: HTMLElement | null;
|
|
11
11
|
plotNode: SVGGElement | null;
|
|
12
|
-
preparedChart: PreparedChart;
|
|
13
12
|
updateZoomState: (nextZoomState: Partial<ZoomState>) => void;
|
|
14
13
|
zoomState: Partial<ZoomState>;
|
|
15
14
|
rangeSliderState?: RangeSliderState;
|
|
@@ -25,6 +24,10 @@ export declare function useChartInnerProps(props: Props): {
|
|
|
25
24
|
shapesData: ShapeData[];
|
|
26
25
|
shapesReady: boolean;
|
|
27
26
|
handleLegendItemClick: OnLegendItemClick;
|
|
27
|
+
preparedTitle: (import("../..").ChartTitle & {
|
|
28
|
+
height: number;
|
|
29
|
+
}) | undefined;
|
|
30
|
+
preparedChart: PreparedChart | undefined;
|
|
28
31
|
allPreparedSeries?: PreparedSeries[] | undefined;
|
|
29
32
|
legendConfig?: LegendConfig | undefined;
|
|
30
33
|
legendItems?: LegendItem[][] | undefined;
|
|
@@ -6,7 +6,7 @@ import { getPreparedOptions } from '../../core/series/prepare-options';
|
|
|
6
6
|
import { getChartDimensions, getEffectiveXRange, getSortedSeriesData, getYAxisWidth, getZoomedSeriesData, isAxisRelatedSeries, } from '../../core/utils';
|
|
7
7
|
import { createScales, getAxes, getPreparedSeries, getShapes, getSplit, getVisibleSeries, useZoom, } from '../../hooks';
|
|
8
8
|
import { getActiveLegendItems, getAllLegendItems } from '../../hooks/useSeries/utils';
|
|
9
|
-
import { getNormalizedXAxis, getNormalizedYAxis, recalculateYAxisLabelsWidth } from './utils';
|
|
9
|
+
import { getNormalizedXAxis, getNormalizedYAxis, getPreparedChart, getPreparedTitle, recalculateYAxisLabelsWidth, } from './utils';
|
|
10
10
|
import { hasAtLeastOneSeriesDataPerPlot } from './utils/common';
|
|
11
11
|
const CLIP_PATH_BY_SERIES_TYPE = {
|
|
12
12
|
[SERIES_TYPE.Scatter]: false,
|
|
@@ -37,8 +37,8 @@ function getBoundsOffsetLeft(args) {
|
|
|
37
37
|
return chartMarginLeft + legendOffset + leftAxisWidth;
|
|
38
38
|
}
|
|
39
39
|
export function useChartInnerProps(props) {
|
|
40
|
-
var _a, _b, _c, _d, _e, _f;
|
|
41
|
-
const { clipPathId, data, dispatcher, height, htmlLayout, plotNode,
|
|
40
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
41
|
+
const { clipPathId, data, dispatcher, height, htmlLayout, plotNode, rangeSliderState, width, updateZoomState, zoomState, } = props;
|
|
42
42
|
const [selectedLegendItems, setSelectedLegendItems] = React.useState(null);
|
|
43
43
|
const [chartState, setState] = React.useState(null);
|
|
44
44
|
const prevStateValue = React.useRef(chartState);
|
|
@@ -50,6 +50,12 @@ export function useChartInnerProps(props) {
|
|
|
50
50
|
(async function () {
|
|
51
51
|
var _a, _b, _c;
|
|
52
52
|
const chartDataChanged = !(previousChartData.current && isEqual(previousChartData.current, data));
|
|
53
|
+
const preparedTitle = await getPreparedTitle({ title: data.title });
|
|
54
|
+
const preparedChart = getPreparedChart({
|
|
55
|
+
chart: data.chart,
|
|
56
|
+
seriesData: data.series.data,
|
|
57
|
+
preparedTitle,
|
|
58
|
+
});
|
|
53
59
|
const colors = (_a = data.colors) !== null && _a !== void 0 ? _a : DEFAULT_PALETTE;
|
|
54
60
|
const normalizedSeriesData = getSortedSeriesData({
|
|
55
61
|
seriesData: data.series.data,
|
|
@@ -119,7 +125,7 @@ export function useChartInnerProps(props) {
|
|
|
119
125
|
let yScale;
|
|
120
126
|
let boundsWidth = 0;
|
|
121
127
|
let boundsHeight = 0;
|
|
122
|
-
const calculateAxisBasedProps = () => {
|
|
128
|
+
const calculateAxisBasedProps = async () => {
|
|
123
129
|
const chartDimensions = getChartDimensions({
|
|
124
130
|
height,
|
|
125
131
|
margin: preparedChart.margin,
|
|
@@ -132,7 +138,11 @@ export function useChartInnerProps(props) {
|
|
|
132
138
|
});
|
|
133
139
|
boundsHeight = chartDimensions.boundsHeight;
|
|
134
140
|
boundsWidth = chartDimensions.boundsWidth;
|
|
135
|
-
preparedSplit = getSplit({
|
|
141
|
+
preparedSplit = await getSplit({
|
|
142
|
+
split: data.split,
|
|
143
|
+
boundsHeight,
|
|
144
|
+
chartWidth: width,
|
|
145
|
+
});
|
|
136
146
|
if (preparedSeries.some(isAxisRelatedSeries)) {
|
|
137
147
|
({ xScale, yScale } = createScales({
|
|
138
148
|
boundsWidth,
|
|
@@ -147,7 +157,7 @@ export function useChartInnerProps(props) {
|
|
|
147
157
|
}));
|
|
148
158
|
}
|
|
149
159
|
};
|
|
150
|
-
calculateAxisBasedProps();
|
|
160
|
+
await calculateAxisBasedProps();
|
|
151
161
|
const newYAxis = await recalculateYAxisLabelsWidth({
|
|
152
162
|
seriesData: preparedSeries,
|
|
153
163
|
yAxis,
|
|
@@ -155,7 +165,7 @@ export function useChartInnerProps(props) {
|
|
|
155
165
|
});
|
|
156
166
|
if (!isEqual(yAxis, newYAxis)) {
|
|
157
167
|
yAxis = newYAxis;
|
|
158
|
-
calculateAxisBasedProps();
|
|
168
|
+
await calculateAxisBasedProps();
|
|
159
169
|
}
|
|
160
170
|
const { shapes, shapesData } = await getShapes({
|
|
161
171
|
boundsWidth,
|
|
@@ -209,6 +219,8 @@ export function useChartInnerProps(props) {
|
|
|
209
219
|
yAxis,
|
|
210
220
|
yScale,
|
|
211
221
|
activeLegendItems,
|
|
222
|
+
preparedChart,
|
|
223
|
+
preparedTitle,
|
|
212
224
|
};
|
|
213
225
|
if (currentRunRef.current === currentRun) {
|
|
214
226
|
if (!isEqual(prevStateValue.current, newStateValue)) {
|
|
@@ -225,7 +237,6 @@ export function useChartInnerProps(props) {
|
|
|
225
237
|
selectedLegendItems,
|
|
226
238
|
zoomState,
|
|
227
239
|
rangeSliderState,
|
|
228
|
-
preparedChart,
|
|
229
240
|
dispatcher,
|
|
230
241
|
htmlLayout,
|
|
231
242
|
clipPathId,
|
|
@@ -277,15 +288,15 @@ export function useChartInnerProps(props) {
|
|
|
277
288
|
plotContainerHeight: boundsHeight,
|
|
278
289
|
plotContainerWidth: boundsWidth,
|
|
279
290
|
preparedSplit: chartState === null || chartState === void 0 ? void 0 : chartState.preparedSplit,
|
|
280
|
-
preparedZoom: preparedChart.zoom,
|
|
291
|
+
preparedZoom: (_e = (_d = chartState === null || chartState === void 0 ? void 0 : chartState.preparedChart) === null || _d === void 0 ? void 0 : _d.zoom) !== null && _e !== void 0 ? _e : null,
|
|
281
292
|
xAxis,
|
|
282
293
|
xScale: chartState === null || chartState === void 0 ? void 0 : chartState.xScale,
|
|
283
294
|
yAxis,
|
|
284
295
|
yScale: chartState === null || chartState === void 0 ? void 0 : chartState.yScale,
|
|
285
296
|
});
|
|
286
297
|
// additional end
|
|
287
|
-
return Object.assign(Object.assign({}, chartState), { preparedSeries, boundsOffsetLeft: (
|
|
298
|
+
return Object.assign(Object.assign({}, chartState), { preparedSeries, boundsOffsetLeft: (_f = chartState === null || chartState === void 0 ? void 0 : chartState.boundsOffsetLeft) !== null && _f !== void 0 ? _f : 0, boundsOffsetTop: (_g = chartState === null || chartState === void 0 ? void 0 : chartState.boundsOffsetTop) !== null && _g !== void 0 ? _g : 0, boundsHeight,
|
|
288
299
|
boundsWidth,
|
|
289
300
|
xAxis,
|
|
290
|
-
yAxis, shapesData: (
|
|
301
|
+
yAxis, shapesData: (_h = chartState === null || chartState === void 0 ? void 0 : chartState.shapesData) !== null && _h !== void 0 ? _h : [], shapesReady: Boolean(chartState), handleLegendItemClick, preparedTitle: chartState === null || chartState === void 0 ? void 0 : chartState.preparedTitle, preparedChart: chartState === null || chartState === void 0 ? void 0 : chartState.preparedChart });
|
|
291
302
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import get from 'lodash/get';
|
|
2
|
-
import {
|
|
2
|
+
import { getTextSizeFn } from '../../../core/utils';
|
|
3
3
|
const DEFAULT_TITLE_FONT_SIZE = '15px';
|
|
4
4
|
const TITLE_PADDINGS = 8 * 2;
|
|
5
|
-
export const getPreparedTitle = ({ title, }) => {
|
|
5
|
+
export const getPreparedTitle = async ({ title, }) => {
|
|
6
6
|
var _a, _b, _c, _d, _e, _f;
|
|
7
7
|
const titleText = get(title, 'text');
|
|
8
8
|
const titleStyle = {
|
|
@@ -11,7 +11,7 @@ export const getPreparedTitle = ({ title, }) => {
|
|
|
11
11
|
fontColor: (_f = (_e = title === null || title === void 0 ? void 0 : title.style) === null || _e === void 0 ? void 0 : _e.fontColor) !== null && _f !== void 0 ? _f : 'var(--g-color-text-primary)',
|
|
12
12
|
};
|
|
13
13
|
const titleHeight = titleText
|
|
14
|
-
?
|
|
14
|
+
? (await getTextSizeFn({ style: titleStyle })(titleText)).height + TITLE_PADDINGS
|
|
15
15
|
: 0;
|
|
16
16
|
const preparedTitle = titleText
|
|
17
17
|
? { text: titleText, style: titleStyle, height: titleHeight, qa: title === null || title === void 0 ? void 0 : title.qa }
|
|
@@ -3,7 +3,7 @@ import { scaleLinear } from 'd3-scale';
|
|
|
3
3
|
import { select } from 'd3-selection';
|
|
4
4
|
import { symbol } from 'd3-shape';
|
|
5
5
|
import { CONTINUOUS_LEGEND_SIZE } from '../../core/constants';
|
|
6
|
-
import { createGradientRect, getContinuesColorFn,
|
|
6
|
+
import { createGradientRect, getContinuesColorFn, getSymbol, getTextSizeFn, getUniqId, } from '../../core/utils';
|
|
7
7
|
import { axisBottom } from '../../core/utils/axis-generators';
|
|
8
8
|
import { formatNumber } from '../../libs';
|
|
9
9
|
import { block } from '../../utils';
|
|
@@ -116,15 +116,13 @@ function renderLegendSymbol(args) {
|
|
|
116
116
|
}
|
|
117
117
|
case 'symbol': {
|
|
118
118
|
const symbolAreaSize = Math.pow(d.symbol.width, 2);
|
|
119
|
-
const y = legendLineHeight / 2;
|
|
120
119
|
const bboxWidth = d.symbol.bboxWidth;
|
|
120
|
+
const translateX = x + bboxWidth / 2;
|
|
121
|
+
const translateY = legendLineHeight / 2;
|
|
121
122
|
element
|
|
122
123
|
.append('svg:path')
|
|
123
124
|
.attr('d', () => symbol(scatterSymbol, symbolAreaSize)())
|
|
124
|
-
.attr('transform', (
|
|
125
|
-
const translateX = x + bboxWidth / 2;
|
|
126
|
-
return 'translate(' + translateX + ',' + y + ')';
|
|
127
|
-
})
|
|
125
|
+
.attr('transform', 'translate(' + translateX + ',' + translateY + ')')
|
|
128
126
|
.attr('class', className)
|
|
129
127
|
.style('fill', color);
|
|
130
128
|
break;
|
|
@@ -234,6 +232,7 @@ export const Legend = (props) => {
|
|
|
234
232
|
legendItem.symbol.bboxWidth +
|
|
235
233
|
legendItem.symbol.padding);
|
|
236
234
|
})
|
|
235
|
+
.attr('y', legend.hangingOffset)
|
|
237
236
|
.attr('height', legend.height)
|
|
238
237
|
.attr('class', function (d) {
|
|
239
238
|
const mods = { selected: d.visible, unselected: !d.visible };
|
|
@@ -364,10 +363,7 @@ export const Legend = (props) => {
|
|
|
364
363
|
}
|
|
365
364
|
const legendTitleClassname = b('title');
|
|
366
365
|
if (legend.title.enable) {
|
|
367
|
-
const {
|
|
368
|
-
labels: [legend.title.text],
|
|
369
|
-
style: legend.title.style,
|
|
370
|
-
});
|
|
366
|
+
const { width: titleWidth } = await getTextSizeFn({ style: legend.title.style })(legend.title.text);
|
|
371
367
|
let dx = 0;
|
|
372
368
|
switch (legend.title.align) {
|
|
373
369
|
case 'center': {
|
|
@@ -390,10 +386,11 @@ export const Legend = (props) => {
|
|
|
390
386
|
.attr('class', legendTitleClassname)
|
|
391
387
|
.append('text')
|
|
392
388
|
.attr('dx', dx)
|
|
389
|
+
.attr('y', legend.title.hangingOffset)
|
|
393
390
|
.attr('font-weight', (_f = legend.title.style.fontWeight) !== null && _f !== void 0 ? _f : null)
|
|
394
391
|
.attr('font-size', (_g = legend.title.style.fontSize) !== null && _g !== void 0 ? _g : null)
|
|
395
392
|
.attr('fill', (_h = legend.title.style.fontColor) !== null && _h !== void 0 ? _h : null)
|
|
396
|
-
.style('dominant-baseline', '
|
|
393
|
+
.style('dominant-baseline', 'hanging')
|
|
397
394
|
.html(legend.title.text);
|
|
398
395
|
}
|
|
399
396
|
else {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import get from 'lodash/get';
|
|
2
|
-
import { TIME_UNITS, calculateCos, calculateNumericProperty, calculateSin, formatAxisTickLabel, getDefaultDateFormat, getHorizontalHtmlTextHeight,
|
|
2
|
+
import { TIME_UNITS, calculateCos, calculateNumericProperty, calculateSin, formatAxisTickLabel, getDefaultDateFormat, getHorizontalHtmlTextHeight, getLabelsSize, getMinSpaceBetween, getTextSizeFn, isAxisRelatedSeries, wrapText, } from '../utils';
|
|
3
3
|
import { DASH_STYLE, DEFAULT_AXIS_LABEL_FONT_SIZE, SERIES_TYPE, axisCrosshairDefaults, axisLabelsDefaults, axisTickMarksDefaults, xAxisTitleDefaults, } from '../constants';
|
|
4
4
|
import { createXScale } from '../scales/x-scale';
|
|
5
5
|
import { getXAxisTickValues } from '../utils/axis/x-axis';
|
|
@@ -90,7 +90,7 @@ export const getPreparedXAxis = async ({ xAxis, seriesData, width, boundsWidth,
|
|
|
90
90
|
if (isLabelsEnabled) {
|
|
91
91
|
labelsLineHeight = labelsHtml
|
|
92
92
|
? getHorizontalHtmlTextHeight({ text: 'Tmp', style: labelsStyle })
|
|
93
|
-
:
|
|
93
|
+
: (await getTextSizeFn({ style: labelsStyle })('Tmp')).height;
|
|
94
94
|
}
|
|
95
95
|
const shouldHideGrid = isAxisVisible === false || seriesData.some((s) => s.type === SERIES_TYPE.Heatmap);
|
|
96
96
|
const preparedRangeSlider = getPreparedRangeSlider({ xAxis });
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import get from 'lodash/get';
|
|
2
|
-
import { calculateNumericProperty, formatAxisTickLabel, getDefaultDateFormat, getDefaultMinYAxisValue, getHorizontalHtmlTextHeight,
|
|
2
|
+
import { calculateNumericProperty, formatAxisTickLabel, getDefaultDateFormat, getDefaultMinYAxisValue, getHorizontalHtmlTextHeight, getLabelsSize, getMinSpaceBetween, getTextSizeFn, isAxisRelatedSeries, shouldSyncAxisWithPrimary, wrapText, } from '../utils';
|
|
3
3
|
import { getTickValues } from '../../components/AxisY/utils';
|
|
4
4
|
import { DASH_STYLE, DEFAULT_AXIS_LABEL_FONT_SIZE, DEFAULT_AXIS_TYPE, SERIES_TYPE, axisCrosshairDefaults, axisLabelsDefaults, axisTickMarksDefaults, yAxisTitleDefaults, } from '../constants';
|
|
5
5
|
import { createYScale } from '../scales/y-scale';
|
|
@@ -68,7 +68,7 @@ export const getPreparedYAxis = ({ height, boundsHeight, width, seriesData, yAxi
|
|
|
68
68
|
const labelsHtml = get(axisItem, 'labels.html', false);
|
|
69
69
|
const labelsLineHeight = labelsHtml
|
|
70
70
|
? getHorizontalHtmlTextHeight({ text: 'Tmp', style: labelsStyle })
|
|
71
|
-
:
|
|
71
|
+
: (await getTextSizeFn({ style: labelsStyle })('Tmp')).height;
|
|
72
72
|
const titleText = isAxisVisible ? get(axisItem, 'title.text', '') : '';
|
|
73
73
|
const titleStyle = Object.assign(Object.assign({}, yAxisTitleDefaults.style), get(axisItem, 'title.style'));
|
|
74
74
|
const titleMaxRowsCount = get(axisItem, 'title.maxRowCount', yAxisTitleDefaults.maxRowCount);
|
|
@@ -10,8 +10,8 @@ export declare function getPlotHeight(args: {
|
|
|
10
10
|
boundsHeight: number;
|
|
11
11
|
gap: number;
|
|
12
12
|
}): number;
|
|
13
|
-
export declare function getSplit(args: UseSplitArgs): {
|
|
13
|
+
export declare function getSplit(args: UseSplitArgs): Promise<{
|
|
14
14
|
plots: PreparedPlot[];
|
|
15
15
|
gap: number;
|
|
16
|
-
}
|
|
16
|
+
}>;
|
|
17
17
|
export {};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import get from 'lodash/get';
|
|
2
2
|
import isEmpty from 'lodash/isEmpty';
|
|
3
|
-
import { calculateNumericProperty,
|
|
3
|
+
import { calculateNumericProperty, getTextSizeFn } from '../utils';
|
|
4
4
|
const DEFAULT_TITLE_FONT_SIZE = '15px';
|
|
5
5
|
const TITLE_TOP_BOTTOM_PADDING = 8;
|
|
6
|
-
function preparePlotTitle(args) {
|
|
6
|
+
async function preparePlotTitle(args) {
|
|
7
7
|
const { title, plotIndex, plotHeight, chartWidth, gap } = args;
|
|
8
8
|
const titleText = (title === null || title === void 0 ? void 0 : title.text) || '';
|
|
9
9
|
const titleStyle = {
|
|
@@ -11,7 +11,7 @@ function preparePlotTitle(args) {
|
|
|
11
11
|
fontWeight: get(title, 'style.fontWeight'),
|
|
12
12
|
};
|
|
13
13
|
const titleHeight = titleText
|
|
14
|
-
?
|
|
14
|
+
? (await getTextSizeFn({ style: titleStyle })(titleText)).height +
|
|
15
15
|
TITLE_TOP_BOTTOM_PADDING * 2
|
|
16
16
|
: 0;
|
|
17
17
|
const top = plotIndex * (plotHeight + gap);
|
|
@@ -31,7 +31,7 @@ export function getPlotHeight(args) {
|
|
|
31
31
|
}
|
|
32
32
|
return boundsHeight;
|
|
33
33
|
}
|
|
34
|
-
export function getSplit(args) {
|
|
34
|
+
export async function getSplit(args) {
|
|
35
35
|
var _a, _b;
|
|
36
36
|
const { split, boundsHeight, chartWidth } = args;
|
|
37
37
|
const splitGap = (_a = calculateNumericProperty({ value: split === null || split === void 0 ? void 0 : split.gap, base: boundsHeight })) !== null && _a !== void 0 ? _a : 0;
|
|
@@ -40,22 +40,25 @@ export function getSplit(args) {
|
|
|
40
40
|
if (isEmpty(plots)) {
|
|
41
41
|
plots.push({});
|
|
42
42
|
}
|
|
43
|
+
const items = [];
|
|
44
|
+
for (let index = 0; index < plots.length; index++) {
|
|
45
|
+
const p = plots[index];
|
|
46
|
+
const title = await preparePlotTitle({
|
|
47
|
+
title: p.title,
|
|
48
|
+
plotIndex: index,
|
|
49
|
+
gap: splitGap,
|
|
50
|
+
plotHeight,
|
|
51
|
+
chartWidth,
|
|
52
|
+
});
|
|
53
|
+
const top = index * (plotHeight + splitGap);
|
|
54
|
+
items.push({
|
|
55
|
+
top: top + title.height,
|
|
56
|
+
height: plotHeight - title.height,
|
|
57
|
+
title,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
43
60
|
return {
|
|
44
|
-
plots:
|
|
45
|
-
const title = preparePlotTitle({
|
|
46
|
-
title: p.title,
|
|
47
|
-
plotIndex: index,
|
|
48
|
-
gap: splitGap,
|
|
49
|
-
plotHeight,
|
|
50
|
-
chartWidth,
|
|
51
|
-
});
|
|
52
|
-
const top = index * (plotHeight + splitGap);
|
|
53
|
-
return {
|
|
54
|
-
top: top + title.height,
|
|
55
|
-
height: plotHeight - title.height,
|
|
56
|
-
title,
|
|
57
|
-
};
|
|
58
|
-
}),
|
|
61
|
+
plots: items,
|
|
59
62
|
gap: splitGap,
|
|
60
63
|
};
|
|
61
64
|
}
|
|
@@ -12,23 +12,21 @@ export async function getPreparedLegend(args) {
|
|
|
12
12
|
const defaultItemStyle = clone(legendDefaults.itemStyle);
|
|
13
13
|
const itemStyle = get(legend, 'itemStyle');
|
|
14
14
|
const computedItemStyle = merge(defaultItemStyle, itemStyle);
|
|
15
|
-
const {
|
|
16
|
-
labels: ['Tmp'],
|
|
17
|
-
style: computedItemStyle,
|
|
18
|
-
});
|
|
15
|
+
const { width: lineWidth, height: lineHeight, hangingOffset: itemHangingOffset, } = await getTextSizeFn({ style: computedItemStyle })('Tmp');
|
|
19
16
|
const legendType = get(legend, 'type', 'discrete');
|
|
20
17
|
const isTitleEnabled = Boolean((_a = legend === null || legend === void 0 ? void 0 : legend.title) === null || _a === void 0 ? void 0 : _a.text);
|
|
21
18
|
const titleMargin = isTitleEnabled ? get(legend, 'title.margin', 4) : 0;
|
|
22
19
|
const titleStyle = Object.assign({ fontSize: '12px', fontWeight: 'bold' }, get(legend, 'title.style'));
|
|
23
20
|
const titleText = isTitleEnabled ? get(legend, 'title.text', '') : '';
|
|
24
|
-
const
|
|
25
|
-
const titleHeight = isTitleEnabled ?
|
|
21
|
+
const titleTextSize = await getTextSizeFn({ style: titleStyle })(titleText);
|
|
22
|
+
const titleHeight = isTitleEnabled ? titleTextSize.height : 0;
|
|
23
|
+
const titleHangingOffset = titleTextSize.hangingOffset;
|
|
26
24
|
const tickStyle = {
|
|
27
25
|
fontSize: '12px',
|
|
28
26
|
};
|
|
29
27
|
const ticks = {
|
|
30
28
|
labelsMargin: 4,
|
|
31
|
-
labelsLineHeight: (await
|
|
29
|
+
labelsLineHeight: (await getTextSizeFn({ style: tickStyle })('Tmp')).height,
|
|
32
30
|
style: tickStyle,
|
|
33
31
|
};
|
|
34
32
|
const colorScale = {
|
|
@@ -60,6 +58,7 @@ export async function getPreparedLegend(args) {
|
|
|
60
58
|
verticalAlign: get(legend, 'verticalAlign', legendDefaults.verticalAlign),
|
|
61
59
|
justifyContent: get(legend, 'justifyContent', legendDefaults.justifyContent),
|
|
62
60
|
enabled,
|
|
61
|
+
hangingOffset: itemHangingOffset,
|
|
63
62
|
height,
|
|
64
63
|
itemDistance: get(legend, 'itemDistance', legendDefaults.itemDistance),
|
|
65
64
|
itemStyle: computedItemStyle,
|
|
@@ -68,6 +67,7 @@ export async function getPreparedLegend(args) {
|
|
|
68
67
|
type: legendType,
|
|
69
68
|
title: {
|
|
70
69
|
enable: isTitleEnabled,
|
|
70
|
+
hangingOffset: titleHangingOffset,
|
|
71
71
|
text: titleText,
|
|
72
72
|
margin: titleMargin,
|
|
73
73
|
style: titleStyle,
|
|
@@ -15,10 +15,12 @@ export type PreparedLegendSymbol = (RectLegendSymbol | PathLegendSymbol | Symbol
|
|
|
15
15
|
bboxWidth: number;
|
|
16
16
|
};
|
|
17
17
|
export type PreparedLegend = Required<Omit<ChartLegend, 'title' | 'colorScale'>> & {
|
|
18
|
+
hangingOffset: number;
|
|
18
19
|
height: number;
|
|
19
20
|
lineHeight: number;
|
|
20
21
|
title: {
|
|
21
22
|
enable: boolean;
|
|
23
|
+
hangingOffset: number;
|
|
22
24
|
text: string;
|
|
23
25
|
margin: number;
|
|
24
26
|
style: BaseTextStyle;
|