@agions/taroviz 1.9.0 → 1.11.1

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
@@ -647,7 +647,7 @@ var HarmonyAdapter = /** @class */function () {
647
647
 
648
648
  /***/ },
649
649
 
650
- /***/ 574
650
+ /***/ 193
651
651
  (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
652
652
 
653
653
 
@@ -1463,7 +1463,7 @@ BarChart.displayName = 'BarChart';
1463
1463
  /* harmony export */ });
1464
1464
  /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(15);
1465
1465
  /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
1466
- /* harmony import */ var _adapters__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(574);
1466
+ /* harmony import */ var _adapters__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(193);
1467
1467
  /* harmony import */ var _core_utils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(524);
1468
1468
  /* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(855);
1469
1469
  var __assign = undefined && undefined.__assign || function () {
@@ -49054,17 +49054,20 @@ var PerformanceAnalyzer = /** @class */function () {
49054
49054
  }
49055
49055
  }
49056
49056
  };
49057
- /**
49058
- * 触发事件
49059
- */
49060
49057
  PerformanceAnalyzer.prototype.emit = function (eventType, data) {
49061
49058
  var handlers = this.eventHandlers.get(eventType);
49059
+ var eventData = data === undefined ? {
49060
+ type: eventType
49061
+ } : eventType === PerformanceEventType.METRIC_UPDATE ? {
49062
+ type: eventType,
49063
+ data: data
49064
+ } : {
49065
+ type: eventType,
49066
+ data: data
49067
+ };
49062
49068
  handlers === null || handlers === void 0 ? void 0 : handlers.forEach(function (handler) {
49063
49069
  try {
49064
- handler({
49065
- type: eventType,
49066
- data: data
49067
- });
49070
+ handler(eventData);
49068
49071
  } catch (error) {
49069
49072
  console.error('Error in performance event handler:', error);
49070
49073
  }
@@ -49493,12 +49496,12 @@ function calculateDataLength(option) {
49493
49496
  function filterDataByKeys(data, filters) {
49494
49497
  if (!filters || Object.keys(filters).length === 0) return data;
49495
49498
  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;
49499
+ for (var _i = 0, _a = Object.entries(filters); _i < _a.length; _i++) {
49500
+ var _b = _a[_i],
49501
+ key = _b[0],
49502
+ value = _b[1];
49503
+ var itemVal = item[key];
49504
+ if (itemVal !== value && !(Array.isArray(itemVal) && itemVal.includes(value))) return false;
49502
49505
  }
49503
49506
  return true;
49504
49507
  });
@@ -49638,23 +49641,24 @@ var BaseChart = function (props) {
49638
49641
  processed = JSON.parse(JSON.stringify(processed));
49639
49642
  if (processed.series && Array.isArray(processed.series)) {
49640
49643
  processed.series = processed.series.map(function (s) {
49641
- if (s.data && Array.isArray(s.data)) {
49642
- var filtered = filterDataByKeys(s.data, filters);
49644
+ var seriesItem = s;
49645
+ if (seriesItem.data && Array.isArray(seriesItem.data)) {
49646
+ var filtered = filterDataByKeys(seriesItem.data, filters);
49643
49647
  if (onDataFiltered) onDataFiltered(filtered, filters);
49644
49648
  if (virtualScroll) {
49645
49649
  virtualScrollRef.current.totalDataCount = filtered.length;
49646
49650
  virtualScrollRef.current.totalPages = Math.ceil(filtered.length / virtualScrollPageSize);
49647
49651
  var start = virtualScrollRef.current.currentPage * virtualScrollPageSize;
49648
49652
  var end = Math.min(start + virtualScrollPageSize + virtualScrollPreloadSize, filtered.length);
49649
- return BaseChart_assign(BaseChart_assign({}, s), {
49653
+ return BaseChart_assign(BaseChart_assign({}, seriesItem), {
49650
49654
  data: filtered.slice(start, end)
49651
49655
  });
49652
49656
  }
49653
- return BaseChart_assign(BaseChart_assign({}, s), {
49657
+ return BaseChart_assign(BaseChart_assign({}, seriesItem), {
49654
49658
  data: filtered
49655
49659
  });
49656
49660
  }
49657
- return s;
49661
+ return seriesItem;
49658
49662
  });
49659
49663
  }
49660
49664
  }
@@ -49718,14 +49722,15 @@ var BaseChart = function (props) {
49718
49722
  }
49719
49723
  // Zoom + zoom linkage + virtual scroll page update
49720
49724
  instance.on('datazoom', function (params) {
49725
+ var p = params;
49721
49726
  if (onZoom) onZoom({
49722
- start: params.start || 0,
49723
- end: params.end || 100,
49724
- dataZoomIndex: params.dataZoomIndex || 0
49727
+ start: p.start || 0,
49728
+ end: p.end || 100,
49729
+ dataZoomIndex: p.dataZoomIndex || 0
49725
49730
  });
49726
49731
  if (virtualScroll && !virtualScrollRef.current.isScrolling) {
49727
49732
  virtualScrollRef.current.isScrolling = true;
49728
- var newPage = Math.floor((params.start || 0) / 100 * virtualScrollRef.current.totalPages);
49733
+ var newPage = Math.floor((p.start || 0) / 100 * virtualScrollRef.current.totalPages);
49729
49734
  if (newPage !== virtualScrollRef.current.currentPage) {
49730
49735
  virtualScrollRef.current.currentPage = newPage;
49731
49736
  // Trigger re-render via option update
@@ -49739,9 +49744,9 @@ var BaseChart = function (props) {
49739
49744
  var linked = getChart(lid);
49740
49745
  if (linked) linked.dispatchAction({
49741
49746
  type: 'dataZoom',
49742
- start: params.start,
49743
- end: params.end,
49744
- dataZoomIndex: params.dataZoomIndex
49747
+ start: p.start,
49748
+ end: p.end,
49749
+ dataZoomIndex: p.dataZoomIndex
49745
49750
  });
49746
49751
  });
49747
49752
  }
@@ -49749,8 +49754,9 @@ var BaseChart = function (props) {
49749
49754
  // Legend interaction
49750
49755
  if (enableLegendInteraction) {
49751
49756
  instance.on('legendselectchanged', function (params) {
49752
- var name = params.name,
49753
- selected = params.selected;
49757
+ var p = params;
49758
+ var name = p.name,
49759
+ selected = p.selected;
49754
49760
  if (linkageConfig.enableLegendLinkage && chartId && linkageConfig.linkedChartIds) {
49755
49761
  linkageConfig.linkedChartIds.forEach(function (lid) {
49756
49762
  var linked = getChart(lid);
@@ -49771,15 +49777,15 @@ var BaseChart = function (props) {
49771
49777
  selected: newSelected_1
49772
49778
  }
49773
49779
  });
49774
- onLegendSelect === null || onLegendSelect === void 0 ? void 0 : onLegendSelect({
49780
+ if (name !== undefined) onLegendSelect === null || onLegendSelect === void 0 ? void 0 : onLegendSelect({
49775
49781
  name: name,
49776
49782
  selected: newSelected_1
49777
49783
  });
49778
49784
  } else {
49779
- if (selected[name]) onLegendSelect === null || onLegendSelect === void 0 ? void 0 : onLegendSelect({
49785
+ if (name !== undefined && selected[name]) onLegendSelect === null || onLegendSelect === void 0 ? void 0 : onLegendSelect({
49780
49786
  name: name,
49781
49787
  selected: selected
49782
- });else onLegendUnselect === null || onLegendUnselect === void 0 ? void 0 : onLegendUnselect({
49788
+ });else if (name !== undefined) onLegendUnselect === null || onLegendUnselect === void 0 ? void 0 : onLegendUnselect({
49783
49789
  name: name,
49784
49790
  selected: selected
49785
49791
  });
@@ -50968,7 +50974,7 @@ function createCategoryDrillDown(categoryData) {
50968
50974
  };
50969
50975
  }
50970
50976
  // EXTERNAL MODULE: ./src/adapters/index.ts + 5 modules
50971
- var adapters = __webpack_require__(574);
50977
+ var adapters = __webpack_require__(193);
50972
50978
  // EXTERNAL MODULE: ./src/charts/utils.ts
50973
50979
  var charts_utils = __webpack_require__(855);
50974
50980
  ;// ./src/charts/liquid/index.tsx
@@ -52486,6 +52492,38 @@ var ThemeManager = /** @class */function () {
52486
52492
  ThemeManager.prototype.isDarkMode = function () {
52487
52493
  return this.currentTheme.isDark || this.currentTheme.type === 'dark';
52488
52494
  };
52495
+ /**
52496
+ * 检测系统 prefers-color-scheme 是否为暗色
52497
+ */
52498
+ ThemeManager.prototype.getSystemPrefersDark = function () {
52499
+ if (typeof window === 'undefined') return false;
52500
+ return window.matchMedia('(prefers-color-scheme: dark)').matches;
52501
+ };
52502
+ /**
52503
+ * 订阅系统主题变化,自动切换匹配的主题
52504
+ * @returns 取消订阅的函数
52505
+ */
52506
+ ThemeManager.prototype.watchSystemTheme = function () {
52507
+ var _this = this;
52508
+ if (typeof window === 'undefined') return function () {};
52509
+ var mq = window.matchMedia('(prefers-color-scheme: dark)');
52510
+ var handler = function (e) {
52511
+ // 当系统主题切换时,自动应用对应主题
52512
+ _this.setTheme(e.matches ? 'dark' : 'default');
52513
+ };
52514
+ mq.addEventListener('change', handler);
52515
+ return function () {
52516
+ return mq.removeEventListener('change', handler);
52517
+ };
52518
+ };
52519
+ /**
52520
+ * 应用初始主题(根据系统偏好自动选择 dark/default)
52521
+ * 必须在 DOM 加载后调用
52522
+ */
52523
+ ThemeManager.prototype.applyInitialTheme = function () {
52524
+ var prefersDark = this.getSystemPrefersDark();
52525
+ this.setTheme(prefersDark ? 'dark' : 'default');
52526
+ };
52489
52527
  /**
52490
52528
  * 注册主题变更监听器
52491
52529
  */
@@ -53842,51 +53880,58 @@ var ErrorBoundary = /** @class */function (_super) {
53842
53880
  if (fallback) {
53843
53881
  return fallback(error, this.handleReset);
53844
53882
  }
53845
- // 默认错误展示
53883
+ // 默认错误展示(使用 CSS 变量,与 ThemeManager 对齐)
53846
53884
  return /*#__PURE__*/external_react_default().createElement("div", {
53885
+ role: "alert",
53886
+ "aria-live": "assertive",
53847
53887
  style: {
53848
53888
  display: 'flex',
53849
53889
  flexDirection: 'column',
53850
53890
  alignItems: 'center',
53851
53891
  justifyContent: 'center',
53852
- padding: '20px',
53853
- backgroundColor: '#fff',
53854
- border: '1px solid #ff4d4f',
53855
- borderRadius: '8px',
53856
- color: '#333',
53857
- minHeight: '200px'
53892
+ padding: 'var(--tv-border-radius, 16px)',
53893
+ backgroundColor: 'var(--tv-bg-color, #fff)',
53894
+ border: '1px solid var(--tv-error-color, #ff4d4f)',
53895
+ borderRadius: 'var(--tv-border-radius, 8px)',
53896
+ color: 'var(--tv-text-color, #333)',
53897
+ minHeight: '200px',
53898
+ fontFamily: 'var(--tv-font-family, sans-serif)'
53858
53899
  }
53859
53900
  }, /*#__PURE__*/external_react_default().createElement("div", {
53860
53901
  style: {
53861
53902
  fontSize: '48px',
53862
53903
  marginBottom: '16px'
53863
- }
53904
+ },
53905
+ "aria-hidden": "true"
53864
53906
  }, "\u26A0\uFE0F"), /*#__PURE__*/external_react_default().createElement("h3", {
53865
53907
  style: {
53866
53908
  margin: '0 0 12px',
53867
- color: '#ff4d4f'
53909
+ color: 'var(--tv-error-color, #ff4d4f)',
53910
+ fontWeight: 700
53868
53911
  }
53869
53912
  }, "\u56FE\u8868\u6E32\u67D3\u5931\u8D25"), /*#__PURE__*/external_react_default().createElement("p", {
53870
53913
  style: {
53871
53914
  margin: '0 0 16px',
53872
- color: '#666',
53873
- textAlign: 'center'
53915
+ color: 'var(--tv-text-color-secondary, #666)',
53916
+ textAlign: 'center',
53917
+ maxWidth: '320px'
53874
53918
  }
53875
53919
  }, "\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
53920
  style: {
53877
53921
  width: '100%',
53878
53922
  padding: '12px',
53879
- backgroundColor: '#f5f5f5',
53880
- borderRadius: '4px',
53881
- fontSize: '12px',
53882
- fontFamily: 'monospace',
53923
+ backgroundColor: 'var(--tv-bg-color-secondary, #f5f5f5)',
53924
+ borderRadius: 'var(--tv-border-radius-small, 4px)',
53925
+ fontSize: 'var(--tv-font-size-small, 12px)',
53926
+ fontFamily: 'var(--tv-font-family, monospace)',
53883
53927
  overflow: 'auto',
53884
53928
  maxHeight: '150px'
53885
53929
  }
53886
53930
  }, /*#__PURE__*/external_react_default().createElement("summary", {
53887
53931
  style: {
53888
53932
  cursor: 'pointer',
53889
- marginBottom: '8px'
53933
+ marginBottom: '8px',
53934
+ fontWeight: 600
53890
53935
  }
53891
53936
  }, "\u9519\u8BEF\u8BE6\u60C5"), /*#__PURE__*/external_react_default().createElement("pre", {
53892
53937
  style: {
@@ -53899,12 +53944,20 @@ var ErrorBoundary = /** @class */function (_super) {
53899
53944
  style: {
53900
53945
  marginTop: '16px',
53901
53946
  padding: '8px 24px',
53902
- backgroundColor: '#1890ff',
53947
+ backgroundColor: 'var(--tv-primary-color, #1890ff)',
53903
53948
  color: '#fff',
53904
53949
  border: 'none',
53905
- borderRadius: '4px',
53950
+ borderRadius: 'var(--tv-border-radius-small, 4px)',
53906
53951
  cursor: 'pointer',
53907
- fontSize: '14px'
53952
+ fontSize: 'var(--tv-font-size, 14px)',
53953
+ fontWeight: 600,
53954
+ transition: 'background-color var(--tv-transition-duration, 0.3s)'
53955
+ },
53956
+ onMouseEnter: function (e) {
53957
+ e.currentTarget.style.backgroundColor = 'var(--tv-primary-color-hover, #40a9ff)';
53958
+ },
53959
+ onMouseLeave: function (e) {
53960
+ e.currentTarget.style.backgroundColor = 'var(--tv-primary-color, #1890ff)';
53908
53961
  }
53909
53962
  }, "\u91CD\u8BD5"));
53910
53963
  }
@@ -54023,12 +54076,16 @@ var LAZY_CHART_MODULES = {
54023
54076
  };
54024
54077
  var LAZY_CHART_TYPES = Object.keys(LAZY_CHART_MODULES);
54025
54078
  /**
54026
- * 默认加载状态组件
54079
+ * 默认加载状态组件(使用 CSS 变量,与 ThemeManager 对齐)
54080
+ * 包含完整的无障碍支持
54027
54081
  */
54028
54082
  var DefaultLoadingFallback = function (_a) {
54029
54083
  var _b = _a.text,
54030
54084
  text = _b === void 0 ? '加载中...' : _b;
54031
54085
  return /*#__PURE__*/external_react_default().createElement("div", {
54086
+ role: "status",
54087
+ "aria-label": text,
54088
+ "aria-busy": "true",
54032
54089
  style: {
54033
54090
  display: 'flex',
54034
54091
  alignItems: 'center',
@@ -54036,8 +54093,8 @@ var DefaultLoadingFallback = function (_a) {
54036
54093
  width: '100%',
54037
54094
  height: '100%',
54038
54095
  minHeight: '200px',
54039
- backgroundColor: '#f5f5f5',
54040
- borderRadius: '8px'
54096
+ backgroundColor: 'var(--tv-bg-color-secondary, #f5f5f5)',
54097
+ borderRadius: 'var(--tv-border-radius, 8px)'
54041
54098
  }
54042
54099
  }, /*#__PURE__*/external_react_default().createElement("div", {
54043
54100
  style: {
@@ -54047,16 +54104,29 @@ var DefaultLoadingFallback = function (_a) {
54047
54104
  style: {
54048
54105
  width: '40px',
54049
54106
  height: '40px',
54050
- border: '3px solid #1890ff',
54107
+ border: '3px solid var(--tv-primary-color, #1890ff)',
54051
54108
  borderTopColor: 'transparent',
54052
54109
  borderRadius: '50%',
54053
54110
  animation: 'taroviz-spin 1s linear infinite',
54054
54111
  margin: '0 auto 12px'
54055
- }
54112
+ },
54113
+ "aria-hidden": "true"
54056
54114
  }), /*#__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
54115
  style: {
54058
- color: '#666',
54059
- fontSize: '14px'
54116
+ position: 'absolute',
54117
+ width: '1px',
54118
+ height: '1px',
54119
+ padding: 0,
54120
+ margin: '-1px',
54121
+ overflow: 'hidden',
54122
+ clip: 'rect(0, 0, 0, 0)',
54123
+ whiteSpace: 'nowrap',
54124
+ border: 0
54125
+ }
54126
+ }, text), /*#__PURE__*/external_react_default().createElement("span", {
54127
+ style: {
54128
+ color: 'var(--tv-text-color-secondary, #666)',
54129
+ fontSize: 'var(--tv-font-size, 14px)'
54060
54130
  }
54061
54131
  }, text)));
54062
54132
  };
@@ -54651,7 +54721,7 @@ var ChartExporter = /** @class */function () {
54651
54721
  _d = options.quality,
54652
54722
  quality = _d === void 0 ? 0.8 : _d;
54653
54723
  var mimeType = "image/".concat(type);
54654
- // 使用 any 避免 ECharts 类型定义与实际支持类型不匹配
54724
+ // 使用类型断言:ECharts 实际支持 webp/gif,但官方类型未声明
54655
54725
  var data = chart.getDataURL({
54656
54726
  type: type,
54657
54727
  pixelRatio: pixelRatio,
@@ -54698,7 +54768,7 @@ var ChartExporter = /** @class */function () {
54698
54768
  */
54699
54769
  ChartExporter.exportPDF = function (chart_1) {
54700
54770
  return ExportUtils_awaiter(this, arguments, Promise, function (chart, options) {
54701
- var _a, orientation, _b, pageSize, _c, title, _d, author, _e, margin, _f, includeTitle, imageData, jsPDF, _g, pageSizes, size, isLandscape, doc, chartWidth, chartHeight, pageWidth, pageHeight, marginTop, marginLeft, chartY, chartX, footerY, pdfBlob;
54771
+ var _a, orientation, _b, pageSize, _c, title, _d, author, _e, margin, _f, includeTitle, imageData, JSPDFClass, module, _g, pageSizes, size, isLandscape, doc, chartWidth, chartHeight, pageWidth, pageHeight, marginTop, marginLeft, chartY, chartX, footerY, pdfBlob;
54702
54772
  var _h;
54703
54773
  if (options === void 0) {
54704
54774
  options = {};
@@ -54722,9 +54792,8 @@ var ChartExporter = /** @class */function () {
54722
54792
  _j.trys.push([1, 3,, 4]);
54723
54793
  return [4 /*yield*/, import(/* webpackIgnore: true */'jspdf')];
54724
54794
  case 2:
54725
- // 尝试使用动态导入,使用 webpackIgnore 注释避免预解析
54726
- // @ts-expect-error - 动态导入
54727
- jsPDF = _j.sent().default;
54795
+ module = _j.sent();
54796
+ JSPDFClass = module.default;
54728
54797
  return [3 /*break*/, 4];
54729
54798
  case 3:
54730
54799
  _g = _j.sent();
@@ -54756,7 +54825,7 @@ var ChartExporter = /** @class */function () {
54756
54825
  };
54757
54826
  size = pageSizes[pageSize];
54758
54827
  isLandscape = orientation === 'landscape';
54759
- doc = new jsPDF({
54828
+ doc = new JSPDFClass({
54760
54829
  orientation: orientation,
54761
54830
  unit: 'mm',
54762
54831
  format: pageSize
@@ -55408,8 +55477,12 @@ function useChartConnect(options) {
55408
55477
  // 导出
55409
55478
  // ============================================================================
55410
55479
  /* harmony default export */ const hooks_useChartConnect = ((/* unused pure expression or super */ null && (useChartConnect)));
55411
- ;// ./src/hooks/useChartDownload.ts
55412
- var useChartDownload_awaiter = undefined && undefined.__awaiter || function (thisArg, _arguments, P, generator) {
55480
+ ;// ./src/hooks/utils/chartDownloadUtils.ts
55481
+ /**
55482
+ * Chart Download Utilities
55483
+ * 图表下载工具函数
55484
+ */
55485
+ var chartDownloadUtils_awaiter = undefined && undefined.__awaiter || function (thisArg, _arguments, P, generator) {
55413
55486
  function adopt(value) {
55414
55487
  return value instanceof P ? value : new P(function (resolve) {
55415
55488
  resolve(value);
@@ -55436,7 +55509,7 @@ var useChartDownload_awaiter = undefined && undefined.__awaiter || function (thi
55436
55509
  step((generator = generator.apply(thisArg, _arguments || [])).next());
55437
55510
  });
55438
55511
  };
55439
- var useChartDownload_generator = undefined && undefined.__generator || function (thisArg, body) {
55512
+ var chartDownloadUtils_generator = undefined && undefined.__generator || function (thisArg, body) {
55440
55513
  var _ = {
55441
55514
  label: 0,
55442
55515
  sent: function () {
@@ -55520,7 +55593,7 @@ var useChartDownload_generator = undefined && undefined.__generator || function
55520
55593
  };
55521
55594
  }
55522
55595
  };
55523
- var useChartDownload_spreadArray = undefined && undefined.__spreadArray || function (to, from, pack) {
55596
+ var chartDownloadUtils_spreadArray = undefined && undefined.__spreadArray || function (to, from, pack) {
55524
55597
  if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
55525
55598
  if (ar || !(i in from)) {
55526
55599
  if (!ar) ar = Array.prototype.slice.call(from, 0, i);
@@ -55529,18 +55602,10 @@ var useChartDownload_spreadArray = undefined && undefined.__spreadArray || funct
55529
55602
  }
55530
55603
  return to.concat(ar || Array.prototype.slice.call(from));
55531
55604
  };
55532
- /**
55533
- * useChartDownload - 图表下载 Hook
55534
- * 支持下载图表为图片(PNG/JPEG/SVG/PDF)或原始数据(CSV/JSON)
55535
- */
55536
-
55537
- // ============================================================================
55538
- // 工具函数
55539
- // ============================================================================
55540
55605
  /**
55541
55606
  * 生成默认文件名
55542
55607
  */
55543
- function useChartDownload_generateFilename(prefix) {
55608
+ function chartDownloadUtils_generateFilename(prefix) {
55544
55609
  if (prefix === void 0) {
55545
55610
  prefix = 'chart';
55546
55611
  }
@@ -55574,7 +55639,7 @@ function downloadDataUrl(dataUrl, filename) {
55574
55639
  /**
55575
55640
  * CSV 转 Blob
55576
55641
  */
55577
- function csvToBlob(csv, filename) {
55642
+ function csvToBlob(csv, _filename) {
55578
55643
  return new Blob([csv], {
55579
55644
  type: 'text/csv;charset=utf-8;'
55580
55645
  });
@@ -55582,7 +55647,7 @@ function csvToBlob(csv, filename) {
55582
55647
  /**
55583
55648
  * JSON 转 Blob
55584
55649
  */
55585
- function jsonToBlob(json, filename) {
55650
+ function jsonToBlob(json, _filename) {
55586
55651
  return new Blob([json], {
55587
55652
  type: 'application/json;charset=utf-8;'
55588
55653
  });
@@ -55593,7 +55658,7 @@ function jsonToBlob(json, filename) {
55593
55658
  function convertToCSV(data, options) {
55594
55659
  if (!data) return '';
55595
55660
  // 处理 ECharts 格式的数据
55596
- if (data.series) {
55661
+ if (typeof data === 'object' && data.series) {
55597
55662
  return convertSeriesToCSV(data, options);
55598
55663
  }
55599
55664
  // 处理数组数据
@@ -55616,30 +55681,32 @@ function convertSeriesToCSV(chartData, options) {
55616
55681
  xAxis = chartData.xAxis,
55617
55682
  dataset = chartData.dataset;
55618
55683
  var includeLabels = (_a = options === null || options === void 0 ? void 0 : options.includeLabels) !== null && _a !== void 0 ? _a : true;
55619
- if (series.length === 0) return '';
55684
+ if (!Array.isArray(series) || series.length === 0) return '';
55620
55685
  // 获取类别轴数据
55621
55686
  var categories = [];
55622
- if (xAxis === null || xAxis === void 0 ? void 0 : xAxis.data) {
55687
+ if ((xAxis === null || xAxis === void 0 ? void 0 : xAxis.data) && Array.isArray(xAxis.data)) {
55623
55688
  categories = xAxis.data;
55624
- } else if ((dataset === null || dataset === void 0 ? void 0 : dataset.dimensions) && dataset.source) {
55689
+ } else if ((dataset === null || dataset === void 0 ? void 0 : dataset.dimensions) && (dataset === null || dataset === void 0 ? void 0 : dataset.source)) {
55625
55690
  categories = dataset.source.map(function (row) {
55626
55691
  return row[0];
55627
55692
  });
55628
55693
  } else if ((_b = series[0]) === null || _b === void 0 ? void 0 : _b.data) {
55629
- categories = series[0].data.map(function (item, index) {
55630
- return typeof item === 'object' ? item[0] || index : index;
55694
+ var firstSeries = series[0];
55695
+ categories = firstSeries.data.map(function (item, index) {
55696
+ return typeof item === 'object' && item !== null ? item[0] || index : index;
55631
55697
  });
55632
55698
  }
55633
55699
  // 构建 CSV 头
55634
- var headers = includeLabels ? useChartDownload_spreadArray(['Category'], series.map(function (s) {
55700
+ var headers = includeLabels ? chartDownloadUtils_spreadArray(['Category'], series.map(function (s) {
55635
55701
  return s.name || s.seriesIndex;
55636
55702
  }), true) : [];
55637
55703
  // 构建 CSV 行
55638
55704
  var rows = [];
55639
55705
  series.forEach(function (s, seriesIndex) {
55640
- var seriesData = s.data || [];
55706
+ var seriesObj = s;
55707
+ var seriesData = seriesObj.data || [];
55641
55708
  seriesData.forEach(function (item, dataIndex) {
55642
- var value = typeof item === 'object' ? item[1] : item;
55709
+ var value = typeof item === 'object' && item !== null ? item[1] : item;
55643
55710
  var category = categories[dataIndex] || dataIndex;
55644
55711
  if (includeLabels) {
55645
55712
  if (seriesIndex === 0) {
@@ -55659,7 +55726,7 @@ function convertSeriesToCSV(chartData, options) {
55659
55726
  });
55660
55727
  });
55661
55728
  // 生成 CSV 字符串
55662
- var csvRows = includeLabels ? useChartDownload_spreadArray([headers.join(',')], rows.map(function (row) {
55729
+ var csvRows = includeLabels ? chartDownloadUtils_spreadArray([headers.join(',')], rows.map(function (row) {
55663
55730
  return row.join(',');
55664
55731
  }), true) : rows.map(function (row) {
55665
55732
  return row.join(',');
@@ -55681,7 +55748,7 @@ function convertArrayToCSV(data) {
55681
55748
  return JSON.stringify((_a = item[key]) !== null && _a !== void 0 ? _a : '');
55682
55749
  }).join(',');
55683
55750
  });
55684
- return useChartDownload_spreadArray([headers], rows, true).join('\n');
55751
+ return chartDownloadUtils_spreadArray([headers], rows, true).join('\n');
55685
55752
  }
55686
55753
  // 简单数组
55687
55754
  return data.join('\n');
@@ -55703,19 +55770,21 @@ function convertObjectToCSV(data) {
55703
55770
  function convertToJSON(data) {
55704
55771
  var _a, _b, _c;
55705
55772
  if (!data) return '{}';
55773
+ var dataObj = data;
55706
55774
  // 如果是 ECharts 格式,简化数据
55707
- if (data.series) {
55775
+ if (dataObj.series) {
55708
55776
  var simplified = {
55709
- title: (_a = data.title) === null || _a === void 0 ? void 0 : _a.text,
55710
- legend: (_b = data.legend) === null || _b === void 0 ? void 0 : _b.data,
55711
- xAxis: (_c = data.xAxis) === null || _c === void 0 ? void 0 : _c.data,
55712
- series: data.series.map(function (s) {
55777
+ title: (_a = dataObj.title) === null || _a === void 0 ? void 0 : _a.text,
55778
+ legend: (_b = dataObj.legend) === null || _b === void 0 ? void 0 : _b.data,
55779
+ xAxis: (_c = dataObj.xAxis) === null || _c === void 0 ? void 0 : _c.data,
55780
+ series: dataObj.series.map(function (s) {
55713
55781
  var _a;
55782
+ var seriesObj = s;
55714
55783
  return {
55715
- name: s.name,
55716
- type: s.type,
55717
- data: (_a = s.data) === null || _a === void 0 ? void 0 : _a.map(function (item) {
55718
- return typeof item === 'object' ? item[1] : item;
55784
+ name: seriesObj.name,
55785
+ type: seriesObj.type,
55786
+ data: (_a = seriesObj.data) === null || _a === void 0 ? void 0 : _a.map(function (item) {
55787
+ return typeof item === 'object' && item !== null ? item[1] : item;
55719
55788
  })
55720
55789
  };
55721
55790
  })
@@ -55724,6 +55793,185 @@ function convertToJSON(data) {
55724
55793
  }
55725
55794
  return JSON.stringify(data, null, 2);
55726
55795
  }
55796
+ /**
55797
+ * 从图片创建 PDF DataURL
55798
+ */
55799
+ function createPdfFromImage(imageDataUrl, title) {
55800
+ return chartDownloadUtils_awaiter(this, void 0, Promise, function () {
55801
+ return chartDownloadUtils_generator(this, function (_a) {
55802
+ return [2 /*return*/, new Promise(function (resolve) {
55803
+ try {
55804
+ // 创建画布
55805
+ var canvas_1 = document.createElement('canvas');
55806
+ var ctx_1 = canvas_1.getContext('2d');
55807
+ if (!ctx_1) {
55808
+ resolve(null);
55809
+ return;
55810
+ }
55811
+ // 加载图片
55812
+ var img_1 = new Image();
55813
+ img_1.onload = function () {
55814
+ // 设置 PDF 尺寸(A4 纵向)
55815
+ var pdfWidth = 595.28; // A4 width in points
55816
+ var pdfHeight = 841.89; // A4 height in points
55817
+ canvas_1.width = pdfWidth;
55818
+ canvas_1.height = pdfHeight;
55819
+ // 填充背景
55820
+ ctx_1.fillStyle = '#ffffff';
55821
+ ctx_1.fillRect(0, 0, pdfWidth, pdfHeight);
55822
+ // 计算图片位置和尺寸(居中)
55823
+ var imgRatio = img_1.width / img_1.height;
55824
+ var canvasRatio = pdfWidth / pdfHeight;
55825
+ var drawWidth, drawHeight, offsetX, offsetY;
55826
+ if (imgRatio > canvasRatio) {
55827
+ drawWidth = pdfWidth * 0.8;
55828
+ drawHeight = drawWidth / imgRatio;
55829
+ } else {
55830
+ drawHeight = pdfHeight * 0.6;
55831
+ drawWidth = drawHeight * imgRatio;
55832
+ }
55833
+ offsetX = (pdfWidth - drawWidth) / 2;
55834
+ offsetY = (pdfHeight - drawHeight) / 2;
55835
+ // 绘制图片
55836
+ ctx_1.drawImage(img_1, offsetX, offsetY, drawWidth, drawHeight);
55837
+ // 添加标题
55838
+ ctx_1.fillStyle = '#333333';
55839
+ ctx_1.font = '16px Arial';
55840
+ ctx_1.textAlign = 'center';
55841
+ ctx_1.fillText(title || 'Chart Export', pdfWidth / 2, offsetY - 20);
55842
+ // 输出为 PNG(实际应用中应该使用 jsPDF 生成真正的 PDF)
55843
+ resolve(canvas_1.toDataURL('image/png'));
55844
+ };
55845
+ img_1.onerror = function () {
55846
+ resolve(null);
55847
+ };
55848
+ img_1.src = imageDataUrl;
55849
+ } catch (e) {
55850
+ console.warn('[chartDownloadUtils] Failed to create PDF:', e);
55851
+ resolve(null);
55852
+ }
55853
+ })];
55854
+ });
55855
+ });
55856
+ }
55857
+ ;// ./src/hooks/useChartDownload.ts
55858
+ var useChartDownload_awaiter = undefined && undefined.__awaiter || function (thisArg, _arguments, P, generator) {
55859
+ function adopt(value) {
55860
+ return value instanceof P ? value : new P(function (resolve) {
55861
+ resolve(value);
55862
+ });
55863
+ }
55864
+ return new (P || (P = Promise))(function (resolve, reject) {
55865
+ function fulfilled(value) {
55866
+ try {
55867
+ step(generator.next(value));
55868
+ } catch (e) {
55869
+ reject(e);
55870
+ }
55871
+ }
55872
+ function rejected(value) {
55873
+ try {
55874
+ step(generator["throw"](value));
55875
+ } catch (e) {
55876
+ reject(e);
55877
+ }
55878
+ }
55879
+ function step(result) {
55880
+ result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
55881
+ }
55882
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
55883
+ });
55884
+ };
55885
+ var useChartDownload_generator = undefined && undefined.__generator || function (thisArg, body) {
55886
+ var _ = {
55887
+ label: 0,
55888
+ sent: function () {
55889
+ if (t[0] & 1) throw t[1];
55890
+ return t[1];
55891
+ },
55892
+ trys: [],
55893
+ ops: []
55894
+ },
55895
+ f,
55896
+ y,
55897
+ t,
55898
+ g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
55899
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function () {
55900
+ return this;
55901
+ }), g;
55902
+ function verb(n) {
55903
+ return function (v) {
55904
+ return step([n, v]);
55905
+ };
55906
+ }
55907
+ function step(op) {
55908
+ if (f) throw new TypeError("Generator is already executing.");
55909
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
55910
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
55911
+ if (y = 0, t) op = [op[0] & 2, t.value];
55912
+ switch (op[0]) {
55913
+ case 0:
55914
+ case 1:
55915
+ t = op;
55916
+ break;
55917
+ case 4:
55918
+ _.label++;
55919
+ return {
55920
+ value: op[1],
55921
+ done: false
55922
+ };
55923
+ case 5:
55924
+ _.label++;
55925
+ y = op[1];
55926
+ op = [0];
55927
+ continue;
55928
+ case 7:
55929
+ op = _.ops.pop();
55930
+ _.trys.pop();
55931
+ continue;
55932
+ default:
55933
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
55934
+ _ = 0;
55935
+ continue;
55936
+ }
55937
+ if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
55938
+ _.label = op[1];
55939
+ break;
55940
+ }
55941
+ if (op[0] === 6 && _.label < t[1]) {
55942
+ _.label = t[1];
55943
+ t = op;
55944
+ break;
55945
+ }
55946
+ if (t && _.label < t[2]) {
55947
+ _.label = t[2];
55948
+ _.ops.push(op);
55949
+ break;
55950
+ }
55951
+ if (t[2]) _.ops.pop();
55952
+ _.trys.pop();
55953
+ continue;
55954
+ }
55955
+ op = body.call(thisArg, _);
55956
+ } catch (e) {
55957
+ op = [6, e];
55958
+ y = 0;
55959
+ } finally {
55960
+ f = t = 0;
55961
+ }
55962
+ if (op[0] & 5) throw op[1];
55963
+ return {
55964
+ value: op[0] ? op[1] : void 0,
55965
+ done: true
55966
+ };
55967
+ }
55968
+ };
55969
+ /**
55970
+ * useChartDownload - 图表下载 Hook
55971
+ * 支持下载图表为图片(PNG/JPEG/SVG/PDF)或原始数据(CSV/JSON)
55972
+ */
55973
+
55974
+
55727
55975
  // ============================================================================
55728
55976
  // Hook 实现
55729
55977
  // ============================================================================
@@ -55827,7 +56075,7 @@ function useChartDownload(instance, options) {
55827
56075
  fmt = customFormat || format;
55828
56076
  ratio = customPixelRatio !== null && customPixelRatio !== void 0 ? customPixelRatio : pixelRatio;
55829
56077
  bg = customBg !== null && customBg !== void 0 ? customBg : backgroundColor;
55830
- name = customFilename || filename || useChartDownload_generateFilename('chart');
56078
+ name = customFilename || filename || chartDownloadUtils_generateFilename('chart');
55831
56079
  try {
55832
56080
  dataUrl = void 0;
55833
56081
  if (fmt === 'svg') {
@@ -55875,7 +56123,7 @@ function useChartDownload(instance, options) {
55875
56123
  _a = downloadOptions || {}, customFilename = _a.filename, customPixelRatio = _a.pixelRatio, customBg = _a.backgroundColor;
55876
56124
  ratio = customPixelRatio !== null && customPixelRatio !== void 0 ? customPixelRatio : pixelRatio;
55877
56125
  bg = customBg !== null && customBg !== void 0 ? customBg : backgroundColor;
55878
- name = customFilename || filename || useChartDownload_generateFilename('chart');
56126
+ name = customFilename || filename || chartDownloadUtils_generateFilename('chart');
55879
56127
  _c.label = 1;
55880
56128
  case 1:
55881
56129
  _c.trys.push([1, 3,, 4]);
@@ -55888,7 +56136,7 @@ function useChartDownload(instance, options) {
55888
56136
  console.warn('[useChartDownload] Failed to get image data for PDF');
55889
56137
  return [2 /*return*/];
55890
56138
  }
55891
- return [4 /*yield*/, createPdfFromImage(dataUrl)];
56139
+ return [4 /*yield*/, createPdfFromImage(dataUrl, name)];
55892
56140
  case 2:
55893
56141
  pdfDataUrl = _c.sent();
55894
56142
  if (pdfDataUrl) {
@@ -55906,67 +56154,6 @@ function useChartDownload(instance, options) {
55906
56154
  });
55907
56155
  });
55908
56156
  }, [filename, pixelRatio, backgroundColor, executeBeforeExport, executeAfterExport]);
55909
- /**
55910
- * 从图片创建 PDF DataURL
55911
- */
55912
- var createPdfFromImage = function (imageDataUrl) {
55913
- return useChartDownload_awaiter(_this, void 0, Promise, function () {
55914
- return useChartDownload_generator(this, function (_a) {
55915
- return [2 /*return*/, new Promise(function (resolve) {
55916
- try {
55917
- // 创建画布
55918
- var canvas_1 = document.createElement('canvas');
55919
- var ctx_1 = canvas_1.getContext('2d');
55920
- if (!ctx_1) {
55921
- resolve(null);
55922
- return;
55923
- }
55924
- // 加载图片
55925
- var img_1 = new Image();
55926
- img_1.onload = function () {
55927
- // 设置 PDF 尺寸(A4 纵向)
55928
- var pdfWidth = 595.28; // A4 width in points
55929
- var pdfHeight = 841.89; // A4 height in points
55930
- canvas_1.width = pdfWidth;
55931
- canvas_1.height = pdfHeight;
55932
- // 填充背景
55933
- ctx_1.fillStyle = '#ffffff';
55934
- ctx_1.fillRect(0, 0, pdfWidth, pdfHeight);
55935
- // 计算图片位置和尺寸(居中)
55936
- var imgRatio = img_1.width / img_1.height;
55937
- var canvasRatio = pdfWidth / pdfHeight;
55938
- var drawWidth, drawHeight, offsetX, offsetY;
55939
- if (imgRatio > canvasRatio) {
55940
- drawWidth = pdfWidth * 0.8;
55941
- drawHeight = drawWidth / imgRatio;
55942
- } else {
55943
- drawHeight = pdfHeight * 0.6;
55944
- drawWidth = drawHeight * imgRatio;
55945
- }
55946
- offsetX = (pdfWidth - drawWidth) / 2;
55947
- offsetY = (pdfHeight - drawHeight) / 2;
55948
- // 绘制图片
55949
- ctx_1.drawImage(img_1, offsetX, offsetY, drawWidth, drawHeight);
55950
- // 添加标题
55951
- ctx_1.fillStyle = '#333333';
55952
- ctx_1.font = '16px Arial';
55953
- ctx_1.textAlign = 'center';
55954
- ctx_1.fillText(filename || 'Chart Export', pdfWidth / 2, offsetY - 20);
55955
- // 输出为 PNG(实际应用中应该使用 jsPDF 生成真正的 PDF)
55956
- resolve(canvas_1.toDataURL('image/png'));
55957
- };
55958
- img_1.onerror = function () {
55959
- resolve(null);
55960
- };
55961
- img_1.src = imageDataUrl;
55962
- } catch (e) {
55963
- console.warn('[useChartDownload] Failed to create PDF:', e);
55964
- resolve(null);
55965
- }
55966
- })];
55967
- });
55968
- });
55969
- };
55970
56157
  /**
55971
56158
  * 获取图表数据
55972
56159
  */
@@ -56010,7 +56197,7 @@ function useChartDownload(instance, options) {
56010
56197
  return [2 /*return*/];
56011
56198
  }
56012
56199
  _a = downloadOptions || {}, customFilename = _a.filename, dataKey = _a.dataKey;
56013
- name = customFilename || filename || useChartDownload_generateFilename('data');
56200
+ name = customFilename || filename || chartDownloadUtils_generateFilename('data');
56014
56201
  try {
56015
56202
  option = (_b = chart.getOption) === null || _b === void 0 ? void 0 : _b.call(chart);
56016
56203
  if (!option) {
@@ -56051,7 +56238,7 @@ function useChartDownload(instance, options) {
56051
56238
  return [2 /*return*/];
56052
56239
  }
56053
56240
  _a = downloadOptions || {}, customFilename = _a.filename, dataKey = _a.dataKey;
56054
- name = customFilename || filename || useChartDownload_generateFilename('data');
56241
+ name = customFilename || filename || chartDownloadUtils_generateFilename('data');
56055
56242
  try {
56056
56243
  option = (_b = chart.getOption) === null || _b === void 0 ? void 0 : _b.call(chart);
56057
56244
  if (!option) {
@@ -56149,18 +56336,503 @@ function useChartDownload(instance, options) {
56149
56336
  // 导出
56150
56337
  // ============================================================================
56151
56338
  /* harmony default export */ const hooks_useChartDownload = ((/* unused pure expression or super */ null && (useChartDownload)));
56152
- ;// ./src/hooks/useDataTransform.ts
56153
- var useDataTransform_assign = undefined && undefined.__assign || function () {
56154
- useDataTransform_assign = Object.assign || function (t) {
56339
+ ;// ./src/hooks/useChartHistory.ts
56340
+ var useChartHistory_spreadArray = undefined && undefined.__spreadArray || function (to, from, pack) {
56341
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
56342
+ if (ar || !(i in from)) {
56343
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
56344
+ ar[i] = from[i];
56345
+ }
56346
+ }
56347
+ return to.concat(ar || Array.prototype.slice.call(from));
56348
+ };
56349
+ /**
56350
+ * useChartHistory - 图表 Undo/Redo Hook
56351
+ * 追踪图表配置历史,支持撤销/重做操作和键盘快捷键
56352
+ *
56353
+ * 特性:
56354
+ * - 最多保存 50 条历史记录(可配置)
56355
+ * - 自动绑定 Ctrl+Z / Ctrl+Y 键盘快捷键
56356
+ * - 支持 ignoreKeys 忽略特定配置字段(如动画、时间戳)
56357
+ * - 暴露 canUndo / canRedo 状态
56358
+ */
56359
+
56360
+ // ============================================================================
56361
+ // 工具函数
56362
+ // ============================================================================
56363
+ /** 深度省略指定键后比较两个配置是否相等 */
56364
+ function omitAndCompare(a, b, ignoreKeys) {
56365
+ if (a === b) return true;
56366
+ if (typeof a !== 'object' || a === null || typeof b !== 'object' || b === null) {
56367
+ return a === b;
56368
+ }
56369
+ var aObj = a;
56370
+ var bObj = b;
56371
+ var aKeys = Object.keys(aObj).filter(function (k) {
56372
+ return !ignoreKeys.has(k);
56373
+ });
56374
+ var bKeys = Object.keys(bObj).filter(function (k) {
56375
+ return !ignoreKeys.has(k);
56376
+ });
56377
+ if (aKeys.length !== bKeys.length) return false;
56378
+ for (var _i = 0, aKeys_1 = aKeys; _i < aKeys_1.length; _i++) {
56379
+ var key = aKeys_1[_i];
56380
+ if (!bObj.hasOwnProperty(key)) return false;
56381
+ if (!omitAndCompare(aObj[key], bObj[key], ignoreKeys)) return false;
56382
+ }
56383
+ return true;
56384
+ }
56385
+ // ============================================================================
56386
+ // Hook 实现
56387
+ // ============================================================================
56388
+ /**
56389
+ * 使用图表历史记录(Undo/Redo)
56390
+ * @param chartInstance 图表实例
56391
+ * @param options 配置选项
56392
+ * @returns 历史记录控制接口
56393
+ */
56394
+ function useChartHistory(chartInstance, options) {
56395
+ if (options === void 0) {
56396
+ options = {};
56397
+ }
56398
+ var _a = options.maxHistorySize,
56399
+ maxHistorySize = _a === void 0 ? 50 : _a,
56400
+ _b = options.ignoreKeys,
56401
+ ignoreKeys = _b === void 0 ? ['animation', 'animationDuration', 'animationEasing', 'animationFrame'] : _b,
56402
+ _c = options.enableKeyboard,
56403
+ enableKeyboard = _c === void 0 ? true : _c,
56404
+ _d = options.clearOnUnmount,
56405
+ clearOnUnmount = _d === void 0 ? false : _d;
56406
+ // 忽略键集合
56407
+ var ignoreKeySet = (0,external_react_.useRef)(new Set(ignoreKeys));
56408
+ // 历史栈(每次 setOption 快照)
56409
+ var historyStack = (0,external_react_.useRef)([]);
56410
+ // 当前索引
56411
+ var _e = (0,external_react_.useState)(-1),
56412
+ currentIndex = _e[0],
56413
+ setCurrentIndex = _e[1];
56414
+ // Chart instance ref
56415
+ var chartRef = (0,external_react_.useRef)(null);
56416
+ chartRef.current = chartInstance;
56417
+ // 是否正在执行 undo/redo(避免 push 时重复记录)
56418
+ var isApplyingRef = (0,external_react_.useRef)(false);
56419
+ // 拦截 chart.setOption,记录历史
56420
+ (0,external_react_.useEffect)(function () {
56421
+ var chart = chartRef.current;
56422
+ if (!chart) return;
56423
+ var originalSetOption = chart.setOption.bind(chart);
56424
+ chart.setOption = function (option, notMerge, lazyUpdate) {
56425
+ // 如果正在执行 undo/redo,跳过历史记录
56426
+ if (isApplyingRef.current) {
56427
+ return originalSetOption(option, notMerge, lazyUpdate);
56428
+ }
56429
+ var stack = historyStack.current;
56430
+ var idx = currentIndex;
56431
+ // 如果当前索引不在栈顶,丢弃redo历史(类似 Git 行为)
56432
+ var newStack = idx < stack.length - 1 ? stack.slice(0, idx + 1) : useChartHistory_spreadArray([], stack, true);
56433
+ // 检查是否与上一次配置相同(忽略动画字段)
56434
+ var lastOption = newStack[newStack.length - 1];
56435
+ if (lastOption && omitAndCompare(lastOption, option, ignoreKeySet.current)) {
56436
+ // 配置没变,直接应用
56437
+ return originalSetOption(option, notMerge, lazyUpdate);
56438
+ }
56439
+ // 入栈
56440
+ newStack.push(option);
56441
+ // 裁剪超出 maxHistorySize
56442
+ if (newStack.length > maxHistorySize) {
56443
+ newStack.shift();
56444
+ } else {
56445
+ // 更新索引
56446
+ setCurrentIndex(newStack.length - 1);
56447
+ }
56448
+ historyStack.current = newStack;
56449
+ return originalSetOption(option, notMerge, lazyUpdate);
56450
+ };
56451
+ return function () {
56452
+ // 恢复原始 setOption
56453
+ chart.setOption = originalSetOption;
56454
+ };
56455
+ }, [chartInstance, currentIndex, maxHistorySize]);
56456
+ // 键盘快捷键:Ctrl+Z 撤销,Ctrl+Y / Ctrl+Shift+Z 重做
56457
+ (0,external_react_.useEffect)(function () {
56458
+ if (!enableKeyboard) return;
56459
+ var handleKeyDown = function (e) {
56460
+ var isMod = e.ctrlKey || e.metaKey;
56461
+ if (!isMod) return;
56462
+ if (e.key === 'z' && !e.shiftKey) {
56463
+ e.preventDefault();
56464
+ undo();
56465
+ } else if (e.key === 'y' || e.key === 'z' && e.shiftKey) {
56466
+ e.preventDefault();
56467
+ redo();
56468
+ }
56469
+ };
56470
+ window.addEventListener('keydown', handleKeyDown);
56471
+ return function () {
56472
+ return window.removeEventListener('keydown', handleKeyDown);
56473
+ };
56474
+ }, [enableKeyboard]); // eslint-disable-line react-hooks/exhaustive-deps
56475
+ // 组件卸载时清空
56476
+ (0,external_react_.useEffect)(function () {
56477
+ return function () {
56478
+ if (clearOnUnmount) {
56479
+ historyStack.current = [];
56480
+ setCurrentIndex(-1);
56481
+ }
56482
+ };
56483
+ }, [clearOnUnmount]);
56484
+ // ─── Public API ───────────────────────────────────────────────────────────
56485
+ var undo = (0,external_react_.useCallback)(function () {
56486
+ var chart = chartRef.current;
56487
+ if (!chart || currentIndex <= 0) return;
56488
+ var idx = currentIndex - 1;
56489
+ isApplyingRef.current = true;
56490
+ chart.setOption(historyStack.current[idx], true, true);
56491
+ isApplyingRef.current = false;
56492
+ setCurrentIndex(idx);
56493
+ }, [currentIndex]);
56494
+ var redo = (0,external_react_.useCallback)(function () {
56495
+ var chart = chartRef.current;
56496
+ if (!chart || currentIndex >= historyStack.current.length - 1) return;
56497
+ var idx = currentIndex + 1;
56498
+ isApplyingRef.current = true;
56499
+ chart.setOption(historyStack.current[idx], true, true);
56500
+ isApplyingRef.current = false;
56501
+ setCurrentIndex(idx);
56502
+ }, [currentIndex]);
56503
+ var goTo = (0,external_react_.useCallback)(function (index) {
56504
+ var chart = chartRef.current;
56505
+ if (!chart) return;
56506
+ if (index < 0 || index >= historyStack.current.length) return;
56507
+ if (index === currentIndex) return;
56508
+ isApplyingRef.current = true;
56509
+ chart.setOption(historyStack.current[index], true, true);
56510
+ isApplyingRef.current = false;
56511
+ setCurrentIndex(index);
56512
+ }, [currentIndex]);
56513
+ var push = (0,external_react_.useCallback)(function (option) {
56514
+ var stack = historyStack.current;
56515
+ var idx = currentIndex;
56516
+ var newStack = idx < stack.length - 1 ? stack.slice(0, idx + 1) : useChartHistory_spreadArray([], stack, true);
56517
+ newStack.push(option);
56518
+ if (newStack.length > maxHistorySize) newStack.shift();
56519
+ historyStack.current = newStack;
56520
+ setCurrentIndex(newStack.length - 1);
56521
+ }, [currentIndex, maxHistorySize]);
56522
+ var clear = (0,external_react_.useCallback)(function () {
56523
+ historyStack.current = [];
56524
+ setCurrentIndex(-1);
56525
+ }, []);
56526
+ return {
56527
+ canUndo: currentIndex > 0,
56528
+ canRedo: currentIndex < historyStack.current.length - 1,
56529
+ currentIndex: currentIndex,
56530
+ historyCount: historyStack.current.length,
56531
+ undo: undo,
56532
+ redo: redo,
56533
+ goTo: goTo,
56534
+ push: push,
56535
+ clear: clear
56536
+ };
56537
+ }
56538
+ /* harmony default export */ const hooks_useChartHistory = ((/* unused pure expression or super */ null && (useChartHistory)));
56539
+ ;// ./src/hooks/useChartSelection.ts
56540
+ var useChartSelection_spreadArray = undefined && undefined.__spreadArray || function (to, from, pack) {
56541
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
56542
+ if (ar || !(i in from)) {
56543
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
56544
+ ar[i] = from[i];
56545
+ }
56546
+ }
56547
+ return to.concat(ar || Array.prototype.slice.call(from));
56548
+ };
56549
+ /**
56550
+ * useChartSelection - 图表数据点选择/高亮 Hook
56551
+ * 支持单个/批量选择、反选、清除选择,配合 ECharts select 事件
56552
+ *
56553
+ * 特性:
56554
+ * - 支持按 seriesIndex + dataIndex 选择
56555
+ * - 支持按 dataIndex 跨系列批量选择
56556
+ * - 支持反选(invertSelection)
56557
+ * - 支持多选模式(multi)
56558
+ * - 自动绑定图表 select/unselect 事件
56559
+ */
56560
+
56561
+ // ============================================================================
56562
+ // 工具函数
56563
+ // ============================================================================
56564
+ /** 生成唯一键字符串 */
56565
+ function keyToString(key) {
56566
+ return "".concat(key.seriesIndex, ":").concat(key.dataIndex);
56567
+ }
56568
+ function stringToKey(str) {
56569
+ var _a = str.split(':').map(Number),
56570
+ seriesIndex = _a[0],
56571
+ dataIndex = _a[1];
56572
+ return {
56573
+ seriesIndex: seriesIndex,
56574
+ dataIndex: dataIndex
56575
+ };
56576
+ }
56577
+ // ============================================================================
56578
+ // Hook 实现
56579
+ // ============================================================================
56580
+ /**
56581
+ * 使用图表数据点选择功能
56582
+ * @param chartInstance 图表实例
56583
+ * @param options 配置选项
56584
+ * @returns 选择控制接口
56585
+ */
56586
+ function useChartSelection(chartInstance, options) {
56587
+ if (options === void 0) {
56588
+ options = {};
56589
+ }
56590
+ var _a = options.mode,
56591
+ mode = _a === void 0 ? 'multiple' : _a,
56592
+ _b = options.clearOnUnmount,
56593
+ clearOnUnmount = _b === void 0 ? true : _b,
56594
+ _c = options.enableCtrlMultiSelect,
56595
+ enableCtrlMultiSelect = _c === void 0 ? true : _c,
56596
+ _d = options.enableShiftRangeSelect,
56597
+ enableShiftRangeSelect = _d === void 0 ? true : _d,
56598
+ onSelectionChange = options.onSelectionChange;
56599
+ // 选中点集合(字符串键)
56600
+ var _e = (0,external_react_.useState)([]),
56601
+ selectedPoints = _e[0],
56602
+ setSelectedPoints = _e[1];
56603
+ // Chart instance ref
56604
+ var chartRef = (0,external_react_.useRef)(null);
56605
+ chartRef.current = chartInstance;
56606
+ // 上一次 shift+click 的数据索引(用于范围选择)
56607
+ var lastShiftIndexRef = (0,external_react_.useRef)(null);
56608
+ // 当前模式 ref(用于事件处理)
56609
+ var modeRef = (0,external_react_.useRef)(mode);
56610
+ modeRef.current = mode;
56611
+ // 绑定图表 select/unselect 事件
56612
+ (0,external_react_.useEffect)(function () {
56613
+ var chart = chartRef.current;
56614
+ if (!chart || !chart.on) return;
56615
+ var handleSelect = function (params) {
56616
+ // ECharts 内置 select 会同步更新 legend
56617
+ // 这里我们用 dispatchAction 来实现纯数据点选择
56618
+ };
56619
+ // 单击 legend 时清除数据点选择(保持一致性)
56620
+ var handleLegendSelectChanged = function (params) {
56621
+ // 清除选择时的视觉反馈
56622
+ };
56623
+ chart.on('selectchanged', function (params) {
56624
+ // 当图表内部选择变化时同步状态
56625
+ var p = params;
56626
+ if (p.isFromClick) {
56627
+ // 用户点击了图例,清除所有数据点选择
56628
+ setSelectedPoints([]);
56629
+ onSelectionChange === null || onSelectionChange === void 0 ? void 0 : onSelectionChange({
56630
+ selected: [],
56631
+ unselected: []
56632
+ });
56633
+ }
56634
+ });
56635
+ return function () {
56636
+ if (chart.off) {
56637
+ chart.off('selectchanged');
56638
+ }
56639
+ };
56640
+ }, [onSelectionChange]);
56641
+ // 组件卸载时清除选择
56642
+ (0,external_react_.useEffect)(function () {
56643
+ return function () {
56644
+ if (clearOnUnmount) {
56645
+ var chart = chartRef.current;
56646
+ if (chart === null || chart === void 0 ? void 0 : chart.dispatchAction) {
56647
+ // 清除所有系列的选择状态
56648
+ chart.dispatchAction({
56649
+ type: 'unselect'
56650
+ });
56651
+ }
56652
+ }
56653
+ };
56654
+ }, [clearOnUnmount]);
56655
+ // ─── 私有方法 ───────────────────────────────────────────────────────────────
56656
+ /** 触发选择变化回调 */
56657
+ var notifyChange = (0,external_react_.useCallback)(function (selected, unselected) {
56658
+ onSelectionChange === null || onSelectionChange === void 0 ? void 0 : onSelectionChange({
56659
+ selected: selected,
56660
+ unselected: unselected
56661
+ });
56662
+ }, [onSelectionChange]);
56663
+ /** 执行 ECharts dispatchAction */
56664
+ var dispatchSelect = (0,external_react_.useCallback)(function (key, select) {
56665
+ var chart = chartRef.current;
56666
+ if (!(chart === null || chart === void 0 ? void 0 : chart.dispatchAction)) return;
56667
+ chart.dispatchAction({
56668
+ type: select ? 'select' : 'unselect',
56669
+ seriesIndex: key.seriesIndex,
56670
+ dataIndex: key.dataIndex
56671
+ });
56672
+ }, []);
56673
+ // ─── Public API ───────────────────────────────────────────────────────────
56674
+ var select = (0,external_react_.useCallback)(function (key) {
56675
+ setSelectedPoints(function (prev) {
56676
+ var str = keyToString(key);
56677
+ if (prev.some(function (p) {
56678
+ return keyToString(p) === str;
56679
+ })) return prev;
56680
+ var next = mode === 'single' ? [key] : useChartSelection_spreadArray(useChartSelection_spreadArray([], prev, true), [key], false);
56681
+ notifyChange(next, []);
56682
+ return next;
56683
+ });
56684
+ dispatchSelect(key, true);
56685
+ }, [mode, notifyChange, dispatchSelect]);
56686
+ var deselect = (0,external_react_.useCallback)(function (key) {
56687
+ setSelectedPoints(function (prev) {
56688
+ var str = keyToString(key);
56689
+ var removed = prev.filter(function (p) {
56690
+ return keyToString(p) !== str;
56691
+ });
56692
+ notifyChange([], removed);
56693
+ return removed;
56694
+ });
56695
+ dispatchSelect(key, false);
56696
+ }, [notifyChange, dispatchSelect]);
56697
+ var toggle = (0,external_react_.useCallback)(function (key) {
56698
+ var str = keyToString(key);
56699
+ if (selectedPoints.some(function (p) {
56700
+ return keyToString(p) === str;
56701
+ })) {
56702
+ deselect(key);
56703
+ } else {
56704
+ select(key);
56705
+ }
56706
+ }, [selectedPoints, select, deselect]);
56707
+ var selectMultiple = (0,external_react_.useCallback)(function (keys) {
56708
+ setSelectedPoints(function (prev) {
56709
+ var newPoints = mode === 'single' ? keys : useChartSelection_spreadArray(useChartSelection_spreadArray([], prev, true), keys.filter(function (k) {
56710
+ return !prev.some(function (p) {
56711
+ return keyToString(p) === keyToString(k);
56712
+ });
56713
+ }), true);
56714
+ notifyChange(newPoints, []);
56715
+ return newPoints;
56716
+ });
56717
+ keys.forEach(function (key) {
56718
+ return dispatchSelect(key, true);
56719
+ });
56720
+ }, [mode, notifyChange, dispatchSelect]);
56721
+ var deselectMultiple = (0,external_react_.useCallback)(function (keys) {
56722
+ setSelectedPoints(function (prev) {
56723
+ var keySet = new Set(keys.map(keyToString));
56724
+ var removed = prev.filter(function (p) {
56725
+ return keySet.has(keyToString(p));
56726
+ });
56727
+ var remaining = prev.filter(function (p) {
56728
+ return !keySet.has(keyToString(p));
56729
+ });
56730
+ notifyChange([], removed);
56731
+ return remaining;
56732
+ });
56733
+ keys.forEach(function (key) {
56734
+ return dispatchSelect(key, false);
56735
+ });
56736
+ }, [notifyChange, dispatchSelect]);
56737
+ var invertSelection = (0,external_react_.useCallback)(function (seriesIndex, dataIndices) {
56738
+ setSelectedPoints(function (prev) {
56739
+ var selectedSet = new Set(prev.filter(function (p) {
56740
+ return p.seriesIndex === seriesIndex;
56741
+ }).map(function (p) {
56742
+ return p.dataIndex;
56743
+ }));
56744
+ var toSelect = [];
56745
+ var toDeselect = [];
56746
+ dataIndices.forEach(function (dataIndex) {
56747
+ var key = {
56748
+ seriesIndex: seriesIndex,
56749
+ dataIndex: dataIndex
56750
+ };
56751
+ var str = keyToString(key);
56752
+ if (selectedSet.has(dataIndex)) {
56753
+ toDeselect.push(key);
56754
+ } else {
56755
+ toSelect.push(key);
56756
+ }
56757
+ });
56758
+ toDeselect.forEach(function (k) {
56759
+ return dispatchSelect(k, false);
56760
+ });
56761
+ toSelect.forEach(function (k) {
56762
+ return dispatchSelect(k, true);
56763
+ });
56764
+ var newSelected = prev.filter(function (p) {
56765
+ return !(p.seriesIndex === seriesIndex && selectedSet.has(p.dataIndex));
56766
+ }).concat(toSelect);
56767
+ notifyChange(toSelect, toDeselect);
56768
+ return newSelected;
56769
+ });
56770
+ }, [notifyChange, dispatchSelect]);
56771
+ var selectAll = (0,external_react_.useCallback)(function (seriesIndex, dataIndices) {
56772
+ var keys = dataIndices.map(function (dataIndex) {
56773
+ return {
56774
+ seriesIndex: seriesIndex,
56775
+ dataIndex: dataIndex
56776
+ };
56777
+ });
56778
+ setSelectedPoints(function (prev) {
56779
+ var newPoints = mode === 'single' ? keys : useChartSelection_spreadArray(useChartSelection_spreadArray([], prev, true), keys.filter(function (k) {
56780
+ return !prev.some(function (p) {
56781
+ return keyToString(p) === keyToString(k);
56782
+ });
56783
+ }), true);
56784
+ notifyChange(newPoints, []);
56785
+ return newPoints;
56786
+ });
56787
+ keys.forEach(function (key) {
56788
+ return dispatchSelect(key, true);
56789
+ });
56790
+ }, [mode, notifyChange, dispatchSelect]);
56791
+ var clearSelection = (0,external_react_.useCallback)(function () {
56792
+ var chart = chartRef.current;
56793
+ if (chart === null || chart === void 0 ? void 0 : chart.dispatchAction) {
56794
+ chart.dispatchAction({
56795
+ type: 'unselect'
56796
+ });
56797
+ }
56798
+ var prev = selectedPoints;
56799
+ setSelectedPoints([]);
56800
+ notifyChange([], prev);
56801
+ }, [selectedPoints, notifyChange]);
56802
+ var isSelected = (0,external_react_.useCallback)(function (key) {
56803
+ var str = keyToString(key);
56804
+ return selectedPoints.some(function (p) {
56805
+ return keyToString(p) === str;
56806
+ });
56807
+ }, [selectedPoints]);
56808
+ return {
56809
+ selectedPoints: selectedPoints,
56810
+ hasSelection: selectedPoints.length > 0,
56811
+ selectionCount: selectedPoints.length,
56812
+ select: select,
56813
+ deselect: deselect,
56814
+ selectMultiple: selectMultiple,
56815
+ deselectMultiple: deselectMultiple,
56816
+ toggle: toggle,
56817
+ invertSelection: invertSelection,
56818
+ selectAll: selectAll,
56819
+ clearSelection: clearSelection,
56820
+ isSelected: isSelected
56821
+ };
56822
+ }
56823
+ /* harmony default export */ const hooks_useChartSelection = ((/* unused pure expression or super */ null && (useChartSelection)));
56824
+ ;// ./src/hooks/utils/dataTransformUtils.ts
56825
+ var dataTransformUtils_assign = undefined && undefined.__assign || function () {
56826
+ dataTransformUtils_assign = Object.assign || function (t) {
56155
56827
  for (var s, i = 1, n = arguments.length; i < n; i++) {
56156
56828
  s = arguments[i];
56157
56829
  for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
56158
56830
  }
56159
56831
  return t;
56160
56832
  };
56161
- return useDataTransform_assign.apply(this, arguments);
56833
+ return dataTransformUtils_assign.apply(this, arguments);
56162
56834
  };
56163
- var useDataTransform_spreadArray = undefined && undefined.__spreadArray || function (to, from, pack) {
56835
+ var dataTransformUtils_spreadArray = undefined && undefined.__spreadArray || function (to, from, pack) {
56164
56836
  if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
56165
56837
  if (ar || !(i in from)) {
56166
56838
  if (!ar) ar = Array.prototype.slice.call(from, 0, i);
@@ -56169,11 +56841,283 @@ var useDataTransform_spreadArray = undefined && undefined.__spreadArray || funct
56169
56841
  }
56170
56842
  return to.concat(ar || Array.prototype.slice.call(from));
56171
56843
  };
56844
+ // ============================================================================
56845
+ // 转换函数
56846
+ // ============================================================================
56847
+ function transformLineOrBar(data, chartType, mapping, extraConfig) {
56848
+ var _a;
56849
+ var _b = mapping || {},
56850
+ _c = _b.xField,
56851
+ xField = _c === void 0 ? 'name' : _c,
56852
+ _d = _b.yField,
56853
+ yField = _d === void 0 ? 'value' : _d,
56854
+ seriesField = _b.seriesField;
56855
+ var categories = data.categories || ((_a = data.rows) === null || _a === void 0 ? void 0 : _a.map(function (r) {
56856
+ return String(r[xField]);
56857
+ })) || [];
56858
+ var seriesData = data.series || data.rows || [];
56859
+ if (seriesField) {
56860
+ var groups_1 = new Map();
56861
+ seriesData.forEach(function (item) {
56862
+ var key = String(item[seriesField] || 'default');
56863
+ if (!groups_1.has(key)) groups_1.set(key, []);
56864
+ groups_1.get(key).push(item);
56865
+ });
56866
+ var series_1 = Array.from(groups_1.entries()).map(function (_a) {
56867
+ var name = _a[0],
56868
+ items = _a[1];
56869
+ return {
56870
+ name: name,
56871
+ type: chartType,
56872
+ data: items.map(function (item) {
56873
+ var _a;
56874
+ return (_a = item[yField]) !== null && _a !== void 0 ? _a : 0;
56875
+ })
56876
+ };
56877
+ });
56878
+ return dataTransformUtils_assign({
56879
+ xAxis: {
56880
+ type: 'category',
56881
+ data: categories
56882
+ },
56883
+ yAxis: {
56884
+ type: 'value'
56885
+ },
56886
+ series: series_1
56887
+ }, extraConfig);
56888
+ }
56889
+ var series = [{
56890
+ type: chartType,
56891
+ data: seriesData.map(function (item) {
56892
+ var _a;
56893
+ return (_a = item[yField]) !== null && _a !== void 0 ? _a : 0;
56894
+ })
56895
+ }];
56896
+ return dataTransformUtils_assign({
56897
+ xAxis: {
56898
+ type: 'category',
56899
+ data: categories
56900
+ },
56901
+ yAxis: {
56902
+ type: 'value'
56903
+ },
56904
+ series: series
56905
+ }, extraConfig);
56906
+ }
56907
+ function transformPie(data, mapping, extraConfig) {
56908
+ var _a = mapping || {},
56909
+ _b = _a.nameField,
56910
+ nameField = _b === void 0 ? 'name' : _b,
56911
+ _c = _a.valueField,
56912
+ valueField = _c === void 0 ? 'value' : _c;
56913
+ var seriesData = (data.series || data.rows || []).map(function (item) {
56914
+ return {
56915
+ name: String(item[nameField] || ''),
56916
+ value: Number(item[valueField]) || 0
56917
+ };
56918
+ });
56919
+ return dataTransformUtils_assign({
56920
+ series: [{
56921
+ type: 'pie',
56922
+ radius: '60%',
56923
+ data: seriesData
56924
+ }]
56925
+ }, extraConfig);
56926
+ }
56927
+ function transformScatter(data, mapping, extraConfig) {
56928
+ var _a = mapping || {},
56929
+ _b = _a.xField,
56930
+ xField = _b === void 0 ? 'x' : _b,
56931
+ _c = _a.yField,
56932
+ yField = _c === void 0 ? 'y' : _c,
56933
+ sizeField = _a.sizeField;
56934
+ var seriesData = (data.series || data.rows || []).map(function (item) {
56935
+ var record = item;
56936
+ var point = [Number(record[xField]) || 0, Number(record[yField]) || 0];
56937
+ if (sizeField) point.push(Number(record[sizeField]) || 1);
56938
+ return point;
56939
+ });
56940
+ return dataTransformUtils_assign({
56941
+ xAxis: {
56942
+ type: 'value',
56943
+ scale: true
56944
+ },
56945
+ yAxis: {
56946
+ type: 'value',
56947
+ scale: true
56948
+ },
56949
+ series: [{
56950
+ type: 'scatter',
56951
+ data: seriesData
56952
+ }]
56953
+ }, extraConfig);
56954
+ }
56955
+ function transformRadar(data, mapping, extraConfig) {
56956
+ var _a = mapping || {},
56957
+ _b = _a.nameField,
56958
+ nameField = _b === void 0 ? 'name' : _b,
56959
+ _c = _a.valueField,
56960
+ valueField = _c === void 0 ? 'value' : _c;
56961
+ var indicators = (data.series || data.rows || []).map(function (item) {
56962
+ var record = item;
56963
+ return {
56964
+ name: String(record[nameField] || ''),
56965
+ max: Math.max(Number(record[valueField]) || 100, 100)
56966
+ };
56967
+ });
56968
+ var values = (data.series || data.rows || []).map(function (item) {
56969
+ return Number(item[valueField]) || 0;
56970
+ });
56971
+ return dataTransformUtils_assign({
56972
+ radar: {
56973
+ indicator: indicators
56974
+ },
56975
+ series: [{
56976
+ type: 'radar',
56977
+ data: [{
56978
+ value: values
56979
+ }]
56980
+ }]
56981
+ }, extraConfig);
56982
+ }
56983
+ function transformHeatmap(data, mapping, extraConfig) {
56984
+ var _a = mapping || {},
56985
+ _b = _a.xField,
56986
+ xField = _b === void 0 ? 'x' : _b,
56987
+ _c = _a.yField,
56988
+ yField = _c === void 0 ? 'y' : _c,
56989
+ _d = _a.valueField,
56990
+ valueField = _d === void 0 ? 'value' : _d;
56991
+ var xCategories = dataTransformUtils_spreadArray([], new Set((data.series || data.rows || []).map(function (d) {
56992
+ return String(d[xField]);
56993
+ })), true);
56994
+ var yCategories = dataTransformUtils_spreadArray([], new Set((data.series || data.rows || []).map(function (d) {
56995
+ return String(d[yField]);
56996
+ })), true);
56997
+ var seriesData = (data.series || data.rows || []).map(function (item) {
56998
+ var record = item;
56999
+ var xIndex = xCategories.indexOf(String(record[xField]));
57000
+ var yIndex = yCategories.indexOf(String(record[yField]));
57001
+ return [xIndex, yIndex, Number(record[valueField]) || 0];
57002
+ });
57003
+ return dataTransformUtils_assign({
57004
+ xAxis: {
57005
+ type: 'category',
57006
+ data: xCategories
57007
+ },
57008
+ yAxis: {
57009
+ type: 'category',
57010
+ data: yCategories
57011
+ },
57012
+ visualMap: {
57013
+ min: 0,
57014
+ calculable: true
57015
+ },
57016
+ series: [{
57017
+ type: 'heatmap',
57018
+ data: seriesData
57019
+ }]
57020
+ }, extraConfig);
57021
+ }
57022
+ function groupByTime(data, dateField, period) {
57023
+ return data.reduce(function (acc, item) {
57024
+ var date = new Date(String(item[dateField]));
57025
+ var key;
57026
+ switch (period) {
57027
+ case 'day':
57028
+ key = date.toISOString().split('T')[0];
57029
+ break;
57030
+ case 'week':
57031
+ {
57032
+ var week = getWeekNumber(date);
57033
+ key = "".concat(date.getFullYear(), "-W").concat(week);
57034
+ break;
57035
+ }
57036
+ case 'month':
57037
+ key = "".concat(date.getFullYear(), "-").concat(String(date.getMonth() + 1).padStart(2, '0'));
57038
+ break;
57039
+ case 'quarter':
57040
+ key = "".concat(date.getFullYear(), "-Q").concat(Math.ceil((date.getMonth() + 1) / 3));
57041
+ break;
57042
+ case 'year':
57043
+ key = String(date.getFullYear());
57044
+ break;
57045
+ default:
57046
+ key = date.toISOString().split('T')[0];
57047
+ }
57048
+ if (!acc[key]) acc[key] = [];
57049
+ acc[key].push(item);
57050
+ return acc;
57051
+ }, {});
57052
+ }
57053
+ function getWeekNumber(date) {
57054
+ var d = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));
57055
+ var dayNum = d.getUTCDay() || 7;
57056
+ d.setUTCDate(d.getUTCDate() + 4 - dayNum);
57057
+ var yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1));
57058
+ return Math.ceil(((d.getTime() - yearStart.getTime()) / 86400000 + 1) / 7);
57059
+ }
57060
+ function aggregateValues(items, field, method, fillMissing) {
57061
+ if (items.length === 0) {
57062
+ if (fillMissing === 'zero') return 0;
57063
+ return NaN;
57064
+ }
57065
+ var values = items.map(function (item) {
57066
+ return Number(item[field]) || 0;
57067
+ });
57068
+ switch (method) {
57069
+ case 'sum':
57070
+ {
57071
+ var sum = 0;
57072
+ for (var i = 0; i < values.length; i++) sum += values[i];
57073
+ return sum;
57074
+ }
57075
+ case 'average':
57076
+ {
57077
+ if (values.length === 0) return 0;
57078
+ var sum = 0;
57079
+ for (var i = 0; i < values.length; i++) sum += values[i];
57080
+ return sum / values.length;
57081
+ }
57082
+ case 'max':
57083
+ {
57084
+ var max = values[0];
57085
+ for (var i = 1; i < values.length; i++) if (values[i] > max) max = values[i];
57086
+ return max;
57087
+ }
57088
+ case 'min':
57089
+ {
57090
+ var min = values[0];
57091
+ for (var i = 1; i < values.length; i++) if (values[i] < min) min = values[i];
57092
+ return min;
57093
+ }
57094
+ case 'count':
57095
+ return values.length;
57096
+ case 'first':
57097
+ return values[0];
57098
+ case 'last':
57099
+ return values[values.length - 1];
57100
+ default:
57101
+ return values[0];
57102
+ }
57103
+ }
57104
+ ;// ./src/hooks/useDataTransform.ts
57105
+ var useDataTransform_assign = undefined && undefined.__assign || function () {
57106
+ useDataTransform_assign = Object.assign || function (t) {
57107
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
57108
+ s = arguments[i];
57109
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
57110
+ }
57111
+ return t;
57112
+ };
57113
+ return useDataTransform_assign.apply(this, arguments);
57114
+ };
56172
57115
  /**
56173
57116
  * useDataTransform - 数据转换 Hook
56174
57117
  * 提供便捷的数据转换功能,将原始数据转换为 ECharts 配置
56175
57118
  */
56176
57119
 
57120
+
56177
57121
  // ============================================================================
56178
57122
  // 数据转换 Hook
56179
57123
  // ============================================================================
@@ -56341,266 +57285,6 @@ function useTimeSeriesTransform(options) {
56341
57285
  }, [data, dateField, valueField, groupField, period, aggregation, fillMissing, extraConfig]);
56342
57286
  }
56343
57287
  // ============================================================================
56344
- // 辅助函数
56345
- // ============================================================================
56346
- function transformLineOrBar(data, chartType, mapping, extraConfig) {
56347
- var _a;
56348
- var _b = mapping || {},
56349
- _c = _b.xField,
56350
- xField = _c === void 0 ? 'name' : _c,
56351
- _d = _b.yField,
56352
- yField = _d === void 0 ? 'value' : _d,
56353
- seriesField = _b.seriesField;
56354
- var categories = data.categories || ((_a = data.rows) === null || _a === void 0 ? void 0 : _a.map(function (r) {
56355
- return String(r[xField]);
56356
- })) || [];
56357
- var seriesData = data.series || data.rows || [];
56358
- if (seriesField) {
56359
- var groups_1 = new Map();
56360
- seriesData.forEach(function (item) {
56361
- var key = String(item[seriesField] || 'default');
56362
- if (!groups_1.has(key)) groups_1.set(key, []);
56363
- groups_1.get(key).push(item);
56364
- });
56365
- var series_1 = Array.from(groups_1.entries()).map(function (_a) {
56366
- var name = _a[0],
56367
- items = _a[1];
56368
- return {
56369
- name: name,
56370
- type: chartType,
56371
- data: items.map(function (item) {
56372
- var _a;
56373
- return (_a = item[yField]) !== null && _a !== void 0 ? _a : 0;
56374
- })
56375
- };
56376
- });
56377
- return useDataTransform_assign({
56378
- xAxis: {
56379
- type: 'category',
56380
- data: categories
56381
- },
56382
- yAxis: {
56383
- type: 'value'
56384
- },
56385
- series: series_1
56386
- }, extraConfig);
56387
- }
56388
- var series = [{
56389
- type: chartType,
56390
- data: seriesData.map(function (item) {
56391
- var _a;
56392
- return (_a = item[yField]) !== null && _a !== void 0 ? _a : 0;
56393
- })
56394
- }];
56395
- return useDataTransform_assign({
56396
- xAxis: {
56397
- type: 'category',
56398
- data: categories
56399
- },
56400
- yAxis: {
56401
- type: 'value'
56402
- },
56403
- series: series
56404
- }, extraConfig);
56405
- }
56406
- function transformPie(data, mapping, extraConfig) {
56407
- var _a = mapping || {},
56408
- _b = _a.nameField,
56409
- nameField = _b === void 0 ? 'name' : _b,
56410
- _c = _a.valueField,
56411
- valueField = _c === void 0 ? 'value' : _c;
56412
- var seriesData = (data.series || data.rows || []).map(function (item) {
56413
- return {
56414
- name: String(item[nameField] || ''),
56415
- value: Number(item[valueField]) || 0
56416
- };
56417
- });
56418
- return useDataTransform_assign({
56419
- series: [{
56420
- type: 'pie',
56421
- radius: '60%',
56422
- data: seriesData
56423
- }]
56424
- }, extraConfig);
56425
- }
56426
- function transformScatter(data, mapping, extraConfig) {
56427
- var _a = mapping || {},
56428
- _b = _a.xField,
56429
- xField = _b === void 0 ? 'x' : _b,
56430
- _c = _a.yField,
56431
- yField = _c === void 0 ? 'y' : _c,
56432
- sizeField = _a.sizeField;
56433
- var seriesData = (data.series || data.rows || []).map(function (item) {
56434
- var record = item;
56435
- var point = [Number(record[xField]) || 0, Number(record[yField]) || 0];
56436
- if (sizeField) point.push(Number(record[sizeField]) || 1);
56437
- return point;
56438
- });
56439
- return useDataTransform_assign({
56440
- xAxis: {
56441
- type: 'value',
56442
- scale: true
56443
- },
56444
- yAxis: {
56445
- type: 'value',
56446
- scale: true
56447
- },
56448
- series: [{
56449
- type: 'scatter',
56450
- data: seriesData
56451
- }]
56452
- }, extraConfig);
56453
- }
56454
- function transformRadar(data, mapping, extraConfig) {
56455
- var _a = mapping || {},
56456
- _b = _a.nameField,
56457
- nameField = _b === void 0 ? 'name' : _b,
56458
- _c = _a.valueField,
56459
- valueField = _c === void 0 ? 'value' : _c;
56460
- var indicators = (data.series || data.rows || []).map(function (item) {
56461
- var record = item;
56462
- return {
56463
- name: String(record[nameField] || ''),
56464
- max: Math.max(Number(record[valueField]) || 100, 100)
56465
- };
56466
- });
56467
- var values = (data.series || data.rows || []).map(function (item) {
56468
- return Number(item[valueField]) || 0;
56469
- });
56470
- return useDataTransform_assign({
56471
- radar: {
56472
- indicator: indicators
56473
- },
56474
- series: [{
56475
- type: 'radar',
56476
- data: [{
56477
- value: values
56478
- }]
56479
- }]
56480
- }, extraConfig);
56481
- }
56482
- function transformHeatmap(data, mapping, extraConfig) {
56483
- var _a = mapping || {},
56484
- _b = _a.xField,
56485
- xField = _b === void 0 ? 'x' : _b,
56486
- _c = _a.yField,
56487
- yField = _c === void 0 ? 'y' : _c,
56488
- _d = _a.valueField,
56489
- valueField = _d === void 0 ? 'value' : _d;
56490
- var xCategories = useDataTransform_spreadArray([], new Set((data.series || data.rows || []).map(function (d) {
56491
- return String(d[xField]);
56492
- })), true);
56493
- var yCategories = useDataTransform_spreadArray([], new Set((data.series || data.rows || []).map(function (d) {
56494
- return String(d[yField]);
56495
- })), true);
56496
- var seriesData = (data.series || data.rows || []).map(function (item) {
56497
- var record = item;
56498
- var xIndex = xCategories.indexOf(String(record[xField]));
56499
- var yIndex = yCategories.indexOf(String(record[yField]));
56500
- return [xIndex, yIndex, Number(record[valueField]) || 0];
56501
- });
56502
- return useDataTransform_assign({
56503
- xAxis: {
56504
- type: 'category',
56505
- data: xCategories
56506
- },
56507
- yAxis: {
56508
- type: 'category',
56509
- data: yCategories
56510
- },
56511
- visualMap: {
56512
- min: 0,
56513
- calculable: true
56514
- },
56515
- series: [{
56516
- type: 'heatmap',
56517
- data: seriesData
56518
- }]
56519
- }, extraConfig);
56520
- }
56521
- function groupByTime(data, dateField, period) {
56522
- return data.reduce(function (acc, item) {
56523
- var date = new Date(String(item[dateField]));
56524
- var key;
56525
- switch (period) {
56526
- case 'day':
56527
- key = date.toISOString().split('T')[0];
56528
- break;
56529
- case 'week':
56530
- {
56531
- var week = getWeekNumber(date);
56532
- key = "".concat(date.getFullYear(), "-W").concat(week);
56533
- break;
56534
- }
56535
- case 'month':
56536
- key = "".concat(date.getFullYear(), "-").concat(String(date.getMonth() + 1).padStart(2, '0'));
56537
- break;
56538
- case 'quarter':
56539
- key = "".concat(date.getFullYear(), "-Q").concat(Math.ceil((date.getMonth() + 1) / 3));
56540
- break;
56541
- case 'year':
56542
- key = String(date.getFullYear());
56543
- break;
56544
- default:
56545
- key = date.toISOString().split('T')[0];
56546
- }
56547
- if (!acc[key]) acc[key] = [];
56548
- acc[key].push(item);
56549
- return acc;
56550
- }, {});
56551
- }
56552
- function getWeekNumber(date) {
56553
- var d = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));
56554
- var dayNum = d.getUTCDay() || 7;
56555
- d.setUTCDate(d.getUTCDate() + 4 - dayNum);
56556
- var yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1));
56557
- return Math.ceil(((d.getTime() - yearStart.getTime()) / 86400000 + 1) / 7);
56558
- }
56559
- function aggregateValues(items, field, method, fillMissing) {
56560
- if (items.length === 0) {
56561
- if (fillMissing === 'zero') return 0;
56562
- return NaN;
56563
- }
56564
- var values = items.map(function (item) {
56565
- return Number(item[field]) || 0;
56566
- });
56567
- switch (method) {
56568
- case 'sum':
56569
- {
56570
- var sum = 0;
56571
- for (var i = 0; i < values.length; i++) sum += values[i];
56572
- return sum;
56573
- }
56574
- case 'average':
56575
- {
56576
- if (values.length === 0) return 0;
56577
- var sum = 0;
56578
- for (var i = 0; i < values.length; i++) sum += values[i];
56579
- return sum / values.length;
56580
- }
56581
- case 'max':
56582
- {
56583
- var max = values[0];
56584
- for (var i = 1; i < values.length; i++) if (values[i] > max) max = values[i];
56585
- return max;
56586
- }
56587
- case 'min':
56588
- {
56589
- var min = values[0];
56590
- for (var i = 1; i < values.length; i++) if (values[i] < min) min = values[i];
56591
- return min;
56592
- }
56593
- case 'count':
56594
- return values.length;
56595
- case 'first':
56596
- return values[0];
56597
- case 'last':
56598
- return values[values.length - 1];
56599
- default:
56600
- return values[0];
56601
- }
56602
- }
56603
- // ============================================================================
56604
57288
  // 导出
56605
57289
  // ============================================================================
56606
57290
  var useTransform = (/* unused pure expression or super */ null && (useDataTransform));
@@ -56740,6 +57424,8 @@ var hooks_spreadArray = undefined && undefined.__spreadArray || function (to, fr
56740
57424
 
56741
57425
 
56742
57426
 
57427
+
57428
+
56743
57429
  // ============================================================================
56744
57430
  // Hooks
56745
57431
  // ============================================================================
@@ -57342,6 +58028,14 @@ function useChartTools(instance) {
57342
58028
 
57343
58029
  // 图表下载 Hook
57344
58030
 
58031
+ // 图表下载工具函数
58032
+
58033
+ // 数据转换工具函数(值导出)
58034
+
58035
+ // 图表历史记录 Hook (Undo/Redo)
58036
+
58037
+ // 图表选择 Hook
58038
+
57345
58039
  // ============================================================================
57346
58040
  // 导出
57347
58041
  // ============================================================================
@@ -57365,7 +58059,9 @@ var hooks_version = '1.7.0';
57365
58059
  // v1.7.0 新增
57366
58060
  useDataZoom: useDataZoom,
57367
58061
  useChartConnect: useChartConnect,
57368
- useChartDownload: useChartDownload
58062
+ useChartDownload: useChartDownload,
58063
+ useChartHistory: useChartHistory,
58064
+ useChartSelection: useChartSelection
57369
58065
  });
57370
58066
  ;// ./src/index.ts
57371
58067
  /**