@hsu-react/ui 2.4.1 → 2.4.2
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/es/components/Chart/Bar/index.js +9 -2
- package/es/components/Chart/Common/index.js +9 -2
- package/es/components/Chart/Gauge/index.js +9 -2
- package/es/components/Chart/Heatmap/index.js +9 -2
- package/es/components/Chart/Line/index.js +9 -2
- package/es/components/Chart/Pie/Pie3D/index.js +9 -2
- package/es/components/Chart/Pie/index.js +9 -2
- package/es/components/Chart/Polar/index.js +9 -2
- package/es/components/Chart/Radar/index.js +9 -2
- package/es/components/Chart/Sankey/index.js +9 -2
- package/es/components/Chart/Tree/index.js +9 -2
- package/es/components/Chart/_hooks/useContainerReady.d.ts +18 -0
- package/es/components/Chart/_hooks/useContainerReady.js +56 -0
- package/lib/components/Chart/Bar/index.js +9 -2
- package/lib/components/Chart/Common/index.js +9 -2
- package/lib/components/Chart/Gauge/index.js +9 -2
- package/lib/components/Chart/Heatmap/index.js +9 -2
- package/lib/components/Chart/Line/index.js +9 -2
- package/lib/components/Chart/Pie/Pie3D/index.js +9 -2
- package/lib/components/Chart/Pie/index.js +9 -2
- package/lib/components/Chart/Polar/index.js +9 -2
- package/lib/components/Chart/Radar/index.js +9 -2
- package/lib/components/Chart/Sankey/index.js +9 -2
- package/lib/components/Chart/Tree/index.js +9 -2
- package/lib/components/Chart/_hooks/useContainerReady.d.ts +18 -0
- package/lib/components/Chart/_hooks/useContainerReady.js +51 -0
- package/package.json +1 -1
- package/src/components/Chart/Bar/index.tsx +10 -1
- package/src/components/Chart/Common/index.tsx +12 -2
- package/src/components/Chart/Gauge/index.tsx +12 -2
- package/src/components/Chart/Heatmap/index.tsx +12 -2
- package/src/components/Chart/Line/index.tsx +10 -1
- package/src/components/Chart/Pie/Pie3D/index.tsx +10 -1
- package/src/components/Chart/Pie/index.tsx +10 -1
- package/src/components/Chart/Polar/index.tsx +12 -2
- package/src/components/Chart/Radar/index.tsx +10 -1
- package/src/components/Chart/Sankey/index.tsx +12 -2
- package/src/components/Chart/Tree/index.tsx +12 -2
- package/src/components/Chart/_hooks/useContainerReady.ts +50 -0
|
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
var _react = _interopRequireWildcard(require("react"));
|
|
8
|
+
var _useContainerReady = _interopRequireDefault(require("../_hooks/useContainerReady"));
|
|
8
9
|
var _indexModule = _interopRequireDefault(require("../index.module.scss"));
|
|
9
10
|
var echarts = _interopRequireWildcard(require("echarts"));
|
|
10
11
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
@@ -20,6 +21,8 @@ const Common = props => {
|
|
|
20
21
|
} = props;
|
|
21
22
|
const chartRef = (0, _react.useRef)(null);
|
|
22
23
|
const chartInstanceRef = (0, _react.useRef)(null);
|
|
24
|
+
// Defers `echarts.init` until the container has a box — see the hook for why
|
|
25
|
+
const containerReady = (0, _useContainerReady.default)(chartRef);
|
|
23
26
|
const resizeObserverRef = (0, _react.useRef)(null);
|
|
24
27
|
|
|
25
28
|
// Cache the chart configuration with useMemo
|
|
@@ -32,12 +35,16 @@ const Common = props => {
|
|
|
32
35
|
|
|
33
36
|
// Callback that handles chart resize
|
|
34
37
|
const handleResize = (0, _react.useCallback)(() => {
|
|
38
|
+
// A keep-alive tab losing focus fires the observer with a 0×0 box; resizing to that throws
|
|
39
|
+
// the laid-out canvas away and it has to be rebuilt when the tab comes back
|
|
40
|
+
const el = chartRef.current;
|
|
41
|
+
if (!el || el.clientWidth === 0 || el.clientHeight === 0) return;
|
|
35
42
|
chartInstanceRef.current?.resize();
|
|
36
43
|
}, []);
|
|
37
44
|
|
|
38
45
|
// Initialize the chart
|
|
39
46
|
(0, _react.useEffect)(() => {
|
|
40
|
-
if (!chartRef.current) return;
|
|
47
|
+
if (!chartRef.current || !containerReady) return;
|
|
41
48
|
|
|
42
49
|
// Initialize or reuse an existing instance
|
|
43
50
|
let chart = chartInstanceRef.current;
|
|
@@ -65,7 +72,7 @@ const Common = props => {
|
|
|
65
72
|
return () => {
|
|
66
73
|
window.removeEventListener("resize", handleResize);
|
|
67
74
|
};
|
|
68
|
-
}, [chartOption, handleResize, onChart]);
|
|
75
|
+
}, [chartOption, handleResize, onChart, containerReady]);
|
|
69
76
|
|
|
70
77
|
// Clean up resources on component unmount
|
|
71
78
|
(0, _react.useEffect)(() => {
|
|
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
var echarts = _interopRequireWildcard(require("echarts"));
|
|
8
|
+
var _useContainerReady = _interopRequireDefault(require("../_hooks/useContainerReady"));
|
|
8
9
|
var _react = _interopRequireWildcard(require("react"));
|
|
9
10
|
var _indexModule = _interopRequireDefault(require("../index.module.scss"));
|
|
10
11
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
@@ -32,6 +33,8 @@ const Gauge = props => {
|
|
|
32
33
|
} = series;
|
|
33
34
|
const chartRef = (0, _react.useRef)(null);
|
|
34
35
|
const chartInstanceRef = (0, _react.useRef)(null);
|
|
36
|
+
// Defers `echarts.init` until the container has a box — see the hook for why
|
|
37
|
+
const containerReady = (0, _useContainerReady.default)(chartRef);
|
|
35
38
|
const resizeObserverRef = (0, _react.useRef)(null);
|
|
36
39
|
|
|
37
40
|
// Cache the chart option with useMemo
|
|
@@ -92,12 +95,16 @@ const Gauge = props => {
|
|
|
92
95
|
|
|
93
96
|
// Callback for handling chart resize
|
|
94
97
|
const handleResize = (0, _react.useCallback)(() => {
|
|
98
|
+
// A keep-alive tab losing focus fires the observer with a 0×0 box; resizing to that throws
|
|
99
|
+
// the laid-out canvas away and it has to be rebuilt when the tab comes back
|
|
100
|
+
const el = chartRef.current;
|
|
101
|
+
if (!el || el.clientWidth === 0 || el.clientHeight === 0) return;
|
|
95
102
|
chartInstanceRef.current?.resize();
|
|
96
103
|
}, []);
|
|
97
104
|
|
|
98
105
|
// Initialize the chart
|
|
99
106
|
(0, _react.useEffect)(() => {
|
|
100
|
-
if (!chartRef.current) return;
|
|
107
|
+
if (!chartRef.current || !containerReady) return;
|
|
101
108
|
|
|
102
109
|
// Initialize or reuse the existing instance
|
|
103
110
|
let chart = chartInstanceRef.current;
|
|
@@ -122,7 +129,7 @@ const Gauge = props => {
|
|
|
122
129
|
return () => {
|
|
123
130
|
window.removeEventListener("resize", handleResize);
|
|
124
131
|
};
|
|
125
|
-
}, [chartOption, handleResize]);
|
|
132
|
+
}, [chartOption, handleResize, containerReady]);
|
|
126
133
|
|
|
127
134
|
// Clean up resources when the component unmounts
|
|
128
135
|
(0, _react.useEffect)(() => {
|
|
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
var _react = _interopRequireWildcard(require("react"));
|
|
8
|
+
var _useContainerReady = _interopRequireDefault(require("../_hooks/useContainerReady"));
|
|
8
9
|
var _indexModule = _interopRequireDefault(require("../index.module.scss"));
|
|
9
10
|
var echarts = _interopRequireWildcard(require("echarts"));
|
|
10
11
|
var _heatmap = require("../_utils/heatmap");
|
|
@@ -37,6 +38,8 @@ const Heatmap = props => {
|
|
|
37
38
|
} = props;
|
|
38
39
|
const chartRef = (0, _react.useRef)(null);
|
|
39
40
|
const chartInstanceRef = (0, _react.useRef)(null);
|
|
41
|
+
// Defers `echarts.init` until the container has a box — see the hook for why
|
|
42
|
+
const containerReady = (0, _useContainerReady.default)(chartRef);
|
|
40
43
|
const resizeObserverRef = (0, _react.useRef)(null);
|
|
41
44
|
// echarts options are plain JS and cannot read the `--vita-*` variables, so the axis and legend
|
|
42
45
|
// colours have to be resolved against the active appearance here
|
|
@@ -182,12 +185,16 @@ const Heatmap = props => {
|
|
|
182
185
|
|
|
183
186
|
// Callback for handling chart resize
|
|
184
187
|
const handleResize = (0, _react.useCallback)(() => {
|
|
188
|
+
// A keep-alive tab losing focus fires the observer with a 0×0 box; resizing to that throws
|
|
189
|
+
// the laid-out canvas away and it has to be rebuilt when the tab comes back
|
|
190
|
+
const el = chartRef.current;
|
|
191
|
+
if (!el || el.clientWidth === 0 || el.clientHeight === 0) return;
|
|
185
192
|
chartInstanceRef.current?.resize();
|
|
186
193
|
}, []);
|
|
187
194
|
|
|
188
195
|
// Initialize the chart
|
|
189
196
|
(0, _react.useEffect)(() => {
|
|
190
|
-
if (!chartRef.current) return;
|
|
197
|
+
if (!chartRef.current || !containerReady) return;
|
|
191
198
|
|
|
192
199
|
// Initialize or reuse the existing instance
|
|
193
200
|
let chart = chartInstanceRef.current;
|
|
@@ -222,7 +229,7 @@ const Heatmap = props => {
|
|
|
222
229
|
chartInstanceRef.current?.off("click", onClick);
|
|
223
230
|
}
|
|
224
231
|
};
|
|
225
|
-
}, [chartOption, handleResize, onChart, onClick]);
|
|
232
|
+
}, [chartOption, handleResize, onChart, onClick, containerReady]);
|
|
226
233
|
|
|
227
234
|
// Clean up resources when the component unmounts
|
|
228
235
|
(0, _react.useEffect)(() => {
|
|
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
var echarts = _interopRequireWildcard(require("echarts"));
|
|
8
|
+
var _useContainerReady = _interopRequireDefault(require("../_hooks/useContainerReady"));
|
|
8
9
|
var _react = _interopRequireWildcard(require("react"));
|
|
9
10
|
var _indexModule = _interopRequireDefault(require("../index.module.scss"));
|
|
10
11
|
var _autoScrollLegend = require("../_utils/autoScrollLegend");
|
|
@@ -45,6 +46,8 @@ const ChartLine = props => {
|
|
|
45
46
|
} = props;
|
|
46
47
|
const chartRef = (0, _react.useRef)(null);
|
|
47
48
|
const chartInstanceRef = (0, _react.useRef)(null);
|
|
49
|
+
// Defers `echarts.init` until the container has a box — see the hook for why
|
|
50
|
+
const containerReady = (0, _useContainerReady.default)(chartRef);
|
|
48
51
|
const resizeObserverRef = (0, _react.useRef)(null);
|
|
49
52
|
const prevXAxisKeyRef = (0, _react.useRef)(null);
|
|
50
53
|
const legendScrollRef = (0, _react.useRef)(null);
|
|
@@ -189,12 +192,16 @@ const ChartLine = props => {
|
|
|
189
192
|
|
|
190
193
|
// Callback for handling chart resize
|
|
191
194
|
const handleResize = (0, _react.useCallback)(() => {
|
|
195
|
+
// A keep-alive tab losing focus fires the observer with a 0×0 box; resizing to that throws
|
|
196
|
+
// the laid-out canvas away and it has to be rebuilt when the tab comes back
|
|
197
|
+
const el = chartRef.current;
|
|
198
|
+
if (!el || el.clientWidth === 0 || el.clientHeight === 0) return;
|
|
192
199
|
chartInstanceRef.current?.resize();
|
|
193
200
|
}, []);
|
|
194
201
|
|
|
195
202
|
// Initialize the chart
|
|
196
203
|
(0, _react.useEffect)(() => {
|
|
197
|
-
if (!chartRef.current) return;
|
|
204
|
+
if (!chartRef.current || !containerReady) return;
|
|
198
205
|
|
|
199
206
|
// Initialize or reuse the existing instance
|
|
200
207
|
let chart = chartInstanceRef.current;
|
|
@@ -324,7 +331,7 @@ const ChartLine = props => {
|
|
|
324
331
|
};
|
|
325
332
|
}, [chartOption, handleResize, onClick, onLegendSelectChanged, onDataZoomWindowChanged, xAxisData, enableLegendAutoScroll, legendVisibleCount, legendScrollInterval,
|
|
326
333
|
// 图例是否接管滚轮由它推导,漏了会拿到过期的滚动配置
|
|
327
|
-
normalizedScroll]);
|
|
334
|
+
normalizedScroll, containerReady]);
|
|
328
335
|
|
|
329
336
|
// Handle auto play
|
|
330
337
|
(0, _react.useEffect)(() => {
|
|
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
var echarts = _interopRequireWildcard(require("echarts"));
|
|
8
|
+
var _useContainerReady = _interopRequireDefault(require("../../_hooks/useContainerReady"));
|
|
8
9
|
require("echarts-gl");
|
|
9
10
|
var _react = _interopRequireWildcard(require("react"));
|
|
10
11
|
var _hooks = require("./_hooks");
|
|
@@ -41,6 +42,8 @@ const ChartPie3D = props => {
|
|
|
41
42
|
} = props;
|
|
42
43
|
const chartRef = (0, _react.useRef)(null);
|
|
43
44
|
const chartInstanceRef = (0, _react.useRef)(null);
|
|
45
|
+
// Defers `echarts.init` until the container has a box — see the hook for why
|
|
46
|
+
const containerReady = (0, _useContainerReady.default)(chartRef);
|
|
44
47
|
const resizeObserverRef = (0, _react.useRef)(null);
|
|
45
48
|
const hoveredIndexRef = (0, _react.useRef)("");
|
|
46
49
|
const optionRef = (0, _react.useRef)(null);
|
|
@@ -62,6 +65,10 @@ const ChartPie3D = props => {
|
|
|
62
65
|
});
|
|
63
66
|
}, [pieData, internalDiameterRatio, tooltip, alpha, beta, autoRotate, distance, coreOption, minHeight, maxHeight, yOffset, label, enableMouseControl]);
|
|
64
67
|
const handleResize = (0, _react.useCallback)(() => {
|
|
68
|
+
// A keep-alive tab losing focus fires the observer with a 0×0 box; resizing to that throws
|
|
69
|
+
// the laid-out canvas away and it has to be rebuilt when the tab comes back
|
|
70
|
+
const el = chartRef.current;
|
|
71
|
+
if (!el || el.clientWidth === 0 || el.clientHeight === 0) return;
|
|
65
72
|
chartInstanceRef.current?.resize();
|
|
66
73
|
}, []);
|
|
67
74
|
const handleMouseOver = (0, _hooks.useMouseOverHandler)(optionRef, chartInstanceRef, hoveredIndexRef, {
|
|
@@ -78,7 +85,7 @@ const ChartPie3D = props => {
|
|
|
78
85
|
autoRotate
|
|
79
86
|
});
|
|
80
87
|
(0, _react.useEffect)(() => {
|
|
81
|
-
if (!chartRef.current) return;
|
|
88
|
+
if (!chartRef.current || !containerReady) return;
|
|
82
89
|
let chart = chartInstanceRef.current;
|
|
83
90
|
if (!chart) {
|
|
84
91
|
chart = echarts.init(chartRef.current);
|
|
@@ -107,7 +114,7 @@ const ChartPie3D = props => {
|
|
|
107
114
|
}
|
|
108
115
|
}
|
|
109
116
|
};
|
|
110
|
-
}, [chartOption, handleResize, handleMouseOver, handleGlobalOut, onChart, onClick]);
|
|
117
|
+
}, [chartOption, handleResize, handleMouseOver, handleGlobalOut, onChart, onClick, containerReady]);
|
|
111
118
|
(0, _react.useEffect)(() => {
|
|
112
119
|
return () => {
|
|
113
120
|
if (resizeObserverRef.current) {
|
|
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
var echarts = _interopRequireWildcard(require("echarts"));
|
|
8
|
+
var _useContainerReady = _interopRequireDefault(require("../_hooks/useContainerReady"));
|
|
8
9
|
var _react = _interopRequireWildcard(require("react"));
|
|
9
10
|
var _chartUtils = require("../chartUtils");
|
|
10
11
|
var _indexModule = _interopRequireDefault(require("../index.module.scss"));
|
|
@@ -38,6 +39,8 @@ const ChartPie = props => {
|
|
|
38
39
|
} = props;
|
|
39
40
|
const chartRef = (0, _react.useRef)(null);
|
|
40
41
|
const chartInstanceRef = (0, _react.useRef)(null);
|
|
42
|
+
// Defers `echarts.init` until the container has a box — see the hook for why
|
|
43
|
+
const containerReady = (0, _useContainerReady.default)(chartRef);
|
|
41
44
|
const resizeObserverRef = (0, _react.useRef)(null);
|
|
42
45
|
const legendScrollRef = (0, _react.useRef)(null);
|
|
43
46
|
|
|
@@ -191,12 +194,16 @@ const ChartPie = props => {
|
|
|
191
194
|
|
|
192
195
|
// Callback for handling chart resize
|
|
193
196
|
const handleResize = (0, _react.useCallback)(() => {
|
|
197
|
+
// A keep-alive tab losing focus fires the observer with a 0×0 box; resizing to that throws
|
|
198
|
+
// the laid-out canvas away and it has to be rebuilt when the tab comes back
|
|
199
|
+
const el = chartRef.current;
|
|
200
|
+
if (!el || el.clientWidth === 0 || el.clientHeight === 0) return;
|
|
194
201
|
chartInstanceRef.current?.resize();
|
|
195
202
|
}, []);
|
|
196
203
|
|
|
197
204
|
// Initialize the chart
|
|
198
205
|
(0, _react.useEffect)(() => {
|
|
199
|
-
if (!chartRef.current) return;
|
|
206
|
+
if (!chartRef.current || !containerReady) return;
|
|
200
207
|
|
|
201
208
|
// Initialize or reuse the existing instance
|
|
202
209
|
let chart = chartInstanceRef.current;
|
|
@@ -252,7 +259,7 @@ const ChartPie = props => {
|
|
|
252
259
|
legendScrollRef.current = null;
|
|
253
260
|
}
|
|
254
261
|
};
|
|
255
|
-
}, [chartOption, handleResize, onChart, onClick, enableLegendAutoScroll, seriesData, legendVisibleCount, legendScrollInterval]);
|
|
262
|
+
}, [chartOption, handleResize, onChart, onClick, enableLegendAutoScroll, seriesData, legendVisibleCount, legendScrollInterval, containerReady]);
|
|
256
263
|
|
|
257
264
|
// Clean up resources when the component unmounts
|
|
258
265
|
(0, _react.useEffect)(() => {
|
|
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
var echarts = _interopRequireWildcard(require("echarts"));
|
|
8
|
+
var _useContainerReady = _interopRequireDefault(require("../_hooks/useContainerReady"));
|
|
8
9
|
var _react = _interopRequireWildcard(require("react"));
|
|
9
10
|
var _indexModule = _interopRequireDefault(require("../index.module.scss"));
|
|
10
11
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
@@ -30,6 +31,8 @@ const Polar = props => {
|
|
|
30
31
|
} = props;
|
|
31
32
|
const chartRef = (0, _react.useRef)(null);
|
|
32
33
|
const chartInstanceRef = (0, _react.useRef)(null);
|
|
34
|
+
// Defers `echarts.init` until the container has a box — see the hook for why
|
|
35
|
+
const containerReady = (0, _useContainerReady.default)(chartRef);
|
|
33
36
|
const resizeObserverRef = (0, _react.useRef)(null);
|
|
34
37
|
|
|
35
38
|
// Cache the chart option with useMemo
|
|
@@ -144,12 +147,16 @@ const Polar = props => {
|
|
|
144
147
|
|
|
145
148
|
// Callback handling chart resize
|
|
146
149
|
const handleResize = (0, _react.useCallback)(() => {
|
|
150
|
+
// A keep-alive tab losing focus fires the observer with a 0×0 box; resizing to that throws
|
|
151
|
+
// the laid-out canvas away and it has to be rebuilt when the tab comes back
|
|
152
|
+
const el = chartRef.current;
|
|
153
|
+
if (!el || el.clientWidth === 0 || el.clientHeight === 0) return;
|
|
147
154
|
chartInstanceRef.current?.resize();
|
|
148
155
|
}, []);
|
|
149
156
|
|
|
150
157
|
// Initialize the chart
|
|
151
158
|
(0, _react.useEffect)(() => {
|
|
152
|
-
if (!chartRef.current) return;
|
|
159
|
+
if (!chartRef.current || !containerReady) return;
|
|
153
160
|
|
|
154
161
|
// Initialize a new instance or reuse the existing one
|
|
155
162
|
let chart = chartInstanceRef.current;
|
|
@@ -174,7 +181,7 @@ const Polar = props => {
|
|
|
174
181
|
return () => {
|
|
175
182
|
window.removeEventListener("resize", handleResize);
|
|
176
183
|
};
|
|
177
|
-
}, [chartOption, handleResize]);
|
|
184
|
+
}, [chartOption, handleResize, containerReady]);
|
|
178
185
|
|
|
179
186
|
// Clean up resources on unmount
|
|
180
187
|
(0, _react.useEffect)(() => {
|
|
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
var echarts = _interopRequireWildcard(require("echarts"));
|
|
8
|
+
var _useContainerReady = _interopRequireDefault(require("../_hooks/useContainerReady"));
|
|
8
9
|
var _react = _interopRequireWildcard(require("react"));
|
|
9
10
|
var _indexModule = _interopRequireDefault(require("../index.module.scss"));
|
|
10
11
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
@@ -33,6 +34,8 @@ const Radar = props => {
|
|
|
33
34
|
} = props;
|
|
34
35
|
const chartRef = (0, _react.useRef)(null);
|
|
35
36
|
const chartInstanceRef = (0, _react.useRef)(null);
|
|
37
|
+
// Defers `echarts.init` until the container has a box — see the hook for why
|
|
38
|
+
const containerReady = (0, _useContainerReady.default)(chartRef);
|
|
36
39
|
const resizeObserverRef = (0, _react.useRef)(null);
|
|
37
40
|
const hoveredIndicatorRef = (0, _react.useRef)(-1);
|
|
38
41
|
const singleIndicatorEnabled = Boolean(singleIndicatorTooltipProp) && singleIndicatorMode !== undefined;
|
|
@@ -144,10 +147,14 @@ const Radar = props => {
|
|
|
144
147
|
return option;
|
|
145
148
|
}, [indicators, data, color, name, radar, series, coreOption, singleIndicatorEnabled, singleIndicatorFormatter, singleIndicatorRegion]);
|
|
146
149
|
const handleResize = (0, _react.useCallback)(() => {
|
|
150
|
+
// A keep-alive tab losing focus fires the observer with a 0×0 box; resizing to that throws
|
|
151
|
+
// the laid-out canvas away and it has to be rebuilt when the tab comes back
|
|
152
|
+
const el = chartRef.current;
|
|
153
|
+
if (!el || el.clientWidth === 0 || el.clientHeight === 0) return;
|
|
147
154
|
chartInstanceRef.current?.resize();
|
|
148
155
|
}, []);
|
|
149
156
|
(0, _react.useEffect)(() => {
|
|
150
|
-
if (!chartRef.current) return;
|
|
157
|
+
if (!chartRef.current || !containerReady) return;
|
|
151
158
|
let chart = chartInstanceRef.current;
|
|
152
159
|
if (!chart) {
|
|
153
160
|
chart = echarts.init(chartRef.current);
|
|
@@ -263,7 +270,7 @@ const Radar = props => {
|
|
|
263
270
|
}
|
|
264
271
|
}
|
|
265
272
|
};
|
|
266
|
-
}, [chartOption, handleResize, singleIndicatorEnabled, singleIndicatorRegion, singleIndicatorHighlight, singleIndicatorHoverFill, color]);
|
|
273
|
+
}, [chartOption, handleResize, singleIndicatorEnabled, singleIndicatorRegion, singleIndicatorHighlight, singleIndicatorHoverFill, color, containerReady]);
|
|
267
274
|
(0, _react.useEffect)(() => {
|
|
268
275
|
return () => {
|
|
269
276
|
if (resizeObserverRef.current) {
|
|
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
var _react = _interopRequireWildcard(require("react"));
|
|
8
|
+
var _useContainerReady = _interopRequireDefault(require("../_hooks/useContainerReady"));
|
|
8
9
|
var _indexModule = _interopRequireDefault(require("../index.module.scss"));
|
|
9
10
|
var echarts = _interopRequireWildcard(require("echarts"));
|
|
10
11
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
@@ -22,6 +23,8 @@ const Sankey = props => {
|
|
|
22
23
|
} = props;
|
|
23
24
|
const chartRef = (0, _react.useRef)(null);
|
|
24
25
|
const chartInstanceRef = (0, _react.useRef)(null);
|
|
26
|
+
// Defers `echarts.init` until the container has a box — see the hook for why
|
|
27
|
+
const containerReady = (0, _useContainerReady.default)(chartRef);
|
|
25
28
|
const resizeObserverRef = (0, _react.useRef)(null);
|
|
26
29
|
|
|
27
30
|
// Cache the chart option with useMemo
|
|
@@ -103,12 +106,16 @@ const Sankey = props => {
|
|
|
103
106
|
|
|
104
107
|
// Callback handling chart resize
|
|
105
108
|
const handleResize = (0, _react.useCallback)(() => {
|
|
109
|
+
// A keep-alive tab losing focus fires the observer with a 0×0 box; resizing to that throws
|
|
110
|
+
// the laid-out canvas away and it has to be rebuilt when the tab comes back
|
|
111
|
+
const el = chartRef.current;
|
|
112
|
+
if (!el || el.clientWidth === 0 || el.clientHeight === 0) return;
|
|
106
113
|
chartInstanceRef.current?.resize();
|
|
107
114
|
}, []);
|
|
108
115
|
|
|
109
116
|
// Initialize the chart
|
|
110
117
|
(0, _react.useEffect)(() => {
|
|
111
|
-
if (!chartRef.current) return;
|
|
118
|
+
if (!chartRef.current || !containerReady) return;
|
|
112
119
|
|
|
113
120
|
// Initialize a new instance or reuse the existing one
|
|
114
121
|
let chart = chartInstanceRef.current;
|
|
@@ -142,7 +149,7 @@ const Sankey = props => {
|
|
|
142
149
|
return () => {
|
|
143
150
|
window.removeEventListener("resize", handleResize);
|
|
144
151
|
};
|
|
145
|
-
}, [chartOption, handleResize, getImage]);
|
|
152
|
+
}, [chartOption, handleResize, getImage, containerReady]);
|
|
146
153
|
|
|
147
154
|
// Clean up resources on unmount
|
|
148
155
|
(0, _react.useEffect)(() => {
|
|
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
var _react = _interopRequireWildcard(require("react"));
|
|
8
|
+
var _useContainerReady = _interopRequireDefault(require("../_hooks/useContainerReady"));
|
|
8
9
|
var _indexModule = _interopRequireDefault(require("../index.module.scss"));
|
|
9
10
|
var echarts = _interopRequireWildcard(require("echarts"));
|
|
10
11
|
var _hsuUtils = require("hsu-utils");
|
|
@@ -23,6 +24,8 @@ const Tree = props => {
|
|
|
23
24
|
} = props;
|
|
24
25
|
const chartRef = (0, _react.useRef)(null);
|
|
25
26
|
const chartInstanceRef = (0, _react.useRef)(null);
|
|
27
|
+
// Defers `echarts.init` until the container has a box — see the hook for why
|
|
28
|
+
const containerReady = (0, _useContainerReady.default)(chartRef);
|
|
26
29
|
const resizeObserverRef = (0, _react.useRef)(null);
|
|
27
30
|
|
|
28
31
|
// Cache the chart option with useMemo
|
|
@@ -43,12 +46,16 @@ const Tree = props => {
|
|
|
43
46
|
|
|
44
47
|
// Callback handling chart resize
|
|
45
48
|
const handleResize = (0, _react.useCallback)(() => {
|
|
49
|
+
// A keep-alive tab losing focus fires the observer with a 0×0 box; resizing to that throws
|
|
50
|
+
// the laid-out canvas away and it has to be rebuilt when the tab comes back
|
|
51
|
+
const el = chartRef.current;
|
|
52
|
+
if (!el || el.clientWidth === 0 || el.clientHeight === 0) return;
|
|
46
53
|
chartInstanceRef.current?.resize();
|
|
47
54
|
}, []);
|
|
48
55
|
|
|
49
56
|
// Initialize the chart
|
|
50
57
|
(0, _react.useEffect)(() => {
|
|
51
|
-
if (!chartRef.current) return;
|
|
58
|
+
if (!chartRef.current || !containerReady) return;
|
|
52
59
|
|
|
53
60
|
// Initialize a new instance or reuse the existing one
|
|
54
61
|
let chart = chartInstanceRef.current;
|
|
@@ -82,7 +89,7 @@ const Tree = props => {
|
|
|
82
89
|
return () => {
|
|
83
90
|
window.removeEventListener("resize", handleResize);
|
|
84
91
|
};
|
|
85
|
-
}, [chartOption, handleResize, getImage]);
|
|
92
|
+
}, [chartOption, handleResize, getImage, containerReady]);
|
|
86
93
|
|
|
87
94
|
// Clean up resources on unmount
|
|
88
95
|
(0, _react.useEffect)(() => {
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { RefObject } from "react";
|
|
2
|
+
/**
|
|
3
|
+
* Whether the referenced element has a non-zero box yet.
|
|
4
|
+
*
|
|
5
|
+
* `echarts.init` on a 0×0 element logs `Can't get DOM width or height` and builds a canvas with no
|
|
6
|
+
* size, recovering only on the next `resize()`. A chart hits that path whenever it mounts before
|
|
7
|
+
* layout has given it space — inside a keep-alive tab that is not the active one, a collapsed
|
|
8
|
+
* panel, a modal that has not opened yet — so consuming apps see the warning for charts that end
|
|
9
|
+
* up rendering perfectly well.
|
|
10
|
+
*
|
|
11
|
+
* Gating `init` on this flag defers it to the first frame the element actually occupies space.
|
|
12
|
+
*
|
|
13
|
+
* It **latches**: once measured, the element going back to 0×0 (a keep-alive tab losing focus)
|
|
14
|
+
* must not read as "not ready" again, or the init effect would tear the chart down and re-create
|
|
15
|
+
* it on every tab switch.
|
|
16
|
+
*/
|
|
17
|
+
declare const useContainerReady: (ref: RefObject<HTMLElement | null>) => boolean;
|
|
18
|
+
export default useContainerReady;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _react = require("react");
|
|
8
|
+
/**
|
|
9
|
+
* Whether the referenced element has a non-zero box yet.
|
|
10
|
+
*
|
|
11
|
+
* `echarts.init` on a 0×0 element logs `Can't get DOM width or height` and builds a canvas with no
|
|
12
|
+
* size, recovering only on the next `resize()`. A chart hits that path whenever it mounts before
|
|
13
|
+
* layout has given it space — inside a keep-alive tab that is not the active one, a collapsed
|
|
14
|
+
* panel, a modal that has not opened yet — so consuming apps see the warning for charts that end
|
|
15
|
+
* up rendering perfectly well.
|
|
16
|
+
*
|
|
17
|
+
* Gating `init` on this flag defers it to the first frame the element actually occupies space.
|
|
18
|
+
*
|
|
19
|
+
* It **latches**: once measured, the element going back to 0×0 (a keep-alive tab losing focus)
|
|
20
|
+
* must not read as "not ready" again, or the init effect would tear the chart down and re-create
|
|
21
|
+
* it on every tab switch.
|
|
22
|
+
*/
|
|
23
|
+
const useContainerReady = ref => {
|
|
24
|
+
const [ready, setReady] = (0, _react.useState)(false);
|
|
25
|
+
(0, _react.useEffect)(() => {
|
|
26
|
+
if (ready) return;
|
|
27
|
+
const el = ref.current;
|
|
28
|
+
if (!el) return;
|
|
29
|
+
const measure = () => {
|
|
30
|
+
const {
|
|
31
|
+
width,
|
|
32
|
+
height
|
|
33
|
+
} = el.getBoundingClientRect();
|
|
34
|
+
if (width > 0 && height > 0) {
|
|
35
|
+
setReady(true);
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
return false;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
// Already laid out on mount — the common case, and it must not cost an extra frame
|
|
42
|
+
if (measure()) return;
|
|
43
|
+
const observer = new ResizeObserver(() => {
|
|
44
|
+
if (measure()) observer.disconnect();
|
|
45
|
+
});
|
|
46
|
+
observer.observe(el);
|
|
47
|
+
return () => observer.disconnect();
|
|
48
|
+
}, [ready, ref]);
|
|
49
|
+
return ready;
|
|
50
|
+
};
|
|
51
|
+
var _default = exports.default = useContainerReady;
|
package/package.json
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as echarts from "echarts";
|
|
2
|
+
import useContainerReady from "../_hooks/useContainerReady";
|
|
2
3
|
|
|
3
4
|
import {
|
|
4
5
|
ChartCommonProps,
|
|
@@ -72,6 +73,8 @@ const ChartBar: React.FC<ChartBarProps> = (props) => {
|
|
|
72
73
|
} = props;
|
|
73
74
|
const chartRef = useRef<HTMLDivElement>(null);
|
|
74
75
|
const chartInstanceRef = useRef<echarts.ECharts | null>(null);
|
|
76
|
+
// Defers `echarts.init` until the container has a box — see the hook for why
|
|
77
|
+
const containerReady = useContainerReady(chartRef);
|
|
75
78
|
const resizeObserverRef = useRef<ResizeObserver | null>(null);
|
|
76
79
|
const prevXAxisKeyRef = useRef<string | null>(null);
|
|
77
80
|
const legendScrollRef = useRef<ReturnType<typeof autoScrollLegend> | null>(
|
|
@@ -269,12 +272,17 @@ const ChartBar: React.FC<ChartBarProps> = (props) => {
|
|
|
269
272
|
|
|
270
273
|
// Callback for handling chart resize
|
|
271
274
|
const handleResize = useCallback(() => {
|
|
275
|
+
// A keep-alive tab losing focus fires the observer with a 0×0 box; resizing to that throws
|
|
276
|
+
// the laid-out canvas away and it has to be rebuilt when the tab comes back
|
|
277
|
+
const el = chartRef.current;
|
|
278
|
+
if (!el || el.clientWidth === 0 || el.clientHeight === 0) return;
|
|
279
|
+
|
|
272
280
|
chartInstanceRef.current?.resize();
|
|
273
281
|
}, []);
|
|
274
282
|
|
|
275
283
|
// Initialize the chart
|
|
276
284
|
useEffect(() => {
|
|
277
|
-
if (!chartRef.current) return;
|
|
285
|
+
if (!chartRef.current || !containerReady) return;
|
|
278
286
|
|
|
279
287
|
// Initialize or reuse the existing instance
|
|
280
288
|
let chart = chartInstanceRef.current;
|
|
@@ -469,6 +477,7 @@ const ChartBar: React.FC<ChartBarProps> = (props) => {
|
|
|
469
477
|
legendScrollInterval,
|
|
470
478
|
// 图例是否接管滚轮由它推导,漏了会拿到过期的滚动配置
|
|
471
479
|
normalizedScroll,
|
|
480
|
+
containerReady,
|
|
472
481
|
]);
|
|
473
482
|
|
|
474
483
|
// Handle auto play
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React, { useCallback, useEffect, useMemo, useRef } from "react";
|
|
2
|
+
import useContainerReady from "../_hooks/useContainerReady";
|
|
2
3
|
import styles from "../index.module.scss";
|
|
3
4
|
import { ChartCommonProps, ChartOptionType, ChartsOption } from "..";
|
|
4
5
|
import * as echarts from "echarts";
|
|
@@ -7,6 +8,8 @@ const Common: React.FC<ChartCommonProps> = (props) => {
|
|
|
7
8
|
const { className, style, onChart, ...coreOption } = props;
|
|
8
9
|
const chartRef = useRef<HTMLDivElement>(null);
|
|
9
10
|
const chartInstanceRef = useRef<echarts.ECharts | null>(null);
|
|
11
|
+
// Defers `echarts.init` until the container has a box — see the hook for why
|
|
12
|
+
const containerReady = useContainerReady(chartRef);
|
|
10
13
|
const resizeObserverRef = useRef<ResizeObserver | null>(null);
|
|
11
14
|
|
|
12
15
|
// Cache the chart configuration with useMemo
|
|
@@ -20,12 +23,17 @@ const Common: React.FC<ChartCommonProps> = (props) => {
|
|
|
20
23
|
|
|
21
24
|
// Callback that handles chart resize
|
|
22
25
|
const handleResize = useCallback(() => {
|
|
26
|
+
// A keep-alive tab losing focus fires the observer with a 0×0 box; resizing to that throws
|
|
27
|
+
// the laid-out canvas away and it has to be rebuilt when the tab comes back
|
|
28
|
+
const el = chartRef.current;
|
|
29
|
+
if (!el || el.clientWidth === 0 || el.clientHeight === 0) return;
|
|
30
|
+
|
|
23
31
|
chartInstanceRef.current?.resize();
|
|
24
32
|
}, []);
|
|
25
33
|
|
|
26
34
|
// Initialize the chart
|
|
27
35
|
useEffect(() => {
|
|
28
|
-
if (!chartRef.current) return;
|
|
36
|
+
if (!chartRef.current || !containerReady) return;
|
|
29
37
|
|
|
30
38
|
// Initialize or reuse an existing instance
|
|
31
39
|
let chart = chartInstanceRef.current;
|
|
@@ -53,7 +61,9 @@ const Common: React.FC<ChartCommonProps> = (props) => {
|
|
|
53
61
|
return () => {
|
|
54
62
|
window.removeEventListener("resize", handleResize);
|
|
55
63
|
};
|
|
56
|
-
}, [chartOption, handleResize, onChart
|
|
64
|
+
}, [chartOption, handleResize, onChart,
|
|
65
|
+
containerReady,
|
|
66
|
+
]);
|
|
57
67
|
|
|
58
68
|
// Clean up resources on component unmount
|
|
59
69
|
useEffect(() => {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as echarts from "echarts";
|
|
2
|
+
import useContainerReady from "../_hooks/useContainerReady";
|
|
2
3
|
|
|
3
4
|
import {
|
|
4
5
|
ChartCommonProps,
|
|
@@ -31,6 +32,8 @@ const Gauge: React.FC<ChartGaugeProps> = (props) => {
|
|
|
31
32
|
} = series as echarts.GaugeSeriesOption;
|
|
32
33
|
const chartRef = useRef<HTMLDivElement>(null);
|
|
33
34
|
const chartInstanceRef = useRef<echarts.ECharts | null>(null);
|
|
35
|
+
// Defers `echarts.init` until the container has a box — see the hook for why
|
|
36
|
+
const containerReady = useContainerReady(chartRef);
|
|
34
37
|
const resizeObserverRef = useRef<ResizeObserver | null>(null);
|
|
35
38
|
|
|
36
39
|
// Cache the chart option with useMemo
|
|
@@ -104,12 +107,17 @@ const Gauge: React.FC<ChartGaugeProps> = (props) => {
|
|
|
104
107
|
|
|
105
108
|
// Callback for handling chart resize
|
|
106
109
|
const handleResize = useCallback(() => {
|
|
110
|
+
// A keep-alive tab losing focus fires the observer with a 0×0 box; resizing to that throws
|
|
111
|
+
// the laid-out canvas away and it has to be rebuilt when the tab comes back
|
|
112
|
+
const el = chartRef.current;
|
|
113
|
+
if (!el || el.clientWidth === 0 || el.clientHeight === 0) return;
|
|
114
|
+
|
|
107
115
|
chartInstanceRef.current?.resize();
|
|
108
116
|
}, []);
|
|
109
117
|
|
|
110
118
|
// Initialize the chart
|
|
111
119
|
useEffect(() => {
|
|
112
|
-
if (!chartRef.current) return;
|
|
120
|
+
if (!chartRef.current || !containerReady) return;
|
|
113
121
|
|
|
114
122
|
// Initialize or reuse the existing instance
|
|
115
123
|
let chart = chartInstanceRef.current;
|
|
@@ -134,7 +142,9 @@ const Gauge: React.FC<ChartGaugeProps> = (props) => {
|
|
|
134
142
|
return () => {
|
|
135
143
|
window.removeEventListener("resize", handleResize);
|
|
136
144
|
};
|
|
137
|
-
}, [chartOption, handleResize
|
|
145
|
+
}, [chartOption, handleResize,
|
|
146
|
+
containerReady,
|
|
147
|
+
]);
|
|
138
148
|
|
|
139
149
|
// Clean up resources when the component unmounts
|
|
140
150
|
useEffect(() => {
|