@agions/taroviz 1.9.0 → 1.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/esm/index.js CHANGED
@@ -49493,12 +49493,12 @@ function calculateDataLength(option) {
49493
49493
  function filterDataByKeys(data, filters) {
49494
49494
  if (!filters || Object.keys(filters).length === 0) return data;
49495
49495
  return data.filter(function (item) {
49496
- var _a, _b;
49497
- for (var _i = 0, _c = Object.entries(filters); _i < _c.length; _i++) {
49498
- var _d = _c[_i],
49499
- key = _d[0],
49500
- value = _d[1];
49501
- if (item[key] !== value && !((_b = (_a = item[key]) === null || _a === void 0 ? void 0 : _a.includes) === null || _b === void 0 ? void 0 : _b.call(_a, value))) return false;
49496
+ for (var _i = 0, _a = Object.entries(filters); _i < _a.length; _i++) {
49497
+ var _b = _a[_i],
49498
+ key = _b[0],
49499
+ value = _b[1];
49500
+ var itemVal = item[key];
49501
+ if (itemVal !== value && !(Array.isArray(itemVal) && itemVal.includes(value))) return false;
49502
49502
  }
49503
49503
  return true;
49504
49504
  });
@@ -52486,6 +52486,38 @@ var ThemeManager = /** @class */function () {
52486
52486
  ThemeManager.prototype.isDarkMode = function () {
52487
52487
  return this.currentTheme.isDark || this.currentTheme.type === 'dark';
52488
52488
  };
52489
+ /**
52490
+ * 检测系统 prefers-color-scheme 是否为暗色
52491
+ */
52492
+ ThemeManager.prototype.getSystemPrefersDark = function () {
52493
+ if (typeof window === 'undefined') return false;
52494
+ return window.matchMedia('(prefers-color-scheme: dark)').matches;
52495
+ };
52496
+ /**
52497
+ * 订阅系统主题变化,自动切换匹配的主题
52498
+ * @returns 取消订阅的函数
52499
+ */
52500
+ ThemeManager.prototype.watchSystemTheme = function () {
52501
+ var _this = this;
52502
+ if (typeof window === 'undefined') return function () {};
52503
+ var mq = window.matchMedia('(prefers-color-scheme: dark)');
52504
+ var handler = function (e) {
52505
+ // 当系统主题切换时,自动应用对应主题
52506
+ _this.setTheme(e.matches ? 'dark' : 'default');
52507
+ };
52508
+ mq.addEventListener('change', handler);
52509
+ return function () {
52510
+ return mq.removeEventListener('change', handler);
52511
+ };
52512
+ };
52513
+ /**
52514
+ * 应用初始主题(根据系统偏好自动选择 dark/default)
52515
+ * 必须在 DOM 加载后调用
52516
+ */
52517
+ ThemeManager.prototype.applyInitialTheme = function () {
52518
+ var prefersDark = this.getSystemPrefersDark();
52519
+ this.setTheme(prefersDark ? 'dark' : 'default');
52520
+ };
52489
52521
  /**
52490
52522
  * 注册主题变更监听器
52491
52523
  */
@@ -53842,51 +53874,58 @@ var ErrorBoundary = /** @class */function (_super) {
53842
53874
  if (fallback) {
53843
53875
  return fallback(error, this.handleReset);
53844
53876
  }
53845
- // 默认错误展示
53877
+ // 默认错误展示(使用 CSS 变量,与 ThemeManager 对齐)
53846
53878
  return /*#__PURE__*/external_react_default().createElement("div", {
53879
+ role: "alert",
53880
+ "aria-live": "assertive",
53847
53881
  style: {
53848
53882
  display: 'flex',
53849
53883
  flexDirection: 'column',
53850
53884
  alignItems: 'center',
53851
53885
  justifyContent: 'center',
53852
- padding: '20px',
53853
- backgroundColor: '#fff',
53854
- border: '1px solid #ff4d4f',
53855
- borderRadius: '8px',
53856
- color: '#333',
53857
- minHeight: '200px'
53886
+ padding: 'var(--tv-border-radius, 16px)',
53887
+ backgroundColor: 'var(--tv-bg-color, #fff)',
53888
+ border: '1px solid var(--tv-error-color, #ff4d4f)',
53889
+ borderRadius: 'var(--tv-border-radius, 8px)',
53890
+ color: 'var(--tv-text-color, #333)',
53891
+ minHeight: '200px',
53892
+ fontFamily: 'var(--tv-font-family, sans-serif)'
53858
53893
  }
53859
53894
  }, /*#__PURE__*/external_react_default().createElement("div", {
53860
53895
  style: {
53861
53896
  fontSize: '48px',
53862
53897
  marginBottom: '16px'
53863
- }
53898
+ },
53899
+ "aria-hidden": "true"
53864
53900
  }, "\u26A0\uFE0F"), /*#__PURE__*/external_react_default().createElement("h3", {
53865
53901
  style: {
53866
53902
  margin: '0 0 12px',
53867
- color: '#ff4d4f'
53903
+ color: 'var(--tv-error-color, #ff4d4f)',
53904
+ fontWeight: 700
53868
53905
  }
53869
53906
  }, "\u56FE\u8868\u6E32\u67D3\u5931\u8D25"), /*#__PURE__*/external_react_default().createElement("p", {
53870
53907
  style: {
53871
53908
  margin: '0 0 16px',
53872
- color: '#666',
53873
- textAlign: 'center'
53909
+ color: 'var(--tv-text-color-secondary, #666)',
53910
+ textAlign: 'center',
53911
+ maxWidth: '320px'
53874
53912
  }
53875
53913
  }, "\u56FE\u8868\u5728\u6E32\u67D3\u8FC7\u7A0B\u4E2D\u9047\u5230\u9519\u8BEF\uFF0C\u8BF7\u68C0\u67E5\u6570\u636E\u914D\u7F6E\u662F\u5426\u6B63\u786E"), showDetails && (/*#__PURE__*/external_react_default().createElement("details", {
53876
53914
  style: {
53877
53915
  width: '100%',
53878
53916
  padding: '12px',
53879
- backgroundColor: '#f5f5f5',
53880
- borderRadius: '4px',
53881
- fontSize: '12px',
53882
- fontFamily: 'monospace',
53917
+ backgroundColor: 'var(--tv-bg-color-secondary, #f5f5f5)',
53918
+ borderRadius: 'var(--tv-border-radius-small, 4px)',
53919
+ fontSize: 'var(--tv-font-size-small, 12px)',
53920
+ fontFamily: 'var(--tv-font-family, monospace)',
53883
53921
  overflow: 'auto',
53884
53922
  maxHeight: '150px'
53885
53923
  }
53886
53924
  }, /*#__PURE__*/external_react_default().createElement("summary", {
53887
53925
  style: {
53888
53926
  cursor: 'pointer',
53889
- marginBottom: '8px'
53927
+ marginBottom: '8px',
53928
+ fontWeight: 600
53890
53929
  }
53891
53930
  }, "\u9519\u8BEF\u8BE6\u60C5"), /*#__PURE__*/external_react_default().createElement("pre", {
53892
53931
  style: {
@@ -53899,12 +53938,20 @@ var ErrorBoundary = /** @class */function (_super) {
53899
53938
  style: {
53900
53939
  marginTop: '16px',
53901
53940
  padding: '8px 24px',
53902
- backgroundColor: '#1890ff',
53941
+ backgroundColor: 'var(--tv-primary-color, #1890ff)',
53903
53942
  color: '#fff',
53904
53943
  border: 'none',
53905
- borderRadius: '4px',
53944
+ borderRadius: 'var(--tv-border-radius-small, 4px)',
53906
53945
  cursor: 'pointer',
53907
- fontSize: '14px'
53946
+ fontSize: 'var(--tv-font-size, 14px)',
53947
+ fontWeight: 600,
53948
+ transition: 'background-color var(--tv-transition-duration, 0.3s)'
53949
+ },
53950
+ onMouseEnter: function (e) {
53951
+ e.currentTarget.style.backgroundColor = 'var(--tv-primary-color-hover, #40a9ff)';
53952
+ },
53953
+ onMouseLeave: function (e) {
53954
+ e.currentTarget.style.backgroundColor = 'var(--tv-primary-color, #1890ff)';
53908
53955
  }
53909
53956
  }, "\u91CD\u8BD5"));
53910
53957
  }
@@ -54023,12 +54070,14 @@ var LAZY_CHART_MODULES = {
54023
54070
  };
54024
54071
  var LAZY_CHART_TYPES = Object.keys(LAZY_CHART_MODULES);
54025
54072
  /**
54026
- * 默认加载状态组件
54073
+ * 默认加载状态组件(使用 CSS 变量,与 ThemeManager 对齐)
54027
54074
  */
54028
54075
  var DefaultLoadingFallback = function (_a) {
54029
54076
  var _b = _a.text,
54030
54077
  text = _b === void 0 ? '加载中...' : _b;
54031
54078
  return /*#__PURE__*/external_react_default().createElement("div", {
54079
+ role: "status",
54080
+ "aria-label": text,
54032
54081
  style: {
54033
54082
  display: 'flex',
54034
54083
  alignItems: 'center',
@@ -54036,8 +54085,8 @@ var DefaultLoadingFallback = function (_a) {
54036
54085
  width: '100%',
54037
54086
  height: '100%',
54038
54087
  minHeight: '200px',
54039
- backgroundColor: '#f5f5f5',
54040
- borderRadius: '8px'
54088
+ backgroundColor: 'var(--tv-bg-color-secondary, #f5f5f5)',
54089
+ borderRadius: 'var(--tv-border-radius, 8px)'
54041
54090
  }
54042
54091
  }, /*#__PURE__*/external_react_default().createElement("div", {
54043
54092
  style: {
@@ -54047,16 +54096,17 @@ var DefaultLoadingFallback = function (_a) {
54047
54096
  style: {
54048
54097
  width: '40px',
54049
54098
  height: '40px',
54050
- border: '3px solid #1890ff',
54099
+ border: '3px solid var(--tv-primary-color, #1890ff)',
54051
54100
  borderTopColor: 'transparent',
54052
54101
  borderRadius: '50%',
54053
54102
  animation: 'taroviz-spin 1s linear infinite',
54054
54103
  margin: '0 auto 12px'
54055
- }
54104
+ },
54105
+ "aria-hidden": "true"
54056
54106
  }), /*#__PURE__*/external_react_default().createElement("style", null, "\n @keyframes taroviz-spin {\n to { transform: rotate(360deg); }\n }\n "), /*#__PURE__*/external_react_default().createElement("span", {
54057
54107
  style: {
54058
- color: '#666',
54059
- fontSize: '14px'
54108
+ color: 'var(--tv-text-color-secondary, #666)',
54109
+ fontSize: 'var(--tv-font-size, 14px)'
54060
54110
  }
54061
54111
  }, text)));
54062
54112
  };
@@ -56149,6 +56199,491 @@ function useChartDownload(instance, options) {
56149
56199
  // 导出
56150
56200
  // ============================================================================
56151
56201
  /* harmony default export */ const hooks_useChartDownload = ((/* unused pure expression or super */ null && (useChartDownload)));
56202
+ ;// ./src/hooks/useChartHistory.ts
56203
+ var useChartHistory_spreadArray = undefined && undefined.__spreadArray || function (to, from, pack) {
56204
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
56205
+ if (ar || !(i in from)) {
56206
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
56207
+ ar[i] = from[i];
56208
+ }
56209
+ }
56210
+ return to.concat(ar || Array.prototype.slice.call(from));
56211
+ };
56212
+ /**
56213
+ * useChartHistory - 图表 Undo/Redo Hook
56214
+ * 追踪图表配置历史,支持撤销/重做操作和键盘快捷键
56215
+ *
56216
+ * 特性:
56217
+ * - 最多保存 50 条历史记录(可配置)
56218
+ * - 自动绑定 Ctrl+Z / Ctrl+Y 键盘快捷键
56219
+ * - 支持 ignoreKeys 忽略特定配置字段(如动画、时间戳)
56220
+ * - 暴露 canUndo / canRedo 状态
56221
+ */
56222
+
56223
+ // ============================================================================
56224
+ // 工具函数
56225
+ // ============================================================================
56226
+ /** 深度省略指定键后比较两个配置是否相等 */
56227
+ function omitAndCompare(a, b, ignoreKeys) {
56228
+ if (a === b) return true;
56229
+ if (typeof a !== 'object' || a === null || typeof b !== 'object' || b === null) {
56230
+ return a === b;
56231
+ }
56232
+ var aObj = a;
56233
+ var bObj = b;
56234
+ var aKeys = Object.keys(aObj).filter(function (k) {
56235
+ return !ignoreKeys.has(k);
56236
+ });
56237
+ var bKeys = Object.keys(bObj).filter(function (k) {
56238
+ return !ignoreKeys.has(k);
56239
+ });
56240
+ if (aKeys.length !== bKeys.length) return false;
56241
+ for (var _i = 0, aKeys_1 = aKeys; _i < aKeys_1.length; _i++) {
56242
+ var key = aKeys_1[_i];
56243
+ if (!bObj.hasOwnProperty(key)) return false;
56244
+ if (!omitAndCompare(aObj[key], bObj[key], ignoreKeys)) return false;
56245
+ }
56246
+ return true;
56247
+ }
56248
+ // ============================================================================
56249
+ // Hook 实现
56250
+ // ============================================================================
56251
+ /**
56252
+ * 使用图表历史记录(Undo/Redo)
56253
+ * @param chartInstance 图表实例
56254
+ * @param options 配置选项
56255
+ * @returns 历史记录控制接口
56256
+ */
56257
+ function useChartHistory(chartInstance, options) {
56258
+ if (options === void 0) {
56259
+ options = {};
56260
+ }
56261
+ var _a = options.maxHistorySize,
56262
+ maxHistorySize = _a === void 0 ? 50 : _a,
56263
+ _b = options.ignoreKeys,
56264
+ ignoreKeys = _b === void 0 ? ['animation', 'animationDuration', 'animationEasing', 'animationFrame'] : _b,
56265
+ _c = options.enableKeyboard,
56266
+ enableKeyboard = _c === void 0 ? true : _c,
56267
+ _d = options.clearOnUnmount,
56268
+ clearOnUnmount = _d === void 0 ? false : _d;
56269
+ // 忽略键集合
56270
+ var ignoreKeySet = (0,external_react_.useRef)(new Set(ignoreKeys));
56271
+ // 历史栈(每次 setOption 快照)
56272
+ var historyStack = (0,external_react_.useRef)([]);
56273
+ // 当前索引
56274
+ var _e = (0,external_react_.useState)(-1),
56275
+ currentIndex = _e[0],
56276
+ setCurrentIndex = _e[1];
56277
+ // Chart instance ref
56278
+ var chartRef = (0,external_react_.useRef)(null);
56279
+ chartRef.current = chartInstance;
56280
+ // 是否正在执行 undo/redo(避免 push 时重复记录)
56281
+ var isApplyingRef = (0,external_react_.useRef)(false);
56282
+ // 拦截 chart.setOption,记录历史
56283
+ (0,external_react_.useEffect)(function () {
56284
+ var chart = chartRef.current;
56285
+ if (!chart) return;
56286
+ var originalSetOption = chart.setOption.bind(chart);
56287
+ chart.setOption = function (option, notMerge, lazyUpdate) {
56288
+ // 如果正在执行 undo/redo,跳过历史记录
56289
+ if (isApplyingRef.current) {
56290
+ return originalSetOption(option, notMerge, lazyUpdate);
56291
+ }
56292
+ var stack = historyStack.current;
56293
+ var idx = currentIndex;
56294
+ // 如果当前索引不在栈顶,丢弃redo历史(类似 Git 行为)
56295
+ var newStack = idx < stack.length - 1 ? stack.slice(0, idx + 1) : useChartHistory_spreadArray([], stack, true);
56296
+ // 检查是否与上一次配置相同(忽略动画字段)
56297
+ var lastOption = newStack[newStack.length - 1];
56298
+ if (lastOption && omitAndCompare(lastOption, option, ignoreKeySet.current)) {
56299
+ // 配置没变,直接应用
56300
+ return originalSetOption(option, notMerge, lazyUpdate);
56301
+ }
56302
+ // 入栈
56303
+ newStack.push(option);
56304
+ // 裁剪超出 maxHistorySize
56305
+ if (newStack.length > maxHistorySize) {
56306
+ newStack.shift();
56307
+ } else {
56308
+ // 更新索引
56309
+ setCurrentIndex(newStack.length - 1);
56310
+ }
56311
+ historyStack.current = newStack;
56312
+ return originalSetOption(option, notMerge, lazyUpdate);
56313
+ };
56314
+ return function () {
56315
+ // 恢复原始 setOption
56316
+ chart.setOption = originalSetOption;
56317
+ };
56318
+ }, [chartInstance, currentIndex, maxHistorySize]);
56319
+ // 键盘快捷键:Ctrl+Z 撤销,Ctrl+Y / Ctrl+Shift+Z 重做
56320
+ (0,external_react_.useEffect)(function () {
56321
+ if (!enableKeyboard) return;
56322
+ var handleKeyDown = function (e) {
56323
+ var isMod = e.ctrlKey || e.metaKey;
56324
+ if (!isMod) return;
56325
+ if (e.key === 'z' && !e.shiftKey) {
56326
+ e.preventDefault();
56327
+ undo();
56328
+ } else if (e.key === 'y' || e.key === 'z' && e.shiftKey) {
56329
+ e.preventDefault();
56330
+ redo();
56331
+ }
56332
+ };
56333
+ window.addEventListener('keydown', handleKeyDown);
56334
+ return function () {
56335
+ return window.removeEventListener('keydown', handleKeyDown);
56336
+ };
56337
+ }, [enableKeyboard]); // eslint-disable-line react-hooks/exhaustive-deps
56338
+ // 组件卸载时清空
56339
+ (0,external_react_.useEffect)(function () {
56340
+ return function () {
56341
+ if (clearOnUnmount) {
56342
+ historyStack.current = [];
56343
+ setCurrentIndex(-1);
56344
+ }
56345
+ };
56346
+ }, [clearOnUnmount]);
56347
+ // ─── Public API ───────────────────────────────────────────────────────────
56348
+ var undo = (0,external_react_.useCallback)(function () {
56349
+ var chart = chartRef.current;
56350
+ if (!chart || currentIndex <= 0) return;
56351
+ var idx = currentIndex - 1;
56352
+ isApplyingRef.current = true;
56353
+ chart.setOption(historyStack.current[idx], true, true);
56354
+ isApplyingRef.current = false;
56355
+ setCurrentIndex(idx);
56356
+ }, [currentIndex]);
56357
+ var redo = (0,external_react_.useCallback)(function () {
56358
+ var chart = chartRef.current;
56359
+ if (!chart || currentIndex >= historyStack.current.length - 1) return;
56360
+ var idx = currentIndex + 1;
56361
+ isApplyingRef.current = true;
56362
+ chart.setOption(historyStack.current[idx], true, true);
56363
+ isApplyingRef.current = false;
56364
+ setCurrentIndex(idx);
56365
+ }, [currentIndex]);
56366
+ var goTo = (0,external_react_.useCallback)(function (index) {
56367
+ var chart = chartRef.current;
56368
+ if (!chart) return;
56369
+ if (index < 0 || index >= historyStack.current.length) return;
56370
+ if (index === currentIndex) return;
56371
+ isApplyingRef.current = true;
56372
+ chart.setOption(historyStack.current[index], true, true);
56373
+ isApplyingRef.current = false;
56374
+ setCurrentIndex(index);
56375
+ }, [currentIndex]);
56376
+ var push = (0,external_react_.useCallback)(function (option) {
56377
+ var stack = historyStack.current;
56378
+ var idx = currentIndex;
56379
+ var newStack = idx < stack.length - 1 ? stack.slice(0, idx + 1) : useChartHistory_spreadArray([], stack, true);
56380
+ newStack.push(option);
56381
+ if (newStack.length > maxHistorySize) newStack.shift();
56382
+ historyStack.current = newStack;
56383
+ setCurrentIndex(newStack.length - 1);
56384
+ }, [currentIndex, maxHistorySize]);
56385
+ var clear = (0,external_react_.useCallback)(function () {
56386
+ historyStack.current = [];
56387
+ setCurrentIndex(-1);
56388
+ }, []);
56389
+ return {
56390
+ canUndo: currentIndex > 0,
56391
+ canRedo: currentIndex < historyStack.current.length - 1,
56392
+ currentIndex: currentIndex,
56393
+ historyCount: historyStack.current.length,
56394
+ undo: undo,
56395
+ redo: redo,
56396
+ goTo: goTo,
56397
+ push: push,
56398
+ clear: clear
56399
+ };
56400
+ }
56401
+ /* harmony default export */ const hooks_useChartHistory = ((/* unused pure expression or super */ null && (useChartHistory)));
56402
+ ;// ./src/hooks/useChartSelection.ts
56403
+ var useChartSelection_spreadArray = undefined && undefined.__spreadArray || function (to, from, pack) {
56404
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
56405
+ if (ar || !(i in from)) {
56406
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
56407
+ ar[i] = from[i];
56408
+ }
56409
+ }
56410
+ return to.concat(ar || Array.prototype.slice.call(from));
56411
+ };
56412
+ /**
56413
+ * useChartSelection - 图表数据点选择/高亮 Hook
56414
+ * 支持单个/批量选择、反选、清除选择,配合 ECharts select 事件
56415
+ *
56416
+ * 特性:
56417
+ * - 支持按 seriesIndex + dataIndex 选择
56418
+ * - 支持按 dataIndex 跨系列批量选择
56419
+ * - 支持反选(invertSelection)
56420
+ * - 支持多选模式(multi)
56421
+ * - 自动绑定图表 select/unselect 事件
56422
+ */
56423
+
56424
+ // ============================================================================
56425
+ // 工具函数
56426
+ // ============================================================================
56427
+ /** 生成唯一键字符串 */
56428
+ function keyToString(key) {
56429
+ return "".concat(key.seriesIndex, ":").concat(key.dataIndex);
56430
+ }
56431
+ function stringToKey(str) {
56432
+ var _a = str.split(':').map(Number),
56433
+ seriesIndex = _a[0],
56434
+ dataIndex = _a[1];
56435
+ return {
56436
+ seriesIndex: seriesIndex,
56437
+ dataIndex: dataIndex
56438
+ };
56439
+ }
56440
+ // ============================================================================
56441
+ // Hook 实现
56442
+ // ============================================================================
56443
+ /**
56444
+ * 使用图表数据点选择功能
56445
+ * @param chartInstance 图表实例
56446
+ * @param options 配置选项
56447
+ * @returns 选择控制接口
56448
+ */
56449
+ function useChartSelection(chartInstance, options) {
56450
+ if (options === void 0) {
56451
+ options = {};
56452
+ }
56453
+ var _a = options.mode,
56454
+ mode = _a === void 0 ? 'multiple' : _a,
56455
+ _b = options.clearOnUnmount,
56456
+ clearOnUnmount = _b === void 0 ? true : _b,
56457
+ _c = options.enableCtrlMultiSelect,
56458
+ enableCtrlMultiSelect = _c === void 0 ? true : _c,
56459
+ _d = options.enableShiftRangeSelect,
56460
+ enableShiftRangeSelect = _d === void 0 ? true : _d,
56461
+ onSelectionChange = options.onSelectionChange;
56462
+ // 选中点集合(字符串键)
56463
+ var _e = (0,external_react_.useState)([]),
56464
+ selectedPoints = _e[0],
56465
+ setSelectedPoints = _e[1];
56466
+ // Chart instance ref
56467
+ var chartRef = (0,external_react_.useRef)(null);
56468
+ chartRef.current = chartInstance;
56469
+ // 上一次 shift+click 的数据索引(用于范围选择)
56470
+ var lastShiftIndexRef = (0,external_react_.useRef)(null);
56471
+ // 当前模式 ref(用于事件处理)
56472
+ var modeRef = (0,external_react_.useRef)(mode);
56473
+ modeRef.current = mode;
56474
+ // 绑定图表 select/unselect 事件
56475
+ (0,external_react_.useEffect)(function () {
56476
+ var chart = chartRef.current;
56477
+ if (!chart || !chart.on) return;
56478
+ var handleSelect = function (params) {
56479
+ // ECharts 内置 select 会同步更新 legend
56480
+ // 这里我们用 dispatchAction 来实现纯数据点选择
56481
+ };
56482
+ // 单击 legend 时清除数据点选择(保持一致性)
56483
+ var handleLegendSelectChanged = function (params) {
56484
+ // 清除选择时的视觉反馈
56485
+ };
56486
+ chart.on('selectchanged', function (params) {
56487
+ // 当图表内部选择变化时同步状态
56488
+ var p = params;
56489
+ if (p.isFromClick) {
56490
+ // 用户点击了图例,清除所有数据点选择
56491
+ setSelectedPoints([]);
56492
+ onSelectionChange === null || onSelectionChange === void 0 ? void 0 : onSelectionChange({
56493
+ selected: [],
56494
+ unselected: []
56495
+ });
56496
+ }
56497
+ });
56498
+ return function () {
56499
+ if (chart.off) {
56500
+ chart.off('selectchanged');
56501
+ }
56502
+ };
56503
+ }, [onSelectionChange]);
56504
+ // 组件卸载时清除选择
56505
+ (0,external_react_.useEffect)(function () {
56506
+ return function () {
56507
+ if (clearOnUnmount) {
56508
+ var chart = chartRef.current;
56509
+ if (chart === null || chart === void 0 ? void 0 : chart.dispatchAction) {
56510
+ // 清除所有系列的选择状态
56511
+ chart.dispatchAction({
56512
+ type: 'unselect'
56513
+ });
56514
+ }
56515
+ }
56516
+ };
56517
+ }, [clearOnUnmount]);
56518
+ // ─── 私有方法 ───────────────────────────────────────────────────────────────
56519
+ /** 触发选择变化回调 */
56520
+ var notifyChange = (0,external_react_.useCallback)(function (selected, unselected) {
56521
+ onSelectionChange === null || onSelectionChange === void 0 ? void 0 : onSelectionChange({
56522
+ selected: selected,
56523
+ unselected: unselected
56524
+ });
56525
+ }, [onSelectionChange]);
56526
+ /** 执行 ECharts dispatchAction */
56527
+ var dispatchSelect = (0,external_react_.useCallback)(function (key, select) {
56528
+ var chart = chartRef.current;
56529
+ if (!(chart === null || chart === void 0 ? void 0 : chart.dispatchAction)) return;
56530
+ chart.dispatchAction({
56531
+ type: select ? 'select' : 'unselect',
56532
+ seriesIndex: key.seriesIndex,
56533
+ dataIndex: key.dataIndex
56534
+ });
56535
+ }, []);
56536
+ // ─── Public API ───────────────────────────────────────────────────────────
56537
+ var select = (0,external_react_.useCallback)(function (key) {
56538
+ setSelectedPoints(function (prev) {
56539
+ var str = keyToString(key);
56540
+ if (prev.some(function (p) {
56541
+ return keyToString(p) === str;
56542
+ })) return prev;
56543
+ var next = mode === 'single' ? [key] : useChartSelection_spreadArray(useChartSelection_spreadArray([], prev, true), [key], false);
56544
+ notifyChange(next, []);
56545
+ return next;
56546
+ });
56547
+ dispatchSelect(key, true);
56548
+ }, [mode, notifyChange, dispatchSelect]);
56549
+ var deselect = (0,external_react_.useCallback)(function (key) {
56550
+ setSelectedPoints(function (prev) {
56551
+ var str = keyToString(key);
56552
+ var removed = prev.filter(function (p) {
56553
+ return keyToString(p) !== str;
56554
+ });
56555
+ notifyChange([], removed);
56556
+ return removed;
56557
+ });
56558
+ dispatchSelect(key, false);
56559
+ }, [notifyChange, dispatchSelect]);
56560
+ var toggle = (0,external_react_.useCallback)(function (key) {
56561
+ var str = keyToString(key);
56562
+ if (selectedPoints.some(function (p) {
56563
+ return keyToString(p) === str;
56564
+ })) {
56565
+ deselect(key);
56566
+ } else {
56567
+ select(key);
56568
+ }
56569
+ }, [selectedPoints, select, deselect]);
56570
+ var selectMultiple = (0,external_react_.useCallback)(function (keys) {
56571
+ setSelectedPoints(function (prev) {
56572
+ var newPoints = mode === 'single' ? keys : useChartSelection_spreadArray(useChartSelection_spreadArray([], prev, true), keys.filter(function (k) {
56573
+ return !prev.some(function (p) {
56574
+ return keyToString(p) === keyToString(k);
56575
+ });
56576
+ }), true);
56577
+ notifyChange(newPoints, []);
56578
+ return newPoints;
56579
+ });
56580
+ keys.forEach(function (key) {
56581
+ return dispatchSelect(key, true);
56582
+ });
56583
+ }, [mode, notifyChange, dispatchSelect]);
56584
+ var deselectMultiple = (0,external_react_.useCallback)(function (keys) {
56585
+ setSelectedPoints(function (prev) {
56586
+ var keySet = new Set(keys.map(keyToString));
56587
+ var removed = prev.filter(function (p) {
56588
+ return keySet.has(keyToString(p));
56589
+ });
56590
+ var remaining = prev.filter(function (p) {
56591
+ return !keySet.has(keyToString(p));
56592
+ });
56593
+ notifyChange([], removed);
56594
+ return remaining;
56595
+ });
56596
+ keys.forEach(function (key) {
56597
+ return dispatchSelect(key, false);
56598
+ });
56599
+ }, [notifyChange, dispatchSelect]);
56600
+ var invertSelection = (0,external_react_.useCallback)(function (seriesIndex, dataIndices) {
56601
+ setSelectedPoints(function (prev) {
56602
+ var selectedSet = new Set(prev.filter(function (p) {
56603
+ return p.seriesIndex === seriesIndex;
56604
+ }).map(function (p) {
56605
+ return p.dataIndex;
56606
+ }));
56607
+ var toSelect = [];
56608
+ var toDeselect = [];
56609
+ dataIndices.forEach(function (dataIndex) {
56610
+ var key = {
56611
+ seriesIndex: seriesIndex,
56612
+ dataIndex: dataIndex
56613
+ };
56614
+ var str = keyToString(key);
56615
+ if (selectedSet.has(dataIndex)) {
56616
+ toDeselect.push(key);
56617
+ } else {
56618
+ toSelect.push(key);
56619
+ }
56620
+ });
56621
+ toDeselect.forEach(function (k) {
56622
+ return dispatchSelect(k, false);
56623
+ });
56624
+ toSelect.forEach(function (k) {
56625
+ return dispatchSelect(k, true);
56626
+ });
56627
+ var newSelected = prev.filter(function (p) {
56628
+ return !(p.seriesIndex === seriesIndex && selectedSet.has(p.dataIndex));
56629
+ }).concat(toSelect);
56630
+ notifyChange(toSelect, toDeselect);
56631
+ return newSelected;
56632
+ });
56633
+ }, [notifyChange, dispatchSelect]);
56634
+ var selectAll = (0,external_react_.useCallback)(function (seriesIndex, dataIndices) {
56635
+ var keys = dataIndices.map(function (dataIndex) {
56636
+ return {
56637
+ seriesIndex: seriesIndex,
56638
+ dataIndex: dataIndex
56639
+ };
56640
+ });
56641
+ setSelectedPoints(function (prev) {
56642
+ var newPoints = mode === 'single' ? keys : useChartSelection_spreadArray(useChartSelection_spreadArray([], prev, true), keys.filter(function (k) {
56643
+ return !prev.some(function (p) {
56644
+ return keyToString(p) === keyToString(k);
56645
+ });
56646
+ }), true);
56647
+ notifyChange(newPoints, []);
56648
+ return newPoints;
56649
+ });
56650
+ keys.forEach(function (key) {
56651
+ return dispatchSelect(key, true);
56652
+ });
56653
+ }, [mode, notifyChange, dispatchSelect]);
56654
+ var clearSelection = (0,external_react_.useCallback)(function () {
56655
+ var chart = chartRef.current;
56656
+ if (chart === null || chart === void 0 ? void 0 : chart.dispatchAction) {
56657
+ chart.dispatchAction({
56658
+ type: 'unselect'
56659
+ });
56660
+ }
56661
+ var prev = selectedPoints;
56662
+ setSelectedPoints([]);
56663
+ notifyChange([], prev);
56664
+ }, [selectedPoints, notifyChange]);
56665
+ var isSelected = (0,external_react_.useCallback)(function (key) {
56666
+ var str = keyToString(key);
56667
+ return selectedPoints.some(function (p) {
56668
+ return keyToString(p) === str;
56669
+ });
56670
+ }, [selectedPoints]);
56671
+ return {
56672
+ selectedPoints: selectedPoints,
56673
+ hasSelection: selectedPoints.length > 0,
56674
+ selectionCount: selectedPoints.length,
56675
+ select: select,
56676
+ deselect: deselect,
56677
+ selectMultiple: selectMultiple,
56678
+ deselectMultiple: deselectMultiple,
56679
+ toggle: toggle,
56680
+ invertSelection: invertSelection,
56681
+ selectAll: selectAll,
56682
+ clearSelection: clearSelection,
56683
+ isSelected: isSelected
56684
+ };
56685
+ }
56686
+ /* harmony default export */ const hooks_useChartSelection = ((/* unused pure expression or super */ null && (useChartSelection)));
56152
56687
  ;// ./src/hooks/useDataTransform.ts
56153
56688
  var useDataTransform_assign = undefined && undefined.__assign || function () {
56154
56689
  useDataTransform_assign = Object.assign || function (t) {
@@ -56740,6 +57275,8 @@ var hooks_spreadArray = undefined && undefined.__spreadArray || function (to, fr
56740
57275
 
56741
57276
 
56742
57277
 
57278
+
57279
+
56743
57280
  // ============================================================================
56744
57281
  // Hooks
56745
57282
  // ============================================================================
@@ -57342,6 +57879,10 @@ function useChartTools(instance) {
57342
57879
 
57343
57880
  // 图表下载 Hook
57344
57881
 
57882
+ // 图表历史记录 Hook (Undo/Redo)
57883
+
57884
+ // 图表选择 Hook
57885
+
57345
57886
  // ============================================================================
57346
57887
  // 导出
57347
57888
  // ============================================================================
@@ -57365,7 +57906,9 @@ var hooks_version = '1.7.0';
57365
57906
  // v1.7.0 新增
57366
57907
  useDataZoom: useDataZoom,
57367
57908
  useChartConnect: useChartConnect,
57368
- useChartDownload: useChartDownload
57909
+ useChartDownload: useChartDownload,
57910
+ useChartHistory: useChartHistory,
57911
+ useChartSelection: useChartSelection
57369
57912
  });
57370
57913
  ;// ./src/index.ts
57371
57914
  /**