@hsu-react/ui 2.4.0 → 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.
Files changed (57) hide show
  1. package/es/components/Chart/Bar/index.js +21 -7
  2. package/es/components/Chart/Common/index.js +9 -2
  3. package/es/components/Chart/Gauge/index.js +9 -2
  4. package/es/components/Chart/Heatmap/index.js +21 -6
  5. package/es/components/Chart/Line/index.js +21 -6
  6. package/es/components/Chart/Pie/Pie3D/index.js +9 -2
  7. package/es/components/Chart/Pie/index.js +9 -2
  8. package/es/components/Chart/Polar/index.js +9 -2
  9. package/es/components/Chart/Radar/index.js +9 -2
  10. package/es/components/Chart/Sankey/index.js +9 -2
  11. package/es/components/Chart/Tree/index.js +9 -2
  12. package/es/components/Chart/_hooks/useContainerReady.d.ts +18 -0
  13. package/es/components/Chart/_hooks/useContainerReady.js +56 -0
  14. package/es/components/Chart/_utils/cartesian.d.ts +3 -2
  15. package/es/components/Chart/_utils/cartesian.js +9 -10
  16. package/es/components/Chart/_utils/chartTheme.d.ts +22 -0
  17. package/es/components/Chart/_utils/chartTheme.js +23 -0
  18. package/es/components/Chart/_utils/heatmap.d.ts +3 -2
  19. package/es/components/Chart/_utils/heatmap.js +7 -10
  20. package/es/components/Panel/ListPanel/ListModalPanel/index.module.scss +10 -0
  21. package/lib/components/Chart/Bar/index.js +19 -7
  22. package/lib/components/Chart/Common/index.js +9 -2
  23. package/lib/components/Chart/Gauge/index.js +9 -2
  24. package/lib/components/Chart/Heatmap/index.js +19 -6
  25. package/lib/components/Chart/Line/index.js +19 -6
  26. package/lib/components/Chart/Pie/Pie3D/index.js +9 -2
  27. package/lib/components/Chart/Pie/index.js +9 -2
  28. package/lib/components/Chart/Polar/index.js +9 -2
  29. package/lib/components/Chart/Radar/index.js +9 -2
  30. package/lib/components/Chart/Sankey/index.js +9 -2
  31. package/lib/components/Chart/Tree/index.js +9 -2
  32. package/lib/components/Chart/_hooks/useContainerReady.d.ts +18 -0
  33. package/lib/components/Chart/_hooks/useContainerReady.js +51 -0
  34. package/lib/components/Chart/_utils/cartesian.d.ts +3 -2
  35. package/lib/components/Chart/_utils/cartesian.js +9 -11
  36. package/lib/components/Chart/_utils/chartTheme.d.ts +22 -0
  37. package/lib/components/Chart/_utils/chartTheme.js +29 -0
  38. package/lib/components/Chart/_utils/heatmap.d.ts +3 -2
  39. package/lib/components/Chart/_utils/heatmap.js +7 -10
  40. package/lib/components/Panel/ListPanel/ListModalPanel/index.module.scss +10 -0
  41. package/package.json +1 -1
  42. package/src/components/Chart/Bar/index.tsx +20 -5
  43. package/src/components/Chart/Common/index.tsx +12 -2
  44. package/src/components/Chart/Gauge/index.tsx +12 -2
  45. package/src/components/Chart/Heatmap/index.tsx +22 -5
  46. package/src/components/Chart/Line/index.tsx +20 -4
  47. package/src/components/Chart/Pie/Pie3D/index.tsx +10 -1
  48. package/src/components/Chart/Pie/index.tsx +10 -1
  49. package/src/components/Chart/Polar/index.tsx +12 -2
  50. package/src/components/Chart/Radar/index.tsx +10 -1
  51. package/src/components/Chart/Sankey/index.tsx +12 -2
  52. package/src/components/Chart/Tree/index.tsx +12 -2
  53. package/src/components/Chart/_hooks/useContainerReady.ts +50 -0
  54. package/src/components/Chart/_utils/cartesian.ts +11 -10
  55. package/src/components/Chart/_utils/chartTheme.ts +34 -0
  56. package/src/components/Chart/_utils/heatmap.ts +10 -10
  57. package/src/components/Panel/ListPanel/ListModalPanel/index.module.scss +10 -0
@@ -0,0 +1,56 @@
1
+ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
2
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
3
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
4
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
5
+ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
6
+ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
7
+ import { useEffect, useState } from "react";
8
+
9
+ /**
10
+ * Whether the referenced element has a non-zero box yet.
11
+ *
12
+ * `echarts.init` on a 0×0 element logs `Can't get DOM width or height` and builds a canvas with no
13
+ * size, recovering only on the next `resize()`. A chart hits that path whenever it mounts before
14
+ * layout has given it space — inside a keep-alive tab that is not the active one, a collapsed
15
+ * panel, a modal that has not opened yet — so consuming apps see the warning for charts that end
16
+ * up rendering perfectly well.
17
+ *
18
+ * Gating `init` on this flag defers it to the first frame the element actually occupies space.
19
+ *
20
+ * It **latches**: once measured, the element going back to 0×0 (a keep-alive tab losing focus)
21
+ * must not read as "not ready" again, or the init effect would tear the chart down and re-create
22
+ * it on every tab switch.
23
+ */
24
+ var useContainerReady = function useContainerReady(ref) {
25
+ var _useState = useState(false),
26
+ _useState2 = _slicedToArray(_useState, 2),
27
+ ready = _useState2[0],
28
+ setReady = _useState2[1];
29
+ useEffect(function () {
30
+ if (ready) return;
31
+ var el = ref.current;
32
+ if (!el) return;
33
+ var measure = function measure() {
34
+ var _el$getBoundingClient = el.getBoundingClientRect(),
35
+ width = _el$getBoundingClient.width,
36
+ height = _el$getBoundingClient.height;
37
+ if (width > 0 && height > 0) {
38
+ setReady(true);
39
+ return true;
40
+ }
41
+ return false;
42
+ };
43
+
44
+ // Already laid out on mount — the common case, and it must not cost an extra frame
45
+ if (measure()) return;
46
+ var observer = new ResizeObserver(function () {
47
+ if (measure()) observer.disconnect();
48
+ });
49
+ observer.observe(el);
50
+ return function () {
51
+ return observer.disconnect();
52
+ };
53
+ }, [ready, ref]);
54
+ return ready;
55
+ };
56
+ export default useContainerReady;
@@ -1,5 +1,6 @@
1
1
  import * as echarts from "echarts";
2
2
  import { ChartOptionType, SeriesDataType } from "..";
3
+ import { ChartChrome } from "./chartTheme";
3
4
  export interface ChartScrollConfig {
4
5
  enabled?: boolean;
5
6
  autoScroll?: boolean;
@@ -29,8 +30,8 @@ export interface DataZoomIndexWindow {
29
30
  * percentages produced by native echarts interactions are rounded outward, so each boundary may include at most one extra item, without affecting the axis magnitude.
30
31
  */
31
32
  export declare const percentWindowToIndexWindow: (startPercent: number, endPercent: number, total: number) => DataZoomIndexWindow;
32
- export declare const createDefaultCategoryXAxis: (xAxisData?: Array<string>) => ChartOptionType;
33
- export declare const createDefaultValueYAxis: (mode?: "bar" | "line") => ChartOptionType;
33
+ export declare const createDefaultCategoryXAxis: (xAxisData: Array<string> | undefined, chrome: ChartChrome) => ChartOptionType;
34
+ export declare const createDefaultValueYAxis: (mode: "bar" | "line" | undefined, chrome: ChartChrome) => ChartOptionType;
34
35
  export declare const buildCartesianSeriesOptions: (mode: "bar" | "line", seriesData?: SeriesDataType, series?: echarts.SeriesOption | echarts.SeriesOption[]) => echarts.SeriesOption[];
35
36
  export declare const getSliderShow: (zoom?: echarts.DataZoomComponentOption | Record<string, unknown>) => boolean | undefined;
36
37
  export declare const resolveScrollConfig: (scrollConfig?: ChartScrollConfig) => NormalizedScrollConfig;
@@ -23,7 +23,7 @@ export var percentWindowToIndexWindow = function percentWindowToIndexWindow(star
23
23
  endIndex: endIndex
24
24
  };
25
25
  };
26
- export var createDefaultCategoryXAxis = function createDefaultCategoryXAxis(xAxisData) {
26
+ export var createDefaultCategoryXAxis = function createDefaultCategoryXAxis(xAxisData, chrome) {
27
27
  return {
28
28
  type: "category",
29
29
  boundaryGap: true,
@@ -31,10 +31,10 @@ export var createDefaultCategoryXAxis = function createDefaultCategoryXAxis(xAxi
31
31
  axisLabel: {
32
32
  interval: 0,
33
33
  hideOverlap: true,
34
- textStyle: {
35
- fontSize: 14,
36
- color: "#373D48"
37
- }
34
+ // echarts removed the `textStyle` nesting under `axisLabel` in v4: keeping it means both
35
+ // properties are silently dropped *and* a deprecation warning is logged on every render.
36
+ fontSize: chrome.fontSize,
37
+ color: chrome.axis
38
38
  },
39
39
  axisTick: {
40
40
  show: false
@@ -43,17 +43,16 @@ export var createDefaultCategoryXAxis = function createDefaultCategoryXAxis(xAxi
43
43
  };
44
44
  export var createDefaultValueYAxis = function createDefaultValueYAxis() {
45
45
  var mode = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "bar";
46
+ var chrome = arguments.length > 1 ? arguments[1] : undefined;
46
47
  return {
47
48
  type: "value",
48
49
  axisLabel: {
49
- textStyle: {
50
- fontSize: 14,
51
- color: "#373D48"
52
- }
50
+ fontSize: chrome.fontSize,
51
+ color: chrome.axis
53
52
  },
54
53
  splitLine: mode === "line" ? {
55
54
  lineStyle: {
56
- color: "#C9CED6",
55
+ color: chrome.splitLine,
57
56
  type: "dashed"
58
57
  }
59
58
  } : {
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Colours for the chart *chrome* — axis ticks, split lines, legend labels.
3
+ *
4
+ * echarts options are plain JS, so they cannot read the `--vita-*` CSS variables the rest of the
5
+ * library styles itself with; the literal values have to be resolved here instead. These used to
6
+ * be hard-coded to a light-mode slate (`#373D48` / `#C9CED6`), which left every axis and legend
7
+ * nearly invisible once the page switched to the dark palette.
8
+ *
9
+ * The plotted data is deliberately *not* covered here: series colours come from echarts' own
10
+ * palette or from whatever the caller passes as `color`, and both read fine on either background.
11
+ */
12
+ export interface ChartChrome {
13
+ /** Legend labels — a real label, so it sits on the foreground ramp */
14
+ text: string;
15
+ /** Axis tick labels — secondary information, one step down */
16
+ axis: string;
17
+ /** Split lines behind the plot area */
18
+ splitLine: string;
19
+ /** Base font size, same scale the rest of the library uses */
20
+ fontSize: number;
21
+ }
22
+ export declare const resolveChartChrome: (dark: boolean) => ChartChrome;
@@ -0,0 +1,23 @@
1
+ import { darkTokens, fontTokens, lightTokens } from "../../../styles/tokens";
2
+
3
+ /**
4
+ * Colours for the chart *chrome* — axis ticks, split lines, legend labels.
5
+ *
6
+ * echarts options are plain JS, so they cannot read the `--vita-*` CSS variables the rest of the
7
+ * library styles itself with; the literal values have to be resolved here instead. These used to
8
+ * be hard-coded to a light-mode slate (`#373D48` / `#C9CED6`), which left every axis and legend
9
+ * nearly invisible once the page switched to the dark palette.
10
+ *
11
+ * The plotted data is deliberately *not* covered here: series colours come from echarts' own
12
+ * palette or from whatever the caller passes as `color`, and both read fine on either background.
13
+ */
14
+
15
+ export var resolveChartChrome = function resolveChartChrome(dark) {
16
+ var t = dark ? darkTokens : lightTokens;
17
+ return {
18
+ text: t.foreground,
19
+ axis: t.mutedForeground,
20
+ splitLine: t.border,
21
+ fontSize: fontTokens.size
22
+ };
23
+ };
@@ -1,3 +1,4 @@
1
1
  import { ChartOptionType } from "..";
2
- export declare const createDefaultHeatmapXAxis: (xAxisData?: string[]) => ChartOptionType;
3
- export declare const createDefaultHeatmapYAxis: (yAxisData?: string[]) => ChartOptionType;
2
+ import { ChartChrome } from "./chartTheme";
3
+ export declare const createDefaultHeatmapXAxis: (xAxisData: string[] | undefined, chrome: ChartChrome) => ChartOptionType;
4
+ export declare const createDefaultHeatmapYAxis: (yAxisData: string[] | undefined, chrome: ChartChrome) => ChartOptionType;
@@ -1,4 +1,4 @@
1
- export var createDefaultHeatmapXAxis = function createDefaultHeatmapXAxis(xAxisData) {
1
+ export var createDefaultHeatmapXAxis = function createDefaultHeatmapXAxis(xAxisData, chrome) {
2
2
  return {
3
3
  type: "category",
4
4
  data: xAxisData,
@@ -8,17 +8,16 @@ export var createDefaultHeatmapXAxis = function createDefaultHeatmapXAxis(xAxisD
8
8
  axisLabel: {
9
9
  interval: 0,
10
10
  hideOverlap: true,
11
- textStyle: {
12
- fontSize: 14,
13
- color: "#373D48"
14
- }
11
+ // See the note in `cartesian.ts`: `axisLabel.textStyle` has been deprecated since echarts 4
12
+ fontSize: chrome.fontSize,
13
+ color: chrome.axis
15
14
  },
16
15
  axisTick: {
17
16
  show: false
18
17
  }
19
18
  };
20
19
  };
21
- export var createDefaultHeatmapYAxis = function createDefaultHeatmapYAxis(yAxisData) {
20
+ export var createDefaultHeatmapYAxis = function createDefaultHeatmapYAxis(yAxisData, chrome) {
22
21
  return {
23
22
  type: "category",
24
23
  data: yAxisData,
@@ -26,10 +25,8 @@ export var createDefaultHeatmapYAxis = function createDefaultHeatmapYAxis(yAxisD
26
25
  show: true
27
26
  },
28
27
  axisLabel: {
29
- textStyle: {
30
- fontSize: 14,
31
- color: "#373D48"
32
- }
28
+ fontSize: chrome.fontSize,
29
+ color: chrome.axis
33
30
  },
34
31
  axisTick: {
35
32
  show: false
@@ -21,8 +21,18 @@
21
21
 
22
22
  height: 100%;
23
23
 
24
+ // Inside a modal the Search must not keep its card chrome. On a page it is an outlined white
25
+ // card standing on the grey page background; in a modal the body is already `--vita-surface`,
26
+ // so the same treatment paints a white card on white and only the border survives — a stray
27
+ // outline around the search row. The padding was already being cleared here; the background and
28
+ // border are the other half of the same intent, and `.tableContainer` below is flush for
29
+ // exactly this reason.
24
30
  .search {
25
31
  padding: 0px;
32
+
33
+ background: transparent;
34
+
35
+ border: none;
26
36
  }
27
37
 
28
38
  .tableContainer {
@@ -5,11 +5,14 @@ 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");
11
12
  var _autoSmooth = require("../_utils/autoSmooth");
12
13
  var _cartesian = require("../_utils/cartesian");
14
+ var _chartTheme = require("../_utils/chartTheme");
15
+ var _useIsDark = _interopRequireDefault(require("../../../hooks/useIsDark"));
13
16
  var _jsxRuntime = require("react/jsx-runtime");
14
17
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
15
18
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
@@ -43,15 +46,21 @@ const ChartBar = props => {
43
46
  } = props;
44
47
  const chartRef = (0, _react.useRef)(null);
45
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);
46
51
  const resizeObserverRef = (0, _react.useRef)(null);
47
52
  const prevXAxisKeyRef = (0, _react.useRef)(null);
48
53
  const legendScrollRef = (0, _react.useRef)(null);
49
54
  const normalizedScroll = (0, _react.useMemo)(() => (0, _cartesian.resolveScrollConfig)(scrollConfig), [scrollConfig]);
55
+ // echarts options are plain JS and cannot read the `--vita-*` variables, so the axis and
56
+ // legend colours have to be resolved against the active appearance here
57
+ const isDark = (0, _useIsDark.default)();
58
+ const chrome = (0, _react.useMemo)(() => (0, _chartTheme.resolveChartChrome)(isDark), [isDark]);
50
59
 
51
60
  // Cache the chart option with useMemo
52
61
  const chartOption = (0, _react.useMemo)(() => {
53
- const def_xAxis = (0, _cartesian.createDefaultCategoryXAxis)(xAxisData);
54
- const def_yAxis = (0, _cartesian.createDefaultValueYAxis)("bar");
62
+ const def_xAxis = (0, _cartesian.createDefaultCategoryXAxis)(xAxisData, chrome);
63
+ const def_yAxis = (0, _cartesian.createDefaultValueYAxis)("bar", chrome);
55
64
 
56
65
  // Process xAxis config
57
66
  const processedXAxis = Array.isArray(xAxis) ? xAxis?.map(item => ({
@@ -155,8 +164,7 @@ const ChartBar = props => {
155
164
  data: legendData,
156
165
  icon: "circle",
157
166
  textStyle: {
158
- color: "#373D48",
159
- fontSize: 16
167
+ color: chrome.text
160
168
  },
161
169
  itemWidth: 8,
162
170
  itemHeight: 8,
@@ -183,16 +191,20 @@ const ChartBar = props => {
183
191
  ...coreOption
184
192
  };
185
193
  return option;
186
- }, [xAxisData, xAxis, yAxis, grid, chartTitle, dataZoom, normalizedScroll, insideDataZoom, sliderDataZoom, title, tooltip, legendData, legend, seriesData, series, enableLegendAutoScroll, coreOption]);
194
+ }, [xAxisData, xAxis, yAxis, grid, chartTitle, dataZoom, normalizedScroll, insideDataZoom, sliderDataZoom, title, tooltip, legendData, legend, seriesData, series, enableLegendAutoScroll, coreOption, chrome]);
187
195
 
188
196
  // Callback for handling chart resize
189
197
  const handleResize = (0, _react.useCallback)(() => {
198
+ // A keep-alive tab losing focus fires the observer with a 0×0 box; resizing to that throws
199
+ // the laid-out canvas away and it has to be rebuilt when the tab comes back
200
+ const el = chartRef.current;
201
+ if (!el || el.clientWidth === 0 || el.clientHeight === 0) return;
190
202
  chartInstanceRef.current?.resize();
191
203
  }, []);
192
204
 
193
205
  // Initialize the chart
194
206
  (0, _react.useEffect)(() => {
195
- if (!chartRef.current) return;
207
+ if (!chartRef.current || !containerReady) return;
196
208
 
197
209
  // Initialize or reuse the existing instance
198
210
  let chart = chartInstanceRef.current;
@@ -322,7 +334,7 @@ const ChartBar = props => {
322
334
  };
323
335
  }, [chartOption, handleResize, onClick, onLegendSelectChanged, onDataZoomWindowChanged, xAxisData, enableLegendAutoScroll, legendVisibleCount, legendScrollInterval,
324
336
  // 图例是否接管滚轮由它推导,漏了会拿到过期的滚动配置
325
- normalizedScroll]);
337
+ normalizedScroll, containerReady]);
326
338
 
327
339
  // Handle auto play
328
340
  (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 _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,9 +5,12 @@ 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");
12
+ var _chartTheme = require("../_utils/chartTheme");
13
+ var _useIsDark = _interopRequireDefault(require("../../../hooks/useIsDark"));
11
14
  var _jsxRuntime = require("react/jsx-runtime");
12
15
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13
16
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
@@ -35,7 +38,13 @@ const Heatmap = props => {
35
38
  } = props;
36
39
  const chartRef = (0, _react.useRef)(null);
37
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);
38
43
  const resizeObserverRef = (0, _react.useRef)(null);
44
+ // echarts options are plain JS and cannot read the `--vita-*` variables, so the axis and legend
45
+ // colours have to be resolved against the active appearance here
46
+ const isDark = (0, _useIsDark.default)();
47
+ const chrome = (0, _react.useMemo)(() => (0, _chartTheme.resolveChartChrome)(isDark), [isDark]);
39
48
 
40
49
  // Process the data and generate the chart option
41
50
  const chartOption = (0, _react.useMemo)(() => {
@@ -76,7 +85,7 @@ const Heatmap = props => {
76
85
  left: "right",
77
86
  top: "center",
78
87
  textStyle: {
79
- color: "#373D48"
88
+ color: chrome.text
80
89
  },
81
90
  inRange: {
82
91
  color: inRangeColor
@@ -84,7 +93,7 @@ const Heatmap = props => {
84
93
  };
85
94
 
86
95
  // Process xAxis config
87
- const def_xAxis = (0, _heatmap.createDefaultHeatmapXAxis)(xAxisData);
96
+ const def_xAxis = (0, _heatmap.createDefaultHeatmapXAxis)(xAxisData, chrome);
88
97
  const processedXAxis = Array.isArray(xAxis) ? xAxis?.map(item => ({
89
98
  ...def_xAxis,
90
99
  data: item?.type === "value" ? undefined : xAxisData,
@@ -96,7 +105,7 @@ const Heatmap = props => {
96
105
  };
97
106
 
98
107
  // Process yAxis config
99
- const def_yAxis = (0, _heatmap.createDefaultHeatmapYAxis)(yAxisData);
108
+ const def_yAxis = (0, _heatmap.createDefaultHeatmapYAxis)(yAxisData, chrome);
100
109
  const processedYAxis = Array.isArray(yAxis) ? yAxis?.map(item => ({
101
110
  ...def_yAxis,
102
111
  data: item?.type === "value" ? undefined : yAxisData,
@@ -172,16 +181,20 @@ const Heatmap = props => {
172
181
  ...coreOption
173
182
  };
174
183
  return option;
175
- }, [data, inRangeColor, xAxisData, xAxis, yAxisData, yAxis, propVisualMap, grid, chartTitle, title, tooltip, series, coreOption, zeroColor]);
184
+ }, [data, inRangeColor, xAxisData, xAxis, yAxisData, yAxis, propVisualMap, grid, chartTitle, title, tooltip, series, coreOption, zeroColor, chrome]);
176
185
 
177
186
  // Callback for handling chart resize
178
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;
179
192
  chartInstanceRef.current?.resize();
180
193
  }, []);
181
194
 
182
195
  // Initialize the chart
183
196
  (0, _react.useEffect)(() => {
184
- if (!chartRef.current) return;
197
+ if (!chartRef.current || !containerReady) return;
185
198
 
186
199
  // Initialize or reuse the existing instance
187
200
  let chart = chartInstanceRef.current;
@@ -216,7 +229,7 @@ const Heatmap = props => {
216
229
  chartInstanceRef.current?.off("click", onClick);
217
230
  }
218
231
  };
219
- }, [chartOption, handleResize, onChart, onClick]);
232
+ }, [chartOption, handleResize, onChart, onClick, containerReady]);
220
233
 
221
234
  // Clean up resources when the component unmounts
222
235
  (0, _react.useEffect)(() => {
@@ -5,11 +5,14 @@ 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");
11
12
  var _autoSmooth = require("../_utils/autoSmooth");
12
13
  var _cartesian = require("../_utils/cartesian");
14
+ var _chartTheme = require("../_utils/chartTheme");
15
+ var _useIsDark = _interopRequireDefault(require("../../../hooks/useIsDark"));
13
16
  var _jsxRuntime = require("react/jsx-runtime");
14
17
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
15
18
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
@@ -43,15 +46,21 @@ const ChartLine = props => {
43
46
  } = props;
44
47
  const chartRef = (0, _react.useRef)(null);
45
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);
46
51
  const resizeObserverRef = (0, _react.useRef)(null);
47
52
  const prevXAxisKeyRef = (0, _react.useRef)(null);
48
53
  const legendScrollRef = (0, _react.useRef)(null);
49
54
  const normalizedScroll = (0, _react.useMemo)(() => (0, _cartesian.resolveScrollConfig)(scrollConfig), [scrollConfig]);
55
+ // echarts options are plain JS and cannot read the `--vita-*` variables, so the axis and
56
+ // legend colours have to be resolved against the active appearance here
57
+ const isDark = (0, _useIsDark.default)();
58
+ const chrome = (0, _react.useMemo)(() => (0, _chartTheme.resolveChartChrome)(isDark), [isDark]);
50
59
 
51
60
  // Cache the chart option with useMemo
52
61
  const chartOption = (0, _react.useMemo)(() => {
53
- const def_xAxis = (0, _cartesian.createDefaultCategoryXAxis)(xAxisData);
54
- const def_yAxis = (0, _cartesian.createDefaultValueYAxis)("line");
62
+ const def_xAxis = (0, _cartesian.createDefaultCategoryXAxis)(xAxisData, chrome);
63
+ const def_yAxis = (0, _cartesian.createDefaultValueYAxis)("line", chrome);
55
64
 
56
65
  // Process xAxis config
57
66
  const processedXAxis = Array.isArray(xAxis) ? xAxis?.map(item => ({
@@ -148,7 +157,7 @@ const ChartLine = props => {
148
157
  top: "5%",
149
158
  icon: "circle",
150
159
  textStyle: {
151
- color: "#373D48"
160
+ color: chrome.text
152
161
  },
153
162
  itemWidth: 8,
154
163
  itemHeight: 8,
@@ -179,16 +188,20 @@ const ChartLine = props => {
179
188
  ...coreOption
180
189
  };
181
190
  return option;
182
- }, [xAxisData, xAxis, yAxis, grid, chartTitle, dataZoom, normalizedScroll, insideDataZoom, sliderDataZoom, title, legendData, legend, tooltip, seriesData, series, enableLegendAutoScroll, coreOption]);
191
+ }, [xAxisData, xAxis, yAxis, grid, chartTitle, dataZoom, normalizedScroll, insideDataZoom, sliderDataZoom, title, legendData, legend, tooltip, seriesData, series, enableLegendAutoScroll, coreOption, chrome]);
183
192
 
184
193
  // Callback for handling chart resize
185
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;
186
199
  chartInstanceRef.current?.resize();
187
200
  }, []);
188
201
 
189
202
  // Initialize the chart
190
203
  (0, _react.useEffect)(() => {
191
- if (!chartRef.current) return;
204
+ if (!chartRef.current || !containerReady) return;
192
205
 
193
206
  // Initialize or reuse the existing instance
194
207
  let chart = chartInstanceRef.current;
@@ -318,7 +331,7 @@ const ChartLine = props => {
318
331
  };
319
332
  }, [chartOption, handleResize, onClick, onLegendSelectChanged, onDataZoomWindowChanged, xAxisData, enableLegendAutoScroll, legendVisibleCount, legendScrollInterval,
320
333
  // 图例是否接管滚轮由它推导,漏了会拿到过期的滚动配置
321
- normalizedScroll]);
334
+ normalizedScroll, containerReady]);
322
335
 
323
336
  // Handle auto play
324
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)(() => {