@gravity-ui/charts 1.26.0 → 1.27.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 (113) hide show
  1. package/dist/cjs/components/AxisX/AxisX.d.ts +5 -20
  2. package/dist/cjs/components/AxisX/AxisX.js +167 -212
  3. package/dist/cjs/components/AxisX/prepare-axis-data.d.ts +10 -0
  4. package/dist/cjs/components/AxisX/prepare-axis-data.js +267 -0
  5. package/dist/cjs/components/AxisX/styles.css +7 -10
  6. package/dist/cjs/components/AxisX/types.d.ts +85 -0
  7. package/dist/cjs/components/AxisX/types.js +1 -0
  8. package/dist/cjs/components/AxisY/AxisY.js +9 -3
  9. package/dist/cjs/components/AxisY/prepare-axis-data.d.ts +1 -1
  10. package/dist/cjs/components/AxisY/prepare-axis-data.js +17 -81
  11. package/dist/cjs/components/AxisY/prepare-axis-title.d.ts +16 -0
  12. package/dist/cjs/components/AxisY/prepare-axis-title.js +149 -0
  13. package/dist/cjs/components/AxisY/types.d.ts +16 -4
  14. package/dist/cjs/components/AxisY/utils.js +1 -8
  15. package/dist/cjs/components/ChartInner/index.js +62 -50
  16. package/dist/cjs/components/ChartInner/useChartInnerProps.d.ts +7 -7
  17. package/dist/cjs/components/ChartInner/useChartInnerProps.js +15 -20
  18. package/dist/cjs/components/ChartInner/useChartInnerState.d.ts +3 -2
  19. package/dist/cjs/components/ChartInner/useChartInnerState.js +23 -4
  20. package/dist/cjs/components/Legend/index.js +21 -14
  21. package/dist/cjs/components/RangeSlider/index.d.ts +5 -3
  22. package/dist/cjs/components/RangeSlider/index.js +36 -4
  23. package/dist/cjs/components/Title/index.js +2 -2
  24. package/dist/cjs/components/utils.d.ts +9 -0
  25. package/dist/cjs/components/utils.js +34 -0
  26. package/dist/cjs/constants/defaults/axis.js +1 -1
  27. package/dist/cjs/hooks/index.d.ts +0 -1
  28. package/dist/cjs/hooks/index.js +0 -1
  29. package/dist/cjs/hooks/useAxis/index.js +10 -0
  30. package/dist/cjs/hooks/useAxis/types.d.ts +3 -0
  31. package/dist/cjs/hooks/useAxis/x-axis.d.ts +2 -1
  32. package/dist/cjs/hooks/useAxis/x-axis.js +36 -28
  33. package/dist/cjs/hooks/useAxis/y-axis.js +38 -11
  34. package/dist/cjs/hooks/useAxisScales/index.d.ts +4 -1
  35. package/dist/cjs/hooks/useAxisScales/index.js +8 -7
  36. package/dist/cjs/hooks/useAxisScales/utils.d.ts +6 -0
  37. package/dist/cjs/hooks/useAxisScales/utils.js +17 -0
  38. package/dist/cjs/hooks/useChartDimensions/utils.js +7 -1
  39. package/dist/cjs/hooks/useNormalizedOriginalData/index.d.ts +1 -7
  40. package/dist/cjs/hooks/useRangeSlider/index.js +1 -2
  41. package/dist/cjs/hooks/useRangeSlider/types.d.ts +1 -3
  42. package/dist/cjs/hooks/useZoom/index.d.ts +1 -0
  43. package/dist/cjs/hooks/useZoom/index.js +12 -2
  44. package/dist/cjs/types/chart/axis.d.ts +45 -17
  45. package/dist/cjs/types/chart/title.d.ts +3 -0
  46. package/dist/{esm/utils/chart/axis.d.ts → cjs/utils/chart/axis/common.d.ts} +4 -16
  47. package/dist/{esm/utils/chart/axis.js → cjs/utils/chart/axis/common.js} +7 -40
  48. package/dist/cjs/utils/chart/axis/x-axis.d.ts +12 -0
  49. package/dist/cjs/utils/chart/axis/x-axis.js +78 -0
  50. package/dist/cjs/utils/chart/axis-generators/bottom.js +1 -1
  51. package/dist/cjs/utils/chart/index.d.ts +1 -1
  52. package/dist/cjs/utils/chart/index.js +1 -1
  53. package/dist/cjs/utils/chart/text.d.ts +0 -6
  54. package/dist/cjs/utils/chart/text.js +7 -19
  55. package/dist/esm/components/AxisX/AxisX.d.ts +5 -20
  56. package/dist/esm/components/AxisX/AxisX.js +167 -212
  57. package/dist/esm/components/AxisX/prepare-axis-data.d.ts +10 -0
  58. package/dist/esm/components/AxisX/prepare-axis-data.js +267 -0
  59. package/dist/esm/components/AxisX/styles.css +7 -10
  60. package/dist/esm/components/AxisX/types.d.ts +85 -0
  61. package/dist/esm/components/AxisX/types.js +1 -0
  62. package/dist/esm/components/AxisY/AxisY.js +9 -3
  63. package/dist/esm/components/AxisY/prepare-axis-data.d.ts +1 -1
  64. package/dist/esm/components/AxisY/prepare-axis-data.js +17 -81
  65. package/dist/esm/components/AxisY/prepare-axis-title.d.ts +16 -0
  66. package/dist/esm/components/AxisY/prepare-axis-title.js +149 -0
  67. package/dist/esm/components/AxisY/types.d.ts +16 -4
  68. package/dist/esm/components/AxisY/utils.js +1 -8
  69. package/dist/esm/components/ChartInner/index.js +62 -50
  70. package/dist/esm/components/ChartInner/useChartInnerProps.d.ts +7 -7
  71. package/dist/esm/components/ChartInner/useChartInnerProps.js +15 -20
  72. package/dist/esm/components/ChartInner/useChartInnerState.d.ts +3 -2
  73. package/dist/esm/components/ChartInner/useChartInnerState.js +23 -4
  74. package/dist/esm/components/Legend/index.js +21 -14
  75. package/dist/esm/components/RangeSlider/index.d.ts +5 -3
  76. package/dist/esm/components/RangeSlider/index.js +36 -4
  77. package/dist/esm/components/Title/index.js +2 -2
  78. package/dist/esm/components/utils.d.ts +9 -0
  79. package/dist/esm/components/utils.js +34 -0
  80. package/dist/esm/constants/defaults/axis.js +1 -1
  81. package/dist/esm/hooks/index.d.ts +0 -1
  82. package/dist/esm/hooks/index.js +0 -1
  83. package/dist/esm/hooks/useAxis/index.js +10 -0
  84. package/dist/esm/hooks/useAxis/types.d.ts +3 -0
  85. package/dist/esm/hooks/useAxis/x-axis.d.ts +2 -1
  86. package/dist/esm/hooks/useAxis/x-axis.js +36 -28
  87. package/dist/esm/hooks/useAxis/y-axis.js +38 -11
  88. package/dist/esm/hooks/useAxisScales/index.d.ts +4 -1
  89. package/dist/esm/hooks/useAxisScales/index.js +8 -7
  90. package/dist/esm/hooks/useAxisScales/utils.d.ts +6 -0
  91. package/dist/esm/hooks/useAxisScales/utils.js +17 -0
  92. package/dist/esm/hooks/useChartDimensions/utils.js +7 -1
  93. package/dist/esm/hooks/useNormalizedOriginalData/index.d.ts +1 -7
  94. package/dist/esm/hooks/useRangeSlider/index.js +1 -2
  95. package/dist/esm/hooks/useRangeSlider/types.d.ts +1 -3
  96. package/dist/esm/hooks/useZoom/index.d.ts +1 -0
  97. package/dist/esm/hooks/useZoom/index.js +12 -2
  98. package/dist/esm/types/chart/axis.d.ts +45 -17
  99. package/dist/esm/types/chart/title.d.ts +3 -0
  100. package/dist/{cjs/utils/chart/axis.d.ts → esm/utils/chart/axis/common.d.ts} +4 -16
  101. package/dist/{cjs/utils/chart/axis.js → esm/utils/chart/axis/common.js} +7 -40
  102. package/dist/esm/utils/chart/axis/x-axis.d.ts +12 -0
  103. package/dist/esm/utils/chart/axis/x-axis.js +78 -0
  104. package/dist/esm/utils/chart/axis-generators/bottom.js +1 -1
  105. package/dist/esm/utils/chart/index.d.ts +1 -1
  106. package/dist/esm/utils/chart/index.js +1 -1
  107. package/dist/esm/utils/chart/text.d.ts +0 -6
  108. package/dist/esm/utils/chart/text.js +7 -19
  109. package/package.json +1 -1
  110. package/dist/cjs/hooks/useChartOptions/index.d.ts +0 -16
  111. package/dist/cjs/hooks/useChartOptions/index.js +0 -21
  112. package/dist/esm/hooks/useChartOptions/index.d.ts +0 -16
  113. package/dist/esm/hooks/useChartOptions/index.js +0 -21
@@ -0,0 +1,267 @@
1
+ import { getUniqId } from '@gravity-ui/uikit';
2
+ import { calculateSin, formatAxisTickLabel, getBandsPosition, getLabelsSize, getMinSpaceBetween, getTextSizeFn, getTextWithElipsis, wrapText, } from '../../utils';
3
+ import { getXAxisTickValues } from '../../utils/chart/axis/x-axis';
4
+ async function getSvgAxisLabel({ getTextSize, text, axis, top, left, labelMaxWidth, axisWidth, boundsOffsetLeft, boundsOffsetRight, }) {
5
+ var _a;
6
+ const rotation = axis.labels.rotation;
7
+ const content = [];
8
+ let rowText = text;
9
+ let textSize = await getTextSize(text);
10
+ const a = (360 + rotation) % 90;
11
+ const textMaxWidth = a === 0
12
+ ? Math.min(labelMaxWidth,
13
+ // rightmost label
14
+ labelMaxWidth / 2 + axisWidth + boundsOffsetRight - left)
15
+ : Math.min(axis.labels.height / calculateSin(a) - textSize.height * calculateSin(90 - a),
16
+ // leftmostLabel
17
+ (boundsOffsetLeft + left) / calculateSin(a));
18
+ if (textSize.width > textMaxWidth) {
19
+ rowText = await getTextWithElipsis({
20
+ text: rowText,
21
+ getTextWidth: async (str) => (await getTextSize(str)).width,
22
+ maxWidth: textMaxWidth,
23
+ });
24
+ textSize = await getTextSize(rowText);
25
+ }
26
+ const actualTextWidth = a
27
+ ? textSize.width * calculateSin(90 - a) + textSize.height * calculateSin(a)
28
+ : textSize.width;
29
+ const xOffset = a ? (textSize.width * calculateSin(90 - a)) / 2 : 0;
30
+ const yOffset = textSize.width * calculateSin(a);
31
+ content.push({
32
+ text: rowText,
33
+ x: 0,
34
+ y: 0,
35
+ size: textSize,
36
+ });
37
+ const x = Math.max(-boundsOffsetLeft, Math.min(left - actualTextWidth / 2 - xOffset, axisWidth - actualTextWidth));
38
+ const y = top + yOffset + axis.labels.margin;
39
+ const svgLabel = {
40
+ title: ((_a = content[0]) === null || _a === void 0 ? void 0 : _a.text) === text ? undefined : text,
41
+ content,
42
+ style: axis.labels.style,
43
+ size: textSize,
44
+ x,
45
+ y,
46
+ angle: rotation,
47
+ };
48
+ return svgLabel;
49
+ }
50
+ // eslint-disable-next-line complexity
51
+ export async function prepareXAxisData({ axis, scale, boundsWidth, boundsOffsetLeft, boundsOffsetRight, height, }) {
52
+ var _a, _b, _c, _d;
53
+ const axisHeight = height;
54
+ const axisWidth = boundsWidth;
55
+ let domain = null;
56
+ if (axis.visible) {
57
+ domain = {
58
+ start: [0, height],
59
+ end: [axisWidth, height],
60
+ lineColor: (_a = axis.lineColor) !== null && _a !== void 0 ? _a : '',
61
+ };
62
+ }
63
+ const ticks = [];
64
+ const getTextSize = getTextSizeFn({ style: axis.labels.style });
65
+ const labelLineHeight = (await getTextSize('Tmp')).height;
66
+ const values = getXAxisTickValues({ scale, axis, labelLineHeight });
67
+ const tickStep = getMinSpaceBetween(values, (d) => Number(d.value));
68
+ const labelMaxWidth = values.length > 1
69
+ ? Math.abs(values[0].x - values[1].x) - axis.labels.padding * 2
70
+ : axisWidth;
71
+ for (let i = 0; i < values.length; i++) {
72
+ const tickValue = values[i];
73
+ let svgLabel = null;
74
+ let htmlLabel = null;
75
+ if (axis.labels.enabled) {
76
+ if (axis.labels.html) {
77
+ const content = String(tickValue.value);
78
+ const labelSize = await getLabelsSize({
79
+ labels: [content],
80
+ html: true,
81
+ style: axis.labels.style,
82
+ });
83
+ const size = { width: labelSize.maxWidth, height: labelSize.maxHeight };
84
+ htmlLabel = {
85
+ content,
86
+ x: tickValue.x - size.width / 2,
87
+ y: height + axis.labels.margin,
88
+ size,
89
+ style: axis.labels.style,
90
+ };
91
+ }
92
+ else {
93
+ const text = formatAxisTickLabel({ value: tickValue.value, axis, step: tickStep });
94
+ svgLabel = await getSvgAxisLabel({
95
+ getTextSize,
96
+ text,
97
+ axis,
98
+ top: height,
99
+ left: tickValue.x,
100
+ labelMaxWidth,
101
+ axisWidth,
102
+ boundsOffsetLeft,
103
+ boundsOffsetRight,
104
+ });
105
+ }
106
+ }
107
+ const tickLine = axis.grid.enabled
108
+ ? {
109
+ points: [
110
+ [tickValue.x, 0],
111
+ [tickValue.x, height],
112
+ ],
113
+ }
114
+ : null;
115
+ ticks.push({
116
+ line: tickLine,
117
+ svgLabel,
118
+ htmlLabel,
119
+ });
120
+ }
121
+ let title = null;
122
+ if (axis.title.text) {
123
+ const getTitleTextSize = getTextSizeFn({ style: axis.title.style });
124
+ const titleContent = [];
125
+ const titleMaxWidth = axisWidth;
126
+ if (axis.title.maxRowCount > 1) {
127
+ const titleTextRows = await wrapText({
128
+ text: axis.title.text,
129
+ style: axis.title.style,
130
+ width: titleMaxWidth,
131
+ getTextSize: getTitleTextSize,
132
+ });
133
+ for (let i = 0; i < axis.title.maxRowCount && i < titleTextRows.length; i++) {
134
+ const textRow = titleTextRows[i];
135
+ const textRowContent = textRow.text.trim();
136
+ const textRowSize = await getTitleTextSize(textRowContent);
137
+ titleContent.push({
138
+ text: textRowContent,
139
+ x: 0,
140
+ y: textRow.y,
141
+ size: textRowSize,
142
+ });
143
+ }
144
+ }
145
+ else {
146
+ const text = await getTextWithElipsis({
147
+ text: axis.title.text,
148
+ maxWidth: titleMaxWidth,
149
+ getTextWidth: async (s) => (await getTitleTextSize(s)).width,
150
+ });
151
+ titleContent.push({
152
+ text,
153
+ x: 0,
154
+ y: 0,
155
+ size: await getTitleTextSize(text),
156
+ });
157
+ }
158
+ const titleTextSize = titleContent.reduce((acc, item) => {
159
+ acc.width = Math.max(acc.width, item.size.width);
160
+ acc.height += item.size.height;
161
+ return acc;
162
+ }, { width: 0, height: 0 });
163
+ let x = 0;
164
+ switch (axis.title.align) {
165
+ case 'left': {
166
+ x = 0;
167
+ break;
168
+ }
169
+ case 'center': {
170
+ x = Math.max(axisWidth / 2 - titleTextSize.width / 2);
171
+ break;
172
+ }
173
+ case 'right': {
174
+ x = Math.max(0, axisWidth - titleTextSize.width);
175
+ break;
176
+ }
177
+ }
178
+ title = {
179
+ content: titleContent,
180
+ style: axis.title.style,
181
+ size: titleTextSize,
182
+ x,
183
+ y: height +
184
+ axis.labels.margin +
185
+ axis.labels.height +
186
+ axis.title.margin +
187
+ titleTextSize.height,
188
+ rotate: 0,
189
+ offset: 0,
190
+ };
191
+ }
192
+ const plotBands = [];
193
+ for (let i = 0; i < axis.plotBands.length; i++) {
194
+ const plotBand = axis.plotBands[i];
195
+ const axisScale = scale;
196
+ const { from, to } = getBandsPosition({
197
+ band: plotBand,
198
+ axisScale,
199
+ axis: 'x',
200
+ });
201
+ const halfBandwidth = ((_c = (_b = axisScale.bandwidth) === null || _b === void 0 ? void 0 : _b.call(axisScale)) !== null && _c !== void 0 ? _c : 0) / 2;
202
+ const startPos = halfBandwidth + Math.min(from, to);
203
+ const endPos = Math.min(Math.abs(to - from), axisWidth - Math.min(from, to));
204
+ const getPlotLabelSize = getTextSizeFn({ style: plotBand.label.style });
205
+ const labelSize = plotBand.label.text ? await getPlotLabelSize(plotBand.label.text) : null;
206
+ plotBands.push({
207
+ layerPlacement: plotBand.layerPlacement,
208
+ x: Math.max(0, startPos),
209
+ y: 0,
210
+ width: Math.min(endPos, axisWidth),
211
+ height: axisHeight,
212
+ color: plotBand.color,
213
+ opacity: plotBand.opacity,
214
+ label: plotBand.label.text
215
+ ? {
216
+ text: plotBand.label.text,
217
+ style: plotBand.label.style,
218
+ x: plotBand.label.padding,
219
+ y: plotBand.label.padding + ((_d = labelSize === null || labelSize === void 0 ? void 0 : labelSize.width) !== null && _d !== void 0 ? _d : 0),
220
+ rotate: -90,
221
+ }
222
+ : null,
223
+ });
224
+ }
225
+ const plotLines = [];
226
+ for (let i = 0; i < axis.plotLines.length; i++) {
227
+ const plotLine = axis.plotLines[i];
228
+ const axisScale = scale;
229
+ const plotLineValue = Number(axisScale(plotLine.value));
230
+ const points = [
231
+ [plotLineValue, 0],
232
+ [plotLineValue, axisHeight],
233
+ ];
234
+ let label = null;
235
+ if (plotLine.label.text) {
236
+ const getTitleTextSize = getTextSizeFn({ style: plotLine.label.style });
237
+ const size = await getTitleTextSize(plotLine.label.text);
238
+ label = {
239
+ text: plotLine.label.text,
240
+ style: plotLine.label.style,
241
+ x: plotLineValue - plotLine.label.padding - size.height,
242
+ y: plotLine.label.padding + size.width,
243
+ rotate: -90,
244
+ };
245
+ }
246
+ plotLines.push({
247
+ layerPlacement: plotLine.layerPlacement,
248
+ x: 0,
249
+ y: 0,
250
+ width: axisWidth,
251
+ color: plotLine.color,
252
+ opacity: plotLine.opacity,
253
+ label,
254
+ points,
255
+ lineWidth: plotLine.width,
256
+ dashStyle: plotLine.dashStyle,
257
+ });
258
+ }
259
+ return {
260
+ id: getUniqId(),
261
+ title,
262
+ ticks,
263
+ domain,
264
+ plotBands,
265
+ plotLines,
266
+ };
267
+ }
@@ -1,17 +1,14 @@
1
- .gcharts-axis .domain {
1
+ .gcharts-x-axis__domain {
2
2
  stroke: var(--g-color-line-generic-active);
3
3
  }
4
- .gcharts-axis .tick text {
5
- color: var(--g-color-text-secondary);
6
- dominant-baseline: text-after-edge;
4
+ .gcharts-x-axis__label {
5
+ fill: var(--g-color-text-secondary);
6
+ stroke: none;
7
7
  }
8
- .gcharts-axis .tick line, .gcharts-axis .tick path {
8
+ .gcharts-x-axis__tick {
9
9
  stroke: var(--g-color-line-generic);
10
10
  }
11
- .gcharts-axis__title {
12
- dominant-baseline: text-after-edge;
11
+ .gcharts-x-axis__title {
12
+ dominant-baseline: text-before-edge;
13
13
  fill: var(--g-color-text-secondary);
14
- }
15
- .gcharts-axis__title tspan {
16
- dominant-baseline: text-after-edge;
17
14
  }
@@ -0,0 +1,85 @@
1
+ import type { DashStyle } from 'src/constants';
2
+ import type { BaseTextStyle, HtmlItem, PlotLayerPlacement, PointPosition } from '../../types';
3
+ export type TextRowData = {
4
+ text: string;
5
+ x: number;
6
+ y: number;
7
+ size: {
8
+ width: number;
9
+ height: number;
10
+ };
11
+ };
12
+ export type AxisSvgLabelData = {
13
+ x: number;
14
+ y: number;
15
+ angle: number;
16
+ content: TextRowData[];
17
+ title?: string;
18
+ style: BaseTextStyle;
19
+ size: {
20
+ width: number;
21
+ height: number;
22
+ };
23
+ };
24
+ export type AxisTickLine = {
25
+ points: PointPosition[];
26
+ };
27
+ export type AxisTickData = {
28
+ line: AxisTickLine | null;
29
+ svgLabel: AxisSvgLabelData | null;
30
+ htmlLabel: HtmlItem | null;
31
+ };
32
+ export type AxisTitleData = {
33
+ content: TextRowData[];
34
+ style: BaseTextStyle;
35
+ size: {
36
+ width: number;
37
+ height: number;
38
+ };
39
+ x: number;
40
+ y: number;
41
+ rotate: number;
42
+ offset: number;
43
+ };
44
+ export type AxisPlotLineLabel = {
45
+ text: string;
46
+ rotate: number;
47
+ style: BaseTextStyle;
48
+ x: number;
49
+ y: number;
50
+ };
51
+ export type AxisPlotLineData = {
52
+ layerPlacement: PlotLayerPlacement;
53
+ x: number;
54
+ y: number;
55
+ width: number;
56
+ points: [number, number][];
57
+ color: string;
58
+ lineWidth: number;
59
+ opacity: number;
60
+ label: AxisPlotLineLabel | null;
61
+ dashStyle: DashStyle;
62
+ };
63
+ export type AxisPlotBandData = {
64
+ layerPlacement: PlotLayerPlacement;
65
+ x: number;
66
+ y: number;
67
+ width: number;
68
+ height: number;
69
+ color: string;
70
+ opacity: number;
71
+ label: AxisPlotLineLabel | null;
72
+ };
73
+ export type AxisDomainData = {
74
+ start: [number, number];
75
+ end: [number, number];
76
+ lineColor: string;
77
+ };
78
+ export type AxisXData = {
79
+ id: string;
80
+ title: AxisTitleData | null;
81
+ domain: AxisDomainData | null;
82
+ ticks: AxisTickData[];
83
+ plotLines: AxisPlotLineData[];
84
+ plotBands: AxisPlotBandData[];
85
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -5,11 +5,17 @@ import { block, getLineDashArray } from '../../utils';
5
5
  import './styles.css';
6
6
  const b = block('y-axis');
7
7
  export const AxisY = (props) => {
8
+ var _a;
8
9
  const { htmlLayout, plotBeforeRef, plotAfterRef, preparedAxisData } = props;
9
10
  const ref = React.useRef(null);
10
11
  const lineGenerator = line();
11
- const htmlLabels = preparedAxisData.ticks.map((d) => d.htmlLabel).filter(Boolean);
12
+ const htmlElements = [];
13
+ htmlElements.push(...preparedAxisData.ticks.map((d) => d.htmlLabel).filter(Boolean));
14
+ if ((_a = preparedAxisData.title) === null || _a === void 0 ? void 0 : _a.html) {
15
+ htmlElements.push(preparedAxisData.title);
16
+ }
12
17
  React.useEffect(() => {
18
+ var _a;
13
19
  if (!ref.current) {
14
20
  return;
15
21
  }
@@ -26,7 +32,7 @@ export const AxisY = (props) => {
26
32
  plotAfterContainer = select(plotAfterRef.current);
27
33
  plotAfterContainer.selectAll(`[${plotDataAttr}]`).remove();
28
34
  }
29
- if (preparedAxisData.title) {
35
+ if (((_a = preparedAxisData.title) === null || _a === void 0 ? void 0 : _a.html) === false) {
30
36
  svgElement
31
37
  .append('g')
32
38
  .attr('class', b('title'))
@@ -177,6 +183,6 @@ export const AxisY = (props) => {
177
183
  }
178
184
  }, [lineGenerator, plotAfterRef, plotBeforeRef, preparedAxisData]);
179
185
  return (React.createElement(React.Fragment, null,
180
- React.createElement(HtmlLayer, { preparedData: { htmlElements: htmlLabels }, htmlLayout: htmlLayout }),
186
+ React.createElement(HtmlLayer, { preparedData: { htmlElements }, htmlLayout: htmlLayout }),
181
187
  React.createElement("g", { ref: ref, className: b() })));
182
188
  };
@@ -1,6 +1,6 @@
1
1
  import type { ChartScale, PreparedAxis, PreparedSeries, PreparedSplit } from '../../hooks';
2
2
  import type { AxisYData } from './types';
3
- export declare function prepareAxisData({ axis, split, scale, top: topOffset, width, height, series, }: {
3
+ export declare function prepareYAxisData({ axis, split, scale, top: topOffset, width, height, series, }: {
4
4
  axis: PreparedAxis;
5
5
  split: PreparedSplit;
6
6
  scale: ChartScale;
@@ -1,5 +1,6 @@
1
1
  import { getUniqId } from '@gravity-ui/uikit';
2
2
  import { calculateCos, calculateSin, formatAxisTickLabel, getBandsPosition, getLabelsSize, getMinSpaceBetween, getTextSizeFn, getTextWithElipsis, wrapText, } from '../../utils';
3
+ import { prepareHtmlYAxisTitle, prepareSvgYAxisTitle } from './prepare-axis-title';
3
4
  import { getTickValues } from './utils';
4
5
  async function getSvgAxisLabel({ getTextSize, text, axis, top, left, labelMaxHeight, topOffset, }) {
5
6
  var _a;
@@ -107,8 +108,7 @@ async function getSvgAxisLabel({ getTextSize, text, axis, top, left, labelMaxHei
107
108
  };
108
109
  return svgLabel;
109
110
  }
110
- // eslint-disable-next-line complexity
111
- export async function prepareAxisData({ axis, split, scale, top: topOffset, width, height, series, }) {
111
+ export async function prepareYAxisData({ axis, split, scale, top: topOffset, width, height, series, }) {
112
112
  var _a, _b, _c;
113
113
  const axisPlotTopPosition = ((_a = split.plots[axis.plotIndex]) === null || _a === void 0 ? void 0 : _a.top) || 0;
114
114
  const axisHeight = ((_b = split.plots[axis.plotIndex]) === null || _b === void 0 ? void 0 : _b.height) || height;
@@ -183,85 +183,21 @@ export async function prepareAxisData({ axis, split, scale, top: topOffset, widt
183
183
  }
184
184
  let labelsWidth = ticks.reduce((acc, item) => { var _a, _b, _c, _d; return Math.max(acc, (_d = (_b = (_a = item.svgLabel) === null || _a === void 0 ? void 0 : _a.size.width) !== null && _b !== void 0 ? _b : (_c = item.htmlLabel) === null || _c === void 0 ? void 0 : _c.size.width) !== null && _d !== void 0 ? _d : 0); }, 0);
185
185
  labelsWidth = Math.min(axis.labels.width, labelsWidth);
186
- let title = null;
187
- if (axis.title.text) {
188
- const getTitleTextSize = getTextSizeFn({ style: axis.title.style });
189
- const rotateAngle = axis.position === 'left' ? -90 : 90;
190
- const sin = Math.abs(calculateSin(rotateAngle));
191
- const cos = Math.abs(calculateCos(rotateAngle));
192
- const titleContent = [];
193
- const titleMaxWidth = sin * axisHeight;
194
- if (axis.title.maxRowCount > 1) {
195
- const titleTextRows = await wrapText({
196
- text: axis.title.text,
197
- style: axis.title.style,
198
- width: titleMaxWidth,
199
- getTextSize: getTitleTextSize,
200
- });
201
- for (let i = 0; i < axis.title.maxRowCount && i < titleTextRows.length; i++) {
202
- const textRow = titleTextRows[i];
203
- const textRowContent = textRow.text.trim();
204
- const textRowSize = await getTitleTextSize(textRowContent);
205
- titleContent.push({
206
- text: textRowContent,
207
- x: 0,
208
- y: textRow.y,
209
- size: textRowSize,
210
- });
211
- }
212
- }
213
- else {
214
- const text = await getTextWithElipsis({
215
- text: axis.title.text,
216
- maxWidth: titleMaxWidth,
217
- getTextWidth: async (s) => (await getTitleTextSize(s)).width,
218
- });
219
- titleContent.push({
220
- text,
221
- x: 0,
222
- y: 0,
223
- size: await getTitleTextSize(text),
224
- });
225
- }
226
- const originalTextSize = titleContent.reduce((acc, item) => {
227
- acc.width = Math.max(acc.width, item.size.width);
228
- acc.height += item.size.height;
229
- return acc;
230
- }, { width: 0, height: 0 });
231
- const rotatedTitleSize = {
232
- width: sin * originalTextSize.height + cos * originalTextSize.width,
233
- height: sin * originalTextSize.width + cos * originalTextSize.height,
234
- };
235
- const bottom = Math.max(0, calculateSin(rotateAngle) * originalTextSize.width);
236
- let y = 0;
237
- switch (axis.title.align) {
238
- case 'left': {
239
- y = -bottom + axisHeight;
240
- break;
241
- }
242
- case 'center': {
243
- y = -bottom + axisHeight / 2 + rotatedTitleSize.height / 2;
244
- break;
245
- }
246
- case 'right': {
247
- y = -bottom + rotatedTitleSize.height;
248
- break;
249
- }
250
- }
251
- const left = Math.min(0, calculateCos(rotateAngle) * originalTextSize.width);
252
- const x = axis.position === 'left'
253
- ? -left - labelsWidth - axis.labels.margin - axis.title.margin
254
- : -left + width + labelsWidth + axis.labels.margin + axis.title.margin;
255
- title = {
256
- content: titleContent,
257
- style: axis.title.style,
258
- size: rotatedTitleSize,
259
- x,
260
- y: axisPlotTopPosition + y,
261
- rotate: rotateAngle,
262
- offset: -(originalTextSize.height / titleContent.length) * (titleContent.length - 1),
263
- };
264
- }
186
+ const title = axis.title.html
187
+ ? await prepareHtmlYAxisTitle({
188
+ axis,
189
+ axisTop: axisPlotTopPosition,
190
+ axisWidth: width,
191
+ axisHeight,
192
+ axisLabelsWidth: labelsWidth,
193
+ })
194
+ : await prepareSvgYAxisTitle({
195
+ axis,
196
+ axisTop: axisPlotTopPosition,
197
+ axisWidth: width,
198
+ axisHeight,
199
+ axisLabelsWidth: labelsWidth,
200
+ });
265
201
  const plotBands = [];
266
202
  axis.plotBands.forEach((plotBand) => {
267
203
  var _a, _b;
@@ -0,0 +1,16 @@
1
+ import type { PreparedAxis } from 'src/hooks';
2
+ import type { HtmlAxisTitleData, SvgAxisTitleData } from './types';
3
+ export declare function prepareSvgYAxisTitle({ axis, axisTop, axisHeight, axisWidth, axisLabelsWidth, }: {
4
+ axis: PreparedAxis;
5
+ axisTop: number;
6
+ axisHeight: number;
7
+ axisWidth: number;
8
+ axisLabelsWidth: number;
9
+ }): Promise<SvgAxisTitleData | null>;
10
+ export declare function prepareHtmlYAxisTitle({ axis, axisTop, axisHeight, axisWidth, axisLabelsWidth, }: {
11
+ axis: PreparedAxis;
12
+ axisTop: number;
13
+ axisHeight: number;
14
+ axisWidth: number;
15
+ axisLabelsWidth: number;
16
+ }): Promise<HtmlAxisTitleData | null>;