@hsu-react/ui 2.5.4 → 2.5.6
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/ChainGraph/_hooks/useChainGraphData.js +29 -8
- package/es/components/ChainGraph/_hooks/useChainGraphLayout.js +14 -3
- package/es/components/Chart/Bar/index.js +55 -20
- package/es/components/Chart/Bubble/index.js +21 -6
- package/es/components/Chart/Common/index.js +6 -1
- package/es/components/Chart/Gauge/index.js +6 -1
- package/es/components/Chart/Heatmap/index.js +24 -7
- package/es/components/Chart/Line/index.js +55 -20
- package/es/components/Chart/Pie/Pie3D/index.js +30 -12
- package/es/components/Chart/Pie/index.js +24 -7
- package/es/components/Chart/Polar/index.js +9 -2
- package/es/components/Chart/Radar/index.js +6 -1
- package/es/components/Chart/Sankey/index.js +11 -2
- package/es/components/Chart/Tree/index.js +11 -2
- package/es/components/Select/_hooks/useSelectComposition.js +6 -2
- package/es/components/Table/_hooks/useAutoScrolling.js +16 -7
- package/es/hooks/useShallowStable.d.ts +32 -0
- package/es/hooks/useShallowStable.js +54 -0
- package/es/layout/Menu/_hooks/useOnlyLvOneMenu.js +9 -2
- package/lib/components/ChainGraph/_hooks/useChainGraphData.js +24 -7
- package/lib/components/ChainGraph/_hooks/useChainGraphLayout.js +12 -2
- package/lib/components/Chart/Bar/index.js +51 -19
- package/lib/components/Chart/Bubble/index.js +20 -6
- package/lib/components/Chart/Common/index.js +6 -1
- package/lib/components/Chart/Gauge/index.js +6 -1
- package/lib/components/Chart/Heatmap/index.js +23 -7
- package/lib/components/Chart/Line/index.js +51 -19
- package/lib/components/Chart/Pie/Pie3D/index.js +29 -12
- package/lib/components/Chart/Pie/index.js +23 -7
- package/lib/components/Chart/Polar/index.js +9 -2
- package/lib/components/Chart/Radar/index.js +6 -1
- package/lib/components/Chart/Sankey/index.js +10 -2
- package/lib/components/Chart/Tree/index.js +10 -2
- package/lib/components/Select/_hooks/useSelectComposition.js +6 -2
- package/lib/components/Table/_hooks/useAutoScrolling.js +16 -7
- package/lib/hooks/useShallowStable.d.ts +32 -0
- package/lib/hooks/useShallowStable.js +59 -0
- package/lib/layout/Menu/_hooks/useOnlyLvOneMenu.js +8 -2
- package/package.json +1 -1
- package/src/__tests__/callbackDepsGuard.test.ts +72 -0
- package/src/__tests__/depsScan.ts +158 -0
- package/src/__tests__/freshObjectDepsGuard.test.ts +144 -0
- package/src/components/ChainGraph/_hooks/callbacks.test.tsx +155 -0
- package/src/components/ChainGraph/_hooks/useChainGraphData.ts +38 -10
- package/src/components/ChainGraph/_hooks/useChainGraphLayout.ts +16 -3
- package/src/components/Chart/Bar/index.tsx +65 -22
- package/src/components/Chart/Bubble/index.tsx +21 -6
- package/src/components/Chart/Common/index.tsx +6 -1
- package/src/components/Chart/Gauge/index.tsx +6 -1
- package/src/components/Chart/Heatmap/index.tsx +39 -17
- package/src/components/Chart/Line/index.tsx +65 -22
- package/src/components/Chart/Pie/Pie3D/index.tsx +27 -8
- package/src/components/Chart/Pie/index.tsx +25 -7
- package/src/components/Chart/Polar/index.tsx +10 -2
- package/src/components/Chart/Radar/index.tsx +6 -1
- package/src/components/Chart/Sankey/index.tsx +10 -4
- package/src/components/Chart/Tree/index.tsx +10 -4
- package/src/components/Chart/callbacks.test.tsx +315 -0
- package/src/components/Chart/optionMemo.test.tsx +232 -0
- package/src/components/Select/_hooks/useSelectComposition.test.ts +47 -0
- package/src/components/Select/_hooks/useSelectComposition.ts +6 -2
- package/src/components/Table/_hooks/useAutoScrolling.test.tsx +95 -0
- package/src/components/Table/_hooks/useAutoScrolling.ts +16 -7
- package/src/hooks/useShallowStable.ts +65 -0
- package/src/layout/Menu/_hooks/useOnlyLvOneMenu.test.tsx +56 -0
- package/src/layout/Menu/_hooks/useOnlyLvOneMenu.ts +8 -2
|
@@ -4,8 +4,9 @@ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o =
|
|
|
4
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
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
6
|
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
7
|
-
import { useEffect, useState } from "react";
|
|
7
|
+
import { useCallback, useEffect, useState } from "react";
|
|
8
8
|
import { Equal } from "hsu-utils";
|
|
9
|
+
import { useLatestRef } from "../../../hooks/useLatestRef";
|
|
9
10
|
export function useChainGraphData(props) {
|
|
10
11
|
var graph = props.graph,
|
|
11
12
|
data = props.data,
|
|
@@ -22,6 +23,29 @@ export function useChainGraphData(props) {
|
|
|
22
23
|
_useState4 = _slicedToArray(_useState3, 2),
|
|
23
24
|
isLayouting = _useState4[0],
|
|
24
25
|
setIsLayouting = _useState4[1];
|
|
26
|
+
|
|
27
|
+
// 这三个回调都是「交给图实例、由它在后续事件里回调」的出口,不是数据本身。
|
|
28
|
+
// 它们进依赖数组是条死依赖:effect 体被 ObjEqual(lastData, data) 挡住,
|
|
29
|
+
// 引用变了也不会重新 setData —— 图里存的还是首次 setData 时那个闭包,
|
|
30
|
+
// 换了引用永远调不到(stale closure)。改成引用恒定的转发函数:
|
|
31
|
+
// 依赖数组只留真正的输入(graph/data/level/rootLevel),调用时总是取到最新的回调。
|
|
32
|
+
var getImageRef = useLatestRef(getImage);
|
|
33
|
+
var labelRenderRef = useLatestRef(labelRender);
|
|
34
|
+
var onLayoutingChangeRef = useLatestRef(onLayoutingChange);
|
|
35
|
+
var emitImage = useCallback(function (img) {
|
|
36
|
+
var _getImageRef$current;
|
|
37
|
+
(_getImageRef$current = getImageRef.current) === null || _getImageRef$current === void 0 || _getImageRef$current.call(getImageRef, img);
|
|
38
|
+
}, [getImageRef]);
|
|
39
|
+
// labelRender 在 ChainGraphServices.setData 里是「传了才改写 label」的真值判断,
|
|
40
|
+
// 所以这里保留「有没有传」的语义:没传就传 undefined,传了才给转发函数。
|
|
41
|
+
var renderLabel = useCallback(function (label) {
|
|
42
|
+
return labelRenderRef.current(label);
|
|
43
|
+
}, [labelRenderRef]);
|
|
44
|
+
var emitLayouting = useCallback(function (value) {
|
|
45
|
+
var _onLayoutingChangeRef;
|
|
46
|
+
setIsLayouting(value);
|
|
47
|
+
(_onLayoutingChangeRef = onLayoutingChangeRef.current) === null || _onLayoutingChangeRef === void 0 || _onLayoutingChangeRef.call(onLayoutingChangeRef, value);
|
|
48
|
+
}, [onLayoutingChangeRef]);
|
|
25
49
|
useEffect(function () {
|
|
26
50
|
if (graph && !Equal.ObjEqual(lastData, data)) {
|
|
27
51
|
setLastData(data);
|
|
@@ -29,15 +53,12 @@ export function useChainGraphData(props) {
|
|
|
29
53
|
data: data,
|
|
30
54
|
level: level,
|
|
31
55
|
rootLevel: rootLevel,
|
|
32
|
-
getImage:
|
|
33
|
-
isLayouting:
|
|
34
|
-
|
|
35
|
-
onLayoutingChange === null || onLayoutingChange === void 0 || onLayoutingChange(value);
|
|
36
|
-
},
|
|
37
|
-
labelRender: labelRender
|
|
56
|
+
getImage: emitImage,
|
|
57
|
+
isLayouting: emitLayouting,
|
|
58
|
+
labelRender: labelRenderRef.current ? renderLabel : undefined
|
|
38
59
|
});
|
|
39
60
|
}
|
|
40
|
-
}, [graph, data, level, rootLevel,
|
|
61
|
+
}, [graph, data, level, rootLevel, lastData, emitImage, emitLayouting, renderLabel, labelRenderRef]);
|
|
41
62
|
return {
|
|
42
63
|
isLayouting: isLayouting
|
|
43
64
|
};
|
|
@@ -1,12 +1,23 @@
|
|
|
1
|
-
import { useEffect } from "react";
|
|
1
|
+
import { useCallback, useEffect } from "react";
|
|
2
|
+
import { useLatestRef } from "../../../hooks/useLatestRef";
|
|
2
3
|
export function useChainGraphLayout(props) {
|
|
3
4
|
var graph = props.graph,
|
|
4
5
|
octopus = props.octopus,
|
|
5
6
|
rootLevel = props.rootLevel,
|
|
6
7
|
getImage = props.getImage;
|
|
8
|
+
|
|
9
|
+
// getImage 只是「布局完成后把截图 dataURL 交出去」的出口,不是布局的输入。
|
|
10
|
+
// 它进依赖数组会让消费方每传一次内联箭头就重新 changeLayout 一次 —— 整张图重排;
|
|
11
|
+
// 消费方再把截图存进 state,就变成「重排 → 出图 → setState → 新引用 → 再重排」的死循环。
|
|
12
|
+
// 用引用恒定的转发函数注册,调用时再取最新的 getImage。
|
|
13
|
+
var getImageRef = useLatestRef(getImage);
|
|
14
|
+
var emitImage = useCallback(function (img) {
|
|
15
|
+
var _getImageRef$current;
|
|
16
|
+
(_getImageRef$current = getImageRef.current) === null || _getImageRef$current === void 0 || _getImageRef$current.call(getImageRef, img);
|
|
17
|
+
}, [getImageRef]);
|
|
7
18
|
useEffect(function () {
|
|
8
19
|
if (graph && octopus !== undefined) {
|
|
9
|
-
graph.changeLayout(octopus, rootLevel,
|
|
20
|
+
graph.changeLayout(octopus, rootLevel, emitImage);
|
|
10
21
|
}
|
|
11
|
-
}, [graph, octopus, rootLevel,
|
|
22
|
+
}, [graph, octopus, rootLevel, emitImage]);
|
|
12
23
|
}
|
|
@@ -16,6 +16,8 @@ import { autoScrollByItem } from "../_utils/autoSmooth";
|
|
|
16
16
|
import { buildCartesianSeriesOptions, createDefaultCategoryXAxis, createDefaultValueYAxis, getSliderShow, percentWindowToIndexWindow, resolveScrollConfig } from "../_utils/cartesian";
|
|
17
17
|
import { resolveChartChrome } from "../_utils/chartTheme";
|
|
18
18
|
import useIsDark from "../../../hooks/useIsDark";
|
|
19
|
+
import useLatestRef from "../../../hooks/useLatestRef";
|
|
20
|
+
import useShallowStable from "../../../hooks/useShallowStable";
|
|
19
21
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
20
22
|
var ChartBar = function ChartBar(props) {
|
|
21
23
|
var className = props.className,
|
|
@@ -44,7 +46,11 @@ var ChartBar = function ChartBar(props) {
|
|
|
44
46
|
legendVisibleCount = _props$legendVisibleC === void 0 ? 8 : _props$legendVisibleC,
|
|
45
47
|
_props$legendScrollIn = props.legendScrollInterval,
|
|
46
48
|
legendScrollInterval = _props$legendScrollIn === void 0 ? 1500 : _props$legendScrollIn,
|
|
47
|
-
|
|
49
|
+
restOption = _objectWithoutProperties(props, _excluded);
|
|
50
|
+
// rest 解构出来的对象每次渲染都是新引用,直接进依赖数组会让 chartOption 的 memo
|
|
51
|
+
// 恒不命中 —— 父组件每渲染一次就重跑一次 setOption(notMerge),动画重播、悬浮态被清掉。
|
|
52
|
+
// useShallowStable 让它回到值语义:内容浅相等就复用同一引用,真变了立刻透出新引用。
|
|
53
|
+
var coreOption = useShallowStable(restOption);
|
|
48
54
|
var chartRef = useRef(null);
|
|
49
55
|
var chartInstanceRef = useRef(null);
|
|
50
56
|
// Defers `echarts.init` until the container has a box — see the hook for why
|
|
@@ -62,6 +68,30 @@ var ChartBar = function ChartBar(props) {
|
|
|
62
68
|
return resolveChartChrome(isDark);
|
|
63
69
|
}, [isDark]);
|
|
64
70
|
|
|
71
|
+
// 回调 prop 一律走 useLatestRef,不进依赖数组:消费方传内联箭头(React 里最常见的
|
|
72
|
+
// 写法)时每次渲染都是新引用,进依赖数组会让「init + setOption(notMerge)」整段重跑,
|
|
73
|
+
// 还会把当前可视窗口再同步一次给父级 —— 父级据此改 state 就是死循环。
|
|
74
|
+
// 但「有没有传回调」决定要不要注册监听,所以单独拆成布尔量进依赖数组,
|
|
75
|
+
// 这样「从无到有传入回调」仍会重新注册,不会漏。
|
|
76
|
+
var onClickRef = useLatestRef(onClick);
|
|
77
|
+
var onLegendSelectChangedRef = useLatestRef(onLegendSelectChanged);
|
|
78
|
+
var onDataZoomWindowChangedRef = useLatestRef(onDataZoomWindowChanged);
|
|
79
|
+
var hasOnClick = !!onClick;
|
|
80
|
+
var hasOnLegendSelectChanged = !!onLegendSelectChanged;
|
|
81
|
+
var hasOnDataZoomWindowChanged = !!onDataZoomWindowChanged;
|
|
82
|
+
// 已通知过父级的窗口用 ref 记账(不参与渲染):窗口没变就不再通知,
|
|
83
|
+
// 掐断「通知 → 父级重算坐标轴 → chartOption 变 → effect 重跑 → 再通知」的自激回路
|
|
84
|
+
var notifiedZoomWindowRef = useRef(null);
|
|
85
|
+
var emitZoomWindow = useCallback(function (next) {
|
|
86
|
+
var _onDataZoomWindowChan;
|
|
87
|
+
var prev = notifiedZoomWindowRef.current;
|
|
88
|
+
if (prev && prev.startIndex === next.startIndex && prev.endIndex === next.endIndex) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
notifiedZoomWindowRef.current = next;
|
|
92
|
+
(_onDataZoomWindowChan = onDataZoomWindowChangedRef.current) === null || _onDataZoomWindowChan === void 0 || _onDataZoomWindowChan.call(onDataZoomWindowChangedRef, next);
|
|
93
|
+
}, [onDataZoomWindowChangedRef]);
|
|
94
|
+
|
|
65
95
|
// Cache the chart option with useMemo
|
|
66
96
|
var chartOption = useMemo(function () {
|
|
67
97
|
var _xAxisData$length, _ref, _ref2;
|
|
@@ -239,16 +269,16 @@ var ChartBar = function ChartBar(props) {
|
|
|
239
269
|
}
|
|
240
270
|
|
|
241
271
|
// Sync the current visible window to the caller (on initial render and after restore), used to recalculate axes based on the displayed portion
|
|
242
|
-
if (
|
|
272
|
+
if (hasOnDataZoomWindowChanged) {
|
|
243
273
|
var _chart$getOption3, _xAxisData$length2;
|
|
244
274
|
var zooms = (_chart$getOption3 = chart.getOption()) === null || _chart$getOption3 === void 0 ? void 0 : _chart$getOption3.dataZoom;
|
|
245
275
|
var zoom = zooms === null || zooms === void 0 ? void 0 : zooms[0];
|
|
246
276
|
var totalLen = (_xAxisData$length2 = xAxisData === null || xAxisData === void 0 ? void 0 : xAxisData.length) !== null && _xAxisData$length2 !== void 0 ? _xAxisData$length2 : 0;
|
|
247
277
|
if (typeof (zoom === null || zoom === void 0 ? void 0 : zoom.start) === "number" && typeof (zoom === null || zoom === void 0 ? void 0 : zoom.end) === "number") {
|
|
248
|
-
|
|
278
|
+
emitZoomWindow(percentWindowToIndexWindow(zoom.start, zoom.end, totalLen));
|
|
249
279
|
} else {
|
|
250
280
|
// Without dataZoom (e.g. scrolling not enabled due to insufficient data) the window is the full range; sync once to avoid a stale old window
|
|
251
|
-
|
|
281
|
+
emitZoomWindow({
|
|
252
282
|
startIndex: 0,
|
|
253
283
|
endIndex: Math.max(0, totalLen - 1)
|
|
254
284
|
});
|
|
@@ -264,17 +294,22 @@ var ChartBar = function ChartBar(props) {
|
|
|
264
294
|
resizeObserverRef.current.observe(chartRef.current);
|
|
265
295
|
}
|
|
266
296
|
|
|
267
|
-
// Add click event
|
|
268
|
-
|
|
297
|
+
// Add click event(注册与否看布尔量,实际调用取最新引用)
|
|
298
|
+
var handleClick = function handleClick(event) {
|
|
299
|
+
var _onClickRef$current;
|
|
300
|
+
(_onClickRef$current = onClickRef.current) === null || _onClickRef$current === void 0 || _onClickRef$current.call(onClickRef, event);
|
|
301
|
+
};
|
|
302
|
+
if (hasOnClick) {
|
|
269
303
|
var _chartInstanceRef$cur2;
|
|
270
|
-
(_chartInstanceRef$cur2 = chartInstanceRef.current) === null || _chartInstanceRef$cur2 === void 0 || _chartInstanceRef$cur2.on("click",
|
|
304
|
+
(_chartInstanceRef$cur2 = chartInstanceRef.current) === null || _chartInstanceRef$cur2 === void 0 || _chartInstanceRef$cur2.on("click", handleClick);
|
|
271
305
|
}
|
|
272
306
|
|
|
273
307
|
// Legend selection event
|
|
274
308
|
var handleLegendSelectChanged = function handleLegendSelectChanged(params) {
|
|
275
|
-
|
|
309
|
+
var _onLegendSelectChange;
|
|
310
|
+
(_onLegendSelectChange = onLegendSelectChangedRef.current) === null || _onLegendSelectChange === void 0 || _onLegendSelectChange.call(onLegendSelectChangedRef, params.selected);
|
|
276
311
|
};
|
|
277
|
-
if (
|
|
312
|
+
if (hasOnLegendSelectChanged) {
|
|
278
313
|
var _chartInstanceRef$cur3;
|
|
279
314
|
(_chartInstanceRef$cur3 = chartInstanceRef.current) === null || _chartInstanceRef$cur3 === void 0 || _chartInstanceRef$cur3.on("legendselectchanged", handleLegendSelectChanged);
|
|
280
315
|
}
|
|
@@ -285,16 +320,16 @@ var ChartBar = function ChartBar(props) {
|
|
|
285
320
|
var raw = params;
|
|
286
321
|
var info = (_raw$batch$ = raw === null || raw === void 0 || (_raw$batch = raw.batch) === null || _raw$batch === void 0 ? void 0 : _raw$batch[0]) !== null && _raw$batch$ !== void 0 ? _raw$batch$ : raw;
|
|
287
322
|
if (typeof (info === null || info === void 0 ? void 0 : info.startValue) === "number" && typeof (info === null || info === void 0 ? void 0 : info.endValue) === "number") {
|
|
288
|
-
|
|
323
|
+
emitZoomWindow({
|
|
289
324
|
startIndex: Math.max(0, Math.round(info.startValue)),
|
|
290
325
|
endIndex: Math.max(0, Math.round(info.endValue))
|
|
291
326
|
});
|
|
292
327
|
} else if (typeof (info === null || info === void 0 ? void 0 : info.start) === "number" && typeof (info === null || info === void 0 ? void 0 : info.end) === "number") {
|
|
293
328
|
var _xAxisData$length3;
|
|
294
|
-
|
|
329
|
+
emitZoomWindow(percentWindowToIndexWindow(info.start, info.end, (_xAxisData$length3 = xAxisData === null || xAxisData === void 0 ? void 0 : xAxisData.length) !== null && _xAxisData$length3 !== void 0 ? _xAxisData$length3 : 0));
|
|
295
330
|
}
|
|
296
331
|
};
|
|
297
|
-
if (
|
|
332
|
+
if (hasOnDataZoomWindowChanged) {
|
|
298
333
|
var _chartInstanceRef$cur4;
|
|
299
334
|
(_chartInstanceRef$cur4 = chartInstanceRef.current) === null || _chartInstanceRef$cur4 === void 0 || _chartInstanceRef$cur4.on("datazoom", handleDataZoom);
|
|
300
335
|
}
|
|
@@ -322,15 +357,15 @@ var ChartBar = function ChartBar(props) {
|
|
|
322
357
|
// Cleanup function
|
|
323
358
|
return function () {
|
|
324
359
|
window.removeEventListener("resize", handleResize);
|
|
325
|
-
if (
|
|
360
|
+
if (hasOnClick) {
|
|
326
361
|
var _chartInstanceRef$cur5;
|
|
327
|
-
(_chartInstanceRef$cur5 = chartInstanceRef.current) === null || _chartInstanceRef$cur5 === void 0 || _chartInstanceRef$cur5.off("click",
|
|
362
|
+
(_chartInstanceRef$cur5 = chartInstanceRef.current) === null || _chartInstanceRef$cur5 === void 0 || _chartInstanceRef$cur5.off("click", handleClick);
|
|
328
363
|
}
|
|
329
|
-
if (
|
|
364
|
+
if (hasOnLegendSelectChanged) {
|
|
330
365
|
var _chartInstanceRef$cur6;
|
|
331
366
|
(_chartInstanceRef$cur6 = chartInstanceRef.current) === null || _chartInstanceRef$cur6 === void 0 || _chartInstanceRef$cur6.off("legendselectchanged", handleLegendSelectChanged);
|
|
332
367
|
}
|
|
333
|
-
if (
|
|
368
|
+
if (hasOnDataZoomWindowChanged) {
|
|
334
369
|
var _chartInstanceRef$cur7;
|
|
335
370
|
(_chartInstanceRef$cur7 = chartInstanceRef.current) === null || _chartInstanceRef$cur7 === void 0 || _chartInstanceRef$cur7.off("datazoom", handleDataZoom);
|
|
336
371
|
}
|
|
@@ -339,7 +374,7 @@ var ChartBar = function ChartBar(props) {
|
|
|
339
374
|
legendScrollRef.current = null;
|
|
340
375
|
}
|
|
341
376
|
};
|
|
342
|
-
}, [chartOption, handleResize,
|
|
377
|
+
}, [chartOption, handleResize, onClickRef, onLegendSelectChangedRef, hasOnClick, hasOnLegendSelectChanged, hasOnDataZoomWindowChanged, emitZoomWindow, xAxisData, enableLegendAutoScroll, legendVisibleCount, legendScrollInterval,
|
|
343
378
|
// 图例是否接管滚轮由它推导,漏了会拿到过期的滚动配置
|
|
344
379
|
normalizedScroll, containerReady]);
|
|
345
380
|
|
|
@@ -359,13 +394,13 @@ var ChartBar = function ChartBar(props) {
|
|
|
359
394
|
startIndex: normalizedScroll.startIndex,
|
|
360
395
|
autoPlay: normalizedScroll.autoScroll,
|
|
361
396
|
enableWheelScroll: enableWheelScroll,
|
|
362
|
-
onWindowChange:
|
|
363
|
-
return
|
|
397
|
+
onWindowChange: hasOnDataZoomWindowChanged ? function (startPercent, endPercent) {
|
|
398
|
+
return emitZoomWindow(percentWindowToIndexWindow(startPercent, endPercent, xAxisData.length));
|
|
364
399
|
} : undefined
|
|
365
400
|
}),
|
|
366
401
|
dispose = _autoScrollByItem.dispose;
|
|
367
402
|
return dispose;
|
|
368
|
-
}, [dataZoom, normalizedScroll, sliderDataZoom, xAxisData,
|
|
403
|
+
}, [dataZoom, normalizedScroll, sliderDataZoom, xAxisData, hasOnDataZoomWindowChanged, emitZoomWindow]);
|
|
369
404
|
|
|
370
405
|
// Clean up resources when the component unmounts
|
|
371
406
|
useEffect(function () {
|
|
@@ -22,6 +22,7 @@ import styles from "../index.module.scss";
|
|
|
22
22
|
import * as echarts from "echarts";
|
|
23
23
|
import { defaultBubbleColorList, drawCircles } from "../_utils/bubble";
|
|
24
24
|
import { useLatestRef } from "../../../hooks/useLatestRef";
|
|
25
|
+
import useShallowStable from "../../../hooks/useShallowStable";
|
|
25
26
|
|
|
26
27
|
// Extended data item type containing all properties the chart needs
|
|
27
28
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
@@ -38,7 +39,11 @@ var Bubble = function Bubble(props) {
|
|
|
38
39
|
title = props.title,
|
|
39
40
|
onChart = props.onChart,
|
|
40
41
|
onClick = props.onClick,
|
|
41
|
-
|
|
42
|
+
restOption = _objectWithoutProperties(props, _excluded);
|
|
43
|
+
// rest 解构出来的对象每次渲染都是新引用,直接进依赖数组会让 chartOption 的 memo
|
|
44
|
+
// 恒不命中 —— 父组件每渲染一次就重跑一次 setOption(notMerge),动画重播、悬浮态被清掉。
|
|
45
|
+
// useShallowStable 让它回到值语义:内容浅相等就复用同一引用,真变了立刻透出新引用。
|
|
46
|
+
var coreOption = useShallowStable(restOption);
|
|
42
47
|
var chartRef = useRef(null);
|
|
43
48
|
var chartInstanceRef = useRef(null);
|
|
44
49
|
var resizeObserverRef = useRef(null);
|
|
@@ -279,6 +284,12 @@ var Bubble = function Bubble(props) {
|
|
|
279
284
|
}, [chartOption, data]);
|
|
280
285
|
var onChartRef = useLatestRef(onChart);
|
|
281
286
|
|
|
287
|
+
// onClick 不进依赖数组:消费方传内联箭头时每次渲染都是新引用,effect 跟着重跑就会
|
|
288
|
+
// 再走一遍 setOption(notMerge),动画重播、悬浮/高亮态被清掉。注册与否看布尔量,
|
|
289
|
+
// 这样「从无到有传入 onClick」仍会注册;实际调用取 ref 里的最新引用。
|
|
290
|
+
var onClickRef = useLatestRef(onClick);
|
|
291
|
+
var hasOnClick = !!onClick;
|
|
292
|
+
|
|
282
293
|
// 回调 prop 不进依赖数组:消费方传内联箭头时每次渲染都是新引用,effect 会跟着
|
|
283
294
|
// 重跑并再调一次回调 —— 回调里 setState 就是死循环(详见 Input/TextArea 的说明)
|
|
284
295
|
// Initialize the chart
|
|
@@ -305,20 +316,24 @@ var Bubble = function Bubble(props) {
|
|
|
305
316
|
window.addEventListener("resize", handleResize);
|
|
306
317
|
|
|
307
318
|
// Add click event
|
|
308
|
-
|
|
319
|
+
var handleClick = function handleClick(event) {
|
|
320
|
+
var _onClickRef$current;
|
|
321
|
+
(_onClickRef$current = onClickRef.current) === null || _onClickRef$current === void 0 || _onClickRef$current.call(onClickRef, event);
|
|
322
|
+
};
|
|
323
|
+
if (hasOnClick) {
|
|
309
324
|
var _chartInstanceRef$cur2;
|
|
310
|
-
(_chartInstanceRef$cur2 = chartInstanceRef.current) === null || _chartInstanceRef$cur2 === void 0 || _chartInstanceRef$cur2.on("click",
|
|
325
|
+
(_chartInstanceRef$cur2 = chartInstanceRef.current) === null || _chartInstanceRef$cur2 === void 0 || _chartInstanceRef$cur2.on("click", handleClick);
|
|
311
326
|
}
|
|
312
327
|
|
|
313
328
|
// Cleanup function
|
|
314
329
|
return function () {
|
|
315
330
|
window.removeEventListener("resize", handleResize);
|
|
316
|
-
if (
|
|
331
|
+
if (hasOnClick) {
|
|
317
332
|
var _chartInstanceRef$cur3;
|
|
318
|
-
(_chartInstanceRef$cur3 = chartInstanceRef.current) === null || _chartInstanceRef$cur3 === void 0 || _chartInstanceRef$cur3.off("click",
|
|
333
|
+
(_chartInstanceRef$cur3 = chartInstanceRef.current) === null || _chartInstanceRef$cur3 === void 0 || _chartInstanceRef$cur3.off("click", handleClick);
|
|
319
334
|
}
|
|
320
335
|
};
|
|
321
|
-
}, [chartOption, containerSize.width, containerSize.height, handleResize, onChartRef,
|
|
336
|
+
}, [chartOption, containerSize.width, containerSize.height, handleResize, onChartRef, onClickRef, hasOnClick]);
|
|
322
337
|
|
|
323
338
|
// Dispose the chart instance when the component unmounts
|
|
324
339
|
useEffect(function () {
|
|
@@ -12,12 +12,17 @@ import useContainerReady from "../_hooks/useContainerReady";
|
|
|
12
12
|
import styles from "../index.module.scss";
|
|
13
13
|
import * as echarts from "echarts";
|
|
14
14
|
import { useLatestRef } from "../../../hooks/useLatestRef";
|
|
15
|
+
import useShallowStable from "../../../hooks/useShallowStable";
|
|
15
16
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
16
17
|
var Common = function Common(props) {
|
|
17
18
|
var className = props.className,
|
|
18
19
|
style = props.style,
|
|
19
20
|
onChart = props.onChart,
|
|
20
|
-
|
|
21
|
+
restOption = _objectWithoutProperties(props, _excluded);
|
|
22
|
+
// rest 解构出来的对象每次渲染都是新引用,直接进依赖数组会让 chartOption 的 memo
|
|
23
|
+
// 恒不命中 —— 父组件每渲染一次就重跑一次 setOption(notMerge),动画重播、悬浮态被清掉。
|
|
24
|
+
// useShallowStable 让它回到值语义:内容浅相等就复用同一引用,真变了立刻透出新引用。
|
|
25
|
+
var coreOption = useShallowStable(restOption);
|
|
21
26
|
var chartRef = useRef(null);
|
|
22
27
|
var chartInstanceRef = useRef(null);
|
|
23
28
|
// Defers `echarts.init` until the container has a box — see the hook for why
|
|
@@ -11,6 +11,7 @@ import * as echarts from "echarts";
|
|
|
11
11
|
import useContainerReady from "../_hooks/useContainerReady";
|
|
12
12
|
import React, { useCallback, useEffect, useMemo, useRef } from "react";
|
|
13
13
|
import styles from "../index.module.scss";
|
|
14
|
+
import useShallowStable from "../../../hooks/useShallowStable";
|
|
14
15
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
15
16
|
var Gauge = function Gauge(props) {
|
|
16
17
|
var className = props.className,
|
|
@@ -29,7 +30,11 @@ var Gauge = function Gauge(props) {
|
|
|
29
30
|
title = _ref.title,
|
|
30
31
|
_ref$color = _ref.color,
|
|
31
32
|
color = _ref$color === void 0 ? "#1675FB" : _ref$color,
|
|
32
|
-
|
|
33
|
+
restSeries = _objectWithoutProperties(_ref, _excluded);
|
|
34
|
+
// rest 解构出来的对象每次渲染都是新引用,直接进依赖数组会让 chartOption 的 memo
|
|
35
|
+
// 恒不命中 —— 父组件每渲染一次就重跑一次 setOption(notMerge),动画重播、悬浮态被清掉。
|
|
36
|
+
// useShallowStable 让它回到值语义:内容浅相等就复用同一引用,真变了立刻透出新引用。
|
|
37
|
+
var coreSeries = useShallowStable(restSeries);
|
|
33
38
|
var chartRef = useRef(null);
|
|
34
39
|
var chartInstanceRef = useRef(null);
|
|
35
40
|
// Defers `echarts.init` until the container has a box — see the hook for why
|
|
@@ -21,7 +21,10 @@ import { createDefaultHeatmapXAxis, createDefaultHeatmapYAxis } from "../_utils/
|
|
|
21
21
|
import { resolveChartChrome } from "../_utils/chartTheme";
|
|
22
22
|
import useIsDark from "../../../hooks/useIsDark";
|
|
23
23
|
import { useLatestRef } from "../../../hooks/useLatestRef";
|
|
24
|
+
import useShallowStable from "../../../hooks/useShallowStable";
|
|
24
25
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
26
|
+
// 解构默认值写成字面量会每次渲染新建一个数组,进依赖数组就让 memo 恒不命中;提到模块级常量
|
|
27
|
+
var DEFAULT_IN_RANGE_COLOR = ["#8BCCFB", "#75C3FB", "#5AB5F6", "#42AEFA", "#2DA1F5", "#0F89E1", "#056FBB", "#025794", "#0A4089"];
|
|
25
28
|
var Heatmap = function Heatmap(props) {
|
|
26
29
|
var className = props.className,
|
|
27
30
|
style = props.style,
|
|
@@ -40,8 +43,12 @@ var Heatmap = function Heatmap(props) {
|
|
|
40
43
|
onClick = props.onClick,
|
|
41
44
|
zeroColor = props.zeroColor,
|
|
42
45
|
_props$inRangeColor = props.inRangeColor,
|
|
43
|
-
inRangeColor = _props$inRangeColor === void 0 ?
|
|
44
|
-
|
|
46
|
+
inRangeColor = _props$inRangeColor === void 0 ? DEFAULT_IN_RANGE_COLOR : _props$inRangeColor,
|
|
47
|
+
restOption = _objectWithoutProperties(props, _excluded);
|
|
48
|
+
// rest 解构出来的对象每次渲染都是新引用,直接进依赖数组会让 chartOption 的 memo
|
|
49
|
+
// 恒不命中 —— 父组件每渲染一次就重跑一次 setOption(notMerge),动画重播、悬浮态被清掉。
|
|
50
|
+
// useShallowStable 让它回到值语义:内容浅相等就复用同一引用,真变了立刻透出新引用。
|
|
51
|
+
var coreOption = useShallowStable(restOption);
|
|
45
52
|
var chartRef = useRef(null);
|
|
46
53
|
var chartInstanceRef = useRef(null);
|
|
47
54
|
// Defers `echarts.init` until the container has a box — see the hook for why
|
|
@@ -195,6 +202,12 @@ var Heatmap = function Heatmap(props) {
|
|
|
195
202
|
}, []);
|
|
196
203
|
var onChartRef = useLatestRef(onChart);
|
|
197
204
|
|
|
205
|
+
// onClick 不进依赖数组:消费方传内联箭头时每次渲染都是新引用,effect 跟着重跑就会
|
|
206
|
+
// 再走一遍 setOption(notMerge),动画重播、悬浮/高亮态被清掉。注册与否看布尔量,
|
|
207
|
+
// 这样「从无到有传入 onClick」仍会注册;实际调用取 ref 里的最新引用。
|
|
208
|
+
var onClickRef = useLatestRef(onClick);
|
|
209
|
+
var hasOnClick = !!onClick;
|
|
210
|
+
|
|
198
211
|
// 回调 prop 不进依赖数组:消费方传内联箭头时每次渲染都是新引用,effect 会跟着
|
|
199
212
|
// 重跑并再调一次回调 —— 回调里 setState 就是死循环(详见 Input/TextArea 的说明)
|
|
200
213
|
// Initialize the chart
|
|
@@ -224,20 +237,24 @@ var Heatmap = function Heatmap(props) {
|
|
|
224
237
|
}
|
|
225
238
|
|
|
226
239
|
// Add click event
|
|
227
|
-
|
|
240
|
+
var handleClick = function handleClick(event) {
|
|
241
|
+
var _onClickRef$current;
|
|
242
|
+
(_onClickRef$current = onClickRef.current) === null || _onClickRef$current === void 0 || _onClickRef$current.call(onClickRef, event);
|
|
243
|
+
};
|
|
244
|
+
if (hasOnClick) {
|
|
228
245
|
var _chartInstanceRef$cur2;
|
|
229
|
-
(_chartInstanceRef$cur2 = chartInstanceRef.current) === null || _chartInstanceRef$cur2 === void 0 || _chartInstanceRef$cur2.on("click",
|
|
246
|
+
(_chartInstanceRef$cur2 = chartInstanceRef.current) === null || _chartInstanceRef$cur2 === void 0 || _chartInstanceRef$cur2.on("click", handleClick);
|
|
230
247
|
}
|
|
231
248
|
|
|
232
249
|
// Cleanup function
|
|
233
250
|
return function () {
|
|
234
251
|
window.removeEventListener("resize", handleResize);
|
|
235
|
-
if (
|
|
252
|
+
if (hasOnClick) {
|
|
236
253
|
var _chartInstanceRef$cur3;
|
|
237
|
-
(_chartInstanceRef$cur3 = chartInstanceRef.current) === null || _chartInstanceRef$cur3 === void 0 || _chartInstanceRef$cur3.off("click",
|
|
254
|
+
(_chartInstanceRef$cur3 = chartInstanceRef.current) === null || _chartInstanceRef$cur3 === void 0 || _chartInstanceRef$cur3.off("click", handleClick);
|
|
238
255
|
}
|
|
239
256
|
};
|
|
240
|
-
}, [chartOption, handleResize, onChartRef,
|
|
257
|
+
}, [chartOption, handleResize, onChartRef, onClickRef, hasOnClick, containerReady]);
|
|
241
258
|
|
|
242
259
|
// Clean up resources when the component unmounts
|
|
243
260
|
useEffect(function () {
|
|
@@ -16,6 +16,8 @@ import { autoScrollByItem } from "../_utils/autoSmooth";
|
|
|
16
16
|
import { buildCartesianSeriesOptions, createDefaultCategoryXAxis, createDefaultValueYAxis, getSliderShow, percentWindowToIndexWindow, resolveScrollConfig } from "../_utils/cartesian";
|
|
17
17
|
import { resolveChartChrome } from "../_utils/chartTheme";
|
|
18
18
|
import useIsDark from "../../../hooks/useIsDark";
|
|
19
|
+
import useLatestRef from "../../../hooks/useLatestRef";
|
|
20
|
+
import useShallowStable from "../../../hooks/useShallowStable";
|
|
19
21
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
20
22
|
var ChartLine = function ChartLine(props) {
|
|
21
23
|
var className = props.className,
|
|
@@ -44,7 +46,11 @@ var ChartLine = function ChartLine(props) {
|
|
|
44
46
|
legendVisibleCount = _props$legendVisibleC === void 0 ? 8 : _props$legendVisibleC,
|
|
45
47
|
_props$legendScrollIn = props.legendScrollInterval,
|
|
46
48
|
legendScrollInterval = _props$legendScrollIn === void 0 ? 1500 : _props$legendScrollIn,
|
|
47
|
-
|
|
49
|
+
restOption = _objectWithoutProperties(props, _excluded);
|
|
50
|
+
// rest 解构出来的对象每次渲染都是新引用,直接进依赖数组会让 chartOption 的 memo
|
|
51
|
+
// 恒不命中 —— 父组件每渲染一次就重跑一次 setOption(notMerge),动画重播、悬浮态被清掉。
|
|
52
|
+
// useShallowStable 让它回到值语义:内容浅相等就复用同一引用,真变了立刻透出新引用。
|
|
53
|
+
var coreOption = useShallowStable(restOption);
|
|
48
54
|
var chartRef = useRef(null);
|
|
49
55
|
var chartInstanceRef = useRef(null);
|
|
50
56
|
// Defers `echarts.init` until the container has a box — see the hook for why
|
|
@@ -62,6 +68,30 @@ var ChartLine = function ChartLine(props) {
|
|
|
62
68
|
return resolveChartChrome(isDark);
|
|
63
69
|
}, [isDark]);
|
|
64
70
|
|
|
71
|
+
// 回调 prop 一律走 useLatestRef,不进依赖数组:消费方传内联箭头(React 里最常见的
|
|
72
|
+
// 写法)时每次渲染都是新引用,进依赖数组会让「init + setOption(notMerge)」整段重跑,
|
|
73
|
+
// 还会把当前可视窗口再同步一次给父级 —— 父级据此改 state 就是死循环。
|
|
74
|
+
// 但「有没有传回调」决定要不要注册监听,所以单独拆成布尔量进依赖数组,
|
|
75
|
+
// 这样「从无到有传入回调」仍会重新注册,不会漏。
|
|
76
|
+
var onClickRef = useLatestRef(onClick);
|
|
77
|
+
var onLegendSelectChangedRef = useLatestRef(onLegendSelectChanged);
|
|
78
|
+
var onDataZoomWindowChangedRef = useLatestRef(onDataZoomWindowChanged);
|
|
79
|
+
var hasOnClick = !!onClick;
|
|
80
|
+
var hasOnLegendSelectChanged = !!onLegendSelectChanged;
|
|
81
|
+
var hasOnDataZoomWindowChanged = !!onDataZoomWindowChanged;
|
|
82
|
+
// 已通知过父级的窗口用 ref 记账(不参与渲染):窗口没变就不再通知,
|
|
83
|
+
// 掐断「通知 → 父级重算坐标轴 → chartOption 变 → effect 重跑 → 再通知」的自激回路
|
|
84
|
+
var notifiedZoomWindowRef = useRef(null);
|
|
85
|
+
var emitZoomWindow = useCallback(function (next) {
|
|
86
|
+
var _onDataZoomWindowChan;
|
|
87
|
+
var prev = notifiedZoomWindowRef.current;
|
|
88
|
+
if (prev && prev.startIndex === next.startIndex && prev.endIndex === next.endIndex) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
notifiedZoomWindowRef.current = next;
|
|
92
|
+
(_onDataZoomWindowChan = onDataZoomWindowChangedRef.current) === null || _onDataZoomWindowChan === void 0 || _onDataZoomWindowChan.call(onDataZoomWindowChangedRef, next);
|
|
93
|
+
}, [onDataZoomWindowChangedRef]);
|
|
94
|
+
|
|
65
95
|
// Cache the chart option with useMemo
|
|
66
96
|
var chartOption = useMemo(function () {
|
|
67
97
|
var _xAxisData$length, _ref, _ref2;
|
|
@@ -236,16 +266,16 @@ var ChartLine = function ChartLine(props) {
|
|
|
236
266
|
}
|
|
237
267
|
|
|
238
268
|
// Sync the current visible window to the caller (on initial render and after restore), used to recalculate axes based on the displayed portion
|
|
239
|
-
if (
|
|
269
|
+
if (hasOnDataZoomWindowChanged) {
|
|
240
270
|
var _chart$getOption3, _xAxisData$length2;
|
|
241
271
|
var zooms = (_chart$getOption3 = chart.getOption()) === null || _chart$getOption3 === void 0 ? void 0 : _chart$getOption3.dataZoom;
|
|
242
272
|
var zoom = zooms === null || zooms === void 0 ? void 0 : zooms[0];
|
|
243
273
|
var totalLen = (_xAxisData$length2 = xAxisData === null || xAxisData === void 0 ? void 0 : xAxisData.length) !== null && _xAxisData$length2 !== void 0 ? _xAxisData$length2 : 0;
|
|
244
274
|
if (typeof (zoom === null || zoom === void 0 ? void 0 : zoom.start) === "number" && typeof (zoom === null || zoom === void 0 ? void 0 : zoom.end) === "number") {
|
|
245
|
-
|
|
275
|
+
emitZoomWindow(percentWindowToIndexWindow(zoom.start, zoom.end, totalLen));
|
|
246
276
|
} else {
|
|
247
277
|
// Without dataZoom (e.g. scrolling not enabled due to insufficient data) the window is the full range; sync once to avoid a stale old window
|
|
248
|
-
|
|
278
|
+
emitZoomWindow({
|
|
249
279
|
startIndex: 0,
|
|
250
280
|
endIndex: Math.max(0, totalLen - 1)
|
|
251
281
|
});
|
|
@@ -261,17 +291,22 @@ var ChartLine = function ChartLine(props) {
|
|
|
261
291
|
resizeObserverRef.current.observe(chartRef.current);
|
|
262
292
|
}
|
|
263
293
|
|
|
264
|
-
// Add click event
|
|
265
|
-
|
|
294
|
+
// Add click event(注册与否看布尔量,实际调用取最新引用)
|
|
295
|
+
var handleClick = function handleClick(event) {
|
|
296
|
+
var _onClickRef$current;
|
|
297
|
+
(_onClickRef$current = onClickRef.current) === null || _onClickRef$current === void 0 || _onClickRef$current.call(onClickRef, event);
|
|
298
|
+
};
|
|
299
|
+
if (hasOnClick) {
|
|
266
300
|
var _chartInstanceRef$cur2;
|
|
267
|
-
(_chartInstanceRef$cur2 = chartInstanceRef.current) === null || _chartInstanceRef$cur2 === void 0 || _chartInstanceRef$cur2.on("click",
|
|
301
|
+
(_chartInstanceRef$cur2 = chartInstanceRef.current) === null || _chartInstanceRef$cur2 === void 0 || _chartInstanceRef$cur2.on("click", handleClick);
|
|
268
302
|
}
|
|
269
303
|
|
|
270
304
|
// Legend selection event
|
|
271
305
|
var handleLegendSelectChanged = function handleLegendSelectChanged(params) {
|
|
272
|
-
|
|
306
|
+
var _onLegendSelectChange;
|
|
307
|
+
(_onLegendSelectChange = onLegendSelectChangedRef.current) === null || _onLegendSelectChange === void 0 || _onLegendSelectChange.call(onLegendSelectChangedRef, params.selected);
|
|
273
308
|
};
|
|
274
|
-
if (
|
|
309
|
+
if (hasOnLegendSelectChanged) {
|
|
275
310
|
var _chartInstanceRef$cur3;
|
|
276
311
|
(_chartInstanceRef$cur3 = chartInstanceRef.current) === null || _chartInstanceRef$cur3 === void 0 || _chartInstanceRef$cur3.on("legendselectchanged", handleLegendSelectChanged);
|
|
277
312
|
}
|
|
@@ -282,16 +317,16 @@ var ChartLine = function ChartLine(props) {
|
|
|
282
317
|
var raw = params;
|
|
283
318
|
var info = (_raw$batch$ = raw === null || raw === void 0 || (_raw$batch = raw.batch) === null || _raw$batch === void 0 ? void 0 : _raw$batch[0]) !== null && _raw$batch$ !== void 0 ? _raw$batch$ : raw;
|
|
284
319
|
if (typeof (info === null || info === void 0 ? void 0 : info.startValue) === "number" && typeof (info === null || info === void 0 ? void 0 : info.endValue) === "number") {
|
|
285
|
-
|
|
320
|
+
emitZoomWindow({
|
|
286
321
|
startIndex: Math.max(0, Math.round(info.startValue)),
|
|
287
322
|
endIndex: Math.max(0, Math.round(info.endValue))
|
|
288
323
|
});
|
|
289
324
|
} else if (typeof (info === null || info === void 0 ? void 0 : info.start) === "number" && typeof (info === null || info === void 0 ? void 0 : info.end) === "number") {
|
|
290
325
|
var _xAxisData$length3;
|
|
291
|
-
|
|
326
|
+
emitZoomWindow(percentWindowToIndexWindow(info.start, info.end, (_xAxisData$length3 = xAxisData === null || xAxisData === void 0 ? void 0 : xAxisData.length) !== null && _xAxisData$length3 !== void 0 ? _xAxisData$length3 : 0));
|
|
292
327
|
}
|
|
293
328
|
};
|
|
294
|
-
if (
|
|
329
|
+
if (hasOnDataZoomWindowChanged) {
|
|
295
330
|
var _chartInstanceRef$cur4;
|
|
296
331
|
(_chartInstanceRef$cur4 = chartInstanceRef.current) === null || _chartInstanceRef$cur4 === void 0 || _chartInstanceRef$cur4.on("datazoom", handleDataZoom);
|
|
297
332
|
}
|
|
@@ -319,15 +354,15 @@ var ChartLine = function ChartLine(props) {
|
|
|
319
354
|
// Cleanup function
|
|
320
355
|
return function () {
|
|
321
356
|
window.removeEventListener("resize", handleResize);
|
|
322
|
-
if (
|
|
357
|
+
if (hasOnClick) {
|
|
323
358
|
var _chartInstanceRef$cur5;
|
|
324
|
-
(_chartInstanceRef$cur5 = chartInstanceRef.current) === null || _chartInstanceRef$cur5 === void 0 || _chartInstanceRef$cur5.off("click",
|
|
359
|
+
(_chartInstanceRef$cur5 = chartInstanceRef.current) === null || _chartInstanceRef$cur5 === void 0 || _chartInstanceRef$cur5.off("click", handleClick);
|
|
325
360
|
}
|
|
326
|
-
if (
|
|
361
|
+
if (hasOnLegendSelectChanged) {
|
|
327
362
|
var _chartInstanceRef$cur6;
|
|
328
363
|
(_chartInstanceRef$cur6 = chartInstanceRef.current) === null || _chartInstanceRef$cur6 === void 0 || _chartInstanceRef$cur6.off("legendselectchanged", handleLegendSelectChanged);
|
|
329
364
|
}
|
|
330
|
-
if (
|
|
365
|
+
if (hasOnDataZoomWindowChanged) {
|
|
331
366
|
var _chartInstanceRef$cur7;
|
|
332
367
|
(_chartInstanceRef$cur7 = chartInstanceRef.current) === null || _chartInstanceRef$cur7 === void 0 || _chartInstanceRef$cur7.off("datazoom", handleDataZoom);
|
|
333
368
|
}
|
|
@@ -336,7 +371,7 @@ var ChartLine = function ChartLine(props) {
|
|
|
336
371
|
legendScrollRef.current = null;
|
|
337
372
|
}
|
|
338
373
|
};
|
|
339
|
-
}, [chartOption, handleResize,
|
|
374
|
+
}, [chartOption, handleResize, onClickRef, onLegendSelectChangedRef, hasOnClick, hasOnLegendSelectChanged, hasOnDataZoomWindowChanged, emitZoomWindow, xAxisData, enableLegendAutoScroll, legendVisibleCount, legendScrollInterval,
|
|
340
375
|
// 图例是否接管滚轮由它推导,漏了会拿到过期的滚动配置
|
|
341
376
|
normalizedScroll, containerReady]);
|
|
342
377
|
|
|
@@ -356,13 +391,13 @@ var ChartLine = function ChartLine(props) {
|
|
|
356
391
|
startIndex: normalizedScroll.startIndex,
|
|
357
392
|
autoPlay: normalizedScroll.autoScroll,
|
|
358
393
|
enableWheelScroll: enableWheelScroll,
|
|
359
|
-
onWindowChange:
|
|
360
|
-
return
|
|
394
|
+
onWindowChange: hasOnDataZoomWindowChanged ? function (startPercent, endPercent) {
|
|
395
|
+
return emitZoomWindow(percentWindowToIndexWindow(startPercent, endPercent, xAxisData.length));
|
|
361
396
|
} : undefined
|
|
362
397
|
}),
|
|
363
398
|
dispose = _autoScrollByItem.dispose;
|
|
364
399
|
return dispose;
|
|
365
|
-
}, [dataZoom, normalizedScroll, sliderDataZoom, xAxisData,
|
|
400
|
+
}, [dataZoom, normalizedScroll, sliderDataZoom, xAxisData, hasOnDataZoomWindowChanged, emitZoomWindow]);
|
|
366
401
|
|
|
367
402
|
// Clean up resources when the component unmounts
|
|
368
403
|
useEffect(function () {
|