@gravity-ui/charts 1.13.2 → 1.14.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 (45) hide show
  1. package/dist/cjs/components/Axis/AxisX.d.ts +5 -2
  2. package/dist/cjs/components/Axis/AxisX.js +28 -11
  3. package/dist/cjs/components/Axis/AxisY.d.ts +5 -2
  4. package/dist/cjs/components/Axis/AxisY.js +67 -9
  5. package/dist/cjs/components/ChartInner/index.js +2 -2
  6. package/dist/cjs/components/Legend/index.js +5 -4
  7. package/dist/cjs/components/Tooltip/DefaultTooltipContent/index.js +3 -3
  8. package/dist/cjs/hooks/useChartOptions/title.js +2 -2
  9. package/dist/cjs/hooks/useChartOptions/types.d.ts +1 -1
  10. package/dist/cjs/hooks/useChartOptions/x-axis.js +18 -10
  11. package/dist/cjs/hooks/useChartOptions/y-axis.js +17 -6
  12. package/dist/cjs/hooks/useSplit/index.js +2 -2
  13. package/dist/cjs/i18n/keysets/en.json +3 -1
  14. package/dist/cjs/i18n/keysets/ru.json +3 -1
  15. package/dist/cjs/types/chart/axis.d.ts +11 -1
  16. package/dist/cjs/utils/chart/axis-generators/bottom.d.ts +18 -13
  17. package/dist/cjs/utils/chart/axis-generators/bottom.js +173 -73
  18. package/dist/cjs/utils/chart/index.d.ts +5 -9
  19. package/dist/cjs/utils/chart/index.js +18 -9
  20. package/dist/cjs/validation/index.js +2 -22
  21. package/dist/cjs/validation/validate-axes.d.ts +5 -0
  22. package/dist/cjs/validation/validate-axes.js +46 -0
  23. package/dist/esm/components/Axis/AxisX.d.ts +5 -2
  24. package/dist/esm/components/Axis/AxisX.js +28 -11
  25. package/dist/esm/components/Axis/AxisY.d.ts +5 -2
  26. package/dist/esm/components/Axis/AxisY.js +67 -9
  27. package/dist/esm/components/ChartInner/index.js +2 -2
  28. package/dist/esm/components/Legend/index.js +5 -4
  29. package/dist/esm/components/Tooltip/DefaultTooltipContent/index.js +3 -3
  30. package/dist/esm/hooks/useChartOptions/title.js +2 -2
  31. package/dist/esm/hooks/useChartOptions/types.d.ts +1 -1
  32. package/dist/esm/hooks/useChartOptions/x-axis.js +18 -10
  33. package/dist/esm/hooks/useChartOptions/y-axis.js +17 -6
  34. package/dist/esm/hooks/useSplit/index.js +2 -2
  35. package/dist/esm/i18n/keysets/en.json +3 -1
  36. package/dist/esm/i18n/keysets/ru.json +3 -1
  37. package/dist/esm/types/chart/axis.d.ts +11 -1
  38. package/dist/esm/utils/chart/axis-generators/bottom.d.ts +18 -13
  39. package/dist/esm/utils/chart/axis-generators/bottom.js +173 -73
  40. package/dist/esm/utils/chart/index.d.ts +5 -9
  41. package/dist/esm/utils/chart/index.js +18 -9
  42. package/dist/esm/validation/index.js +2 -22
  43. package/dist/esm/validation/validate-axes.d.ts +5 -0
  44. package/dist/esm/validation/validate-axes.js +46 -0
  45. package/package.json +1 -1
@@ -2,6 +2,7 @@ import { path, select } from 'd3';
2
2
  import { getXAxisItems, getXAxisOffset, getXTickPosition } from '../axis';
3
3
  import { calculateCos, calculateSin } from '../math';
4
4
  import { getLabelsSize, setEllipsisForOverflowText } from '../text';
5
+ const AXIS_BOTTOM_HTML_LABELS_DATA_ATTR = 'data-axis-bottom-html-labels';
5
6
  function addDomain(selection, options) {
6
7
  const { size, color } = options;
7
8
  const domainPath = selection
@@ -15,8 +16,139 @@ function addDomain(selection, options) {
15
16
  domainPath.style('stroke', color);
16
17
  }
17
18
  }
19
+ function appendSvgLabels(args) {
20
+ var _a;
21
+ const { leftmostLimit, right, ticksSelection, ticks, transform, translateY, x } = args;
22
+ ticksSelection
23
+ .append('text')
24
+ .html(ticks.labelFormat)
25
+ .style('font-size', ((_a = ticks.labelsStyle) === null || _a === void 0 ? void 0 : _a.fontSize) || '')
26
+ .attr('fill', 'currentColor')
27
+ .attr('text-anchor', () => {
28
+ if (ticks.rotation) {
29
+ return ticks.rotation > 0 ? 'start' : 'end';
30
+ }
31
+ return 'middle';
32
+ })
33
+ .style('transform', transform)
34
+ .style('dominant-baseline', 'text-after-edge');
35
+ const labels = ticksSelection.selectAll('.tick text');
36
+ // FIXME: handle rotated overlapping labels (with a smarter approach)
37
+ if (ticks.rotation) {
38
+ const maxWidth = ticks.labelsMaxWidth * calculateCos(ticks.rotation) +
39
+ ticks.labelsLineHeight * calculateSin(ticks.rotation);
40
+ labels.each(function () {
41
+ setEllipsisForOverflowText(select(this), maxWidth);
42
+ });
43
+ }
44
+ else {
45
+ let elementX = 0;
46
+ // add an ellipsis to the labels that go beyond the boundaries of the chart
47
+ // and remove overlapping labels
48
+ labels
49
+ .nodes()
50
+ .map((element) => {
51
+ const r = element.getBoundingClientRect();
52
+ return {
53
+ left: r.left,
54
+ right: r.right,
55
+ node: element,
56
+ };
57
+ }, {})
58
+ .sort((a, b) => {
59
+ return a.left - b.left;
60
+ })
61
+ .forEach(function (item, i, nodes) {
62
+ var _a, _b, _c, _d;
63
+ const { node, left, right: currentElementPositionRigth } = item;
64
+ const currentElement = node;
65
+ if (i === 0) {
66
+ const text = select(currentElement);
67
+ const nextElement = (_a = nodes[i + 1]) === null || _a === void 0 ? void 0 : _a.node;
68
+ const nextElementPosition = nextElement === null || nextElement === void 0 ? void 0 : nextElement.getBoundingClientRect();
69
+ if (left < leftmostLimit) {
70
+ const rightmostPossiblePoint = (_b = nextElementPosition === null || nextElementPosition === void 0 ? void 0 : nextElementPosition.left) !== null && _b !== void 0 ? _b : right;
71
+ const remainSpace = rightmostPossiblePoint -
72
+ currentElementPositionRigth +
73
+ x -
74
+ ticks.labelsMargin;
75
+ text.attr('text-anchor', 'start');
76
+ setEllipsisForOverflowText(text, remainSpace);
77
+ }
78
+ }
79
+ else {
80
+ if (left < elementX) {
81
+ (_c = currentElement.closest('.tick')) === null || _c === void 0 ? void 0 : _c.remove();
82
+ return;
83
+ }
84
+ elementX = currentElementPositionRigth + ticks.labelsPaddings;
85
+ if (i === nodes.length - 1) {
86
+ const prevElement = (_d = nodes[i - 1]) === null || _d === void 0 ? void 0 : _d.node;
87
+ const text = select(currentElement);
88
+ const prevElementPosition = prevElement === null || prevElement === void 0 ? void 0 : prevElement.getBoundingClientRect();
89
+ const lackingSpace = Math.max(0, currentElementPositionRigth - right);
90
+ if (lackingSpace) {
91
+ const remainSpace = right - ((prevElementPosition === null || prevElementPosition === void 0 ? void 0 : prevElementPosition.right) || 0) - ticks.labelsPaddings;
92
+ const translateX = -lackingSpace;
93
+ text.style('transform', `translate(${translateX}px,${translateY}px)`);
94
+ setEllipsisForOverflowText(text, remainSpace);
95
+ }
96
+ }
97
+ }
98
+ });
99
+ }
100
+ }
101
+ function appendHtmlLabels(args) {
102
+ const { htmlSelection, labelsData, right, ticks } = args;
103
+ htmlSelection
104
+ .append('div')
105
+ .attr(AXIS_BOTTOM_HTML_LABELS_DATA_ATTR, 1)
106
+ .style('position', 'absolute');
107
+ labelsData.forEach((label) => {
108
+ var _a;
109
+ htmlSelection
110
+ .selectAll(`[${AXIS_BOTTOM_HTML_LABELS_DATA_ATTR}]`)
111
+ .data([label])
112
+ .append('div')
113
+ .html(function (d) {
114
+ return ticks.labelFormat(d.content);
115
+ })
116
+ .style('font-size', ((_a = ticks.labelsStyle) === null || _a === void 0 ? void 0 : _a.fontSize) || '')
117
+ .style('position', 'absolute')
118
+ .style('white-space', 'nowrap')
119
+ .style('color', 'var(--g-color-text-secondary)')
120
+ .style('overflow', 'hidden')
121
+ .style('text-overflow', 'ellipsis')
122
+ .style('left', function (d) {
123
+ const rect = this.getBoundingClientRect();
124
+ return `${d.left - rect.width / 2}px`;
125
+ })
126
+ .style('top', function (d) {
127
+ return `${d.top}px`;
128
+ });
129
+ });
130
+ const labelNodes = htmlSelection
131
+ .selectAll(`[${AXIS_BOTTOM_HTML_LABELS_DATA_ATTR}] > div`)
132
+ .nodes();
133
+ labelNodes.forEach((node, i, nodes) => {
134
+ var _a;
135
+ if (i === nodes.length - 1) {
136
+ const prevNodeSelection = select(nodes[i - 1]);
137
+ const prevRect = (_a = prevNodeSelection.node()) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect();
138
+ const nodeSelection = select(node);
139
+ const rect = node.getBoundingClientRect();
140
+ if (prevRect && prevRect.right + ticks.labelsPaddings > rect.left) {
141
+ const maxWidth = right - prevRect.right - ticks.labelsPaddings;
142
+ const leftMin = prevRect.right - ticks.labelsPaddings / 2;
143
+ nodeSelection.style('left', `${leftMin}px`);
144
+ nodeSelection.style('max-width', `${maxWidth}px`);
145
+ }
146
+ }
147
+ });
148
+ }
18
149
  export async function axisBottom(args) {
19
- const { leftmostLimit = 0, scale, ticks: { labelFormat = (value) => String(value), labelsPaddings = 0, labelsMargin = 0, labelsMaxWidth = Infinity, labelsStyle, labelsLineHeight, items: tickItems, count: ticksCount, maxTickCount, rotation = 0, tickColor, }, domain, } = args;
150
+ const { boundsOffsetLeft = 0, boundsOffsetTop = 0, domain, htmlLayout, leftmostLimit = 0, scale, ticks: { count: ticksCount, items: tickItems, labelFormat = (value) => String(value), labelsHeight = 0, labelsHtml, labelsLineHeight, labelsMargin = 0, labelsMaxWidth = Infinity, labelsPaddings = 0, labelsStyle, maxTickCount, rotation = 0, tickColor, }, } = args;
151
+ const htmlSelection = select(htmlLayout);
20
152
  const offset = getXAxisOffset();
21
153
  const position = getXTickPosition({ scale, offset });
22
154
  const values = getXAxisItems({ scale, count: ticksCount, maxCount: maxTickCount });
@@ -27,6 +159,7 @@ export async function axisBottom(args) {
27
159
  return function (selection) {
28
160
  var _a, _b, _c;
29
161
  selection.selectAll('.tick, .domain').remove();
162
+ htmlSelection.selectAll(`[${AXIS_BOTTOM_HTML_LABELS_DATA_ATTR}]`).remove();
30
163
  const rect = (_a = selection.node()) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect();
31
164
  const x = (rect === null || rect === void 0 ? void 0 : rect.x) || 0;
32
165
  const right = x + domain.size;
@@ -46,6 +179,16 @@ export async function axisBottom(args) {
46
179
  tickPath.moveTo(0, start);
47
180
  tickPath.lineTo(0, end);
48
181
  });
182
+ const htmlLabelsData = labelsHtml
183
+ ? values.map((v) => {
184
+ var _a;
185
+ return {
186
+ content: v,
187
+ left: position(v) + offset + boundsOffsetLeft,
188
+ top: Math.abs(((_a = tickItems === null || tickItems === void 0 ? void 0 : tickItems[0]) === null || _a === void 0 ? void 0 : _a[1]) || 0) + labelsMargin + boundsOffsetTop,
189
+ };
190
+ })
191
+ : [];
49
192
  const ticks = selection
50
193
  .selectAll('.tick')
51
194
  .data(values)
@@ -60,19 +203,6 @@ export async function axisBottom(args) {
60
203
  .append('path')
61
204
  .attr('d', tickPath.toString())
62
205
  .attr('stroke', tickColor !== null && tickColor !== void 0 ? tickColor : 'currentColor');
63
- ticks
64
- .append('text')
65
- .text(labelFormat)
66
- .style('font-size', (labelsStyle === null || labelsStyle === void 0 ? void 0 : labelsStyle.fontSize) || '')
67
- .attr('fill', 'currentColor')
68
- .attr('text-anchor', () => {
69
- if (rotation) {
70
- return rotation > 0 ? 'start' : 'end';
71
- }
72
- return 'middle';
73
- })
74
- .style('transform', transform)
75
- .style('dominant-baseline', 'text-after-edge');
76
206
  // Remove tick that has the same x coordinate like domain
77
207
  selection
78
208
  .selectAll('.tick')
@@ -81,68 +211,38 @@ export async function axisBottom(args) {
81
211
  })
82
212
  .select('path')
83
213
  .remove();
84
- const labels = selection.selectAll('.tick text');
85
- // FIXME: handle rotated overlapping labels (with a smarter approach)
86
- if (rotation) {
87
- const maxWidth = labelsMaxWidth * calculateCos(rotation) + labelsLineHeight * calculateSin(rotation);
88
- labels.each(function () {
89
- setEllipsisForOverflowText(select(this), maxWidth);
214
+ if (labelsHtml) {
215
+ appendHtmlLabels({
216
+ htmlSelection,
217
+ labelsData: htmlLabelsData,
218
+ right,
219
+ ticks: {
220
+ labelFormat,
221
+ labelsHeight,
222
+ labelsMaxWidth,
223
+ labelsPaddings,
224
+ labelsStyle,
225
+ rotation,
226
+ },
90
227
  });
91
228
  }
92
229
  else {
93
- let elementX = 0;
94
- // add an ellipsis to the labels that go beyond the boundaries of the chart
95
- // and remove overlapping labels
96
- labels
97
- .nodes()
98
- .map((element) => {
99
- const r = element.getBoundingClientRect();
100
- return {
101
- left: r.left,
102
- right: r.right,
103
- node: element,
104
- };
105
- }, {})
106
- .sort((a, b) => {
107
- return a.left - b.left;
108
- })
109
- .forEach(function (item, i, nodes) {
110
- var _a, _b, _c, _d;
111
- const { node, left, right: currentElementPositionRigth } = item;
112
- const currentElement = node;
113
- if (i === 0) {
114
- const text = select(currentElement);
115
- const nextElement = (_a = nodes[i + 1]) === null || _a === void 0 ? void 0 : _a.node;
116
- const nextElementPosition = nextElement === null || nextElement === void 0 ? void 0 : nextElement.getBoundingClientRect();
117
- if (left < leftmostLimit) {
118
- const rightmostPossiblePoint = (_b = nextElementPosition === null || nextElementPosition === void 0 ? void 0 : nextElementPosition.left) !== null && _b !== void 0 ? _b : right;
119
- const remainSpace = rightmostPossiblePoint -
120
- currentElementPositionRigth +
121
- x -
122
- labelsMargin;
123
- text.attr('text-anchor', 'start');
124
- setEllipsisForOverflowText(text, remainSpace);
125
- }
126
- }
127
- else {
128
- if (left < elementX) {
129
- (_c = currentElement.closest('.tick')) === null || _c === void 0 ? void 0 : _c.remove();
130
- return;
131
- }
132
- elementX = currentElementPositionRigth + labelsPaddings;
133
- if (i === nodes.length - 1) {
134
- const prevElement = (_d = nodes[i - 1]) === null || _d === void 0 ? void 0 : _d.node;
135
- const text = select(currentElement);
136
- const prevElementPosition = prevElement === null || prevElement === void 0 ? void 0 : prevElement.getBoundingClientRect();
137
- const lackingSpace = Math.max(0, currentElementPositionRigth - right);
138
- if (lackingSpace) {
139
- const remainSpace = right - ((prevElementPosition === null || prevElementPosition === void 0 ? void 0 : prevElementPosition.right) || 0) - labelsPaddings;
140
- const translateX = -lackingSpace;
141
- text.style('transform', `translate(${translateX}px,${translateY}px)`);
142
- setEllipsisForOverflowText(text, remainSpace);
143
- }
144
- }
145
- }
230
+ appendSvgLabels({
231
+ leftmostLimit,
232
+ right,
233
+ ticksSelection: ticks,
234
+ ticks: {
235
+ labelFormat,
236
+ labelsLineHeight,
237
+ labelsMaxWidth,
238
+ labelsMargin,
239
+ labelsPaddings,
240
+ labelsStyle,
241
+ rotation,
242
+ },
243
+ transform,
244
+ translateY,
245
+ x,
146
246
  });
147
247
  }
148
248
  const { size: domainSize, color: domainColor } = domain;
@@ -61,15 +61,11 @@ export declare const formatAxisTickLabel: (args: {
61
61
  value: AxisDomain;
62
62
  step?: number;
63
63
  }) => string;
64
- /**
65
- * Calculates the height of a text element in a horizontal SVG layout.
66
- *
67
- * @param {Object} args - The arguments for the function.
68
- * @param {string} args.text - The text to be measured.
69
- * @param {Partial<BaseTextStyle>} args.style - Optional style properties for the text element.
70
- * @return {number} The height of the text element.
71
- */
72
- export declare const getHorisontalSvgTextHeight: (args: {
64
+ export declare const getHorizontalHtmlTextHeight: (args: {
65
+ text: string;
66
+ style?: Partial<BaseTextStyle>;
67
+ }) => number;
68
+ export declare const getHorizontalSvgTextHeight: (args: {
73
69
  text: string;
74
70
  style?: Partial<BaseTextStyle>;
75
71
  }) => number;
@@ -190,15 +190,24 @@ export const formatAxisTickLabel = (args) => {
190
190
  }
191
191
  }
192
192
  };
193
- /**
194
- * Calculates the height of a text element in a horizontal SVG layout.
195
- *
196
- * @param {Object} args - The arguments for the function.
197
- * @param {string} args.text - The text to be measured.
198
- * @param {Partial<BaseTextStyle>} args.style - Optional style properties for the text element.
199
- * @return {number} The height of the text element.
200
- */
201
- export const getHorisontalSvgTextHeight = (args) => {
193
+ export const getHorizontalHtmlTextHeight = (args) => {
194
+ var _a;
195
+ const { text, style } = args;
196
+ const container = select(document.body).append('div');
197
+ const fontSize = get(style, 'fontSize', DEFAULT_AXIS_LABEL_FONT_SIZE);
198
+ container
199
+ .style('position', 'absolute')
200
+ .style('visibility', 'hidden')
201
+ .style('white-space', 'nowrap')
202
+ .html(text);
203
+ if (fontSize) {
204
+ container.style('font-size', fontSize);
205
+ }
206
+ const height = ((_a = container.node()) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect().height) || 0;
207
+ container.remove();
208
+ return height;
209
+ };
210
+ export const getHorizontalSvgTextHeight = (args) => {
202
211
  var _a;
203
212
  const { text, style } = args;
204
213
  const container = select(document.body).append('svg');
@@ -1,35 +1,15 @@
1
1
  import get from 'lodash/get';
2
2
  import isEmpty from 'lodash/isEmpty';
3
- import { AXIS_TYPE, DEFAULT_AXIS_TYPE, SeriesType, TOOLTIP_TOTALS_BUILT_IN_AGGREGATION, } from '../constants';
3
+ import { DEFAULT_AXIS_TYPE, SeriesType, TOOLTIP_TOTALS_BUILT_IN_AGGREGATION } from '../constants';
4
4
  import { i18n } from '../i18n';
5
5
  import { CHART_ERROR_CODE, ChartError } from '../libs';
6
+ import { validateAxes } from './validate-axes';
6
7
  function getTypeOf(value) {
7
8
  return typeof value;
8
9
  }
9
10
  const AVAILABLE_SERIES_TYPES = Object.values(SeriesType);
10
11
  const AVAILABLE_TOOLTIP_TOTALS_BUILT_IN_AGGREGATIONS = Object.values(TOOLTIP_TOTALS_BUILT_IN_AGGREGATION);
11
12
  const AVAILABLE_TOOLTIP_TOTALS_AGGREGATION_TYPES = ['function', 'string'];
12
- const AVAILABLE_AXIS_TYPES = Object.values(AXIS_TYPE);
13
- function validateAxisType({ axis, key }) {
14
- if (axis.type && !AVAILABLE_AXIS_TYPES.includes(axis.type)) {
15
- throw new ChartError({
16
- code: CHART_ERROR_CODE.INVALID_DATA,
17
- message: i18n('error', 'label_invalid-axis-type', {
18
- key,
19
- values: AVAILABLE_AXIS_TYPES,
20
- }),
21
- });
22
- }
23
- }
24
- function validateAxes(args) {
25
- const { xAxis, yAxis = [] } = args;
26
- if (xAxis) {
27
- validateAxisType({ axis: xAxis, key: 'x' });
28
- }
29
- yAxis.forEach((axis) => {
30
- validateAxisType({ axis, key: 'y' });
31
- });
32
- }
33
13
  function validateXYSeries(args) {
34
14
  const { series, xAxis, yAxis = [] } = args;
35
15
  const yAxisIndex = get(series, 'yAxis', 0);
@@ -0,0 +1,5 @@
1
+ import type { ChartXAxis, ChartYAxis } from '../types';
2
+ export declare function validateAxes(args: {
3
+ xAxis?: ChartXAxis;
4
+ yAxis?: ChartYAxis[];
5
+ }): void;
@@ -0,0 +1,46 @@
1
+ import { AXIS_TYPE } from '../constants';
2
+ import { i18n } from '../i18n';
3
+ import { CHART_ERROR_CODE, ChartError } from '../libs';
4
+ const AVAILABLE_AXIS_TYPES = Object.values(AXIS_TYPE);
5
+ function validateAxisType({ axis, key }) {
6
+ if (axis.type && !AVAILABLE_AXIS_TYPES.includes(axis.type)) {
7
+ throw new ChartError({
8
+ code: CHART_ERROR_CODE.INVALID_DATA,
9
+ message: i18n('error', 'label_invalid-axis-type', {
10
+ key,
11
+ values: AVAILABLE_AXIS_TYPES,
12
+ }),
13
+ });
14
+ }
15
+ }
16
+ function validateLabelsHtmlOptions(args) {
17
+ var _a;
18
+ const { axis } = args;
19
+ const html = (_a = axis.labels) === null || _a === void 0 ? void 0 : _a.html;
20
+ if (typeof html === 'undefined') {
21
+ return;
22
+ }
23
+ if (typeof html !== 'boolean') {
24
+ throw new ChartError({
25
+ code: CHART_ERROR_CODE.INVALID_DATA,
26
+ message: i18n('error', 'label_invalid-axis-labels-html-type'),
27
+ });
28
+ }
29
+ if (html && axis.type !== 'category') {
30
+ throw new ChartError({
31
+ code: CHART_ERROR_CODE.INVALID_DATA,
32
+ message: i18n('error', 'label_invalid-axis-labels-html-not-supported-axis-type'),
33
+ });
34
+ }
35
+ }
36
+ export function validateAxes(args) {
37
+ const { xAxis, yAxis = [] } = args;
38
+ if (xAxis) {
39
+ validateAxisType({ axis: xAxis, key: 'x' });
40
+ validateLabelsHtmlOptions({ axis: xAxis });
41
+ }
42
+ yAxis.forEach((axis) => {
43
+ validateAxisType({ axis, key: 'y' });
44
+ validateLabelsHtmlOptions({ axis });
45
+ });
46
+ }
@@ -3,13 +3,16 @@ import type { ChartScale, PreparedAxis, PreparedSplit } from '../../hooks';
3
3
  import './styles.css';
4
4
  type Props = {
5
5
  axis: PreparedAxis;
6
- width: number;
6
+ boundsOffsetLeft: number;
7
+ boundsOffsetTop: number;
7
8
  height: number;
9
+ htmlLayout: HTMLElement | null;
8
10
  scale: ChartScale;
9
11
  split: PreparedSplit;
12
+ width: number;
13
+ leftmostLimit?: number;
10
14
  plotBeforeRef?: React.MutableRefObject<SVGGElement | null>;
11
15
  plotAfterRef?: React.MutableRefObject<SVGGElement | null>;
12
- leftmostLimit?: number;
13
16
  };
14
17
  export declare function getTitlePosition(args: {
15
18
  axis: PreparedAxis;
@@ -42,11 +42,11 @@ export function getTitlePosition(args) {
42
42
  return { x, y };
43
43
  }
44
44
  export const AxisX = React.memo(function AxisX(props) {
45
- const { axis, width, height: totalHeight, scale, split, plotBeforeRef, plotAfterRef, leftmostLimit, } = props;
45
+ const { axis, boundsOffsetLeft, boundsOffsetTop, height: totalHeight, htmlLayout, leftmostLimit, plotAfterRef, plotBeforeRef, split, scale, width, } = props;
46
46
  const ref = React.useRef(null);
47
47
  React.useEffect(() => {
48
48
  (async () => {
49
- if (!ref.current) {
49
+ if (!ref.current || !htmlLayout) {
50
50
  return;
51
51
  }
52
52
  const svgElement = select(ref.current);
@@ -65,24 +65,29 @@ export const AxisX = React.memo(function AxisX(props) {
65
65
  }
66
66
  const axisScale = scale;
67
67
  const xAxisGenerator = await axisBottom({
68
+ boundsOffsetLeft,
69
+ boundsOffsetTop,
70
+ domain: {
71
+ size: width,
72
+ color: axis.lineColor,
73
+ },
74
+ htmlLayout,
68
75
  leftmostLimit,
69
76
  scale: axisScale,
70
77
  ticks: {
78
+ count: getTicksCount({ axis, range: width }),
79
+ labelsHtml: axis.labels.html,
71
80
  items: tickItems,
72
81
  labelFormat: getLabelFormatter({ axis, scale }),
73
- labelsPaddings: axis.labels.padding,
82
+ labelsHeight: axis.labels.height,
83
+ labelsLineHeight: axis.labels.lineHeight,
74
84
  labelsMargin: axis.labels.margin,
75
- labelsStyle: axis.labels.style,
76
85
  labelsMaxWidth: axis.labels.maxWidth,
77
- labelsLineHeight: axis.labels.lineHeight,
78
- count: getTicksCount({ axis, range: width }),
86
+ labelsPaddings: axis.labels.padding,
87
+ labelsStyle: axis.labels.style,
79
88
  maxTickCount: getMaxTickCount({ axis, width }),
80
89
  rotation: axis.labels.rotation,
81
90
  },
82
- domain: {
83
- size: width,
84
- color: axis.lineColor,
85
- },
86
91
  });
87
92
  svgElement.call(xAxisGenerator).attr('class', b());
88
93
  // add an axis header if necessary
@@ -219,6 +224,18 @@ export const AxisX = React.memo(function AxisX(props) {
219
224
  setPlotLines(plotAfterContainer, axis.plotLines.filter((d) => d.layerPlacement === 'after'));
220
225
  }
221
226
  })();
222
- }, [axis, width, totalHeight, scale, split, leftmostLimit, plotBeforeRef, plotAfterRef]);
227
+ }, [
228
+ axis,
229
+ boundsOffsetLeft,
230
+ boundsOffsetTop,
231
+ htmlLayout,
232
+ leftmostLimit,
233
+ plotAfterRef,
234
+ plotBeforeRef,
235
+ scale,
236
+ split,
237
+ totalHeight,
238
+ width,
239
+ ]);
223
240
  return React.createElement("g", { ref: ref });
224
241
  });
@@ -1,16 +1,19 @@
1
1
  import React from 'react';
2
2
  import type { ChartScale, PreparedAxis, PreparedSplit } from '../../hooks';
3
3
  import './styles.css';
4
- type Props = {
4
+ interface Props {
5
5
  axes: PreparedAxis[];
6
+ boundsOffsetTop: number;
7
+ boundsOffsetLeft: number;
6
8
  scale: ChartScale[];
7
9
  width: number;
8
10
  height: number;
11
+ htmlLayout: HTMLElement | null;
9
12
  split: PreparedSplit;
10
13
  plotBeforeRef?: React.MutableRefObject<SVGGElement | null>;
11
14
  plotAfterRef?: React.MutableRefObject<SVGGElement | null>;
12
15
  bottomLimit?: number;
13
16
  topLimit?: number;
14
- };
17
+ }
15
18
  export declare const AxisY: (props: Props) => React.JSX.Element;
16
19
  export {};