@gravity-ui/charts 1.9.0 → 1.10.1

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 (199) hide show
  1. package/dist/cjs/components/Axis/AxisX.d.ts +2 -1
  2. package/dist/cjs/components/Axis/AxisX.js +149 -143
  3. package/dist/cjs/components/Axis/AxisY.d.ts +2 -1
  4. package/dist/cjs/components/Axis/AxisY.js +113 -91
  5. package/dist/cjs/components/ChartInner/index.js +23 -10
  6. package/dist/cjs/components/ChartInner/useChartInnerHandlers.d.ts +1 -1
  7. package/dist/cjs/components/ChartInner/useChartInnerProps.d.ts +8 -5
  8. package/dist/cjs/components/ChartInner/useChartInnerProps.js +55 -9
  9. package/dist/cjs/components/ChartInner/utils.d.ts +3 -0
  10. package/dist/cjs/components/ChartInner/utils.js +28 -0
  11. package/dist/cjs/components/Legend/index.js +203 -195
  12. package/dist/cjs/components/Tooltip/ChartTooltipContent.d.ts +1 -1
  13. package/dist/cjs/components/Tooltip/DefaultContent.d.ts +1 -1
  14. package/dist/cjs/components/Tooltip/DefaultContent.js +1 -1
  15. package/dist/cjs/components/Tooltip/index.d.ts +1 -1
  16. package/dist/cjs/hooks/hooks-utils/index.d.ts +1 -0
  17. package/dist/cjs/hooks/hooks-utils/index.js +1 -0
  18. package/dist/cjs/hooks/hooks-utils/zoom.d.ts +8 -0
  19. package/dist/cjs/hooks/hooks-utils/zoom.js +81 -0
  20. package/dist/cjs/hooks/useAxisScales/index.d.ts +4 -2
  21. package/dist/cjs/hooks/useAxisScales/index.js +22 -8
  22. package/dist/cjs/hooks/useBrush/index.d.ts +3 -0
  23. package/dist/cjs/hooks/useBrush/index.js +70 -0
  24. package/dist/cjs/hooks/useBrush/styles.css +10 -0
  25. package/dist/cjs/hooks/useBrush/types.d.ts +24 -0
  26. package/dist/cjs/hooks/useBrush/types.js +1 -0
  27. package/dist/cjs/hooks/useChartDimensions/index.d.ts +3 -3
  28. package/dist/cjs/hooks/useChartDimensions/index.js +2 -2
  29. package/dist/cjs/hooks/useChartDimensions/utils.d.ts +2 -2
  30. package/dist/cjs/hooks/useChartOptions/chart.d.ts +2 -1
  31. package/dist/cjs/hooks/useChartOptions/chart.js +80 -1
  32. package/dist/cjs/hooks/useChartOptions/index.js +3 -2
  33. package/dist/cjs/hooks/useChartOptions/types.d.ts +3 -1
  34. package/dist/cjs/hooks/useChartOptions/x-axis.d.ts +3 -3
  35. package/dist/cjs/hooks/useChartOptions/x-axis.js +11 -11
  36. package/dist/cjs/hooks/useChartOptions/y-axis.d.ts +3 -3
  37. package/dist/cjs/hooks/useChartOptions/y-axis.js +22 -18
  38. package/dist/cjs/hooks/useCrosshair/index.d.ts +1 -1
  39. package/dist/cjs/hooks/useCrosshair/index.js +2 -2
  40. package/dist/cjs/hooks/useSeries/index.d.ts +8 -6
  41. package/dist/cjs/hooks/useSeries/index.js +41 -22
  42. package/dist/cjs/hooks/useSeries/prepare-bar-y.d.ts +27 -2
  43. package/dist/cjs/hooks/useSeries/prepare-bar-y.js +5 -5
  44. package/dist/cjs/hooks/useSeries/prepare-legend.d.ts +1 -1
  45. package/dist/cjs/hooks/useSeries/prepare-legend.js +6 -5
  46. package/dist/cjs/hooks/useSeries/prepareSeries.d.ts +1 -1
  47. package/dist/cjs/hooks/useSeries/prepareSeries.js +2 -2
  48. package/dist/cjs/hooks/useShapes/area/index.js +1 -1
  49. package/dist/cjs/hooks/useShapes/area/prepare-data.d.ts +1 -1
  50. package/dist/cjs/hooks/useShapes/area/prepare-data.js +32 -16
  51. package/dist/cjs/hooks/useShapes/area/types.d.ts +1 -0
  52. package/dist/cjs/hooks/useShapes/bar-x/prepare-data.d.ts +1 -1
  53. package/dist/cjs/hooks/useShapes/bar-x/prepare-data.js +17 -13
  54. package/dist/cjs/hooks/useShapes/bar-y/prepare-data.d.ts +1 -1
  55. package/dist/cjs/hooks/useShapes/bar-y/prepare-data.js +6 -6
  56. package/dist/cjs/hooks/useShapes/index.d.ts +1 -1
  57. package/dist/cjs/hooks/useShapes/index.js +40 -31
  58. package/dist/cjs/hooks/useShapes/line/prepare-data.d.ts +1 -1
  59. package/dist/cjs/hooks/useShapes/line/prepare-data.js +14 -11
  60. package/dist/cjs/hooks/useShapes/line/types.d.ts +1 -0
  61. package/dist/cjs/hooks/useShapes/marker.js +2 -2
  62. package/dist/cjs/hooks/useShapes/pie/index.js +3 -3
  63. package/dist/cjs/hooks/useShapes/pie/prepare-data.d.ts +1 -1
  64. package/dist/cjs/hooks/useShapes/pie/prepare-data.js +15 -11
  65. package/dist/cjs/hooks/useShapes/radar/prepare-data.d.ts +1 -1
  66. package/dist/cjs/hooks/useShapes/radar/prepare-data.js +6 -7
  67. package/dist/cjs/hooks/useShapes/radar/types.d.ts +1 -0
  68. package/dist/cjs/hooks/useShapes/scatter/index.js +0 -1
  69. package/dist/cjs/hooks/useShapes/scatter/prepare-data.js +2 -0
  70. package/dist/cjs/hooks/useShapes/scatter/types.d.ts +1 -0
  71. package/dist/cjs/hooks/useShapes/treemap/prepare-data.d.ts +1 -1
  72. package/dist/cjs/hooks/useShapes/treemap/prepare-data.js +19 -16
  73. package/dist/cjs/hooks/useShapes/waterfall/prepare-data.d.ts +1 -1
  74. package/dist/cjs/hooks/useShapes/waterfall/prepare-data.js +8 -7
  75. package/dist/cjs/hooks/useZoom/index.d.ts +18 -0
  76. package/dist/cjs/hooks/useZoom/index.js +54 -0
  77. package/dist/cjs/hooks/useZoom/types.d.ts +19 -0
  78. package/dist/cjs/hooks/useZoom/types.js +1 -0
  79. package/dist/cjs/hooks/useZoom/utils.d.ts +12 -0
  80. package/dist/cjs/hooks/useZoom/utils.js +128 -0
  81. package/dist/cjs/types/chart/chart.d.ts +5 -0
  82. package/dist/cjs/types/chart/pie.d.ts +1 -1
  83. package/dist/cjs/types/chart/tooltip.d.ts +1 -1
  84. package/dist/cjs/types/chart/zoom.d.ts +36 -0
  85. package/dist/cjs/types/chart/zoom.js +1 -0
  86. package/dist/cjs/types/index.d.ts +1 -0
  87. package/dist/cjs/types/index.js +1 -0
  88. package/dist/cjs/types/misc.d.ts +7 -0
  89. package/dist/cjs/utils/chart/axis-generators/bottom.d.ts +1 -1
  90. package/dist/cjs/utils/chart/axis-generators/bottom.js +29 -28
  91. package/dist/cjs/utils/chart/axis.d.ts +1 -1
  92. package/dist/cjs/utils/chart/axis.js +2 -2
  93. package/dist/cjs/utils/chart/get-closest-data.js +1 -1
  94. package/dist/cjs/utils/chart/text.d.ts +7 -7
  95. package/dist/cjs/utils/chart/text.js +45 -30
  96. package/dist/cjs/utils/chart-ui/pie-center-text.d.ts +1 -1
  97. package/dist/cjs/utils/chart-ui/pie-center-text.js +2 -2
  98. package/dist/cjs/validation/index.d.ts +1 -1
  99. package/dist/cjs/validation/index.js +16 -16
  100. package/dist/esm/components/Axis/AxisX.d.ts +2 -1
  101. package/dist/esm/components/Axis/AxisX.js +149 -143
  102. package/dist/esm/components/Axis/AxisY.d.ts +2 -1
  103. package/dist/esm/components/Axis/AxisY.js +113 -91
  104. package/dist/esm/components/ChartInner/index.js +23 -10
  105. package/dist/esm/components/ChartInner/useChartInnerHandlers.d.ts +1 -1
  106. package/dist/esm/components/ChartInner/useChartInnerProps.d.ts +8 -5
  107. package/dist/esm/components/ChartInner/useChartInnerProps.js +55 -9
  108. package/dist/esm/components/ChartInner/utils.d.ts +3 -0
  109. package/dist/esm/components/ChartInner/utils.js +28 -0
  110. package/dist/esm/components/Legend/index.js +203 -195
  111. package/dist/esm/components/Tooltip/ChartTooltipContent.d.ts +1 -1
  112. package/dist/esm/components/Tooltip/DefaultContent.d.ts +1 -1
  113. package/dist/esm/components/Tooltip/DefaultContent.js +1 -1
  114. package/dist/esm/components/Tooltip/index.d.ts +1 -1
  115. package/dist/esm/hooks/hooks-utils/index.d.ts +1 -0
  116. package/dist/esm/hooks/hooks-utils/index.js +1 -0
  117. package/dist/esm/hooks/hooks-utils/zoom.d.ts +8 -0
  118. package/dist/esm/hooks/hooks-utils/zoom.js +81 -0
  119. package/dist/esm/hooks/useAxisScales/index.d.ts +4 -2
  120. package/dist/esm/hooks/useAxisScales/index.js +22 -8
  121. package/dist/esm/hooks/useBrush/index.d.ts +3 -0
  122. package/dist/esm/hooks/useBrush/index.js +70 -0
  123. package/dist/esm/hooks/useBrush/styles.css +10 -0
  124. package/dist/esm/hooks/useBrush/types.d.ts +24 -0
  125. package/dist/esm/hooks/useBrush/types.js +1 -0
  126. package/dist/esm/hooks/useChartDimensions/index.d.ts +3 -3
  127. package/dist/esm/hooks/useChartDimensions/index.js +2 -2
  128. package/dist/esm/hooks/useChartDimensions/utils.d.ts +2 -2
  129. package/dist/esm/hooks/useChartOptions/chart.d.ts +2 -1
  130. package/dist/esm/hooks/useChartOptions/chart.js +80 -1
  131. package/dist/esm/hooks/useChartOptions/index.js +3 -2
  132. package/dist/esm/hooks/useChartOptions/types.d.ts +3 -1
  133. package/dist/esm/hooks/useChartOptions/x-axis.d.ts +3 -3
  134. package/dist/esm/hooks/useChartOptions/x-axis.js +11 -11
  135. package/dist/esm/hooks/useChartOptions/y-axis.d.ts +3 -3
  136. package/dist/esm/hooks/useChartOptions/y-axis.js +22 -18
  137. package/dist/esm/hooks/useCrosshair/index.d.ts +1 -1
  138. package/dist/esm/hooks/useCrosshair/index.js +2 -2
  139. package/dist/esm/hooks/useSeries/index.d.ts +8 -6
  140. package/dist/esm/hooks/useSeries/index.js +41 -22
  141. package/dist/esm/hooks/useSeries/prepare-bar-y.d.ts +27 -2
  142. package/dist/esm/hooks/useSeries/prepare-bar-y.js +5 -5
  143. package/dist/esm/hooks/useSeries/prepare-legend.d.ts +1 -1
  144. package/dist/esm/hooks/useSeries/prepare-legend.js +6 -5
  145. package/dist/esm/hooks/useSeries/prepareSeries.d.ts +1 -1
  146. package/dist/esm/hooks/useSeries/prepareSeries.js +2 -2
  147. package/dist/esm/hooks/useShapes/area/index.js +1 -1
  148. package/dist/esm/hooks/useShapes/area/prepare-data.d.ts +1 -1
  149. package/dist/esm/hooks/useShapes/area/prepare-data.js +32 -16
  150. package/dist/esm/hooks/useShapes/area/types.d.ts +1 -0
  151. package/dist/esm/hooks/useShapes/bar-x/prepare-data.d.ts +1 -1
  152. package/dist/esm/hooks/useShapes/bar-x/prepare-data.js +17 -13
  153. package/dist/esm/hooks/useShapes/bar-y/prepare-data.d.ts +1 -1
  154. package/dist/esm/hooks/useShapes/bar-y/prepare-data.js +6 -6
  155. package/dist/esm/hooks/useShapes/index.d.ts +1 -1
  156. package/dist/esm/hooks/useShapes/index.js +40 -31
  157. package/dist/esm/hooks/useShapes/line/prepare-data.d.ts +1 -1
  158. package/dist/esm/hooks/useShapes/line/prepare-data.js +14 -11
  159. package/dist/esm/hooks/useShapes/line/types.d.ts +1 -0
  160. package/dist/esm/hooks/useShapes/marker.js +2 -2
  161. package/dist/esm/hooks/useShapes/pie/index.js +3 -3
  162. package/dist/esm/hooks/useShapes/pie/prepare-data.d.ts +1 -1
  163. package/dist/esm/hooks/useShapes/pie/prepare-data.js +15 -11
  164. package/dist/esm/hooks/useShapes/radar/prepare-data.d.ts +1 -1
  165. package/dist/esm/hooks/useShapes/radar/prepare-data.js +6 -7
  166. package/dist/esm/hooks/useShapes/radar/types.d.ts +1 -0
  167. package/dist/esm/hooks/useShapes/scatter/index.js +0 -1
  168. package/dist/esm/hooks/useShapes/scatter/prepare-data.js +2 -0
  169. package/dist/esm/hooks/useShapes/scatter/types.d.ts +1 -0
  170. package/dist/esm/hooks/useShapes/treemap/prepare-data.d.ts +1 -1
  171. package/dist/esm/hooks/useShapes/treemap/prepare-data.js +19 -16
  172. package/dist/esm/hooks/useShapes/waterfall/prepare-data.d.ts +1 -1
  173. package/dist/esm/hooks/useShapes/waterfall/prepare-data.js +8 -7
  174. package/dist/esm/hooks/useZoom/index.d.ts +18 -0
  175. package/dist/esm/hooks/useZoom/index.js +54 -0
  176. package/dist/esm/hooks/useZoom/types.d.ts +19 -0
  177. package/dist/esm/hooks/useZoom/types.js +1 -0
  178. package/dist/esm/hooks/useZoom/utils.d.ts +12 -0
  179. package/dist/esm/hooks/useZoom/utils.js +128 -0
  180. package/dist/esm/types/chart/chart.d.ts +5 -0
  181. package/dist/esm/types/chart/pie.d.ts +1 -1
  182. package/dist/esm/types/chart/tooltip.d.ts +1 -1
  183. package/dist/esm/types/chart/zoom.d.ts +36 -0
  184. package/dist/esm/types/chart/zoom.js +1 -0
  185. package/dist/esm/types/index.d.ts +1 -0
  186. package/dist/esm/types/index.js +1 -0
  187. package/dist/esm/types/misc.d.ts +7 -0
  188. package/dist/esm/utils/chart/axis-generators/bottom.d.ts +1 -1
  189. package/dist/esm/utils/chart/axis-generators/bottom.js +29 -28
  190. package/dist/esm/utils/chart/axis.d.ts +1 -1
  191. package/dist/esm/utils/chart/axis.js +2 -2
  192. package/dist/esm/utils/chart/get-closest-data.js +1 -1
  193. package/dist/esm/utils/chart/text.d.ts +7 -7
  194. package/dist/esm/utils/chart/text.js +45 -30
  195. package/dist/esm/utils/chart-ui/pie-center-text.d.ts +1 -1
  196. package/dist/esm/utils/chart-ui/pie-center-text.js +2 -2
  197. package/dist/esm/validation/index.d.ts +1 -1
  198. package/dist/esm/validation/index.js +16 -16
  199. package/package.json +2 -1
@@ -14,10 +14,10 @@ export declare function getLabelsSize({ labels, style, rotation, html, }: {
14
14
  style?: BaseTextStyle & React.CSSProperties;
15
15
  rotation?: number;
16
16
  html?: boolean;
17
- }): {
17
+ }): Promise<{
18
18
  maxHeight: number;
19
19
  maxWidth: number;
20
- };
20
+ }>;
21
21
  export type TextRow = {
22
22
  text: string;
23
23
  y: number;
@@ -26,15 +26,15 @@ export declare function wrapText(args: {
26
26
  text: string;
27
27
  style?: BaseTextStyle;
28
28
  width: number;
29
- }): TextRow[];
29
+ }): Promise<TextRow[]>;
30
30
  export declare function getTextSizeFn({ style }: {
31
31
  style: BaseTextStyle;
32
- }): (str: string) => {
32
+ }): (str: string) => Promise<{
33
33
  width: number;
34
34
  height: number;
35
- };
35
+ }>;
36
36
  export declare function getTextWithElipsis({ text: originalText, getTextWidth, maxWidth, }: {
37
37
  text: string;
38
- getTextWidth: (s: string) => number;
38
+ getTextWidth: (s: string) => number | Promise<number>;
39
39
  maxWidth: number;
40
- }): string;
40
+ }): Promise<string>;
@@ -85,12 +85,21 @@ function renderLabels(selection, { labels, style = {}, attrs = {}, }) {
85
85
  .html((d) => d);
86
86
  return text;
87
87
  }
88
- export function getLabelsSize({ labels, style, rotation, html, }) {
89
- var _a, _b, _c, _d, _e, _f, _g;
88
+ // since we don't know in advance the font that will be used for the text,
89
+ // we need to wait for it and only then we can count all the sizes.
90
+ export async function getLabelsSize({ labels, style, rotation, html, }) {
91
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
90
92
  if (!labels.filter(Boolean).length) {
91
93
  return { maxHeight: 0, maxWidth: 0 };
92
94
  }
93
- const container = select(document.body).append('div');
95
+ const container = select(document.body)
96
+ .append('div')
97
+ .style('visibility', 'hidden')
98
+ .style('position', 'absolute')
99
+ .style('top', '-200vw')
100
+ .style('left', '-200vwx')
101
+ .style('width', '100vw')
102
+ .style('height', '100vh');
94
103
  const result = { maxHeight: 0, maxWidth: 0 };
95
104
  let labelWrapper;
96
105
  if (html) {
@@ -103,17 +112,18 @@ export function getLabelsSize({ labels, style, rotation, html, }) {
103
112
  .style('max-width', (_c = style === null || style === void 0 ? void 0 : style.maxWidth) !== null && _c !== void 0 ? _c : '')
104
113
  .style('max-height', (_d = style === null || style === void 0 ? void 0 : style.maxHeight) !== null && _d !== void 0 ? _d : '')
105
114
  .node();
106
- const { height, width } = labels.reduce((acc, l) => {
107
- var _a, _b;
115
+ let height = 0;
116
+ let width = 0;
117
+ for (let i = 0; i < labels.length; i++) {
118
+ const l = labels[i];
108
119
  if (labelWrapper) {
109
120
  labelWrapper.innerHTML = l;
110
121
  }
122
+ await document.fonts.ready;
111
123
  const rect = labelWrapper === null || labelWrapper === void 0 ? void 0 : labelWrapper.getBoundingClientRect();
112
- return {
113
- width: Math.max(acc.width, (_a = rect === null || rect === void 0 ? void 0 : rect.width) !== null && _a !== void 0 ? _a : 0),
114
- height: Math.max(acc.height, (_b = rect === null || rect === void 0 ? void 0 : rect.height) !== null && _b !== void 0 ? _b : 0),
115
- };
116
- }, { height: 0, width: 0 });
124
+ width = Math.max(width, (_e = rect === null || rect === void 0 ? void 0 : rect.width) !== null && _e !== void 0 ? _e : 0);
125
+ height = Math.max(height, (_f = rect === null || rect === void 0 ? void 0 : rect.height) !== null && _f !== void 0 ? _f : 0);
126
+ }
117
127
  result.maxWidth = width;
118
128
  result.maxHeight = height;
119
129
  }
@@ -125,23 +135,26 @@ export function getLabelsSize({ labels, style, rotation, html, }) {
125
135
  .attr('text-anchor', rotation > 0 ? 'start' : 'end')
126
136
  .style('transform', `rotate(${rotation}deg)`);
127
137
  }
128
- const rect = (_e = svg.select('g').node()) === null || _e === void 0 ? void 0 : _e.getBoundingClientRect();
129
- result.maxWidth = (_f = rect === null || rect === void 0 ? void 0 : rect.width) !== null && _f !== void 0 ? _f : 0;
130
- result.maxHeight = (_g = rect === null || rect === void 0 ? void 0 : rect.height) !== null && _g !== void 0 ? _g : 0;
138
+ await document.fonts.ready;
139
+ const rect = (_g = svg.select('g').node()) === null || _g === void 0 ? void 0 : _g.getBoundingClientRect();
140
+ result.maxWidth = (_h = rect === null || rect === void 0 ? void 0 : rect.width) !== null && _h !== void 0 ? _h : 0;
141
+ result.maxHeight = (_j = rect === null || rect === void 0 ? void 0 : rect.height) !== null && _j !== void 0 ? _j : 0;
131
142
  }
132
143
  container.remove();
133
144
  return result;
134
145
  }
135
- export function wrapText(args) {
146
+ export async function wrapText(args) {
136
147
  const { text, style, width } = args;
137
- const height = getLabelsSize({
148
+ const height = (await getLabelsSize({
138
149
  labels: [text],
139
150
  style: style,
140
- }).maxHeight;
151
+ })).maxHeight;
141
152
  // @ts-ignore
142
153
  const segmenter = new Intl.Segmenter([], { granularity: 'word' });
143
154
  const segments = Array.from(segmenter.segment(text));
144
- return segments.reduce((acc, s) => {
155
+ const acc = [];
156
+ for (let i = 0; i < segments.length; i++) {
157
+ const s = segments[i];
145
158
  const item = s;
146
159
  if (!acc.length) {
147
160
  acc.push({
@@ -151,10 +164,10 @@ export function wrapText(args) {
151
164
  }
152
165
  let lastRow = acc[acc.length - 1];
153
166
  if (item.isWordLike &&
154
- getLabelsSize({
167
+ (await getLabelsSize({
155
168
  labels: [lastRow.text + item.segment],
156
169
  style,
157
- }).maxWidth > width) {
170
+ })).maxWidth > width) {
158
171
  lastRow = {
159
172
  text: '',
160
173
  y: acc.length * height,
@@ -162,8 +175,8 @@ export function wrapText(args) {
162
175
  acc.push(lastRow);
163
176
  }
164
177
  lastRow.text += item.segment;
165
- return acc;
166
- }, []);
178
+ }
179
+ return acc;
167
180
  }
168
181
  const entityMap = {
169
182
  '&': '&amp;',
@@ -182,31 +195,33 @@ function unescapeHtml(str) {
182
195
  }
183
196
  export function getTextSizeFn({ style }) {
184
197
  const map = {};
185
- const setSymbolSize = (s) => {
198
+ const setSymbolSize = async (s) => {
186
199
  const labels = [s === ' ' ? '&nbsp;' : s];
187
- const size = getLabelsSize({
200
+ const size = await getLabelsSize({
188
201
  labels,
189
202
  style,
190
203
  });
191
204
  map[s] = { width: size.maxWidth, height: size.maxHeight };
192
205
  };
193
- return (str) => {
206
+ return async (str) => {
194
207
  let width = 0;
195
208
  let height = 0;
196
- [...unescapeHtml(str)].forEach((s) => {
209
+ const symbols = unescapeHtml(str);
210
+ for (let i = 0; i < symbols.length; i++) {
211
+ const s = symbols[i];
197
212
  if (!map[s]) {
198
- setSymbolSize(s);
213
+ await setSymbolSize(s);
199
214
  }
200
215
  width += map[s].width;
201
216
  height = Math.max(height, map[s].height);
202
- });
217
+ }
203
218
  return { width, height };
204
219
  };
205
220
  }
206
221
  // We ignore an inaccuracy of less than a pixel.
207
222
  // To do this, we round the font size down when comparing it, and the size of the allowed space up.
208
- export function getTextWithElipsis({ text: originalText, getTextWidth, maxWidth, }) {
209
- let textWidth = Math.floor(getTextWidth(originalText));
223
+ export async function getTextWithElipsis({ text: originalText, getTextWidth, maxWidth, }) {
224
+ let textWidth = Math.floor(await getTextWidth(originalText));
210
225
  const textMaxWidth = Math.ceil(maxWidth);
211
226
  if (textWidth <= textMaxWidth) {
212
227
  return originalText;
@@ -214,7 +229,7 @@ export function getTextWithElipsis({ text: originalText, getTextWidth, maxWidth,
214
229
  let text = originalText + '…';
215
230
  while (textWidth > textMaxWidth && text.length > 2) {
216
231
  text = text.slice(0, -2) + '…';
217
- textWidth = Math.floor(getTextWidth(text));
232
+ textWidth = Math.floor(await getTextWidth(text));
218
233
  }
219
234
  if (textWidth > textMaxWidth) {
220
235
  text = '';
@@ -6,4 +6,4 @@ export declare function pieCenterText(text: string, options?: {
6
6
  series: {
7
7
  innerRadius: number;
8
8
  };
9
- }) => SVGGElement | null) | undefined;
9
+ }) => Promise<SVGGElement | null>) | undefined;
@@ -9,10 +9,10 @@ export function pieCenterText(text, options) {
9
9
  return undefined;
10
10
  }
11
11
  const color = get(options, 'color', 'currentColor');
12
- return function (args) {
12
+ return async function (args) {
13
13
  var _a, _b;
14
14
  let fontSize = MAX_FONT_SIZE;
15
- const textSize = getLabelsSize({ labels: [text], style: { fontSize: `${fontSize}px` } });
15
+ const textSize = await getLabelsSize({ labels: [text], style: { fontSize: `${fontSize}px` } });
16
16
  let availableSpace = args.series.innerRadius * 2;
17
17
  const padding = (_a = calculateNumericProperty({
18
18
  base: availableSpace,
@@ -1,2 +1,2 @@
1
1
  import type { ChartData } from '../types';
2
- export declare const validateData: (data?: ChartData) => void;
2
+ export declare function validateData(data?: ChartData): void;
@@ -4,7 +4,7 @@ import { DEFAULT_AXIS_TYPE, SeriesType } from '../constants';
4
4
  import { i18n } from '../i18n';
5
5
  import { CHART_ERROR_CODE, ChartError } from '../libs';
6
6
  const AVAILABLE_SERIES_TYPES = Object.values(SeriesType);
7
- const validateXYSeries = (args) => {
7
+ function validateXYSeries(args) {
8
8
  const { series, xAxis, yAxis = [] } = args;
9
9
  const yAxisIndex = get(series, 'yAxis', 0);
10
10
  const seriesYAxis = yAxis[yAxisIndex];
@@ -94,8 +94,8 @@ const validateXYSeries = (args) => {
94
94
  }
95
95
  }
96
96
  });
97
- };
98
- const validateAxisPlotValues = (args) => {
97
+ }
98
+ function validateAxisPlotValues(args) {
99
99
  const { series, xAxis, yAxis = [] } = args;
100
100
  const yAxisIndex = get(series, 'yAxis', 0);
101
101
  const seriesYAxis = yAxis[yAxisIndex];
@@ -236,8 +236,8 @@ const validateAxisPlotValues = (args) => {
236
236
  }
237
237
  }
238
238
  });
239
- };
240
- const validatePieSeries = ({ series }) => {
239
+ }
240
+ function validatePieSeries({ series }) {
241
241
  series.data.forEach(({ value }) => {
242
242
  if (typeof value !== 'number') {
243
243
  throw new ChartError({
@@ -246,8 +246,8 @@ const validatePieSeries = ({ series }) => {
246
246
  });
247
247
  }
248
248
  });
249
- };
250
- const validateStacking = ({ series }) => {
249
+ }
250
+ function validateStacking({ series }) {
251
251
  const availableStackingValues = ['normal', 'percent'];
252
252
  if (series.stacking && !availableStackingValues.includes(series.stacking)) {
253
253
  throw new ChartError({
@@ -258,8 +258,8 @@ const validateStacking = ({ series }) => {
258
258
  }),
259
259
  });
260
260
  }
261
- };
262
- const validateTreemapSeries = ({ series }) => {
261
+ }
262
+ function validateTreemapSeries({ series }) {
263
263
  const parentIds = {};
264
264
  series.data.forEach((d) => {
265
265
  if (d.parentId && !parentIds[d.parentId]) {
@@ -290,8 +290,8 @@ const validateTreemapSeries = ({ series }) => {
290
290
  });
291
291
  }
292
292
  });
293
- };
294
- const validateSeries = (args) => {
293
+ }
294
+ function validateSeries(args) {
295
295
  const { series, xAxis, yAxis } = args;
296
296
  if (!AVAILABLE_SERIES_TYPES.includes(series.type)) {
297
297
  throw new ChartError({
@@ -324,8 +324,8 @@ const validateSeries = (args) => {
324
324
  validateTreemapSeries({ series });
325
325
  }
326
326
  }
327
- };
328
- const countSeriesByType = (args) => {
327
+ }
328
+ function countSeriesByType(args) {
329
329
  const { series, type } = args;
330
330
  let count = 0;
331
331
  series.forEach((s) => {
@@ -334,8 +334,8 @@ const countSeriesByType = (args) => {
334
334
  }
335
335
  });
336
336
  return count;
337
- };
338
- export const validateData = (data) => {
337
+ }
338
+ export function validateData(data) {
339
339
  if (isEmpty(data) || isEmpty(data.series) || isEmpty(data.series.data)) {
340
340
  throw new ChartError({
341
341
  code: CHART_ERROR_CODE.NO_DATA,
@@ -361,4 +361,4 @@ export const validateData = (data) => {
361
361
  data.series.data.forEach((series) => {
362
362
  validateSeries({ series, yAxis: data.yAxis, xAxis: data.xAxis });
363
363
  });
364
- };
364
+ }
@@ -7,7 +7,8 @@ type Props = {
7
7
  height: number;
8
8
  scale: ChartScale;
9
9
  split: PreparedSplit;
10
- plotRef?: React.MutableRefObject<SVGGElement | null>;
10
+ plotBeforeRef?: React.MutableRefObject<SVGGElement | null>;
11
+ plotAfterRef?: React.MutableRefObject<SVGGElement | null>;
11
12
  leftmostLimit?: number;
12
13
  };
13
14
  export declare function getTitlePosition(args: {
@@ -42,151 +42,157 @@ 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, plotRef, leftmostLimit } = props;
45
+ const { axis, width, height: totalHeight, scale, split, plotBeforeRef, plotAfterRef, leftmostLimit, } = props;
46
46
  const ref = React.useRef(null);
47
47
  React.useEffect(() => {
48
- if (!ref.current) {
49
- return;
50
- }
51
- const svgElement = select(ref.current);
52
- svgElement.selectAll('*').remove();
53
- const plotDataAttr = 'data-plot-x';
54
- let plotContainer = null;
55
- if (plotRef === null || plotRef === void 0 ? void 0 : plotRef.current) {
56
- plotContainer = select(plotRef.current);
57
- plotContainer.selectAll(`[${plotDataAttr}]`).remove();
58
- }
59
- if (!axis.visible) {
60
- return;
61
- }
62
- let tickItems = [];
63
- if (axis.grid.enabled) {
64
- tickItems = new Array(split.plots.length || 1).fill(null).map((_, index) => {
65
- var _a, _b;
66
- const top = ((_a = split.plots[index]) === null || _a === void 0 ? void 0 : _a.top) || 0;
67
- const height = ((_b = split.plots[index]) === null || _b === void 0 ? void 0 : _b.height) || totalHeight;
68
- return [-top, -(top + height)];
69
- });
70
- }
71
- const axisScale = scale;
72
- const xAxisGenerator = axisBottom({
73
- leftmostLimit,
74
- scale: axisScale,
75
- ticks: {
76
- items: tickItems,
77
- labelFormat: getLabelFormatter({ axis, scale }),
78
- labelsPaddings: axis.labels.padding,
79
- labelsMargin: axis.labels.margin,
80
- labelsStyle: axis.labels.style,
81
- labelsMaxWidth: axis.labels.maxWidth,
82
- labelsLineHeight: axis.labels.lineHeight,
83
- count: getTicksCount({ axis, range: width }),
84
- maxTickCount: getMaxTickCount({ axis, width }),
85
- rotation: axis.labels.rotation,
86
- },
87
- domain: {
88
- size: width,
89
- color: axis.lineColor,
90
- },
91
- });
92
- svgElement.call(xAxisGenerator).attr('class', b());
93
- // add an axis header if necessary
94
- if (axis.title.text) {
95
- const titleRows = getAxisTitleRows({ axis, textMaxWidth: width });
96
- svgElement
97
- .append('text')
98
- .attr('class', b('title'))
99
- .attr('transform', () => {
100
- const { x, y } = getTitlePosition({ axis, width, rowCount: titleRows.length });
101
- return `translate(${x}, ${y})`;
102
- })
103
- .attr('font-size', axis.title.style.fontSize)
104
- .attr('text-anchor', 'middle')
105
- .selectAll('tspan')
106
- .data(titleRows)
107
- .join('tspan')
108
- .attr('x', 0)
109
- .attr('y', (d) => d.y)
110
- .text((d) => d.text)
111
- .each((_d, index, nodes) => {
112
- if (index === axis.title.maxRowCount - 1) {
113
- handleOverflowingText(nodes[index], width);
114
- }
48
+ (async () => {
49
+ if (!ref.current) {
50
+ return;
51
+ }
52
+ const svgElement = select(ref.current);
53
+ svgElement.selectAll('*').remove();
54
+ const plotDataAttr = 'data-plot-x';
55
+ let plotBeforeContainer = null;
56
+ let plotAfterContainer = null;
57
+ if (plotBeforeRef === null || plotBeforeRef === void 0 ? void 0 : plotBeforeRef.current) {
58
+ plotBeforeContainer = select(plotBeforeRef.current);
59
+ plotBeforeContainer.selectAll(`[${plotDataAttr}]`).remove();
60
+ }
61
+ if (plotAfterRef === null || plotAfterRef === void 0 ? void 0 : plotAfterRef.current) {
62
+ plotAfterContainer = select(plotAfterRef.current);
63
+ plotAfterContainer.selectAll(`[${plotDataAttr}]`).remove();
64
+ }
65
+ if (!axis.visible) {
66
+ return;
67
+ }
68
+ let tickItems = [];
69
+ if (axis.grid.enabled) {
70
+ tickItems = new Array(split.plots.length || 1).fill(null).map((_, index) => {
71
+ var _a, _b;
72
+ const top = ((_a = split.plots[index]) === null || _a === void 0 ? void 0 : _a.top) || 0;
73
+ const height = ((_b = split.plots[index]) === null || _b === void 0 ? void 0 : _b.height) || totalHeight;
74
+ return [-top, -(top + height)];
75
+ });
76
+ }
77
+ const axisScale = scale;
78
+ const xAxisGenerator = await axisBottom({
79
+ leftmostLimit,
80
+ scale: axisScale,
81
+ ticks: {
82
+ items: tickItems,
83
+ labelFormat: getLabelFormatter({ axis, scale }),
84
+ labelsPaddings: axis.labels.padding,
85
+ labelsMargin: axis.labels.margin,
86
+ labelsStyle: axis.labels.style,
87
+ labelsMaxWidth: axis.labels.maxWidth,
88
+ labelsLineHeight: axis.labels.lineHeight,
89
+ count: getTicksCount({ axis, range: width }),
90
+ maxTickCount: getMaxTickCount({ axis, width }),
91
+ rotation: axis.labels.rotation,
92
+ },
93
+ domain: {
94
+ size: width,
95
+ color: axis.lineColor,
96
+ },
115
97
  });
116
- }
117
- // add plot bands
118
- if (plotContainer && axis.plotBands.length > 0) {
119
- const plotBandDataAttr = 'plot-x-band';
120
- const plotBandsSelection = plotContainer
121
- .selectAll(`[${plotBandDataAttr}]`)
122
- .data(axis.plotBands)
123
- .join('g')
124
- .attr(plotDataAttr, 1)
125
- .attr(plotBandDataAttr, 1);
126
- plotBandsSelection
127
- .append('rect')
128
- .attr('x', (band) => {
129
- var _a, _b;
130
- const { from, to } = getBandsPosition({ band, axisScale, axis: 'x' });
131
- const halfBandwidth = ((_b = (_a = axisScale.bandwidth) === null || _a === void 0 ? void 0 : _a.call(axisScale)) !== null && _b !== void 0 ? _b : 0) / 2;
132
- const startPos = halfBandwidth + Math.min(from, to);
133
- return Math.max(0, startPos);
134
- })
135
- .attr('width', (band) => {
136
- const { from, to } = getBandsPosition({ band, axisScale, axis: 'x' });
137
- const startPos = width - Math.min(from, to);
138
- const endPos = Math.min(Math.abs(to - from), startPos);
139
- return Math.min(endPos, width);
140
- })
141
- .attr('y', 0)
142
- .attr('height', totalHeight)
143
- .attr('fill', (band) => band.color)
144
- .attr('opacity', (band) => band.opacity);
145
- plotBandsSelection.each((plotBandData, i, nodes) => {
146
- const plotLineSelection = select(nodes[i]);
147
- if (plotBandData.layerPlacement === 'before') {
148
- plotLineSelection.lower();
149
- }
150
- else {
151
- plotLineSelection.raise();
152
- }
153
- });
154
- }
155
- // add plot lines
156
- if (plotContainer && axis.plotLines.length > 0) {
157
- const plotLineDataAttr = 'plot-x-line';
158
- const plotLinesSelection = plotContainer
159
- .selectAll(`[${plotLineDataAttr}]`)
160
- .data(axis.plotLines)
161
- .join('g')
162
- .attr(plotDataAttr, 1)
163
- .attr(plotLineDataAttr, 1);
164
- const lineGenerator = line();
165
- plotLinesSelection
166
- .append('path')
167
- .attr('d', (plotLine) => {
168
- const plotLineValue = Number(axisScale(plotLine.value));
169
- const points = [
170
- [plotLineValue, 0],
171
- [plotLineValue, totalHeight],
172
- ];
173
- return lineGenerator(points);
174
- })
175
- .attr('stroke', (plotLine) => plotLine.color)
176
- .attr('stroke-width', (plotLine) => plotLine.width)
177
- .attr('stroke-dasharray', (plotLine) => getLineDashArray(plotLine.dashStyle, plotLine.width))
178
- .attr('opacity', (plotLine) => plotLine.opacity);
179
- // set layer placement
180
- plotLinesSelection.each((plotLineData, i, nodes) => {
181
- const plotLineSelection = select(nodes[i]);
182
- if (plotLineData.layerPlacement === 'before') {
183
- plotLineSelection.lower();
184
- }
185
- else {
186
- plotLineSelection.raise();
187
- }
188
- });
189
- }
190
- }, [axis, width, totalHeight, scale, split, plotRef, leftmostLimit]);
98
+ svgElement.call(xAxisGenerator).attr('class', b());
99
+ // add an axis header if necessary
100
+ if (axis.title.text) {
101
+ const titleRows = await getAxisTitleRows({ axis, textMaxWidth: width });
102
+ const titleClassName = b('title');
103
+ svgElement.selectAll(`.${titleClassName}`).remove();
104
+ svgElement
105
+ .append('text')
106
+ .attr('class', titleClassName)
107
+ .attr('transform', () => {
108
+ const { x, y } = getTitlePosition({ axis, width, rowCount: titleRows.length });
109
+ return `translate(${x}, ${y})`;
110
+ })
111
+ .attr('font-size', axis.title.style.fontSize)
112
+ .attr('text-anchor', 'middle')
113
+ .selectAll('tspan')
114
+ .data(titleRows)
115
+ .join('tspan')
116
+ .attr('x', 0)
117
+ .attr('y', (d) => d.y)
118
+ .text((d) => d.text)
119
+ .each((_d, index, nodes) => {
120
+ if (index === axis.title.maxRowCount - 1) {
121
+ handleOverflowingText(nodes[index], width);
122
+ }
123
+ });
124
+ }
125
+ // add plot bands
126
+ if (axis.plotBands.length > 0) {
127
+ const plotBandDataAttr = 'plot-x-band';
128
+ const setPlotBands = (plotContainer, plotBands) => {
129
+ if (!plotContainer || !plotBands.length) {
130
+ return;
131
+ }
132
+ const plotBandsSelection = plotContainer
133
+ .selectAll(`[${plotBandDataAttr}]`)
134
+ .remove()
135
+ .data(plotBands)
136
+ .join('g')
137
+ .attr(plotDataAttr, 1)
138
+ .attr(plotBandDataAttr, 1);
139
+ plotBandsSelection
140
+ .append('rect')
141
+ .attr('x', (band) => {
142
+ var _a, _b;
143
+ const { from, to } = getBandsPosition({ band, axisScale, axis: 'x' });
144
+ const halfBandwidth = ((_b = (_a = axisScale.bandwidth) === null || _a === void 0 ? void 0 : _a.call(axisScale)) !== null && _b !== void 0 ? _b : 0) / 2;
145
+ const startPos = halfBandwidth + Math.min(from, to);
146
+ return Math.max(0, startPos);
147
+ })
148
+ .attr('width', (band) => {
149
+ const { from, to } = getBandsPosition({ band, axisScale, axis: 'x' });
150
+ const startPos = width - Math.min(from, to);
151
+ const endPos = Math.min(Math.abs(to - from), startPos);
152
+ return Math.min(endPos, width);
153
+ })
154
+ .attr('y', 0)
155
+ .attr('height', totalHeight)
156
+ .attr('fill', (band) => band.color)
157
+ .attr('opacity', (band) => band.opacity);
158
+ };
159
+ setPlotBands(plotBeforeContainer, axis.plotBands.filter((d) => d.layerPlacement === 'before'));
160
+ setPlotBands(plotAfterContainer, axis.plotBands.filter((d) => d.layerPlacement === 'after'));
161
+ }
162
+ // add plot lines
163
+ if (axis.plotLines.length > 0) {
164
+ const plotLineDataAttr = 'plot-x-line';
165
+ const setPlotLines = (plotContainer, plotLines) => {
166
+ if (!plotContainer || !plotLines.length) {
167
+ return;
168
+ }
169
+ const plotLinesSelection = plotContainer
170
+ .selectAll(`[${plotLineDataAttr}]`)
171
+ .remove()
172
+ .data(plotLines)
173
+ .join('g')
174
+ .attr(plotDataAttr, 1)
175
+ .attr(plotLineDataAttr, 1);
176
+ const lineGenerator = line();
177
+ plotLinesSelection
178
+ .append('path')
179
+ .attr('d', (plotLine) => {
180
+ const plotLineValue = Number(axisScale(plotLine.value));
181
+ const points = [
182
+ [plotLineValue, 0],
183
+ [plotLineValue, totalHeight],
184
+ ];
185
+ return lineGenerator(points);
186
+ })
187
+ .attr('stroke', (plotLine) => plotLine.color)
188
+ .attr('stroke-width', (plotLine) => plotLine.width)
189
+ .attr('stroke-dasharray', (plotLine) => getLineDashArray(plotLine.dashStyle, plotLine.width))
190
+ .attr('opacity', (plotLine) => plotLine.opacity);
191
+ };
192
+ setPlotLines(plotBeforeContainer, axis.plotLines.filter((d) => d.layerPlacement === 'before'));
193
+ setPlotLines(plotAfterContainer, axis.plotLines.filter((d) => d.layerPlacement === 'after'));
194
+ }
195
+ })();
196
+ }, [axis, width, totalHeight, scale, split, leftmostLimit, plotBeforeRef, plotAfterRef]);
191
197
  return React.createElement("g", { ref: ref });
192
198
  });
@@ -7,7 +7,8 @@ type Props = {
7
7
  width: number;
8
8
  height: number;
9
9
  split: PreparedSplit;
10
- plotRef?: React.MutableRefObject<SVGGElement | null>;
10
+ plotBeforeRef?: React.MutableRefObject<SVGGElement | null>;
11
+ plotAfterRef?: React.MutableRefObject<SVGGElement | null>;
11
12
  bottomLimit?: number;
12
13
  };
13
14
  export declare const AxisY: (props: Props) => React.JSX.Element;