@hsu-react/ui 0.0.8 → 0.0.9

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 (53) hide show
  1. package/es/components/Chart/Bar/index.d.ts +5 -1
  2. package/es/components/Chart/Bar/index.js +84 -9
  3. package/es/components/Chart/Line/index.d.ts +5 -1
  4. package/es/components/Chart/Line/index.js +84 -9
  5. package/es/components/Chart/_utils/autoSmooth.d.ts +2 -0
  6. package/es/components/Chart/_utils/autoSmooth.js +12 -2
  7. package/es/components/Chart/_utils/cartesian.d.ts +11 -0
  8. package/es/components/Chart/_utils/cartesian.js +19 -0
  9. package/es/components/Chart/chartUtils/chartTooltipFormatter.d.ts +2 -0
  10. package/es/components/Chart/chartUtils/chartTooltipFormatter.js +13 -3
  11. package/es/components/Chart/chartUtils/index.d.ts +5 -2
  12. package/es/components/Chart/chartUtils/index.js +3 -1
  13. package/es/components/Chart/chartUtils/useDataZoomWindow.d.ts +19 -0
  14. package/es/components/Chart/chartUtils/useDataZoomWindow.js +37 -0
  15. package/es/components/Chart/chartUtils/useLegendSelection.d.ts +14 -0
  16. package/es/components/Chart/chartUtils/useLegendSelection.js +35 -0
  17. package/es/components/Modal/index.module.scss +1 -0
  18. package/es/components/Panel/ListPanel/ListModalPanel/index.js +33 -5
  19. package/es/components/Panel/ListPanel/ListModalPanel/index.module.scss +17 -2
  20. package/es/components/Panel/ListPanel/index.module.scss +11 -12
  21. package/lib/components/Chart/Bar/index.d.ts +5 -1
  22. package/lib/components/Chart/Bar/index.js +68 -4
  23. package/lib/components/Chart/Line/index.d.ts +5 -1
  24. package/lib/components/Chart/Line/index.js +68 -4
  25. package/lib/components/Chart/_utils/autoSmooth.d.ts +2 -0
  26. package/lib/components/Chart/_utils/autoSmooth.js +11 -1
  27. package/lib/components/Chart/_utils/cartesian.d.ts +11 -0
  28. package/lib/components/Chart/_utils/cartesian.js +21 -1
  29. package/lib/components/Chart/chartUtils/chartTooltipFormatter.d.ts +2 -0
  30. package/lib/components/Chart/chartUtils/chartTooltipFormatter.js +5 -3
  31. package/lib/components/Chart/chartUtils/index.d.ts +5 -2
  32. package/lib/components/Chart/chartUtils/index.js +14 -0
  33. package/lib/components/Chart/chartUtils/useDataZoomWindow.d.ts +19 -0
  34. package/lib/components/Chart/chartUtils/useDataZoomWindow.js +31 -0
  35. package/lib/components/Chart/chartUtils/useLegendSelection.d.ts +14 -0
  36. package/lib/components/Chart/chartUtils/useLegendSelection.js +26 -0
  37. package/lib/components/Modal/index.module.scss +1 -0
  38. package/lib/components/Panel/ListPanel/ListModalPanel/index.js +21 -2
  39. package/lib/components/Panel/ListPanel/ListModalPanel/index.module.scss +17 -2
  40. package/lib/components/Panel/ListPanel/index.module.scss +11 -12
  41. package/package.json +1 -1
  42. package/src/components/Chart/Bar/index.tsx +132 -2
  43. package/src/components/Chart/Line/index.tsx +132 -2
  44. package/src/components/Chart/_utils/autoSmooth.ts +181 -164
  45. package/src/components/Chart/_utils/cartesian.ts +28 -0
  46. package/src/components/Chart/chartUtils/chartTooltipFormatter.ts +11 -2
  47. package/src/components/Chart/chartUtils/index.ts +53 -37
  48. package/src/components/Chart/chartUtils/useDataZoomWindow.ts +61 -0
  49. package/src/components/Chart/chartUtils/useLegendSelection.ts +35 -0
  50. package/src/components/Modal/index.module.scss +1 -0
  51. package/src/components/Panel/ListPanel/ListModalPanel/index.module.scss +17 -2
  52. package/src/components/Panel/ListPanel/ListModalPanel/index.tsx +261 -233
  53. package/src/components/Panel/ListPanel/index.module.scss +11 -12
@@ -1,7 +1,7 @@
1
1
  import * as echarts from "echarts";
2
2
  import { ChartCommonProps, SeriesDataType } from "..";
3
3
  import React from "react";
4
- import { ChartScrollConfig } from "../_utils/cartesian";
4
+ import { ChartScrollConfig, DataZoomIndexWindow } from "../_utils/cartesian";
5
5
  export interface ChartBarProps extends ChartCommonProps {
6
6
  chartTitle?: string;
7
7
  xAxisData?: Array<string>;
@@ -9,6 +9,10 @@ export interface ChartBarProps extends ChartCommonProps {
9
9
  legendData?: string[];
10
10
  scrollConfig?: ChartScrollConfig;
11
11
  onClick?: (event: echarts.ECElementEvent) => void;
12
+ /** 图例点选变化回调,参数为当前各系列选中状态(配合 legend.selected 可实现坐标轴重算) */
13
+ onLegendSelectChanged?: (selected: Record<string, boolean>) => void;
14
+ /** dataZoom 可见窗口变化回调(滑块/滚轮/自动滚动/初始同步均触发),参数为当前可见的 x 轴索引区间(配合 useDataZoomWindow 可按展示部分重算坐标轴) */
15
+ onDataZoomWindowChanged?: (window: DataZoomIndexWindow) => void;
12
16
  /** 是否启用图例自动滚动,默认 false */
13
17
  enableLegendAutoScroll?: boolean;
14
18
  /** 图例每页可见数量,默认 8 */
@@ -1,5 +1,5 @@
1
1
  function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
2
- var _excluded = ["className", "style", "chartTitle", "xAxisData", "seriesData", "legendData", "legend", "grid", "tooltip", "xAxis", "yAxis", "series", "title", "scrollConfig", "dataZoom", "insideDataZoom", "sliderDataZoom", "onClick", "enableLegendAutoScroll", "legendVisibleCount", "legendScrollInterval"];
2
+ var _excluded = ["className", "style", "chartTitle", "xAxisData", "seriesData", "legendData", "legend", "grid", "tooltip", "xAxis", "yAxis", "series", "title", "scrollConfig", "dataZoom", "insideDataZoom", "sliderDataZoom", "onClick", "onLegendSelectChanged", "onDataZoomWindowChanged", "enableLegendAutoScroll", "legendVisibleCount", "legendScrollInterval"];
3
3
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
4
4
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
5
5
  function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
@@ -12,7 +12,7 @@ import React, { useCallback, useEffect, useMemo, useRef } from "react";
12
12
  import styles from "../index.module.scss";
13
13
  import { autoScrollLegend } from "../_utils/autoScrollLegend";
14
14
  import { autoScrollByItem } from "../_utils/autoSmooth";
15
- import { buildCartesianSeriesOptions, createDefaultCategoryXAxis, createDefaultValueYAxis, getSliderShow, resolveScrollConfig } from "../_utils/cartesian";
15
+ import { buildCartesianSeriesOptions, createDefaultCategoryXAxis, createDefaultValueYAxis, getSliderShow, percentWindowToIndexWindow, resolveScrollConfig } from "../_utils/cartesian";
16
16
  import { jsx as _jsx } from "react/jsx-runtime";
17
17
  var ChartBar = function ChartBar(props) {
18
18
  var className = props.className,
@@ -33,6 +33,8 @@ var ChartBar = function ChartBar(props) {
33
33
  insideDataZoom = props.insideDataZoom,
34
34
  sliderDataZoom = props.sliderDataZoom,
35
35
  onClick = props.onClick,
36
+ onLegendSelectChanged = props.onLegendSelectChanged,
37
+ onDataZoomWindowChanged = props.onDataZoomWindowChanged,
36
38
  _props$enableLegendAu = props.enableLegendAutoScroll,
37
39
  enableLegendAutoScroll = _props$enableLegendAu === void 0 ? false : _props$enableLegendAu,
38
40
  _props$legendVisibleC = props.legendVisibleCount,
@@ -43,6 +45,7 @@ var ChartBar = function ChartBar(props) {
43
45
  var chartRef = useRef(null);
44
46
  var chartInstanceRef = useRef(null);
45
47
  var resizeObserverRef = useRef(null);
48
+ var prevXAxisKeyRef = useRef(null);
46
49
  var legendScrollRef = useRef(null);
47
50
  var normalizedScroll = useMemo(function () {
48
51
  return resolveScrollConfig(scrollConfig);
@@ -182,7 +185,7 @@ var ChartBar = function ChartBar(props) {
182
185
 
183
186
  // 初始化图表
184
187
  useEffect(function () {
185
- var _opt$legend$, _opt$legend, _ref3;
188
+ var _xAxisData$join, _chart$getOption, _opt$legend$, _opt$legend, _ref3;
186
189
  if (!chartRef.current) return;
187
190
 
188
191
  // 初始化或获取已存在的实例
@@ -192,8 +195,40 @@ var ChartBar = function ChartBar(props) {
192
195
  chartInstanceRef.current = chart;
193
196
  }
194
197
 
195
- // 设置配置
198
+ // 设置配置:notMerge 会把 dataZoom 窗口重置回初始位置,
199
+ // x 轴数据未变化时(如坐标轴重算/图例点选触发的重渲染)先记录当前窗口,设置后恢复
200
+ var xAxisKey = (_xAxisData$join = xAxisData === null || xAxisData === void 0 ? void 0 : xAxisData.join("\x01")) !== null && _xAxisData$join !== void 0 ? _xAxisData$join : "";
201
+ var prevZoomRanges = prevXAxisKeyRef.current === xAxisKey ? (_chart$getOption = chart.getOption()) === null || _chart$getOption === void 0 ? void 0 : _chart$getOption.dataZoom : undefined;
202
+ prevXAxisKeyRef.current = xAxisKey;
196
203
  chart.setOption(chartOption, true);
204
+ var nextZooms = chartOption.dataZoom;
205
+ if (prevZoomRanges !== null && prevZoomRanges !== void 0 && prevZoomRanges.length && Array.isArray(nextZooms) && nextZooms.length === prevZoomRanges.length) {
206
+ chart.setOption({
207
+ dataZoom: prevZoomRanges.map(function (z) {
208
+ return {
209
+ start: z.start,
210
+ end: z.end
211
+ };
212
+ })
213
+ });
214
+ }
215
+
216
+ // 向调用方同步当前可见窗口(初始渲染与恢复后),用于按展示部分重算坐标轴
217
+ if (onDataZoomWindowChanged) {
218
+ var _chart$getOption2, _xAxisData$length2;
219
+ var zooms = (_chart$getOption2 = chart.getOption()) === null || _chart$getOption2 === void 0 ? void 0 : _chart$getOption2.dataZoom;
220
+ var zoom = zooms === null || zooms === void 0 ? void 0 : zooms[0];
221
+ var totalLen = (_xAxisData$length2 = xAxisData === null || xAxisData === void 0 ? void 0 : xAxisData.length) !== null && _xAxisData$length2 !== void 0 ? _xAxisData$length2 : 0;
222
+ if (typeof (zoom === null || zoom === void 0 ? void 0 : zoom.start) === "number" && typeof (zoom === null || zoom === void 0 ? void 0 : zoom.end) === "number") {
223
+ onDataZoomWindowChanged(percentWindowToIndexWindow(zoom.start, zoom.end, totalLen));
224
+ } else {
225
+ // 无 dataZoom(如数据量不足未启用滚动)时窗口即全量,同步一次避免残留旧窗口
226
+ onDataZoomWindowChanged({
227
+ startIndex: 0,
228
+ endIndex: Math.max(0, totalLen - 1)
229
+ });
230
+ }
231
+ }
197
232
 
198
233
  // 添加 resize 监听
199
234
  window.addEventListener("resize", handleResize);
@@ -210,6 +245,35 @@ var ChartBar = function ChartBar(props) {
210
245
  (_chartInstanceRef$cur2 = chartInstanceRef.current) === null || _chartInstanceRef$cur2 === void 0 || _chartInstanceRef$cur2.on("click", onClick);
211
246
  }
212
247
 
248
+ // 图例点选事件
249
+ var handleLegendSelectChanged = function handleLegendSelectChanged(params) {
250
+ onLegendSelectChanged === null || onLegendSelectChanged === void 0 || onLegendSelectChanged(params.selected);
251
+ };
252
+ if (onLegendSelectChanged) {
253
+ var _chartInstanceRef$cur3;
254
+ (_chartInstanceRef$cur3 = chartInstanceRef.current) === null || _chartInstanceRef$cur3 === void 0 || _chartInstanceRef$cur3.on("legendselectchanged", handleLegendSelectChanged);
255
+ }
256
+
257
+ // dataZoom 原生交互(slider 拖动 / inside 缩放)→ 同步可见窗口
258
+ var handleDataZoom = function handleDataZoom(params) {
259
+ var _raw$batch$, _raw$batch;
260
+ var raw = params;
261
+ 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;
262
+ if (typeof (info === null || info === void 0 ? void 0 : info.startValue) === "number" && typeof (info === null || info === void 0 ? void 0 : info.endValue) === "number") {
263
+ onDataZoomWindowChanged === null || onDataZoomWindowChanged === void 0 || onDataZoomWindowChanged({
264
+ startIndex: Math.max(0, Math.round(info.startValue)),
265
+ endIndex: Math.max(0, Math.round(info.endValue))
266
+ });
267
+ } else if (typeof (info === null || info === void 0 ? void 0 : info.start) === "number" && typeof (info === null || info === void 0 ? void 0 : info.end) === "number") {
268
+ var _xAxisData$length3;
269
+ onDataZoomWindowChanged === null || onDataZoomWindowChanged === void 0 || onDataZoomWindowChanged(percentWindowToIndexWindow(info.start, info.end, (_xAxisData$length3 = xAxisData === null || xAxisData === void 0 ? void 0 : xAxisData.length) !== null && _xAxisData$length3 !== void 0 ? _xAxisData$length3 : 0));
270
+ }
271
+ };
272
+ if (onDataZoomWindowChanged) {
273
+ var _chartInstanceRef$cur4;
274
+ (_chartInstanceRef$cur4 = chartInstanceRef.current) === null || _chartInstanceRef$cur4 === void 0 || _chartInstanceRef$cur4.on("datazoom", handleDataZoom);
275
+ }
276
+
213
277
  // 图例自动滚动(参考 Pie 组件)
214
278
  var opt = chartOption;
215
279
  var legendDataLen = Array.isArray(opt.legend) ? (_opt$legend$ = opt.legend[0]) === null || _opt$legend$ === void 0 || (_opt$legend$ = _opt$legend$.data) === null || _opt$legend$ === void 0 ? void 0 : _opt$legend$.length : (_opt$legend = opt.legend) === null || _opt$legend === void 0 || (_opt$legend = _opt$legend.data) === null || _opt$legend === void 0 ? void 0 : _opt$legend.length;
@@ -232,15 +296,23 @@ var ChartBar = function ChartBar(props) {
232
296
  return function () {
233
297
  window.removeEventListener("resize", handleResize);
234
298
  if (onClick) {
235
- var _chartInstanceRef$cur3;
236
- (_chartInstanceRef$cur3 = chartInstanceRef.current) === null || _chartInstanceRef$cur3 === void 0 || _chartInstanceRef$cur3.off("click", onClick);
299
+ var _chartInstanceRef$cur5;
300
+ (_chartInstanceRef$cur5 = chartInstanceRef.current) === null || _chartInstanceRef$cur5 === void 0 || _chartInstanceRef$cur5.off("click", onClick);
301
+ }
302
+ if (onLegendSelectChanged) {
303
+ var _chartInstanceRef$cur6;
304
+ (_chartInstanceRef$cur6 = chartInstanceRef.current) === null || _chartInstanceRef$cur6 === void 0 || _chartInstanceRef$cur6.off("legendselectchanged", handleLegendSelectChanged);
305
+ }
306
+ if (onDataZoomWindowChanged) {
307
+ var _chartInstanceRef$cur7;
308
+ (_chartInstanceRef$cur7 = chartInstanceRef.current) === null || _chartInstanceRef$cur7 === void 0 || _chartInstanceRef$cur7.off("datazoom", handleDataZoom);
237
309
  }
238
310
  if (legendScrollRef.current) {
239
311
  legendScrollRef.current.dispose();
240
312
  legendScrollRef.current = null;
241
313
  }
242
314
  };
243
- }, [chartOption, handleResize, onClick, enableLegendAutoScroll, legendVisibleCount, legendScrollInterval]);
315
+ }, [chartOption, handleResize, onClick, onLegendSelectChanged, onDataZoomWindowChanged, xAxisData, enableLegendAutoScroll, legendVisibleCount, legendScrollInterval]);
244
316
 
245
317
  // 处理自动播放
246
318
  useEffect(function () {
@@ -257,11 +329,14 @@ var ChartBar = function ChartBar(props) {
257
329
  interval: normalizedScroll.interval,
258
330
  startIndex: normalizedScroll.startIndex,
259
331
  autoPlay: normalizedScroll.autoScroll,
260
- enableWheelScroll: enableWheelScroll
332
+ enableWheelScroll: enableWheelScroll,
333
+ onWindowChange: onDataZoomWindowChanged ? function (startPercent, endPercent) {
334
+ return onDataZoomWindowChanged(percentWindowToIndexWindow(startPercent, endPercent, xAxisData.length));
335
+ } : undefined
261
336
  }),
262
337
  dispose = _autoScrollByItem.dispose;
263
338
  return dispose;
264
- }, [dataZoom, normalizedScroll, sliderDataZoom, xAxisData]);
339
+ }, [dataZoom, normalizedScroll, sliderDataZoom, xAxisData, onDataZoomWindowChanged]);
265
340
 
266
341
  // 组件卸载时清理资源
267
342
  useEffect(function () {
@@ -1,7 +1,7 @@
1
1
  import * as echarts from "echarts";
2
2
  import { ChartCommonProps, SeriesDataType } from "..";
3
3
  import React from "react";
4
- import { ChartScrollConfig } from "../_utils/cartesian";
4
+ import { ChartScrollConfig, DataZoomIndexWindow } from "../_utils/cartesian";
5
5
  export interface ChartLineProps extends ChartCommonProps {
6
6
  chartTitle?: string;
7
7
  xAxisData?: Array<string>;
@@ -10,6 +10,10 @@ export interface ChartLineProps extends ChartCommonProps {
10
10
  scrollConfig?: ChartScrollConfig;
11
11
  yAxisNameOffsets?: number[];
12
12
  onClick?: (event: echarts.ECElementEvent) => void;
13
+ /** 图例点选变化回调,参数为当前各系列选中状态(配合 legend.selected 可实现坐标轴重算) */
14
+ onLegendSelectChanged?: (selected: Record<string, boolean>) => void;
15
+ /** dataZoom 可见窗口变化回调(滑块/滚轮/自动滚动/初始同步均触发),参数为当前可见的 x 轴索引区间(配合 useDataZoomWindow 可按展示部分重算坐标轴) */
16
+ onDataZoomWindowChanged?: (window: DataZoomIndexWindow) => void;
13
17
  /** 是否启用图例自动滚动,默认 false */
14
18
  enableLegendAutoScroll?: boolean;
15
19
  /** 图例每页可见数量,默认 8 */
@@ -1,5 +1,5 @@
1
1
  function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
2
- var _excluded = ["className", "style", "chartTitle", "xAxisData", "seriesData", "legendData", "grid", "tooltip", "xAxis", "yAxis", "series", "title", "legend", "scrollConfig", "dataZoom", "insideDataZoom", "sliderDataZoom", "onClick", "enableLegendAutoScroll", "legendVisibleCount", "legendScrollInterval"];
2
+ var _excluded = ["className", "style", "chartTitle", "xAxisData", "seriesData", "legendData", "grid", "tooltip", "xAxis", "yAxis", "series", "title", "legend", "scrollConfig", "dataZoom", "insideDataZoom", "sliderDataZoom", "onClick", "onLegendSelectChanged", "onDataZoomWindowChanged", "enableLegendAutoScroll", "legendVisibleCount", "legendScrollInterval"];
3
3
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
4
4
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
5
5
  function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
@@ -12,7 +12,7 @@ import React, { useCallback, useEffect, useMemo, useRef } from "react";
12
12
  import styles from "../index.module.scss";
13
13
  import { autoScrollLegend } from "../_utils/autoScrollLegend";
14
14
  import { autoScrollByItem } from "../_utils/autoSmooth";
15
- import { buildCartesianSeriesOptions, createDefaultCategoryXAxis, createDefaultValueYAxis, getSliderShow, resolveScrollConfig } from "../_utils/cartesian";
15
+ import { buildCartesianSeriesOptions, createDefaultCategoryXAxis, createDefaultValueYAxis, getSliderShow, percentWindowToIndexWindow, resolveScrollConfig } from "../_utils/cartesian";
16
16
  import { jsx as _jsx } from "react/jsx-runtime";
17
17
  var ChartLine = function ChartLine(props) {
18
18
  var className = props.className,
@@ -33,6 +33,8 @@ var ChartLine = function ChartLine(props) {
33
33
  insideDataZoom = props.insideDataZoom,
34
34
  sliderDataZoom = props.sliderDataZoom,
35
35
  onClick = props.onClick,
36
+ onLegendSelectChanged = props.onLegendSelectChanged,
37
+ onDataZoomWindowChanged = props.onDataZoomWindowChanged,
36
38
  _props$enableLegendAu = props.enableLegendAutoScroll,
37
39
  enableLegendAutoScroll = _props$enableLegendAu === void 0 ? false : _props$enableLegendAu,
38
40
  _props$legendVisibleC = props.legendVisibleCount,
@@ -43,6 +45,7 @@ var ChartLine = function ChartLine(props) {
43
45
  var chartRef = useRef(null);
44
46
  var chartInstanceRef = useRef(null);
45
47
  var resizeObserverRef = useRef(null);
48
+ var prevXAxisKeyRef = useRef(null);
46
49
  var legendScrollRef = useRef(null);
47
50
  var normalizedScroll = useMemo(function () {
48
51
  return resolveScrollConfig(scrollConfig);
@@ -178,7 +181,7 @@ var ChartLine = function ChartLine(props) {
178
181
 
179
182
  // 初始化图表
180
183
  useEffect(function () {
181
- var _opt$legend$, _opt$legend, _ref3;
184
+ var _xAxisData$join, _chart$getOption, _opt$legend$, _opt$legend, _ref3;
182
185
  if (!chartRef.current) return;
183
186
 
184
187
  // 初始化或获取已存在的实例
@@ -188,8 +191,40 @@ var ChartLine = function ChartLine(props) {
188
191
  chartInstanceRef.current = chart;
189
192
  }
190
193
 
191
- // 设置配置
194
+ // 设置配置:notMerge 会把 dataZoom 窗口重置回初始位置,
195
+ // x 轴数据未变化时(如坐标轴重算/图例点选触发的重渲染)先记录当前窗口,设置后恢复
196
+ var xAxisKey = (_xAxisData$join = xAxisData === null || xAxisData === void 0 ? void 0 : xAxisData.join("\x01")) !== null && _xAxisData$join !== void 0 ? _xAxisData$join : "";
197
+ var prevZoomRanges = prevXAxisKeyRef.current === xAxisKey ? (_chart$getOption = chart.getOption()) === null || _chart$getOption === void 0 ? void 0 : _chart$getOption.dataZoom : undefined;
198
+ prevXAxisKeyRef.current = xAxisKey;
192
199
  chart.setOption(chartOption, true);
200
+ var nextZooms = chartOption.dataZoom;
201
+ if (prevZoomRanges !== null && prevZoomRanges !== void 0 && prevZoomRanges.length && Array.isArray(nextZooms) && nextZooms.length === prevZoomRanges.length) {
202
+ chart.setOption({
203
+ dataZoom: prevZoomRanges.map(function (z) {
204
+ return {
205
+ start: z.start,
206
+ end: z.end
207
+ };
208
+ })
209
+ });
210
+ }
211
+
212
+ // 向调用方同步当前可见窗口(初始渲染与恢复后),用于按展示部分重算坐标轴
213
+ if (onDataZoomWindowChanged) {
214
+ var _chart$getOption2, _xAxisData$length2;
215
+ var zooms = (_chart$getOption2 = chart.getOption()) === null || _chart$getOption2 === void 0 ? void 0 : _chart$getOption2.dataZoom;
216
+ var zoom = zooms === null || zooms === void 0 ? void 0 : zooms[0];
217
+ var totalLen = (_xAxisData$length2 = xAxisData === null || xAxisData === void 0 ? void 0 : xAxisData.length) !== null && _xAxisData$length2 !== void 0 ? _xAxisData$length2 : 0;
218
+ if (typeof (zoom === null || zoom === void 0 ? void 0 : zoom.start) === "number" && typeof (zoom === null || zoom === void 0 ? void 0 : zoom.end) === "number") {
219
+ onDataZoomWindowChanged(percentWindowToIndexWindow(zoom.start, zoom.end, totalLen));
220
+ } else {
221
+ // 无 dataZoom(如数据量不足未启用滚动)时窗口即全量,同步一次避免残留旧窗口
222
+ onDataZoomWindowChanged({
223
+ startIndex: 0,
224
+ endIndex: Math.max(0, totalLen - 1)
225
+ });
226
+ }
227
+ }
193
228
 
194
229
  // 添加 resize 监听
195
230
  window.addEventListener("resize", handleResize);
@@ -206,6 +241,35 @@ var ChartLine = function ChartLine(props) {
206
241
  (_chartInstanceRef$cur2 = chartInstanceRef.current) === null || _chartInstanceRef$cur2 === void 0 || _chartInstanceRef$cur2.on("click", onClick);
207
242
  }
208
243
 
244
+ // 图例点选事件
245
+ var handleLegendSelectChanged = function handleLegendSelectChanged(params) {
246
+ onLegendSelectChanged === null || onLegendSelectChanged === void 0 || onLegendSelectChanged(params.selected);
247
+ };
248
+ if (onLegendSelectChanged) {
249
+ var _chartInstanceRef$cur3;
250
+ (_chartInstanceRef$cur3 = chartInstanceRef.current) === null || _chartInstanceRef$cur3 === void 0 || _chartInstanceRef$cur3.on("legendselectchanged", handleLegendSelectChanged);
251
+ }
252
+
253
+ // dataZoom 原生交互(slider 拖动 / inside 缩放)→ 同步可见窗口
254
+ var handleDataZoom = function handleDataZoom(params) {
255
+ var _raw$batch$, _raw$batch;
256
+ var raw = params;
257
+ 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;
258
+ if (typeof (info === null || info === void 0 ? void 0 : info.startValue) === "number" && typeof (info === null || info === void 0 ? void 0 : info.endValue) === "number") {
259
+ onDataZoomWindowChanged === null || onDataZoomWindowChanged === void 0 || onDataZoomWindowChanged({
260
+ startIndex: Math.max(0, Math.round(info.startValue)),
261
+ endIndex: Math.max(0, Math.round(info.endValue))
262
+ });
263
+ } else if (typeof (info === null || info === void 0 ? void 0 : info.start) === "number" && typeof (info === null || info === void 0 ? void 0 : info.end) === "number") {
264
+ var _xAxisData$length3;
265
+ onDataZoomWindowChanged === null || onDataZoomWindowChanged === void 0 || onDataZoomWindowChanged(percentWindowToIndexWindow(info.start, info.end, (_xAxisData$length3 = xAxisData === null || xAxisData === void 0 ? void 0 : xAxisData.length) !== null && _xAxisData$length3 !== void 0 ? _xAxisData$length3 : 0));
266
+ }
267
+ };
268
+ if (onDataZoomWindowChanged) {
269
+ var _chartInstanceRef$cur4;
270
+ (_chartInstanceRef$cur4 = chartInstanceRef.current) === null || _chartInstanceRef$cur4 === void 0 || _chartInstanceRef$cur4.on("datazoom", handleDataZoom);
271
+ }
272
+
209
273
  // 图例自动滚动(与 Pie/Bar 一致)
210
274
  var opt = chartOption;
211
275
  var legendDataLen = Array.isArray(opt.legend) ? (_opt$legend$ = opt.legend[0]) === null || _opt$legend$ === void 0 || (_opt$legend$ = _opt$legend$.data) === null || _opt$legend$ === void 0 ? void 0 : _opt$legend$.length : (_opt$legend = opt.legend) === null || _opt$legend === void 0 || (_opt$legend = _opt$legend.data) === null || _opt$legend === void 0 ? void 0 : _opt$legend.length;
@@ -228,15 +292,23 @@ var ChartLine = function ChartLine(props) {
228
292
  return function () {
229
293
  window.removeEventListener("resize", handleResize);
230
294
  if (onClick) {
231
- var _chartInstanceRef$cur3;
232
- (_chartInstanceRef$cur3 = chartInstanceRef.current) === null || _chartInstanceRef$cur3 === void 0 || _chartInstanceRef$cur3.off("click", onClick);
295
+ var _chartInstanceRef$cur5;
296
+ (_chartInstanceRef$cur5 = chartInstanceRef.current) === null || _chartInstanceRef$cur5 === void 0 || _chartInstanceRef$cur5.off("click", onClick);
297
+ }
298
+ if (onLegendSelectChanged) {
299
+ var _chartInstanceRef$cur6;
300
+ (_chartInstanceRef$cur6 = chartInstanceRef.current) === null || _chartInstanceRef$cur6 === void 0 || _chartInstanceRef$cur6.off("legendselectchanged", handleLegendSelectChanged);
301
+ }
302
+ if (onDataZoomWindowChanged) {
303
+ var _chartInstanceRef$cur7;
304
+ (_chartInstanceRef$cur7 = chartInstanceRef.current) === null || _chartInstanceRef$cur7 === void 0 || _chartInstanceRef$cur7.off("datazoom", handleDataZoom);
233
305
  }
234
306
  if (legendScrollRef.current) {
235
307
  legendScrollRef.current.dispose();
236
308
  legendScrollRef.current = null;
237
309
  }
238
310
  };
239
- }, [chartOption, handleResize, onClick, enableLegendAutoScroll, legendVisibleCount, legendScrollInterval]);
311
+ }, [chartOption, handleResize, onClick, onLegendSelectChanged, onDataZoomWindowChanged, xAxisData, enableLegendAutoScroll, legendVisibleCount, legendScrollInterval]);
240
312
 
241
313
  // 处理自动播放
242
314
  useEffect(function () {
@@ -253,11 +325,14 @@ var ChartLine = function ChartLine(props) {
253
325
  interval: normalizedScroll.interval,
254
326
  startIndex: normalizedScroll.startIndex,
255
327
  autoPlay: normalizedScroll.autoScroll,
256
- enableWheelScroll: enableWheelScroll
328
+ enableWheelScroll: enableWheelScroll,
329
+ onWindowChange: onDataZoomWindowChanged ? function (startPercent, endPercent) {
330
+ return onDataZoomWindowChanged(percentWindowToIndexWindow(startPercent, endPercent, xAxisData.length));
331
+ } : undefined
257
332
  }),
258
333
  dispose = _autoScrollByItem.dispose;
259
334
  return dispose;
260
- }, [dataZoom, normalizedScroll, sliderDataZoom, xAxisData]);
335
+ }, [dataZoom, normalizedScroll, sliderDataZoom, xAxisData, onDataZoomWindowChanged]);
261
336
 
262
337
  // 组件卸载时清理资源
263
338
  useEffect(function () {
@@ -7,6 +7,8 @@ export interface AutoScrollByItemProps {
7
7
  startIndex?: number;
8
8
  autoPlay?: boolean;
9
9
  enableWheelScroll?: boolean;
10
+ /** 窗口变化回调(创建同步、自动滚动、滚轮、resize 均触发),参数为当前窗口 start/end 百分比 */
11
+ onWindowChange?: (startPercent: number, endPercent: number) => void;
10
12
  }
11
13
  export declare function autoScrollByItem(props: AutoScrollByItemProps): {
12
14
  pause: () => void;
@@ -5,7 +5,7 @@ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key i
5
5
  function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
6
6
  function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
7
7
  export function autoScrollByItem(props) {
8
- var _xAxisData$length;
8
+ var _xAxisData$length, _chart$getOption;
9
9
  var chart = props.chart,
10
10
  xAxisData = props.xAxisData,
11
11
  _props$windowSize = props.windowSize,
@@ -17,7 +17,8 @@ export function autoScrollByItem(props) {
17
17
  _props$autoPlay = props.autoPlay,
18
18
  autoPlay = _props$autoPlay === void 0 ? true : _props$autoPlay,
19
19
  _props$enableWheelScr = props.enableWheelScroll,
20
- enableWheelScroll = _props$enableWheelScr === void 0 ? true : _props$enableWheelScr;
20
+ enableWheelScroll = _props$enableWheelScr === void 0 ? true : _props$enableWheelScr,
21
+ onWindowChange = props.onWindowChange;
21
22
  var total = (_xAxisData$length = xAxisData === null || xAxisData === void 0 ? void 0 : xAxisData.length) !== null && _xAxisData$length !== void 0 ? _xAxisData$length : 0;
22
23
  if (total <= 0) {
23
24
  return {
@@ -32,6 +33,14 @@ export function autoScrollByItem(props) {
32
33
  var initialStartPercent = total > 0 ? initialStartIndex / total * 100 : 0;
33
34
  var start = initialStartPercent;
34
35
  var end = Math.min(initialStartPercent + windowSizePercent, 100);
36
+
37
+ // 图表已有 dataZoom 窗口时(组件重渲染重建滚动器)从当前位置继续,
38
+ // 避免图例点选、坐标轴重算等触发的重渲染把已滚动位置重置回初始窗口
39
+ var currentZoom = (_chart$getOption = chart.getOption()) === null || _chart$getOption === void 0 || (_chart$getOption = _chart$getOption.dataZoom) === null || _chart$getOption === void 0 ? void 0 : _chart$getOption[0];
40
+ if (typeof (currentZoom === null || currentZoom === void 0 ? void 0 : currentZoom.start) === "number" && typeof (currentZoom === null || currentZoom === void 0 ? void 0 : currentZoom.end) === "number") {
41
+ start = currentZoom.start;
42
+ end = currentZoom.end;
43
+ }
35
44
  var syncDataZoomRange = function syncDataZoomRange() {
36
45
  var option = chart.getOption();
37
46
  var currentDataZoom = option === null || option === void 0 ? void 0 : option.dataZoom;
@@ -44,6 +53,7 @@ export function autoScrollByItem(props) {
44
53
  });
45
54
  })
46
55
  });
56
+ onWindowChange === null || onWindowChange === void 0 || onWindowChange(start, end);
47
57
  };
48
58
  syncDataZoomRange();
49
59
  var timer = null;
@@ -18,6 +18,17 @@ export interface NormalizedScrollConfig {
18
18
  sliderVisible?: boolean;
19
19
  wheelModeWhenSliderHidden: "scroll" | "none";
20
20
  }
21
+ /** dataZoom 当前可见窗口对应的 x 轴索引区间(闭区间) */
22
+ export interface DataZoomIndexWindow {
23
+ startIndex: number;
24
+ endIndex: number;
25
+ }
26
+ /**
27
+ * 把 dataZoom 的 start/end 百分比换算为 x 轴索引窗口。
28
+ * 与本组件族写入 dataZoom 的百分比约定一致(index / total * 100),
29
+ * 对 echarts 原生交互产生的百分比做外扩取整,边界最多多含一项,不影响坐标轴量级。
30
+ */
31
+ export declare const percentWindowToIndexWindow: (startPercent: number, endPercent: number, total: number) => DataZoomIndexWindow;
21
32
  export declare const createDefaultCategoryXAxis: (xAxisData?: Array<string>) => ChartOptionType;
22
33
  export declare const createDefaultValueYAxis: (mode?: "bar" | "line") => ChartOptionType;
23
34
  export declare const buildCartesianSeriesOptions: (mode: "bar" | "line", seriesData?: SeriesDataType, series?: echarts.SeriesOption | echarts.SeriesOption[]) => echarts.SeriesOption[];
@@ -4,6 +4,25 @@ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key i
4
4
  function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
5
5
  function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
6
6
  function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
7
+ /** dataZoom 当前可见窗口对应的 x 轴索引区间(闭区间) */
8
+
9
+ /**
10
+ * 把 dataZoom 的 start/end 百分比换算为 x 轴索引窗口。
11
+ * 与本组件族写入 dataZoom 的百分比约定一致(index / total * 100),
12
+ * 对 echarts 原生交互产生的百分比做外扩取整,边界最多多含一项,不影响坐标轴量级。
13
+ */
14
+ export var percentWindowToIndexWindow = function percentWindowToIndexWindow(startPercent, endPercent, total) {
15
+ if (total <= 0) return {
16
+ startIndex: 0,
17
+ endIndex: 0
18
+ };
19
+ var startIndex = Math.max(0, Math.min(total - 1, Math.floor(startPercent / 100 * total)));
20
+ var endIndex = Math.max(startIndex, Math.min(total - 1, Math.ceil(endPercent / 100 * total) - 1));
21
+ return {
22
+ startIndex: startIndex,
23
+ endIndex: endIndex
24
+ };
25
+ };
7
26
  export var createDefaultCategoryXAxis = function createDefaultCategoryXAxis(xAxisData) {
8
27
  return {
9
28
  type: "category",
@@ -18,6 +18,8 @@ export interface ChartTooltipFormatterProps {
18
18
  hideMarker?: boolean;
19
19
  textStyle?: Record<string, unknown>;
20
20
  unit?: string;
21
+ /** 多系列时按数值从大到小排序展示(大的在上) */
22
+ sortDescending?: boolean;
21
23
  }
22
24
  declare const chartTooltipFormatter: (props: ChartTooltipFormatterProps) => string;
23
25
  export default chartTooltipFormatter;
@@ -1,3 +1,9 @@
1
+ function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
2
+ function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread 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 _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
5
+ function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
6
+ 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; }
1
7
  var chartTooltipFormatter = function chartTooltipFormatter(props) {
2
8
  var _params$;
3
9
  var params = props.params,
@@ -9,7 +15,8 @@ var chartTooltipFormatter = function chartTooltipFormatter(props) {
9
15
  color: "#666",
10
16
  fontWeight: 400
11
17
  } : _props$textStyle,
12
- unit = props.unit;
18
+ unit = props.unit,
19
+ sortDescending = props.sortDescending;
13
20
  if (!Array.isArray(params)) {
14
21
  return "\n <div style=\"margin: 0;line-height:1;\">\n <div style=\"margin: 0;line-height:1;\">\n ".concat(hideMarker ? "" : "".concat(params === null || params === void 0 ? void 0 : params.marker), "\n <span style=\"font-size:").concat(textStyle === null || textStyle === void 0 ? void 0 : textStyle.fontSize, "px;color:").concat(textStyle === null || textStyle === void 0 ? void 0 : textStyle.color, ";font-weight:").concat(textStyle === null || textStyle === void 0 ? void 0 : textStyle.fontWeight, ";margin-left:2px\">").concat(params === null || params === void 0 ? void 0 : params.name, "</span>\n <span style=\"float:right;margin-left:20px;font-size:").concat(textStyle === null || textStyle === void 0 ? void 0 : textStyle.fontSize, "px;color:").concat(textStyle === null || textStyle === void 0 ? void 0 : textStyle.color, ";font-weight:").concat(textStyle === null || textStyle === void 0 ? void 0 : textStyle.fontWeight, "\">").concat(params === null || params === void 0 ? void 0 : params.value).concat(unit ? " " + unit : "", "</span>\n <div style=\"clear:both\"></div>\n </div>\n <div style=\"clear:both\"></div>\n </div>\n ");
15
22
  }
@@ -17,10 +24,13 @@ var chartTooltipFormatter = function chartTooltipFormatter(props) {
17
24
  var item = params[0];
18
25
  return "\n <div style=\"margin: 0;line-height:1;\">\n <div style=\"margin: 0;line-height:1;\">\n ".concat(hideMarker ? "" : "".concat(item === null || item === void 0 ? void 0 : item.marker), "\n <span style=\"font-size:").concat(textStyle === null || textStyle === void 0 ? void 0 : textStyle.fontSize, "px;color:").concat(textStyle === null || textStyle === void 0 ? void 0 : textStyle.color, ";font-weight:").concat(textStyle === null || textStyle === void 0 ? void 0 : textStyle.fontWeight, ";margin-left:2px\">").concat(item === null || item === void 0 ? void 0 : item.name, "</span>\n <span style=\"float:right;margin-left:20px;font-size:").concat(textStyle === null || textStyle === void 0 ? void 0 : textStyle.fontSize, "px;color:").concat(textStyle === null || textStyle === void 0 ? void 0 : textStyle.color, ";font-weight:").concat(textStyle === null || textStyle === void 0 ? void 0 : textStyle.fontWeight, "\">").concat(item === null || item === void 0 ? void 0 : item.value).concat(unit ? " ".concat(unit) : "", "</span>\n <div style=\"clear:both\"></div>\n </div>\n <div style=\"clear:both\"></div>\n </div>\n ");
19
26
  }
20
- var items = params === null || params === void 0 ? void 0 : params.map(function (item, idx) {
27
+ var sortedParams = sortDescending ? _toConsumableArray(params).sort(function (a, b) {
28
+ return (Number(b.value) || 0) - (Number(a.value) || 0);
29
+ }) : params;
30
+ var items = sortedParams === null || sortedParams === void 0 ? void 0 : sortedParams.map(function (item, idx) {
21
31
  var _item$value;
22
32
  var value = (_item$value = item.value) !== null && _item$value !== void 0 ? _item$value : "";
23
- return "\n <div style=\"margin: 0 0 ".concat(idx === params.length - 1 ? "0" : "10px", " 0;line-height:1;\">\n <div style=\"margin: 0px 0 0;line-height:1;\">\n ").concat(hideMarker ? "" : "".concat(item === null || item === void 0 ? void 0 : item.marker), "\n <span style=\"font-size:").concat(textStyle === null || textStyle === void 0 ? void 0 : textStyle.fontSize, "px;color:").concat(textStyle === null || textStyle === void 0 ? void 0 : textStyle.color, ";font-weight:").concat(textStyle === null || textStyle === void 0 ? void 0 : textStyle.fontWeight, ";margin-left:2px\">").concat(item === null || item === void 0 ? void 0 : item.seriesName, "</span>\n <span style=\"float:right;margin-left:20px;font-size:").concat(textStyle === null || textStyle === void 0 ? void 0 : textStyle.fontSize, "px;color:").concat(textStyle === null || textStyle === void 0 ? void 0 : textStyle.color, ";font-weight:").concat(textStyle === null || textStyle === void 0 ? void 0 : textStyle.fontWeight, "\">").concat(value).concat(unit ? " ".concat(unit) : "", "</span>\n <div style=\"clear:both\"></div>\n </div>\n <div style=\"clear:both\"></div>\n </div>\n ");
33
+ return "\n <div style=\"margin: 0 0 ".concat(idx === sortedParams.length - 1 ? "0" : "10px", " 0;line-height:1;\">\n <div style=\"margin: 0px 0 0;line-height:1;\">\n ").concat(hideMarker ? "" : "".concat(item === null || item === void 0 ? void 0 : item.marker), "\n <span style=\"font-size:").concat(textStyle === null || textStyle === void 0 ? void 0 : textStyle.fontSize, "px;color:").concat(textStyle === null || textStyle === void 0 ? void 0 : textStyle.color, ";font-weight:").concat(textStyle === null || textStyle === void 0 ? void 0 : textStyle.fontWeight, ";margin-left:2px\">").concat(item === null || item === void 0 ? void 0 : item.seriesName, "</span>\n <span style=\"float:right;margin-left:20px;font-size:").concat(textStyle === null || textStyle === void 0 ? void 0 : textStyle.fontSize, "px;color:").concat(textStyle === null || textStyle === void 0 ? void 0 : textStyle.color, ";font-weight:").concat(textStyle === null || textStyle === void 0 ? void 0 : textStyle.fontWeight, "\">").concat(value).concat(unit ? " ".concat(unit) : "", "</span>\n <div style=\"clear:both\"></div>\n </div>\n <div style=\"clear:both\"></div>\n </div>\n ");
24
34
  }).join("");
25
35
  return "\n <div style=\"margin: 0px 0 0;line-height:1;\">\n <div style=\"margin: 0px 0 0;line-height:1;\">\n ".concat(hideName ? "" : "<div style=\"margin-bottom: 10px;font-size:".concat(textStyle === null || textStyle === void 0 ? void 0 : textStyle.fontSize, "px;color:").concat(textStyle === null || textStyle === void 0 ? void 0 : textStyle.color, ";font-weight:").concat(textStyle === null || textStyle === void 0 ? void 0 : textStyle.fontWeight, ";line-height:1;\">").concat(((_params$ = params[0]) === null || _params$ === void 0 ? void 0 : _params$.name) || "", "</div>"), "\n ").concat(items, "\n <div style=\"clear:both\"></div>\n </div>\n <div style=\"clear:both\"></div>\n </div>\n ");
26
36
  };
@@ -2,6 +2,9 @@ import chartTooltipFormatter from "./chartTooltipFormatter";
2
2
  import { TooltipParams, ChartTooltipFormatterProps } from "./chartTooltipFormatter";
3
3
  import { autoScrollLegend, AutoScrollLegendProps } from "../_utils/autoScrollLegend";
4
4
  import { calculateAxisConfig } from "./calculateAxisConfig";
5
+ import { useLegendSelection, LegendSelectionResult } from "./useLegendSelection";
6
+ import { useDataZoomWindow, DataZoomWindowOptions, DataZoomWindowResult } from "./useDataZoomWindow";
7
+ import { DataZoomIndexWindow } from "../_utils/cartesian";
5
8
  import { MB_PER_GB, MB_PER_TB, trimAxisNumber, chineseMagnitudeDivisor, formatChineseMagnitudeTick, mbDisplayTier, formatMbAxisTick } from "./yAxisDisplayUnit";
6
- export { chartTooltipFormatter, autoScrollLegend, calculateAxisConfig, MB_PER_GB, MB_PER_TB, trimAxisNumber, chineseMagnitudeDivisor, formatChineseMagnitudeTick, mbDisplayTier, formatMbAxisTick, };
7
- export type { TooltipParams, ChartTooltipFormatterProps, AutoScrollLegendProps, };
9
+ export { chartTooltipFormatter, autoScrollLegend, calculateAxisConfig, useLegendSelection, useDataZoomWindow, MB_PER_GB, MB_PER_TB, trimAxisNumber, chineseMagnitudeDivisor, formatChineseMagnitudeTick, mbDisplayTier, formatMbAxisTick, };
10
+ export type { TooltipParams, ChartTooltipFormatterProps, AutoScrollLegendProps, LegendSelectionResult, DataZoomWindowOptions, DataZoomWindowResult, DataZoomIndexWindow, };
@@ -1,5 +1,7 @@
1
1
  import chartTooltipFormatter from "./chartTooltipFormatter";
2
2
  import { autoScrollLegend } from "../_utils/autoScrollLegend";
3
3
  import { calculateAxisConfig } from "./calculateAxisConfig";
4
+ import { useLegendSelection } from "./useLegendSelection";
5
+ import { useDataZoomWindow } from "./useDataZoomWindow";
4
6
  import { MB_PER_GB, MB_PER_TB, trimAxisNumber, chineseMagnitudeDivisor, formatChineseMagnitudeTick, mbDisplayTier, formatMbAxisTick } from "./yAxisDisplayUnit";
5
- export { chartTooltipFormatter, autoScrollLegend, calculateAxisConfig, MB_PER_GB, MB_PER_TB, trimAxisNumber, chineseMagnitudeDivisor, formatChineseMagnitudeTick, mbDisplayTier, formatMbAxisTick };
7
+ export { chartTooltipFormatter, autoScrollLegend, calculateAxisConfig, useLegendSelection, useDataZoomWindow, MB_PER_GB, MB_PER_TB, trimAxisNumber, chineseMagnitudeDivisor, formatChineseMagnitudeTick, mbDisplayTier, formatMbAxisTick };
@@ -0,0 +1,19 @@
1
+ import { DataZoomIndexWindow } from "../_utils/cartesian";
2
+ export interface DataZoomWindowOptions {
3
+ /** 开关:是否按 dataZoom 当前可见窗口重算坐标轴,默认开启 */
4
+ enabled?: boolean;
5
+ }
6
+ export interface DataZoomWindowResult {
7
+ /** 当前可见窗口;开关关闭或尚未收到回调时为 null(表示全量) */
8
+ zoomWindow: DataZoomIndexWindow | null;
9
+ /** 传给 Chart.Bar / Chart.Line 的 onDataZoomWindowChanged;开关关闭时为 undefined(不绑定事件) */
10
+ onDataZoomWindowChanged?: (window: DataZoomIndexWindow) => void;
11
+ /** 按当前可见窗口裁剪系列数据,配合 calculateAxisConfig 只对展示部分重算坐标轴 */
12
+ sliceByZoomWindow: <T>(values?: T[] | null) => T[];
13
+ }
14
+ /**
15
+ * dataZoom 可见窗口管理:配合 Chart.Bar / Chart.Line 的 onDataZoomWindowChanged,
16
+ * 在调用方按"当前可见窗口"裁剪数据后重算 Y 轴 min/max/interval(calculateAxisConfig),
17
+ * 实现滑块拖动/滚轮/自动滚动时坐标轴跟随展示部分动态重算;可与 useLegendSelection 叠加。
18
+ */
19
+ export declare function useDataZoomWindow(options?: DataZoomWindowOptions): DataZoomWindowResult;
@@ -0,0 +1,37 @@
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 { useCallback, useState } from "react";
8
+ /**
9
+ * dataZoom 可见窗口管理:配合 Chart.Bar / Chart.Line 的 onDataZoomWindowChanged,
10
+ * 在调用方按"当前可见窗口"裁剪数据后重算 Y 轴 min/max/interval(calculateAxisConfig),
11
+ * 实现滑块拖动/滚轮/自动滚动时坐标轴跟随展示部分动态重算;可与 useLegendSelection 叠加。
12
+ */
13
+ export function useDataZoomWindow(options) {
14
+ var _options$enabled;
15
+ var enabled = (_options$enabled = options === null || options === void 0 ? void 0 : options.enabled) !== null && _options$enabled !== void 0 ? _options$enabled : true;
16
+ var _useState = useState(null),
17
+ _useState2 = _slicedToArray(_useState, 2),
18
+ zoomWindow = _useState2[0],
19
+ setZoomWindow = _useState2[1];
20
+ var onDataZoomWindowChanged = useCallback(function (next) {
21
+ // 窗口未变化时保持原引用,避免重渲染 → 同步回调 → 再重渲染的循环
22
+ setZoomWindow(function (prev) {
23
+ return prev && prev.startIndex === next.startIndex && prev.endIndex === next.endIndex ? prev : next;
24
+ });
25
+ }, []);
26
+ var effectiveWindow = enabled ? zoomWindow : null;
27
+ var sliceByZoomWindow = useCallback(function (values) {
28
+ if (!values) return [];
29
+ if (!effectiveWindow) return values;
30
+ return values.slice(effectiveWindow.startIndex, effectiveWindow.endIndex + 1);
31
+ }, [effectiveWindow]);
32
+ return {
33
+ zoomWindow: effectiveWindow,
34
+ onDataZoomWindowChanged: enabled ? onDataZoomWindowChanged : undefined,
35
+ sliceByZoomWindow: sliceByZoomWindow
36
+ };
37
+ }
@@ -0,0 +1,14 @@
1
+ export interface LegendSelectionResult {
2
+ /** 传给图表 legend.selected,保证重渲染(setOption notMerge)后隐藏状态不丢 */
3
+ legendSelected: Record<string, boolean>;
4
+ /** 传给图表 onLegendSelectChanged */
5
+ onLegendSelectChanged: (selected: Record<string, boolean>) => void;
6
+ /** 判断某系列当前是否可见(未点过的系列默认可见) */
7
+ isSeriesVisible: (name?: string | null) => boolean;
8
+ }
9
+ /**
10
+ * 图例选中状态管理:配合 Chart.Bar / Chart.Line 的 onLegendSelectChanged,
11
+ * 在调用方按"当前可见系列"重算 Y 轴 min/max/interval(calculateAxisConfig),
12
+ * 实现图例隐藏某一项后坐标轴自动重算。
13
+ */
14
+ export declare function useLegendSelection(): LegendSelectionResult;