@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.
- package/dist/cjs/components/Axis/AxisX.d.ts +2 -1
- package/dist/cjs/components/Axis/AxisX.js +149 -143
- package/dist/cjs/components/Axis/AxisY.d.ts +2 -1
- package/dist/cjs/components/Axis/AxisY.js +113 -91
- package/dist/cjs/components/ChartInner/index.js +23 -10
- package/dist/cjs/components/ChartInner/useChartInnerHandlers.d.ts +1 -1
- package/dist/cjs/components/ChartInner/useChartInnerProps.d.ts +8 -5
- package/dist/cjs/components/ChartInner/useChartInnerProps.js +55 -9
- package/dist/cjs/components/ChartInner/utils.d.ts +3 -0
- package/dist/cjs/components/ChartInner/utils.js +28 -0
- package/dist/cjs/components/Legend/index.js +203 -195
- package/dist/cjs/components/Tooltip/ChartTooltipContent.d.ts +1 -1
- package/dist/cjs/components/Tooltip/DefaultContent.d.ts +1 -1
- package/dist/cjs/components/Tooltip/DefaultContent.js +1 -1
- package/dist/cjs/components/Tooltip/index.d.ts +1 -1
- package/dist/cjs/hooks/hooks-utils/index.d.ts +1 -0
- package/dist/cjs/hooks/hooks-utils/index.js +1 -0
- package/dist/cjs/hooks/hooks-utils/zoom.d.ts +8 -0
- package/dist/cjs/hooks/hooks-utils/zoom.js +81 -0
- package/dist/cjs/hooks/useAxisScales/index.d.ts +4 -2
- package/dist/cjs/hooks/useAxisScales/index.js +22 -8
- package/dist/cjs/hooks/useBrush/index.d.ts +3 -0
- package/dist/cjs/hooks/useBrush/index.js +70 -0
- package/dist/cjs/hooks/useBrush/styles.css +10 -0
- package/dist/cjs/hooks/useBrush/types.d.ts +24 -0
- package/dist/cjs/hooks/useBrush/types.js +1 -0
- package/dist/cjs/hooks/useChartDimensions/index.d.ts +3 -3
- package/dist/cjs/hooks/useChartDimensions/index.js +2 -2
- package/dist/cjs/hooks/useChartDimensions/utils.d.ts +2 -2
- package/dist/cjs/hooks/useChartOptions/chart.d.ts +2 -1
- package/dist/cjs/hooks/useChartOptions/chart.js +80 -1
- package/dist/cjs/hooks/useChartOptions/index.js +3 -2
- package/dist/cjs/hooks/useChartOptions/types.d.ts +3 -1
- package/dist/cjs/hooks/useChartOptions/x-axis.d.ts +3 -3
- package/dist/cjs/hooks/useChartOptions/x-axis.js +11 -11
- package/dist/cjs/hooks/useChartOptions/y-axis.d.ts +3 -3
- package/dist/cjs/hooks/useChartOptions/y-axis.js +22 -18
- package/dist/cjs/hooks/useCrosshair/index.d.ts +1 -1
- package/dist/cjs/hooks/useCrosshair/index.js +2 -2
- package/dist/cjs/hooks/useSeries/index.d.ts +8 -6
- package/dist/cjs/hooks/useSeries/index.js +41 -22
- package/dist/cjs/hooks/useSeries/prepare-bar-y.d.ts +27 -2
- package/dist/cjs/hooks/useSeries/prepare-bar-y.js +5 -5
- package/dist/cjs/hooks/useSeries/prepare-legend.d.ts +1 -1
- package/dist/cjs/hooks/useSeries/prepare-legend.js +6 -5
- package/dist/cjs/hooks/useSeries/prepareSeries.d.ts +1 -1
- package/dist/cjs/hooks/useSeries/prepareSeries.js +2 -2
- package/dist/cjs/hooks/useShapes/area/index.js +1 -1
- package/dist/cjs/hooks/useShapes/area/prepare-data.d.ts +1 -1
- package/dist/cjs/hooks/useShapes/area/prepare-data.js +32 -16
- package/dist/cjs/hooks/useShapes/area/types.d.ts +1 -0
- package/dist/cjs/hooks/useShapes/bar-x/prepare-data.d.ts +1 -1
- package/dist/cjs/hooks/useShapes/bar-x/prepare-data.js +17 -13
- package/dist/cjs/hooks/useShapes/bar-y/prepare-data.d.ts +1 -1
- package/dist/cjs/hooks/useShapes/bar-y/prepare-data.js +6 -6
- package/dist/cjs/hooks/useShapes/index.d.ts +1 -1
- package/dist/cjs/hooks/useShapes/index.js +40 -31
- package/dist/cjs/hooks/useShapes/line/prepare-data.d.ts +1 -1
- package/dist/cjs/hooks/useShapes/line/prepare-data.js +14 -11
- package/dist/cjs/hooks/useShapes/line/types.d.ts +1 -0
- package/dist/cjs/hooks/useShapes/marker.js +2 -2
- package/dist/cjs/hooks/useShapes/pie/index.js +3 -3
- package/dist/cjs/hooks/useShapes/pie/prepare-data.d.ts +1 -1
- package/dist/cjs/hooks/useShapes/pie/prepare-data.js +15 -11
- package/dist/cjs/hooks/useShapes/radar/prepare-data.d.ts +1 -1
- package/dist/cjs/hooks/useShapes/radar/prepare-data.js +6 -7
- package/dist/cjs/hooks/useShapes/radar/types.d.ts +1 -0
- package/dist/cjs/hooks/useShapes/scatter/index.js +0 -1
- package/dist/cjs/hooks/useShapes/scatter/prepare-data.js +2 -0
- package/dist/cjs/hooks/useShapes/scatter/types.d.ts +1 -0
- package/dist/cjs/hooks/useShapes/treemap/prepare-data.d.ts +1 -1
- package/dist/cjs/hooks/useShapes/treemap/prepare-data.js +19 -16
- package/dist/cjs/hooks/useShapes/waterfall/prepare-data.d.ts +1 -1
- package/dist/cjs/hooks/useShapes/waterfall/prepare-data.js +8 -7
- package/dist/cjs/hooks/useZoom/index.d.ts +18 -0
- package/dist/cjs/hooks/useZoom/index.js +54 -0
- package/dist/cjs/hooks/useZoom/types.d.ts +19 -0
- package/dist/cjs/hooks/useZoom/types.js +1 -0
- package/dist/cjs/hooks/useZoom/utils.d.ts +12 -0
- package/dist/cjs/hooks/useZoom/utils.js +128 -0
- package/dist/cjs/types/chart/chart.d.ts +5 -0
- package/dist/cjs/types/chart/pie.d.ts +1 -1
- package/dist/cjs/types/chart/tooltip.d.ts +1 -1
- package/dist/cjs/types/chart/zoom.d.ts +36 -0
- package/dist/cjs/types/chart/zoom.js +1 -0
- package/dist/cjs/types/index.d.ts +1 -0
- package/dist/cjs/types/index.js +1 -0
- package/dist/cjs/types/misc.d.ts +7 -0
- package/dist/cjs/utils/chart/axis-generators/bottom.d.ts +1 -1
- package/dist/cjs/utils/chart/axis-generators/bottom.js +29 -28
- package/dist/cjs/utils/chart/axis.d.ts +1 -1
- package/dist/cjs/utils/chart/axis.js +2 -2
- package/dist/cjs/utils/chart/get-closest-data.js +1 -1
- package/dist/cjs/utils/chart/text.d.ts +7 -7
- package/dist/cjs/utils/chart/text.js +45 -30
- package/dist/cjs/utils/chart-ui/pie-center-text.d.ts +1 -1
- package/dist/cjs/utils/chart-ui/pie-center-text.js +2 -2
- package/dist/cjs/validation/index.d.ts +1 -1
- package/dist/cjs/validation/index.js +16 -16
- package/dist/esm/components/Axis/AxisX.d.ts +2 -1
- package/dist/esm/components/Axis/AxisX.js +149 -143
- package/dist/esm/components/Axis/AxisY.d.ts +2 -1
- package/dist/esm/components/Axis/AxisY.js +113 -91
- package/dist/esm/components/ChartInner/index.js +23 -10
- package/dist/esm/components/ChartInner/useChartInnerHandlers.d.ts +1 -1
- package/dist/esm/components/ChartInner/useChartInnerProps.d.ts +8 -5
- package/dist/esm/components/ChartInner/useChartInnerProps.js +55 -9
- package/dist/esm/components/ChartInner/utils.d.ts +3 -0
- package/dist/esm/components/ChartInner/utils.js +28 -0
- package/dist/esm/components/Legend/index.js +203 -195
- package/dist/esm/components/Tooltip/ChartTooltipContent.d.ts +1 -1
- package/dist/esm/components/Tooltip/DefaultContent.d.ts +1 -1
- package/dist/esm/components/Tooltip/DefaultContent.js +1 -1
- package/dist/esm/components/Tooltip/index.d.ts +1 -1
- package/dist/esm/hooks/hooks-utils/index.d.ts +1 -0
- package/dist/esm/hooks/hooks-utils/index.js +1 -0
- package/dist/esm/hooks/hooks-utils/zoom.d.ts +8 -0
- package/dist/esm/hooks/hooks-utils/zoom.js +81 -0
- package/dist/esm/hooks/useAxisScales/index.d.ts +4 -2
- package/dist/esm/hooks/useAxisScales/index.js +22 -8
- package/dist/esm/hooks/useBrush/index.d.ts +3 -0
- package/dist/esm/hooks/useBrush/index.js +70 -0
- package/dist/esm/hooks/useBrush/styles.css +10 -0
- package/dist/esm/hooks/useBrush/types.d.ts +24 -0
- package/dist/esm/hooks/useBrush/types.js +1 -0
- package/dist/esm/hooks/useChartDimensions/index.d.ts +3 -3
- package/dist/esm/hooks/useChartDimensions/index.js +2 -2
- package/dist/esm/hooks/useChartDimensions/utils.d.ts +2 -2
- package/dist/esm/hooks/useChartOptions/chart.d.ts +2 -1
- package/dist/esm/hooks/useChartOptions/chart.js +80 -1
- package/dist/esm/hooks/useChartOptions/index.js +3 -2
- package/dist/esm/hooks/useChartOptions/types.d.ts +3 -1
- package/dist/esm/hooks/useChartOptions/x-axis.d.ts +3 -3
- package/dist/esm/hooks/useChartOptions/x-axis.js +11 -11
- package/dist/esm/hooks/useChartOptions/y-axis.d.ts +3 -3
- package/dist/esm/hooks/useChartOptions/y-axis.js +22 -18
- package/dist/esm/hooks/useCrosshair/index.d.ts +1 -1
- package/dist/esm/hooks/useCrosshair/index.js +2 -2
- package/dist/esm/hooks/useSeries/index.d.ts +8 -6
- package/dist/esm/hooks/useSeries/index.js +41 -22
- package/dist/esm/hooks/useSeries/prepare-bar-y.d.ts +27 -2
- package/dist/esm/hooks/useSeries/prepare-bar-y.js +5 -5
- package/dist/esm/hooks/useSeries/prepare-legend.d.ts +1 -1
- package/dist/esm/hooks/useSeries/prepare-legend.js +6 -5
- package/dist/esm/hooks/useSeries/prepareSeries.d.ts +1 -1
- package/dist/esm/hooks/useSeries/prepareSeries.js +2 -2
- package/dist/esm/hooks/useShapes/area/index.js +1 -1
- package/dist/esm/hooks/useShapes/area/prepare-data.d.ts +1 -1
- package/dist/esm/hooks/useShapes/area/prepare-data.js +32 -16
- package/dist/esm/hooks/useShapes/area/types.d.ts +1 -0
- package/dist/esm/hooks/useShapes/bar-x/prepare-data.d.ts +1 -1
- package/dist/esm/hooks/useShapes/bar-x/prepare-data.js +17 -13
- package/dist/esm/hooks/useShapes/bar-y/prepare-data.d.ts +1 -1
- package/dist/esm/hooks/useShapes/bar-y/prepare-data.js +6 -6
- package/dist/esm/hooks/useShapes/index.d.ts +1 -1
- package/dist/esm/hooks/useShapes/index.js +40 -31
- package/dist/esm/hooks/useShapes/line/prepare-data.d.ts +1 -1
- package/dist/esm/hooks/useShapes/line/prepare-data.js +14 -11
- package/dist/esm/hooks/useShapes/line/types.d.ts +1 -0
- package/dist/esm/hooks/useShapes/marker.js +2 -2
- package/dist/esm/hooks/useShapes/pie/index.js +3 -3
- package/dist/esm/hooks/useShapes/pie/prepare-data.d.ts +1 -1
- package/dist/esm/hooks/useShapes/pie/prepare-data.js +15 -11
- package/dist/esm/hooks/useShapes/radar/prepare-data.d.ts +1 -1
- package/dist/esm/hooks/useShapes/radar/prepare-data.js +6 -7
- package/dist/esm/hooks/useShapes/radar/types.d.ts +1 -0
- package/dist/esm/hooks/useShapes/scatter/index.js +0 -1
- package/dist/esm/hooks/useShapes/scatter/prepare-data.js +2 -0
- package/dist/esm/hooks/useShapes/scatter/types.d.ts +1 -0
- package/dist/esm/hooks/useShapes/treemap/prepare-data.d.ts +1 -1
- package/dist/esm/hooks/useShapes/treemap/prepare-data.js +19 -16
- package/dist/esm/hooks/useShapes/waterfall/prepare-data.d.ts +1 -1
- package/dist/esm/hooks/useShapes/waterfall/prepare-data.js +8 -7
- package/dist/esm/hooks/useZoom/index.d.ts +18 -0
- package/dist/esm/hooks/useZoom/index.js +54 -0
- package/dist/esm/hooks/useZoom/types.d.ts +19 -0
- package/dist/esm/hooks/useZoom/types.js +1 -0
- package/dist/esm/hooks/useZoom/utils.d.ts +12 -0
- package/dist/esm/hooks/useZoom/utils.js +128 -0
- package/dist/esm/types/chart/chart.d.ts +5 -0
- package/dist/esm/types/chart/pie.d.ts +1 -1
- package/dist/esm/types/chart/tooltip.d.ts +1 -1
- package/dist/esm/types/chart/zoom.d.ts +36 -0
- package/dist/esm/types/chart/zoom.js +1 -0
- package/dist/esm/types/index.d.ts +1 -0
- package/dist/esm/types/index.js +1 -0
- package/dist/esm/types/misc.d.ts +7 -0
- package/dist/esm/utils/chart/axis-generators/bottom.d.ts +1 -1
- package/dist/esm/utils/chart/axis-generators/bottom.js +29 -28
- package/dist/esm/utils/chart/axis.d.ts +1 -1
- package/dist/esm/utils/chart/axis.js +2 -2
- package/dist/esm/utils/chart/get-closest-data.js +1 -1
- package/dist/esm/utils/chart/text.d.ts +7 -7
- package/dist/esm/utils/chart/text.js +45 -30
- package/dist/esm/utils/chart-ui/pie-center-text.d.ts +1 -1
- package/dist/esm/utils/chart-ui/pie-center-text.js +2 -2
- package/dist/esm/validation/index.d.ts +1 -1
- package/dist/esm/validation/index.js +16 -16
- 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
|
-
|
|
89
|
-
|
|
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)
|
|
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
|
-
|
|
107
|
-
|
|
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
|
-
|
|
113
|
-
|
|
114
|
-
|
|
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
|
-
|
|
129
|
-
|
|
130
|
-
result.
|
|
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
|
-
|
|
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
|
-
|
|
166
|
-
|
|
178
|
+
}
|
|
179
|
+
return acc;
|
|
167
180
|
}
|
|
168
181
|
const entityMap = {
|
|
169
182
|
'&': '&',
|
|
@@ -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 === ' ' ? ' ' : 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
|
-
|
|
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 = '';
|
|
@@ -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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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,
|
|
45
|
+
const { axis, width, height: totalHeight, scale, split, plotBeforeRef, plotAfterRef, leftmostLimit, } = props;
|
|
46
46
|
const ref = React.useRef(null);
|
|
47
47
|
React.useEffect(() => {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
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
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
.selectAll(
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
const
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
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
|
-
|
|
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;
|