@gravity-ui/charts 1.42.3 → 1.43.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.
- package/dist/cjs/components/AxisX/AxisX.js +31 -4
- package/dist/cjs/components/AxisX/prepare-axis-data.js +58 -13
- package/dist/cjs/components/AxisX/types.d.ts +18 -1
- package/dist/cjs/components/AxisY/AxisY.js +31 -4
- package/dist/cjs/components/AxisY/prepare-axis-data.js +68 -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/AxisY/types.d.ts +18 -1
- package/dist/cjs/components/ChartInner/index.js +21 -15
- package/dist/cjs/components/ChartInner/useChartInnerHandlers.js +6 -5
- package/dist/cjs/components/ChartInner/useChartInnerProps.d.ts +3 -2
- package/dist/cjs/components/ChartInner/useChartInnerProps.js +22 -11
- package/dist/cjs/components/ChartInner/useDefaultState.js +4 -3
- package/dist/cjs/components/ChartInner/utils/chart.js +1 -1
- package/dist/cjs/components/ChartInner/utils/normalized-original-data.d.ts +1 -0
- package/dist/cjs/components/ChartInner/utils/title.d.ts +3 -2
- package/dist/cjs/components/ChartInner/utils/title.js +69 -11
- package/dist/cjs/components/Legend/index.js +8 -11
- package/dist/cjs/components/Legend/styles.css +1 -1
- package/dist/cjs/components/Title/index.js +3 -5
- package/dist/cjs/components/Tooltip/ChartTooltipContent.d.ts +2 -1
- package/dist/cjs/components/Tooltip/ChartTooltipContent.js +3 -2
- package/dist/cjs/components/Tooltip/index.js +2 -2
- package/dist/cjs/components/utils/axis-title.js +1 -1
- package/dist/cjs/core/axes/types.d.ts +26 -9
- package/dist/cjs/core/axes/x-axis.js +16 -3
- package/dist/cjs/core/axes/y-axis.js +21 -8
- package/dist/cjs/core/constants/defaults/axis.d.ts +1 -0
- package/dist/cjs/core/constants/defaults/axis.js +1 -0
- package/dist/cjs/core/layout/split.d.ts +2 -2
- package/dist/cjs/core/layout/split.js +22 -19
- package/dist/cjs/core/scales/y-scale.js +37 -13
- package/dist/cjs/core/series/prepare-legend.js +7 -7
- package/dist/cjs/core/series/types.d.ts +2 -0
- package/dist/cjs/core/types/chart/axis.d.ts +43 -1
- package/dist/cjs/core/types/chart/title.d.ts +10 -0
- package/dist/cjs/core/types/chart/tooltip.d.ts +3 -1
- 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 +1 -14
- package/dist/cjs/core/utils/get-hovered-plots.d.ts +3 -2
- package/dist/cjs/core/utils/get-hovered-plots.js +28 -4
- 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 +16 -2
- package/dist/cjs/hooks/types.d.ts +5 -2
- package/dist/cjs/hooks/useShapes/area/prepare-data.js +12 -7
- package/dist/cjs/hooks/useShapes/bar-x/prepare-data.js +12 -4
- 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/hooks/useTooltip/index.d.ts +3 -2
- package/dist/cjs/hooks/useTooltip/index.js +5 -3
- package/dist/cjs/types/chart-ui.d.ts +1 -0
- package/dist/esm/components/AxisX/AxisX.js +31 -4
- package/dist/esm/components/AxisX/prepare-axis-data.js +58 -13
- package/dist/esm/components/AxisX/types.d.ts +18 -1
- package/dist/esm/components/AxisY/AxisY.js +31 -4
- package/dist/esm/components/AxisY/prepare-axis-data.js +68 -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/AxisY/types.d.ts +18 -1
- package/dist/esm/components/ChartInner/index.js +21 -15
- package/dist/esm/components/ChartInner/useChartInnerHandlers.js +6 -5
- package/dist/esm/components/ChartInner/useChartInnerProps.d.ts +3 -2
- package/dist/esm/components/ChartInner/useChartInnerProps.js +22 -11
- package/dist/esm/components/ChartInner/useDefaultState.js +4 -3
- package/dist/esm/components/ChartInner/utils/chart.js +1 -1
- package/dist/esm/components/ChartInner/utils/normalized-original-data.d.ts +1 -0
- package/dist/esm/components/ChartInner/utils/title.d.ts +3 -2
- package/dist/esm/components/ChartInner/utils/title.js +69 -11
- package/dist/esm/components/Legend/index.js +8 -11
- package/dist/esm/components/Legend/styles.css +1 -1
- package/dist/esm/components/Title/index.js +3 -5
- package/dist/esm/components/Tooltip/ChartTooltipContent.d.ts +2 -1
- package/dist/esm/components/Tooltip/ChartTooltipContent.js +3 -2
- package/dist/esm/components/Tooltip/index.js +2 -2
- package/dist/esm/components/utils/axis-title.js +1 -1
- package/dist/esm/core/axes/types.d.ts +26 -9
- package/dist/esm/core/axes/x-axis.js +16 -3
- package/dist/esm/core/axes/y-axis.js +21 -8
- package/dist/esm/core/constants/defaults/axis.d.ts +1 -0
- package/dist/esm/core/constants/defaults/axis.js +1 -0
- package/dist/esm/core/layout/split.d.ts +2 -2
- package/dist/esm/core/layout/split.js +22 -19
- package/dist/esm/core/scales/y-scale.js +37 -13
- package/dist/esm/core/series/prepare-legend.js +7 -7
- package/dist/esm/core/series/types.d.ts +2 -0
- package/dist/esm/core/types/chart/axis.d.ts +43 -1
- package/dist/esm/core/types/chart/title.d.ts +10 -0
- package/dist/esm/core/types/chart/tooltip.d.ts +3 -1
- 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 +1 -14
- package/dist/esm/core/utils/get-hovered-plots.d.ts +3 -2
- package/dist/esm/core/utils/get-hovered-plots.js +28 -4
- 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 +16 -2
- package/dist/esm/hooks/types.d.ts +5 -2
- package/dist/esm/hooks/useShapes/area/prepare-data.js +12 -7
- package/dist/esm/hooks/useShapes/bar-x/prepare-data.js +12 -4
- 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/hooks/useTooltip/index.d.ts +3 -2
- package/dist/esm/hooks/useTooltip/index.js +5 -3
- package/dist/esm/types/chart-ui.d.ts +1 -0
- package/package.json +1 -3
|
@@ -43,20 +43,20 @@ export function filterOverlappingLabels(labels) {
|
|
|
43
43
|
return result;
|
|
44
44
|
}
|
|
45
45
|
export function getSvgLabelConstraintedPosition(args) {
|
|
46
|
-
const { boundsHeight, boundsWidth, height, width, x, y } = args;
|
|
46
|
+
const { boundsHeight, boundsWidth, height, width, x, y, hangingOffset } = args;
|
|
47
47
|
let resultX = x;
|
|
48
|
-
let resultY = y;
|
|
48
|
+
let resultY = y - height / 2 + hangingOffset;
|
|
49
49
|
if (x < 0) {
|
|
50
50
|
resultX = 0;
|
|
51
51
|
}
|
|
52
52
|
if (x + width > boundsWidth) {
|
|
53
53
|
resultX = boundsWidth - width;
|
|
54
54
|
}
|
|
55
|
-
if (
|
|
55
|
+
if (resultY < 0) {
|
|
56
56
|
resultY = 0;
|
|
57
57
|
}
|
|
58
|
-
if (
|
|
59
|
-
resultY = boundsHeight;
|
|
58
|
+
if (resultY + height > boundsHeight) {
|
|
59
|
+
resultY = boundsHeight - height + hangingOffset;
|
|
60
60
|
}
|
|
61
61
|
return { x: resultX, y: resultY };
|
|
62
62
|
}
|
|
@@ -27,6 +27,7 @@ export declare function getTextSizeFn({ style }: {
|
|
|
27
27
|
}): (str: string) => Promise<{
|
|
28
28
|
width: number;
|
|
29
29
|
height: number;
|
|
30
|
+
hangingOffset: number;
|
|
30
31
|
}>;
|
|
31
32
|
export declare function getTextWithElipsis({ text: originalText, getTextWidth, maxWidth, }: {
|
|
32
33
|
text: string;
|
|
@@ -189,14 +189,28 @@ export function getTextSizeFn({ style }) {
|
|
|
189
189
|
const defaultFontFamily = computedStyle.getPropertyValue('font-family');
|
|
190
190
|
const defaultFontSize = computedStyle.getPropertyValue('font-size');
|
|
191
191
|
const defaultFontWeight = computedStyle.getPropertyValue('font-weight');
|
|
192
|
+
const resolveCSSVar = (value) => {
|
|
193
|
+
const match = value.match(/^var\(\s*([\w-]+)/);
|
|
194
|
+
if (match) {
|
|
195
|
+
return computedStyle.getPropertyValue(match[1]).trim() || value;
|
|
196
|
+
}
|
|
197
|
+
return value;
|
|
198
|
+
};
|
|
192
199
|
return async (str) => {
|
|
193
|
-
var _a, _b;
|
|
194
200
|
await document.fonts.ready;
|
|
195
|
-
|
|
201
|
+
const fontWeight = (style === null || style === void 0 ? void 0 : style.fontWeight)
|
|
202
|
+
? resolveCSSVar(String(style.fontWeight))
|
|
203
|
+
: defaultFontWeight;
|
|
204
|
+
const fontSize = (style === null || style === void 0 ? void 0 : style.fontSize) ? resolveCSSVar(style.fontSize) : defaultFontSize;
|
|
205
|
+
context.font = `${fontWeight} ${fontSize} ${defaultFontFamily}`;
|
|
196
206
|
const textMetric = context.measureText(unescapeHtml(str));
|
|
207
|
+
// we calculate hanging based on an approximate algorithm from chromium
|
|
208
|
+
// https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/html/canvas/text_metrics.cc;l=32;drc=7cf6ac3dd6dca800fbc0d28e80a7732d4ea90340?q=member_hanging_&ss=chromium%2Fchromium%2Fsrc
|
|
209
|
+
// it would be possible to use native, but the browsers are not working in harmony right now
|
|
197
210
|
return {
|
|
198
211
|
width: textMetric.width,
|
|
199
212
|
height: textMetric.fontBoundingBoxDescent + textMetric.fontBoundingBoxAscent,
|
|
213
|
+
hangingOffset: textMetric.fontBoundingBoxAscent * 0.2,
|
|
200
214
|
};
|
|
201
215
|
};
|
|
202
216
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { TextRowData } from '../components/types';
|
|
2
|
+
import type { ChartBrush, ChartData, ChartMargin, ChartTitle, ChartZoom, DeepRequired } from '../types';
|
|
2
3
|
export type PreparedZoom = DeepRequired<Omit<ChartZoom, 'enabled' | 'brush'>> & DeepRequired<{
|
|
3
4
|
brush: ChartBrush;
|
|
4
5
|
}>;
|
|
@@ -6,8 +7,10 @@ export type PreparedChart = {
|
|
|
6
7
|
margin: ChartMargin;
|
|
7
8
|
zoom: PreparedZoom | null;
|
|
8
9
|
};
|
|
9
|
-
export type PreparedTitle =
|
|
10
|
+
export type PreparedTitle = Omit<ChartTitle, 'margin'> & {
|
|
10
11
|
height: number;
|
|
12
|
+
margin: number;
|
|
13
|
+
contentRows: TextRowData[];
|
|
11
14
|
};
|
|
12
15
|
export type PreparedTooltip = ChartData['tooltip'] & {
|
|
13
16
|
enabled: boolean;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { group } from 'd3-array';
|
|
1
|
+
import { group, min } from 'd3-array';
|
|
2
2
|
import isNil from 'lodash/isNil';
|
|
3
3
|
import round from 'lodash/round';
|
|
4
4
|
import { getDataCategoryValue, getLabelsSize, getTextSizeFn } from '../../../core/utils';
|
|
@@ -60,7 +60,7 @@ async function prepareDataLabels({ series, points, xMax, yAxisTop, isOutsideBoun
|
|
|
60
60
|
else {
|
|
61
61
|
const labelSize = await getTextSize(text);
|
|
62
62
|
const x = Math.min(xMax - labelSize.width, Math.max(0, point.x - labelSize.width / 2));
|
|
63
|
-
const y = Math.max(yAxisTop, point.y - series.dataLabels.padding - labelSize.height);
|
|
63
|
+
const y = Math.max(yAxisTop, point.y - series.dataLabels.padding - labelSize.height + labelSize.hangingOffset);
|
|
64
64
|
svgLabels.push({
|
|
65
65
|
text,
|
|
66
66
|
x,
|
|
@@ -76,7 +76,7 @@ async function prepareDataLabels({ series, points, xMax, yAxisTop, isOutsideBoun
|
|
|
76
76
|
return { svgLabels, htmlLabels };
|
|
77
77
|
}
|
|
78
78
|
export const prepareAreaData = async (args) => {
|
|
79
|
-
var _a, _b, _c;
|
|
79
|
+
var _a, _b, _c, _d;
|
|
80
80
|
const { series, xAxis, xScale, yAxis, yScale, split, isOutsideBounds, isRangeSlider } = args;
|
|
81
81
|
const [_xMin, xRangeMax] = xScale.range();
|
|
82
82
|
const xMax = xRangeMax;
|
|
@@ -144,12 +144,17 @@ export const prepareAreaData = async (args) => {
|
|
|
144
144
|
continue;
|
|
145
145
|
}
|
|
146
146
|
const yAxisTop = ((_a = split.plots[plotIndex]) === null || _a === void 0 ? void 0 : _a.top) || 0;
|
|
147
|
-
|
|
148
|
-
|
|
147
|
+
let base = 0;
|
|
148
|
+
if (seriesYAxis.type === 'logarithmic') {
|
|
149
|
+
const domainData = seriesYScale.domain();
|
|
150
|
+
base = (_b = min(domainData)) !== null && _b !== void 0 ? _b : 0;
|
|
151
|
+
}
|
|
152
|
+
const yMin = (_c = getYValue({
|
|
153
|
+
point: { y: base },
|
|
149
154
|
points: s.data,
|
|
150
155
|
yAxis: seriesYAxis,
|
|
151
156
|
yScale: seriesYScale,
|
|
152
|
-
})) !== null &&
|
|
157
|
+
})) !== null && _c !== void 0 ? _c : 0;
|
|
153
158
|
const seriesData = s.data.reduce((m, d) => {
|
|
154
159
|
const key = String(xAxis.type === 'category'
|
|
155
160
|
? getDataCategoryValue({
|
|
@@ -309,7 +314,7 @@ export const prepareAreaData = async (args) => {
|
|
|
309
314
|
for (let itemIndex = 0; itemIndex < seriesStackData.length; itemIndex++) {
|
|
310
315
|
const item = seriesStackData[itemIndex];
|
|
311
316
|
const currentYAxis = yAxis[item.series.yAxis];
|
|
312
|
-
const itemYAxisTop = ((
|
|
317
|
+
const itemYAxisTop = ((_d = split.plots[currentYAxis.plotIndex]) === null || _d === void 0 ? void 0 : _d.top) || 0;
|
|
313
318
|
if (item.series.dataLabels.enabled && !isRangeSlider) {
|
|
314
319
|
const labelsData = await prepareDataLabels({
|
|
315
320
|
series: item.series,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ascending, descending, max, reverse, sort } from 'd3-array';
|
|
1
|
+
import { ascending, descending, max, min, reverse, sort } from 'd3-array';
|
|
2
2
|
import get from 'lodash/get';
|
|
3
3
|
import { getDataCategoryValue, getLabelsSize } from '../../../core/utils';
|
|
4
4
|
import { getFormattedValue } from '../../../core/utils/format';
|
|
@@ -35,7 +35,7 @@ async function getLabelData(d, xMax) {
|
|
|
35
35
|
};
|
|
36
36
|
}
|
|
37
37
|
export const prepareBarXData = async (args) => {
|
|
38
|
-
var _a, _b, _c, _d, _e;
|
|
38
|
+
var _a, _b, _c, _d, _e, _f;
|
|
39
39
|
const { series, seriesOptions, xAxis, xScale, yAxis, yScale, boundsHeight: plotHeight, split, isRangeSlider, } = args;
|
|
40
40
|
const stackGap = seriesOptions['bar-x'].stackGap;
|
|
41
41
|
const categories = (_a = xAxis === null || xAxis === void 0 ? void 0 : xAxis.categories) !== null && _a !== void 0 ? _a : [];
|
|
@@ -145,7 +145,15 @@ export const prepareBarXData = async (args) => {
|
|
|
145
145
|
const x = xCenter - currentGroupWidth / 2 + (rectWidth + rectGap) * groupItemIndex;
|
|
146
146
|
const yDataValue = ((_d = yValue.data.y) !== null && _d !== void 0 ? _d : 0);
|
|
147
147
|
const y = seriesYScale(yDataValue);
|
|
148
|
-
|
|
148
|
+
let base = 0;
|
|
149
|
+
if (seriesYAxis.type === 'logarithmic') {
|
|
150
|
+
const domainData = seriesYScale.domain();
|
|
151
|
+
const yMinValue = (_e = min(domainData)) !== null && _e !== void 0 ? _e : 0;
|
|
152
|
+
base = seriesYScale(yMinValue);
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
base = seriesYScale(0);
|
|
156
|
+
}
|
|
149
157
|
const isLastStackItem = yValueIndex === sortedData.length - 1;
|
|
150
158
|
const height = Math.abs(base - y);
|
|
151
159
|
let shapeHeight = height - (stackItems.length ? stackGap : 0);
|
|
@@ -198,7 +206,7 @@ export const prepareBarXData = async (args) => {
|
|
|
198
206
|
barData.x >= xMax ||
|
|
199
207
|
barData.y + barData.height <= 0 ||
|
|
200
208
|
barData.y >= plotHeight;
|
|
201
|
-
const isZeroValue = ((
|
|
209
|
+
const isZeroValue = ((_f = barData.data.y) !== null && _f !== void 0 ? _f : 0) === 0;
|
|
202
210
|
if (barData.series.dataLabels.enabled &&
|
|
203
211
|
!isRangeSlider &&
|
|
204
212
|
(!isBarOutsideBounds || isZeroValue)) {
|
|
@@ -171,7 +171,7 @@ export async function prepareBarYData(args) {
|
|
|
171
171
|
map.set(dataLabels.style, getTextSizeFn({ style: dataLabels.style }));
|
|
172
172
|
}
|
|
173
173
|
const getTextSize = map.get(dataLabels.style);
|
|
174
|
-
const { width, height } = await getTextSize(content);
|
|
174
|
+
const { width, height, hangingOffset } = await getTextSize(content);
|
|
175
175
|
const x = dataLabels.inside
|
|
176
176
|
? prepared.x + prepared.width / 2 - width / 2
|
|
177
177
|
: prepared.x + prepared.width + dataLabels.padding;
|
|
@@ -181,7 +181,8 @@ export async function prepareBarYData(args) {
|
|
|
181
181
|
height,
|
|
182
182
|
width,
|
|
183
183
|
x,
|
|
184
|
-
y
|
|
184
|
+
y,
|
|
185
|
+
hangingOffset,
|
|
185
186
|
});
|
|
186
187
|
labels.push({
|
|
187
188
|
size: { width, height },
|
|
@@ -62,7 +62,10 @@ export async function prepareFunnelData(args) {
|
|
|
62
62
|
}
|
|
63
63
|
svgLabels.push({
|
|
64
64
|
x,
|
|
65
|
-
y: getSegmentY(index) +
|
|
65
|
+
y: getSegmentY(index) +
|
|
66
|
+
itemHeight / 2 -
|
|
67
|
+
labelSize.height / 2 +
|
|
68
|
+
labelSize.hangingOffset,
|
|
66
69
|
text: labelContent,
|
|
67
70
|
style: s.dataLabels.style,
|
|
68
71
|
size: labelSize,
|
|
@@ -82,7 +82,7 @@ export async function prepareHeatmapData({ series, xAxis, xScale, yAxis, yScale,
|
|
|
82
82
|
if (text) {
|
|
83
83
|
svgDataLabels.push({
|
|
84
84
|
x: item.x + item.width / 2 - size.width / 2,
|
|
85
|
-
y: item.y + item.height / 2 - size.height / 2,
|
|
85
|
+
y: item.y + item.height / 2 - size.height / 2 + size.hangingOffset,
|
|
86
86
|
text,
|
|
87
87
|
style: series.dataLabels.style,
|
|
88
88
|
});
|
|
@@ -68,7 +68,10 @@ export const prepareLineData = async (args) => {
|
|
|
68
68
|
const text = getFormattedValue(Object.assign({ value: labelValue }, s.dataLabels));
|
|
69
69
|
const labelSize = await getTextSize(text);
|
|
70
70
|
const style = s.dataLabels.style;
|
|
71
|
-
const y = Math.max(yAxisTop, point.y -
|
|
71
|
+
const y = Math.max(yAxisTop, point.y -
|
|
72
|
+
s.dataLabels.padding -
|
|
73
|
+
labelSize.height +
|
|
74
|
+
labelSize.hangingOffset);
|
|
72
75
|
const x = Math.min(xMax - labelSize.width, Math.max(0, point.x - labelSize.width / 2));
|
|
73
76
|
const labelData = {
|
|
74
77
|
text,
|
|
@@ -95,6 +95,7 @@ export function preparePieData(args) {
|
|
|
95
95
|
const text = getFormattedValue(Object.assign({ value: (_a = d.data.label) !== null && _a !== void 0 ? _a : d.data.value }, d.dataLabels));
|
|
96
96
|
let labelWidth = 0;
|
|
97
97
|
let labelHeight = 0;
|
|
98
|
+
let labelHangingOffset = 0;
|
|
98
99
|
if (dataLabels.html) {
|
|
99
100
|
const size = await getLabelsSize({
|
|
100
101
|
labels: [text],
|
|
@@ -108,10 +109,11 @@ export function preparePieData(args) {
|
|
|
108
109
|
const size = await getTextSize(text);
|
|
109
110
|
labelWidth = size.width;
|
|
110
111
|
labelHeight = size.height;
|
|
112
|
+
labelHangingOffset = size.hangingOffset;
|
|
111
113
|
}
|
|
112
114
|
const label = {
|
|
113
115
|
text,
|
|
114
|
-
size: { width: labelWidth, height: labelHeight },
|
|
116
|
+
size: { width: labelWidth, height: labelHeight, hangingOffset: labelHangingOffset },
|
|
115
117
|
};
|
|
116
118
|
acc[d.id] = label;
|
|
117
119
|
}
|
|
@@ -165,11 +167,16 @@ export function preparePieData(args) {
|
|
|
165
167
|
* @returns {[number, number]} A tuple [x, y] relative to the pie center.
|
|
166
168
|
*/
|
|
167
169
|
const getLabelPosition = (angle) => {
|
|
170
|
+
var _a;
|
|
168
171
|
let [x, y] = labelArcGenerator.centroid(Object.assign(Object.assign({}, relatedSegment), { startAngle: angle, endAngle: angle }));
|
|
169
172
|
if (shouldUseHtml) {
|
|
170
173
|
x = x < 0 ? x - labelWidth : x;
|
|
174
|
+
y = y < 0 ? y - labelHeight : y;
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
const hangingOffset = (_a = labelSize === null || labelSize === void 0 ? void 0 : labelSize.hangingOffset) !== null && _a !== void 0 ? _a : 0;
|
|
178
|
+
y = y < 0 ? y - labelHeight + hangingOffset : y + hangingOffset;
|
|
171
179
|
}
|
|
172
|
-
y = y < 0 ? y - labelHeight : y;
|
|
173
180
|
return [x, y];
|
|
174
181
|
};
|
|
175
182
|
const getConnectorPoints = (angle) => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { range } from 'd3-array';
|
|
2
2
|
import { scaleLinear } from 'd3-scale';
|
|
3
3
|
import { curveLinearClosed, line } from 'd3-shape';
|
|
4
|
-
import { getLabelsSize } from '../../../core/utils';
|
|
4
|
+
import { getLabelsSize, getTextSizeFn } from '../../../core/utils';
|
|
5
5
|
import { getFormattedValue } from '../../../core/utils/format';
|
|
6
6
|
export async function prepareRadarData(args) {
|
|
7
7
|
const { series: preparedSeries, boundsWidth, boundsHeight } = args;
|
|
@@ -116,18 +116,28 @@ export async function prepareRadarData(args) {
|
|
|
116
116
|
const shouldUseHtml = dataLabels.html;
|
|
117
117
|
data.labels = await Promise.all(categories.map(async (category, index) => {
|
|
118
118
|
const text = getFormattedValue(Object.assign({ value: category.key }, dataLabels));
|
|
119
|
-
const labelSize = await getLabelsSize({ labels: [text], style });
|
|
120
119
|
const angle = index * angleStep - Math.PI / 2;
|
|
121
120
|
// Position label slightly outside the point
|
|
122
121
|
const labelRadius = data.radius + 10;
|
|
123
122
|
let x = center[0] + Math.cos(angle) * labelRadius;
|
|
124
123
|
let y = center[1] + Math.sin(angle) * labelRadius;
|
|
124
|
+
let labelWidth = 0;
|
|
125
|
+
let labelHeight = 0;
|
|
125
126
|
if (shouldUseHtml) {
|
|
126
|
-
|
|
127
|
-
|
|
127
|
+
const labelSize = await getLabelsSize({ labels: [text], style });
|
|
128
|
+
labelWidth = labelSize.maxWidth;
|
|
129
|
+
labelHeight = labelSize.maxHeight;
|
|
130
|
+
x = x < center[0] ? x - labelWidth : x;
|
|
131
|
+
y = y - labelHeight;
|
|
128
132
|
}
|
|
129
133
|
else {
|
|
130
|
-
|
|
134
|
+
const labelSize = await getTextSizeFn({ style })(text);
|
|
135
|
+
labelWidth = labelSize.width;
|
|
136
|
+
labelHeight = labelSize.height;
|
|
137
|
+
y =
|
|
138
|
+
y < center[1]
|
|
139
|
+
? y - labelHeight + labelSize.hangingOffset
|
|
140
|
+
: y + labelSize.hangingOffset;
|
|
131
141
|
}
|
|
132
142
|
x = Math.max(-boundsWidth / 2, x);
|
|
133
143
|
return {
|
|
@@ -135,8 +145,8 @@ export async function prepareRadarData(args) {
|
|
|
135
145
|
x,
|
|
136
146
|
y,
|
|
137
147
|
style,
|
|
138
|
-
size: { width:
|
|
139
|
-
maxWidth:
|
|
148
|
+
size: { width: labelWidth, height: labelHeight },
|
|
149
|
+
maxWidth: labelWidth,
|
|
140
150
|
textAnchor: angle > Math.PI / 2 && angle < (3 * Math.PI) / 2 ? 'end' : 'start',
|
|
141
151
|
series: { id: series.id },
|
|
142
152
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { sankey, sankeyLinkHorizontal } from 'd3-sankey';
|
|
2
1
|
import { getFormattedValue } from '../../../core/utils/format';
|
|
2
|
+
import { sankey, sankeyLinkHorizontal } from './sankey-layout';
|
|
3
3
|
export function prepareSankeyData(args) {
|
|
4
4
|
const { series, width, height } = args;
|
|
5
5
|
const htmlElements = [];
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
type SankeyLayoutNodeProps = {
|
|
2
|
+
index: number;
|
|
3
|
+
depth: number;
|
|
4
|
+
height: number;
|
|
5
|
+
layer: number;
|
|
6
|
+
value: number;
|
|
7
|
+
fixedValue?: number;
|
|
8
|
+
x0: number;
|
|
9
|
+
x1: number;
|
|
10
|
+
y0: number;
|
|
11
|
+
y1: number;
|
|
12
|
+
};
|
|
13
|
+
type SankeyLayoutLinkProps = {
|
|
14
|
+
index: number;
|
|
15
|
+
value: number;
|
|
16
|
+
width: number;
|
|
17
|
+
y0: number;
|
|
18
|
+
y1: number;
|
|
19
|
+
};
|
|
20
|
+
export type SankeyComputedNode<N, L> = N & SankeyLayoutNodeProps & {
|
|
21
|
+
sourceLinks: SankeyComputedLink<N, L>[];
|
|
22
|
+
targetLinks: SankeyComputedLink<N, L>[];
|
|
23
|
+
};
|
|
24
|
+
export type SankeyComputedLink<N, L> = L & SankeyLayoutLinkProps & {
|
|
25
|
+
source: SankeyComputedNode<N, L>;
|
|
26
|
+
target: SankeyComputedNode<N, L>;
|
|
27
|
+
};
|
|
28
|
+
export type SankeyGraph<N, L> = {
|
|
29
|
+
nodes: SankeyComputedNode<N, L>[];
|
|
30
|
+
links: SankeyComputedLink<N, L>[];
|
|
31
|
+
};
|
|
32
|
+
type AlignFn<N, L> = (node: SankeyComputedNode<N, L>, n: number) => number;
|
|
33
|
+
type SortFn<T> = (a: T, b: T) => number;
|
|
34
|
+
export declare function sankey<N, L>(): {
|
|
35
|
+
(input: {
|
|
36
|
+
nodes: N[];
|
|
37
|
+
links: L[];
|
|
38
|
+
}): SankeyGraph<N, L>;
|
|
39
|
+
nodeId(fn: (d: N, i: number) => string | number): /*elided*/ any;
|
|
40
|
+
nodeAlign(fn: AlignFn<N, L>): /*elided*/ any;
|
|
41
|
+
nodeSort(fn: SortFn<SankeyComputedNode<N, L>> | undefined): /*elided*/ any;
|
|
42
|
+
nodeWidth(value: number): /*elided*/ any;
|
|
43
|
+
nodePadding(value: number): /*elided*/ any;
|
|
44
|
+
linkSort(fn: SortFn<SankeyComputedLink<N, L>> | undefined): /*elided*/ any;
|
|
45
|
+
extent([[left, top], [right, bottom]]: [[number, number], [number, number]]): /*elided*/ any;
|
|
46
|
+
iterations(value: number): /*elided*/ any;
|
|
47
|
+
};
|
|
48
|
+
export declare function sankeyLinkHorizontal<N, L>(): import("d3-shape").Link<any, SankeyComputedLink<N, L>, [number, number]>;
|
|
49
|
+
export {};
|