@gravity-ui/charts 1.43.0 → 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.
Files changed (125) hide show
  1. package/dist/cjs/components/ChartInner/index.js +3 -3
  2. package/dist/cjs/components/ChartInner/useChartInnerHandlers.d.ts +3 -3
  3. package/dist/cjs/components/ChartInner/useChartInnerHandlers.js +10 -12
  4. package/dist/cjs/components/ChartInner/useChartInnerProps.js +8 -4
  5. package/dist/cjs/components/ChartInner/utils/title.d.ts +3 -2
  6. package/dist/cjs/components/ChartInner/utils/title.js +19 -14
  7. package/dist/cjs/components/ChartInner/utils/zoom.js +3 -1
  8. package/dist/cjs/components/Title/index.d.ts +1 -3
  9. package/dist/cjs/components/Title/index.js +2 -2
  10. package/dist/cjs/components/Tooltip/DefaultTooltipContent/index.js +31 -6
  11. package/dist/cjs/components/Tooltip/DefaultTooltipContent/utils.js +4 -5
  12. package/dist/cjs/core/constants/chart-types.d.ts +1 -0
  13. package/dist/cjs/core/constants/chart-types.js +1 -0
  14. package/dist/cjs/core/constants/defaults/series-options.d.ts +5 -1
  15. package/dist/cjs/core/constants/defaults/series-options.js +13 -0
  16. package/dist/cjs/core/constants/index.d.ts +0 -1
  17. package/dist/cjs/core/constants/index.js +0 -1
  18. package/dist/cjs/core/i18n/keysets/en.json +2 -1
  19. package/dist/cjs/core/i18n/keysets/ru.json +2 -1
  20. package/dist/cjs/core/series/prepare-legend.js +2 -2
  21. package/dist/cjs/core/series/prepare-x-range.d.ts +11 -0
  22. package/dist/cjs/core/series/prepare-x-range.js +41 -0
  23. package/dist/cjs/core/series/prepareSeries.js +9 -0
  24. package/dist/cjs/core/series/types.d.ts +18 -2
  25. package/dist/cjs/core/types/chart/area.d.ts +2 -1
  26. package/dist/cjs/core/types/chart/series.d.ts +29 -2
  27. package/dist/cjs/core/types/chart/tooltip.d.ts +6 -1
  28. package/dist/cjs/core/types/chart/x-range.d.ts +59 -0
  29. package/dist/cjs/core/types/chart/x-range.js +1 -0
  30. package/dist/cjs/core/types/chart/zoom.d.ts +1 -1
  31. package/dist/cjs/core/types/index.d.ts +1 -0
  32. package/dist/cjs/core/types/index.js +1 -0
  33. package/dist/cjs/core/utils/axis/x-axis.js +9 -1
  34. package/dist/cjs/core/utils/color.js +6 -0
  35. package/dist/cjs/core/utils/common.js +10 -0
  36. package/dist/cjs/core/utils/get-closest-data.js +19 -0
  37. package/dist/cjs/core/utils/labels.d.ts +1 -1
  38. package/dist/cjs/core/utils/labels.js +3 -2
  39. package/dist/cjs/core/validation/index.js +13 -0
  40. package/dist/cjs/core/zoom/zoom.js +24 -7
  41. package/dist/cjs/hooks/useSeries/index.js +8 -2
  42. package/dist/cjs/hooks/useShapes/area/index.js +2 -2
  43. package/dist/cjs/hooks/useShapes/area/prepare-data.js +19 -18
  44. package/dist/cjs/hooks/useShapes/area/types.d.ts +2 -2
  45. package/dist/cjs/hooks/useShapes/bar-x/index.js +2 -2
  46. package/dist/cjs/hooks/useShapes/bar-x/prepare-data.js +37 -21
  47. package/dist/cjs/hooks/useShapes/bar-x/types.d.ts +2 -2
  48. package/dist/cjs/hooks/useShapes/index.d.ts +2 -1
  49. package/dist/cjs/hooks/useShapes/index.js +35 -5
  50. package/dist/cjs/hooks/useShapes/line/index.js +7 -16
  51. package/dist/cjs/hooks/useShapes/line/prepare-data.d.ts +2 -0
  52. package/dist/cjs/hooks/useShapes/line/prepare-data.js +11 -7
  53. package/dist/cjs/hooks/useShapes/line/types.d.ts +2 -2
  54. package/dist/cjs/hooks/useShapes/x-range/index.d.ts +14 -0
  55. package/dist/cjs/hooks/useShapes/x-range/index.js +115 -0
  56. package/dist/cjs/hooks/useShapes/x-range/prepare-data.d.ts +15 -0
  57. package/dist/cjs/hooks/useShapes/x-range/prepare-data.js +147 -0
  58. package/dist/cjs/hooks/useShapes/x-range/types.d.ts +12 -0
  59. package/dist/cjs/hooks/useShapes/x-range/types.js +1 -0
  60. package/dist/cjs/types/chart-ui.d.ts +4 -0
  61. package/dist/esm/components/ChartInner/index.js +3 -3
  62. package/dist/esm/components/ChartInner/useChartInnerHandlers.d.ts +3 -3
  63. package/dist/esm/components/ChartInner/useChartInnerHandlers.js +10 -12
  64. package/dist/esm/components/ChartInner/useChartInnerProps.js +8 -4
  65. package/dist/esm/components/ChartInner/utils/title.d.ts +3 -2
  66. package/dist/esm/components/ChartInner/utils/title.js +19 -14
  67. package/dist/esm/components/ChartInner/utils/zoom.js +3 -1
  68. package/dist/esm/components/Title/index.d.ts +1 -3
  69. package/dist/esm/components/Title/index.js +2 -2
  70. package/dist/esm/components/Tooltip/DefaultTooltipContent/index.js +31 -6
  71. package/dist/esm/components/Tooltip/DefaultTooltipContent/utils.js +4 -5
  72. package/dist/esm/core/constants/chart-types.d.ts +1 -0
  73. package/dist/esm/core/constants/chart-types.js +1 -0
  74. package/dist/esm/core/constants/defaults/series-options.d.ts +5 -1
  75. package/dist/esm/core/constants/defaults/series-options.js +13 -0
  76. package/dist/esm/core/constants/index.d.ts +0 -1
  77. package/dist/esm/core/constants/index.js +0 -1
  78. package/dist/esm/core/i18n/keysets/en.json +2 -1
  79. package/dist/esm/core/i18n/keysets/ru.json +2 -1
  80. package/dist/esm/core/series/prepare-legend.js +2 -2
  81. package/dist/esm/core/series/prepare-x-range.d.ts +11 -0
  82. package/dist/esm/core/series/prepare-x-range.js +41 -0
  83. package/dist/esm/core/series/prepareSeries.js +9 -0
  84. package/dist/esm/core/series/types.d.ts +18 -2
  85. package/dist/esm/core/types/chart/area.d.ts +2 -1
  86. package/dist/esm/core/types/chart/series.d.ts +29 -2
  87. package/dist/esm/core/types/chart/tooltip.d.ts +6 -1
  88. package/dist/esm/core/types/chart/x-range.d.ts +59 -0
  89. package/dist/esm/core/types/chart/x-range.js +1 -0
  90. package/dist/esm/core/types/chart/zoom.d.ts +1 -1
  91. package/dist/esm/core/types/index.d.ts +1 -0
  92. package/dist/esm/core/types/index.js +1 -0
  93. package/dist/esm/core/utils/axis/x-axis.js +9 -1
  94. package/dist/esm/core/utils/color.js +6 -0
  95. package/dist/esm/core/utils/common.js +10 -0
  96. package/dist/esm/core/utils/get-closest-data.js +19 -0
  97. package/dist/esm/core/utils/labels.d.ts +1 -1
  98. package/dist/esm/core/utils/labels.js +3 -2
  99. package/dist/esm/core/validation/index.js +13 -0
  100. package/dist/esm/core/zoom/zoom.js +24 -7
  101. package/dist/esm/hooks/useSeries/index.js +8 -2
  102. package/dist/esm/hooks/useShapes/area/index.js +2 -2
  103. package/dist/esm/hooks/useShapes/area/prepare-data.js +19 -18
  104. package/dist/esm/hooks/useShapes/area/types.d.ts +2 -2
  105. package/dist/esm/hooks/useShapes/bar-x/index.js +2 -2
  106. package/dist/esm/hooks/useShapes/bar-x/prepare-data.js +37 -21
  107. package/dist/esm/hooks/useShapes/bar-x/types.d.ts +2 -2
  108. package/dist/esm/hooks/useShapes/index.d.ts +2 -1
  109. package/dist/esm/hooks/useShapes/index.js +35 -5
  110. package/dist/esm/hooks/useShapes/line/index.js +7 -16
  111. package/dist/esm/hooks/useShapes/line/prepare-data.d.ts +2 -0
  112. package/dist/esm/hooks/useShapes/line/prepare-data.js +11 -7
  113. package/dist/esm/hooks/useShapes/line/types.d.ts +2 -2
  114. package/dist/esm/hooks/useShapes/x-range/index.d.ts +14 -0
  115. package/dist/esm/hooks/useShapes/x-range/index.js +115 -0
  116. package/dist/esm/hooks/useShapes/x-range/prepare-data.d.ts +15 -0
  117. package/dist/esm/hooks/useShapes/x-range/prepare-data.js +147 -0
  118. package/dist/esm/hooks/useShapes/x-range/types.d.ts +12 -0
  119. package/dist/esm/hooks/useShapes/x-range/types.js +1 -0
  120. package/dist/esm/types/chart-ui.d.ts +4 -0
  121. package/package.json +1 -1
  122. package/dist/cjs/core/constants/misc.d.ts +0 -1
  123. package/dist/cjs/core/constants/misc.js +0 -7
  124. package/dist/esm/core/constants/misc.d.ts +0 -1
  125. package/dist/esm/core/constants/misc.js +0 -7
@@ -1,5 +1,6 @@
1
1
  import type { PreparedSplit } from '../../../core/layout/split-types';
2
2
  import type { ChartScale } from '../../../core/scales/types';
3
+ import type { ShapeDataWithLabels } from '../../../types';
3
4
  import type { PreparedXAxis, PreparedYAxis } from '../../useAxis/types';
4
5
  import type { PreparedLineSeries } from '../../useSeries/types';
5
6
  import type { PreparedLineData } from './types';
@@ -12,4 +13,5 @@ export declare const prepareLineData: (args: {
12
13
  split: PreparedSplit;
13
14
  isOutsideBounds: (x: number, y: number) => boolean;
14
15
  isRangeSlider?: boolean;
16
+ otherLayers: ShapeDataWithLabels[];
15
17
  }) => Promise<PreparedLineData[]>;
@@ -1,4 +1,4 @@
1
- import { getLabelsSize, getTextSizeFn } from '../../../core/utils';
1
+ import { filterOverlappingLabels, getLabelsSize, getTextSizeFn } from '../../../core/utils';
2
2
  import { getFormattedValue } from '../../../core/utils/format';
3
3
  import { getXValue, getYValue } from '../utils';
4
4
  async function getHtmlLabel(point, series, xMax) {
@@ -16,7 +16,7 @@ async function getHtmlLabel(point, series, xMax) {
16
16
  }
17
17
  export const prepareLineData = async (args) => {
18
18
  var _a, _b, _c, _d;
19
- const { series, xAxis, yAxis, xScale, yScale, split, isOutsideBounds, isRangeSlider } = args;
19
+ const { series, xAxis, yAxis, xScale, yScale, split, isOutsideBounds, isRangeSlider, otherLayers, } = args;
20
20
  const [_xMin, xRangeMax] = xScale.range();
21
21
  const xMax = xRangeMax;
22
22
  const acc = [];
@@ -44,8 +44,8 @@ export const prepareLineData = async (args) => {
44
44
  series: s,
45
45
  };
46
46
  });
47
- const htmlElements = [];
48
- const labels = [];
47
+ let htmlElements = [];
48
+ let svgLabels = [];
49
49
  if (s.dataLabels.enabled && !isRangeSlider) {
50
50
  if (s.dataLabels.html) {
51
51
  const list = await Promise.all(points.reduce((result, p) => {
@@ -83,11 +83,15 @@ export const prepareLineData = async (args) => {
83
83
  series: s,
84
84
  active: true,
85
85
  };
86
- labels.push(labelData);
86
+ svgLabels.push(labelData);
87
87
  }
88
88
  }
89
89
  }
90
90
  }
91
+ if (!s.dataLabels.allowOverlap) {
92
+ svgLabels = filterOverlappingLabels(svgLabels, otherLayers.map((l) => l.svgLabels).flat());
93
+ htmlElements = filterOverlappingLabels(htmlElements, otherLayers.map((l) => l.htmlLabels).flat());
94
+ }
91
95
  let markers = [];
92
96
  const hasPerPointNormalMarkers = s.data.some((d) => { var _a, _b, _c; return (_c = (_b = (_a = d.marker) === null || _a === void 0 ? void 0 : _a.states) === null || _b === void 0 ? void 0 : _b.normal) === null || _c === void 0 ? void 0 : _c.enabled; });
93
97
  if (s.marker.states.normal.enabled || hasPerPointNormalMarkers) {
@@ -111,12 +115,12 @@ export const prepareLineData = async (args) => {
111
115
  const result = {
112
116
  points,
113
117
  markers,
114
- labels,
118
+ svgLabels: svgLabels,
115
119
  series: s,
116
120
  hovered: false,
117
121
  active: true,
118
122
  id: s.id,
119
- htmlElements,
123
+ htmlLabels: htmlElements,
120
124
  color: s.color,
121
125
  lineWidth: (_c = (isRangeSlider ? s.rangeSlider.lineWidth : undefined)) !== null && _c !== void 0 ? _c : s.lineWidth,
122
126
  dashStyle: s.dashStyle,
@@ -25,8 +25,8 @@ export type PreparedLineData = {
25
25
  series: PreparedLineSeries;
26
26
  hovered: boolean;
27
27
  active: boolean;
28
- labels: LabelData[];
29
- htmlElements: HtmlItem[];
28
+ svgLabels: LabelData[];
29
+ htmlLabels: HtmlItem[];
30
30
  color: string;
31
31
  dashStyle: DashStyle;
32
32
  linecap: LineCap;
@@ -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 {};
@@ -25,6 +25,10 @@ export interface HtmlItem {
25
25
  };
26
26
  style?: BaseTextStyle & React.CSSProperties;
27
27
  }
28
+ export interface ShapeDataWithLabels {
29
+ svgLabels: LabelData[];
30
+ htmlLabels: HtmlItem[];
31
+ }
28
32
  export interface ShapeDataWithHtmlItems {
29
33
  htmlElements: HtmlItem[];
30
34
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gravity-ui/charts",
3
- "version": "1.43.0",
3
+ "version": "1.44.0",
4
4
  "description": "A flexible JavaScript library for data visualization and chart rendering using React",
5
5
  "license": "MIT",
6
6
  "main": "dist/cjs/index.js",
@@ -1 +0,0 @@
1
- export declare const IS_TOUCH_ENABLED: boolean;
@@ -1,7 +0,0 @@
1
- function isTouchEnabled() {
2
- if (typeof window !== 'object') {
3
- return false;
4
- }
5
- return 'ontouchstart' in window || navigator.maxTouchPoints > 0;
6
- }
7
- export const IS_TOUCH_ENABLED = isTouchEnabled();
@@ -1 +0,0 @@
1
- export declare const IS_TOUCH_ENABLED: boolean;
@@ -1,7 +0,0 @@
1
- function isTouchEnabled() {
2
- if (typeof window !== 'object') {
3
- return false;
4
- }
5
- return 'ontouchstart' in window || navigator.maxTouchPoints > 0;
6
- }
7
- export const IS_TOUCH_ENABLED = isTouchEnabled();