@gravity-ui/charts 1.43.1 → 1.44.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/ChartInner/utils/zoom.js +3 -1
- package/dist/cjs/components/Tooltip/DefaultTooltipContent/index.js +31 -6
- package/dist/cjs/components/Tooltip/DefaultTooltipContent/utils.js +4 -5
- package/dist/cjs/core/constants/chart-types.d.ts +1 -0
- package/dist/cjs/core/constants/chart-types.js +1 -0
- package/dist/cjs/core/constants/defaults/series-options.d.ts +5 -1
- package/dist/cjs/core/constants/defaults/series-options.js +13 -0
- package/dist/cjs/core/i18n/keysets/en.json +2 -1
- package/dist/cjs/core/i18n/keysets/ru.json +2 -1
- package/dist/cjs/core/series/prepare-legend.js +2 -2
- package/dist/cjs/core/series/prepare-x-range.d.ts +11 -0
- package/dist/cjs/core/series/prepare-x-range.js +41 -0
- package/dist/cjs/core/series/prepareSeries.js +9 -0
- package/dist/cjs/core/series/types.d.ts +18 -2
- package/dist/cjs/core/types/chart/area.d.ts +2 -1
- package/dist/cjs/core/types/chart/series.d.ts +29 -2
- package/dist/cjs/core/types/chart/tooltip.d.ts +6 -1
- package/dist/cjs/core/types/chart/x-range.d.ts +59 -0
- package/dist/cjs/core/types/chart/x-range.js +1 -0
- package/dist/cjs/core/types/chart/zoom.d.ts +1 -1
- package/dist/cjs/core/types/index.d.ts +1 -0
- package/dist/cjs/core/types/index.js +1 -0
- package/dist/cjs/core/utils/axis/x-axis.js +9 -1
- package/dist/cjs/core/utils/color.js +6 -0
- package/dist/cjs/core/utils/common.js +10 -0
- package/dist/cjs/core/utils/get-closest-data.js +19 -0
- package/dist/cjs/core/validation/index.js +13 -0
- package/dist/cjs/core/zoom/zoom.js +24 -7
- package/dist/cjs/hooks/useShapes/area/prepare-data.js +15 -14
- package/dist/cjs/hooks/useShapes/bar-x/prepare-data.js +22 -9
- package/dist/cjs/hooks/useShapes/index.d.ts +2 -1
- package/dist/cjs/hooks/useShapes/index.js +17 -0
- package/dist/cjs/hooks/useShapes/x-range/index.d.ts +14 -0
- package/dist/cjs/hooks/useShapes/x-range/index.js +115 -0
- package/dist/cjs/hooks/useShapes/x-range/prepare-data.d.ts +15 -0
- package/dist/cjs/hooks/useShapes/x-range/prepare-data.js +147 -0
- package/dist/cjs/hooks/useShapes/x-range/types.d.ts +12 -0
- package/dist/cjs/hooks/useShapes/x-range/types.js +1 -0
- package/dist/esm/components/ChartInner/utils/zoom.js +3 -1
- package/dist/esm/components/Tooltip/DefaultTooltipContent/index.js +31 -6
- package/dist/esm/components/Tooltip/DefaultTooltipContent/utils.js +4 -5
- package/dist/esm/core/constants/chart-types.d.ts +1 -0
- package/dist/esm/core/constants/chart-types.js +1 -0
- package/dist/esm/core/constants/defaults/series-options.d.ts +5 -1
- package/dist/esm/core/constants/defaults/series-options.js +13 -0
- package/dist/esm/core/i18n/keysets/en.json +2 -1
- package/dist/esm/core/i18n/keysets/ru.json +2 -1
- package/dist/esm/core/series/prepare-legend.js +2 -2
- package/dist/esm/core/series/prepare-x-range.d.ts +11 -0
- package/dist/esm/core/series/prepare-x-range.js +41 -0
- package/dist/esm/core/series/prepareSeries.js +9 -0
- package/dist/esm/core/series/types.d.ts +18 -2
- package/dist/esm/core/types/chart/area.d.ts +2 -1
- package/dist/esm/core/types/chart/series.d.ts +29 -2
- package/dist/esm/core/types/chart/tooltip.d.ts +6 -1
- package/dist/esm/core/types/chart/x-range.d.ts +59 -0
- package/dist/esm/core/types/chart/x-range.js +1 -0
- package/dist/esm/core/types/chart/zoom.d.ts +1 -1
- package/dist/esm/core/types/index.d.ts +1 -0
- package/dist/esm/core/types/index.js +1 -0
- package/dist/esm/core/utils/axis/x-axis.js +9 -1
- package/dist/esm/core/utils/color.js +6 -0
- package/dist/esm/core/utils/common.js +10 -0
- package/dist/esm/core/utils/get-closest-data.js +19 -0
- package/dist/esm/core/validation/index.js +13 -0
- package/dist/esm/core/zoom/zoom.js +24 -7
- package/dist/esm/hooks/useShapes/area/prepare-data.js +15 -14
- package/dist/esm/hooks/useShapes/bar-x/prepare-data.js +22 -9
- package/dist/esm/hooks/useShapes/index.d.ts +2 -1
- package/dist/esm/hooks/useShapes/index.js +17 -0
- package/dist/esm/hooks/useShapes/x-range/index.d.ts +14 -0
- package/dist/esm/hooks/useShapes/x-range/index.js +115 -0
- package/dist/esm/hooks/useShapes/x-range/prepare-data.d.ts +15 -0
- package/dist/esm/hooks/useShapes/x-range/prepare-data.js +147 -0
- package/dist/esm/hooks/useShapes/x-range/types.d.ts +12 -0
- package/dist/esm/hooks/useShapes/x-range/types.js +1 -0
- package/package.json +1 -1
|
@@ -22,6 +22,7 @@ import { TreemapSeriesShape } from './treemap';
|
|
|
22
22
|
import { prepareTreemapData } from './treemap/prepare-data';
|
|
23
23
|
import { getSeriesClipPathId } from './utils';
|
|
24
24
|
import { WaterfallSeriesShapes, prepareWaterfallData } from './waterfall';
|
|
25
|
+
import { XRangeSeriesShapes, prepareXRangeData } from './x-range';
|
|
25
26
|
import './styles.css';
|
|
26
27
|
function IS_OUTSIDE_BOUNDS() {
|
|
27
28
|
return false;
|
|
@@ -224,6 +225,22 @@ export async function getShapes(args) {
|
|
|
224
225
|
shapesData.splice(index, 0, preparedData);
|
|
225
226
|
break;
|
|
226
227
|
}
|
|
228
|
+
case SERIES_TYPE.XRange: {
|
|
229
|
+
if (xAxis && xScale && (yScale === null || yScale === void 0 ? void 0 : yScale.length)) {
|
|
230
|
+
const preparedData = await prepareXRangeData({
|
|
231
|
+
series: chartSeries,
|
|
232
|
+
xAxis,
|
|
233
|
+
xScale,
|
|
234
|
+
yAxis,
|
|
235
|
+
yScale,
|
|
236
|
+
boundsWidth,
|
|
237
|
+
isRangeSlider,
|
|
238
|
+
});
|
|
239
|
+
shapes[index] = (React.createElement(XRangeSeriesShapes, { key: SERIES_TYPE.XRange, dispatcher: dispatcher, preparedData: preparedData, seriesOptions: seriesOptions, htmlLayout: htmlLayout, clipPathId: clipPathId }));
|
|
240
|
+
shapesData.splice(index, 0, ...preparedData);
|
|
241
|
+
}
|
|
242
|
+
break;
|
|
243
|
+
}
|
|
227
244
|
default: {
|
|
228
245
|
throw new ChartError({
|
|
229
246
|
message: `The display method is not defined for a series with type "${seriesType}"`,
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { Dispatch } from 'd3-dispatch';
|
|
3
|
+
import type { PreparedSeriesOptions } from '../../useSeries/types';
|
|
4
|
+
export { prepareXRangeData } from './prepare-data';
|
|
5
|
+
export type { PreparedXRangeData } from './types';
|
|
6
|
+
import type { PreparedXRangeData } from './types';
|
|
7
|
+
type Args = {
|
|
8
|
+
clipPathId: string;
|
|
9
|
+
htmlLayout: HTMLElement | null;
|
|
10
|
+
preparedData: PreparedXRangeData[];
|
|
11
|
+
seriesOptions: PreparedSeriesOptions;
|
|
12
|
+
dispatcher?: Dispatch<object>;
|
|
13
|
+
};
|
|
14
|
+
export declare function XRangeSeriesShapes(args: Args): React.JSX.Element;
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { color } from 'd3-color';
|
|
3
|
+
import { select } from 'd3-selection';
|
|
4
|
+
import get from 'lodash/get';
|
|
5
|
+
import { getLineDashArray } from '../../../core/utils';
|
|
6
|
+
import { block } from '../../../utils';
|
|
7
|
+
import { HtmlLayer } from '../HtmlLayer';
|
|
8
|
+
import { getRectPath } from '../utils';
|
|
9
|
+
export { prepareXRangeData } from './prepare-data';
|
|
10
|
+
const b = block('x-range');
|
|
11
|
+
export function XRangeSeriesShapes(args) {
|
|
12
|
+
const { dispatcher, preparedData, seriesOptions, htmlLayout, clipPathId } = args;
|
|
13
|
+
const hoveredDataRef = React.useRef(null);
|
|
14
|
+
const ref = React.useRef(null);
|
|
15
|
+
React.useEffect(() => {
|
|
16
|
+
var _a;
|
|
17
|
+
if (!ref.current) {
|
|
18
|
+
return () => { };
|
|
19
|
+
}
|
|
20
|
+
const svgElement = select(ref.current);
|
|
21
|
+
svgElement.selectAll('*').remove();
|
|
22
|
+
const segmentSelection = svgElement
|
|
23
|
+
.selectAll(`path.${b('segment')}`)
|
|
24
|
+
.data(preparedData)
|
|
25
|
+
.join('path')
|
|
26
|
+
.attr('d', (d) => {
|
|
27
|
+
const borderRadius = Math.min(d.height / 2, d.width / 2, d.series.borderRadius);
|
|
28
|
+
return getRectPath({
|
|
29
|
+
x: d.x,
|
|
30
|
+
y: d.y,
|
|
31
|
+
width: d.width,
|
|
32
|
+
height: d.height,
|
|
33
|
+
borderRadius,
|
|
34
|
+
}).toString();
|
|
35
|
+
})
|
|
36
|
+
.attr('class', b('segment'))
|
|
37
|
+
.attr('fill', (d) => d.color)
|
|
38
|
+
.attr('opacity', (d) => { var _a; return (_a = d.data.opacity) !== null && _a !== void 0 ? _a : d.series.opacity; })
|
|
39
|
+
.attr('cursor', (d) => d.series.cursor);
|
|
40
|
+
svgElement
|
|
41
|
+
.selectAll(`path.${b('segment-border')}`)
|
|
42
|
+
.data(preparedData.filter((d) => d.series.borderWidth > 0))
|
|
43
|
+
.join('path')
|
|
44
|
+
.attr('d', (d) => {
|
|
45
|
+
const borderRadius = Math.min(d.height / 2, d.width / 2, d.series.borderRadius);
|
|
46
|
+
return getRectPath({
|
|
47
|
+
x: d.x,
|
|
48
|
+
y: d.y,
|
|
49
|
+
width: d.width,
|
|
50
|
+
height: d.height,
|
|
51
|
+
borderRadius,
|
|
52
|
+
}).toString();
|
|
53
|
+
})
|
|
54
|
+
.attr('class', b('segment-border'))
|
|
55
|
+
.attr('fill', 'none')
|
|
56
|
+
.attr('stroke', (d) => d.series.borderColor)
|
|
57
|
+
.attr('stroke-width', (d) => d.series.borderWidth)
|
|
58
|
+
.attr('stroke-dasharray', (d) => getLineDashArray(d.series.borderDashStyle, d.series.borderWidth))
|
|
59
|
+
.attr('opacity', (d) => { var _a; return (_a = d.data.opacity) !== null && _a !== void 0 ? _a : d.series.opacity; })
|
|
60
|
+
.attr('pointer-events', 'none');
|
|
61
|
+
const svgLabels = preparedData.flatMap((d) => d.svgLabels);
|
|
62
|
+
svgElement
|
|
63
|
+
.selectAll(`text.${b('label')}`)
|
|
64
|
+
.data(svgLabels)
|
|
65
|
+
.join('text')
|
|
66
|
+
.attr('class', b('label'))
|
|
67
|
+
.attr('x', (d) => d.x)
|
|
68
|
+
.attr('y', (d) => d.y)
|
|
69
|
+
.attr('text-anchor', (d) => d.textAnchor)
|
|
70
|
+
.attr('dominant-baseline', 'central')
|
|
71
|
+
.attr('pointer-events', 'none')
|
|
72
|
+
.style('font-size', (d) => d.style.fontSize)
|
|
73
|
+
.style('font-weight', (d) => d.style.fontWeight || null)
|
|
74
|
+
.style('fill', (d) => d.style.fontColor || null)
|
|
75
|
+
.html((d) => d.text);
|
|
76
|
+
const hoverOptions = get(seriesOptions, 'x-range.states.hover');
|
|
77
|
+
const inactiveOptions = get(seriesOptions, 'x-range.states.inactive');
|
|
78
|
+
function handleShapeHover(data) {
|
|
79
|
+
hoveredDataRef.current = data;
|
|
80
|
+
if (hoverOptions === null || hoverOptions === void 0 ? void 0 : hoverOptions.enabled) {
|
|
81
|
+
const hoveredSet = new Set(data === null || data === void 0 ? void 0 : data.map((d) => d.data));
|
|
82
|
+
segmentSelection.attr('fill', (d) => {
|
|
83
|
+
var _a;
|
|
84
|
+
const fillColor = d.color;
|
|
85
|
+
if (hoveredSet.has(d.data)) {
|
|
86
|
+
return (((_a = color(fillColor)) === null || _a === void 0 ? void 0 : _a.brighter(hoverOptions.brightness).toString()) ||
|
|
87
|
+
fillColor);
|
|
88
|
+
}
|
|
89
|
+
return fillColor;
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
if (inactiveOptions === null || inactiveOptions === void 0 ? void 0 : inactiveOptions.enabled) {
|
|
93
|
+
const hoveredSeries = data === null || data === void 0 ? void 0 : data.map((d) => d.series.id);
|
|
94
|
+
segmentSelection.attr('opacity', (d) => {
|
|
95
|
+
var _a, _b;
|
|
96
|
+
if ((hoveredSeries === null || hoveredSeries === void 0 ? void 0 : hoveredSeries.length) && !hoveredSeries.includes(d.series.id)) {
|
|
97
|
+
return inactiveOptions.opacity || null;
|
|
98
|
+
}
|
|
99
|
+
return (_b = (_a = d.data.opacity) !== null && _a !== void 0 ? _a : d.series.opacity) !== null && _b !== void 0 ? _b : null;
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
if (hoveredDataRef.current !== null) {
|
|
104
|
+
handleShapeHover((_a = hoveredDataRef.current) !== null && _a !== void 0 ? _a : undefined);
|
|
105
|
+
}
|
|
106
|
+
dispatcher === null || dispatcher === void 0 ? void 0 : dispatcher.on('hover-shape.x-range', handleShapeHover);
|
|
107
|
+
return () => {
|
|
108
|
+
dispatcher === null || dispatcher === void 0 ? void 0 : dispatcher.on('hover-shape.x-range', null);
|
|
109
|
+
};
|
|
110
|
+
}, [dispatcher, preparedData, seriesOptions]);
|
|
111
|
+
const htmlLayerData = React.useMemo(() => ({ htmlElements: preparedData.flatMap((d) => d.htmlLabels) }), [preparedData]);
|
|
112
|
+
return (React.createElement(React.Fragment, null,
|
|
113
|
+
React.createElement("g", { ref: ref, className: b(), clipPath: `url(#${clipPathId})` }),
|
|
114
|
+
React.createElement(HtmlLayer, { preparedData: htmlLayerData, htmlLayout: htmlLayout })));
|
|
115
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ChartScale } from '../../../core/scales/types';
|
|
2
|
+
import type { PreparedXAxis, PreparedYAxis } from '../../useAxis/types';
|
|
3
|
+
import type { PreparedXRangeSeries } from '../../useSeries/types';
|
|
4
|
+
import type { PreparedXRangeData } from './types';
|
|
5
|
+
type PrepareXRangeDataArgs = {
|
|
6
|
+
series: PreparedXRangeSeries[];
|
|
7
|
+
xAxis: PreparedXAxis;
|
|
8
|
+
xScale: ChartScale;
|
|
9
|
+
yAxis: PreparedYAxis[];
|
|
10
|
+
yScale: (ChartScale | undefined)[];
|
|
11
|
+
boundsWidth?: number;
|
|
12
|
+
isRangeSlider?: boolean;
|
|
13
|
+
};
|
|
14
|
+
export declare function prepareXRangeData(args: PrepareXRangeDataArgs): Promise<PreparedXRangeData[]>;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import get from 'lodash/get';
|
|
2
|
+
import { getDataCategoryValue, getLabelsSize, getTextSizeFn, getTextWithElipsis } from '../../../core/utils';
|
|
3
|
+
import { getFormattedValue } from '../../../core/utils/format';
|
|
4
|
+
import { MIN_BAR_WIDTH } from '../../constants';
|
|
5
|
+
import { getBandSize } from '../../utils/get-band-size';
|
|
6
|
+
const DEFAULT_BAR_PADDING = 0.2;
|
|
7
|
+
export async function prepareXRangeData(args) {
|
|
8
|
+
var _a;
|
|
9
|
+
const { series, xAxis, xScale, yAxis, yScale: [yScale], boundsWidth, isRangeSlider, } = args;
|
|
10
|
+
if (!yScale) {
|
|
11
|
+
return [];
|
|
12
|
+
}
|
|
13
|
+
// Collect unique y-domain values
|
|
14
|
+
const domain = [];
|
|
15
|
+
const seen = new Set();
|
|
16
|
+
const categories = get(yAxis[0], 'categories', []);
|
|
17
|
+
series.forEach((s) => {
|
|
18
|
+
s.data.forEach((d) => {
|
|
19
|
+
const key = yAxis[0].type === 'category'
|
|
20
|
+
? getDataCategoryValue({ axisDirection: 'y', categories, data: d })
|
|
21
|
+
: d.y;
|
|
22
|
+
if (key !== undefined && !seen.has(key)) {
|
|
23
|
+
seen.add(key);
|
|
24
|
+
domain.push(key);
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
const bandSize = getBandSize({ domain, scale: yScale });
|
|
29
|
+
const barSize = Math.max(MIN_BAR_WIDTH, bandSize * (1 - DEFAULT_BAR_PADDING));
|
|
30
|
+
const result = [];
|
|
31
|
+
series.forEach((s) => {
|
|
32
|
+
s.data.forEach((d) => {
|
|
33
|
+
let center;
|
|
34
|
+
if (yAxis[0].type === 'category') {
|
|
35
|
+
const bandScale = yScale;
|
|
36
|
+
const yCategory = getDataCategoryValue({ axisDirection: 'y', categories, data: d });
|
|
37
|
+
if (!bandScale.domain().includes(yCategory)) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
center = (bandScale(yCategory) || 0) + bandSize / 2;
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
const linearScale = yScale;
|
|
44
|
+
if (d.y === undefined) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
center = linearScale(Number(d.y));
|
|
48
|
+
}
|
|
49
|
+
let xStart;
|
|
50
|
+
let xEnd;
|
|
51
|
+
if (xAxis.type === 'category') {
|
|
52
|
+
// x-range on a category x-axis is unusual but supported
|
|
53
|
+
const xBandScale = xScale;
|
|
54
|
+
const xCategories = get(xAxis, 'categories', []);
|
|
55
|
+
const startCategory = getDataCategoryValue({
|
|
56
|
+
axisDirection: 'x',
|
|
57
|
+
categories: xCategories,
|
|
58
|
+
data: { x: d.x0 },
|
|
59
|
+
});
|
|
60
|
+
const endCategory = getDataCategoryValue({
|
|
61
|
+
axisDirection: 'x',
|
|
62
|
+
categories: xCategories,
|
|
63
|
+
data: { x: d.x1 },
|
|
64
|
+
});
|
|
65
|
+
xStart = xBandScale(startCategory) || 0;
|
|
66
|
+
xEnd = (xBandScale(endCategory) || 0) + xBandScale.bandwidth();
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
const linearScale = xScale;
|
|
70
|
+
xStart = linearScale(Number(d.x0));
|
|
71
|
+
xEnd = linearScale(Number(d.x1));
|
|
72
|
+
}
|
|
73
|
+
const width = xEnd - xStart;
|
|
74
|
+
if (width <= 0) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
result.push({
|
|
78
|
+
x: xStart,
|
|
79
|
+
y: center - barSize / 2,
|
|
80
|
+
width,
|
|
81
|
+
height: barSize,
|
|
82
|
+
color: d.color || s.color,
|
|
83
|
+
data: d,
|
|
84
|
+
series: s,
|
|
85
|
+
htmlLabels: [],
|
|
86
|
+
svgLabels: [],
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
const textSizeFnCache = new Map();
|
|
91
|
+
for (let i = 0; i < result.length; i++) {
|
|
92
|
+
const item = result[i];
|
|
93
|
+
const { dataLabels } = item.series;
|
|
94
|
+
if (!dataLabels.enabled || item.data.label === null || isRangeSlider) {
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
const content = getFormattedValue(Object.assign({ value: item.data.label }, dataLabels));
|
|
98
|
+
const visibleStart = Math.max(0, item.x);
|
|
99
|
+
const visibleEnd = boundsWidth === undefined
|
|
100
|
+
? item.x + item.width
|
|
101
|
+
: Math.min(boundsWidth, item.x + item.width);
|
|
102
|
+
const visibleWidth = visibleEnd - visibleStart;
|
|
103
|
+
const visibleCenterX = visibleStart + visibleWidth / 2;
|
|
104
|
+
if (dataLabels.html) {
|
|
105
|
+
const { maxHeight: height, maxWidth: width } = await getLabelsSize({
|
|
106
|
+
labels: [content],
|
|
107
|
+
style: dataLabels.style,
|
|
108
|
+
html: true,
|
|
109
|
+
});
|
|
110
|
+
const htmlItem = {
|
|
111
|
+
content,
|
|
112
|
+
size: { width, height },
|
|
113
|
+
style: dataLabels.style,
|
|
114
|
+
x: visibleCenterX - width / 2,
|
|
115
|
+
y: item.y + item.height / 2 - height / 2,
|
|
116
|
+
};
|
|
117
|
+
item.htmlLabels.push(htmlItem);
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
if (!textSizeFnCache.has(dataLabels.style)) {
|
|
121
|
+
textSizeFnCache.set(dataLabels.style, getTextSizeFn({ style: dataLabels.style }));
|
|
122
|
+
}
|
|
123
|
+
const getTextSize = (_a = textSizeFnCache.get(dataLabels.style)) !== null && _a !== void 0 ? _a : getTextSizeFn({ style: dataLabels.style });
|
|
124
|
+
const availableWidth = Math.max(0, visibleWidth - 2 * dataLabels.padding);
|
|
125
|
+
const text = await getTextWithElipsis({
|
|
126
|
+
text: content,
|
|
127
|
+
getTextWidth: (s) => getTextSize(s).then((r) => r.width),
|
|
128
|
+
maxWidth: availableWidth,
|
|
129
|
+
});
|
|
130
|
+
if (!text) {
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
const { width, height, hangingOffset } = await getTextSize(text);
|
|
134
|
+
const svgItem = {
|
|
135
|
+
text,
|
|
136
|
+
size: { width, height, hangingOffset },
|
|
137
|
+
style: dataLabels.style,
|
|
138
|
+
textAnchor: 'middle',
|
|
139
|
+
x: visibleCenterX,
|
|
140
|
+
y: item.y + item.height / 2,
|
|
141
|
+
series: item.series,
|
|
142
|
+
};
|
|
143
|
+
item.svgLabels.push(svgItem);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return result;
|
|
147
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { HtmlItem, LabelData, TooltipDataChunkXRange } from '../../../types';
|
|
2
|
+
import type { PreparedXRangeSeries } from '../../useSeries/types';
|
|
3
|
+
export type PreparedXRangeData = Omit<TooltipDataChunkXRange, 'series'> & {
|
|
4
|
+
x: number;
|
|
5
|
+
y: number;
|
|
6
|
+
width: number;
|
|
7
|
+
height: number;
|
|
8
|
+
color: string;
|
|
9
|
+
series: PreparedXRangeSeries;
|
|
10
|
+
svgLabels: LabelData[];
|
|
11
|
+
htmlLabels: HtmlItem[];
|
|
12
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|