@agions/taroviz 1.11.1 → 2.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (164) hide show
  1. package/CHANGELOG.md +245 -0
  2. package/README.md +104 -302
  3. package/dist/cjs/index.js +1 -1
  4. package/dist/cjs/vendors.js +1 -0
  5. package/dist/cjs/vendors~echarts.js +1 -0
  6. package/dist/esm/index.js +1 -58151
  7. package/dist/esm/vendors.js +1 -0
  8. package/dist/esm/vendors~echarts.js +1 -0
  9. package/package.json +19 -25
  10. package/src/adapters/MiniAppAdapter.ts +136 -0
  11. package/src/adapters/__tests__/index.test.ts +1 -1
  12. package/src/adapters/h5/__tests__/index.test.ts +4 -2
  13. package/src/adapters/h5/index.ts +63 -64
  14. package/src/adapters/harmony/index.ts +23 -245
  15. package/src/adapters/index.ts +49 -45
  16. package/src/adapters/swan/index.ts +6 -69
  17. package/src/adapters/tt/index.ts +7 -70
  18. package/src/adapters/types.ts +25 -58
  19. package/src/adapters/weapp/index.ts +6 -69
  20. package/src/charts/__tests__/testUtils.tsx +87 -0
  21. package/src/charts/boxplot/__tests__/index.test.tsx +49 -103
  22. package/src/charts/boxplot/index.tsx +2 -1
  23. package/src/charts/boxplot/types.ts +17 -16
  24. package/src/charts/common/BaseChartWrapper.tsx +90 -82
  25. package/src/charts/common/__mocks__/BaseChartWrapper.tsx +17 -0
  26. package/src/charts/createChartComponent.tsx +36 -0
  27. package/src/charts/createOptionChartComponent.tsx +32 -0
  28. package/src/charts/funnel/__tests__/index.test.tsx +99 -0
  29. package/src/charts/funnel/index.tsx +60 -10
  30. package/src/charts/funnel/types.ts +6 -0
  31. package/src/charts/graph/__tests__/index.test.tsx +102 -33
  32. package/src/charts/graph/index.tsx +66 -9
  33. package/src/charts/graph/types.ts +6 -0
  34. package/src/charts/heatmap/__tests__/index.test.tsx +139 -0
  35. package/src/charts/heatmap/index.tsx +103 -10
  36. package/src/charts/heatmap/types.ts +6 -0
  37. package/src/charts/index.ts +74 -26
  38. package/src/charts/liquid/__tests__/index.test.tsx +52 -0
  39. package/src/charts/liquid/index.tsx +239 -182
  40. package/src/charts/liquid/types.ts +11 -11
  41. package/src/charts/parallel/__tests__/index.test.tsx +40 -67
  42. package/src/charts/parallel/index.tsx +2 -1
  43. package/src/charts/parallel/types.ts +19 -18
  44. package/src/charts/radar/__tests__/index.test.tsx +210 -0
  45. package/src/charts/radar/index.tsx +143 -10
  46. package/src/charts/radar/types.ts +13 -0
  47. package/src/charts/sankey/__tests__/index.test.tsx +124 -0
  48. package/src/charts/sankey/index.tsx +62 -10
  49. package/src/charts/sankey/types.ts +6 -0
  50. package/src/charts/tree/__tests__/index.test.tsx +71 -0
  51. package/src/charts/tree/index.tsx +5 -2
  52. package/src/charts/tree/types.ts +9 -9
  53. package/src/charts/types.ts +208 -106
  54. package/src/charts/utils.ts +9 -7
  55. package/src/charts/wordcloud/__tests__/index.test.tsx +98 -31
  56. package/src/charts/wordcloud/index.tsx +75 -9
  57. package/src/charts/wordcloud/types.ts +6 -0
  58. package/src/components/DataFilter/index.tsx +32 -10
  59. package/src/core/animation/types.ts +6 -6
  60. package/src/core/components/Annotation.tsx +6 -7
  61. package/src/core/components/BaseChart.tsx +110 -168
  62. package/src/core/components/ErrorBoundary.tsx +17 -4
  63. package/src/core/components/LazyChart.tsx +54 -55
  64. package/src/core/components/hooks/index.ts +6 -2
  65. package/src/core/components/hooks/useChartInit.ts +6 -3
  66. package/src/core/components/hooks/usePerformance.ts +8 -2
  67. package/src/core/components/hooks/useVirtualScroll.ts +2 -1
  68. package/src/core/index.ts +1 -1
  69. package/src/core/themes/ThemeManager.ts +1 -1
  70. package/src/core/types/common.ts +2 -1
  71. package/src/core/types/index.ts +0 -12
  72. package/src/core/types/platform.ts +3 -5
  73. package/src/core/utils/__tests__/deepClone.test.ts +317 -0
  74. package/src/core/utils/__tests__/index.test.ts +2 -1
  75. package/src/core/utils/chartInstances.ts +13 -0
  76. package/src/core/utils/common.ts +20 -29
  77. package/src/core/utils/deepClone.ts +114 -0
  78. package/src/core/utils/download.ts +128 -0
  79. package/src/core/utils/drillDown.ts +34 -353
  80. package/src/core/utils/drillDownHelpers.ts +426 -0
  81. package/src/core/utils/events.ts +12 -0
  82. package/src/core/utils/export/ExportUtils.ts +36 -67
  83. package/src/core/utils/format.ts +44 -0
  84. package/src/core/utils/index.ts +21 -154
  85. package/src/core/utils/merge.ts +25 -0
  86. package/src/core/utils/performance/PerformanceAnalyzer.ts +38 -21
  87. package/src/core/utils/performance/hooks.ts +7 -0
  88. package/src/core/utils/performance/index.ts +2 -0
  89. package/src/{hooks → core/utils/performance}/useAnimation.ts +45 -41
  90. package/src/core/utils/performance/useDataZoom.ts +324 -0
  91. package/src/{hooks → core/utils/performance}/usePerformance.ts +49 -41
  92. package/src/core/utils/performance/usePerformanceHooks.ts +278 -0
  93. package/src/core/utils/performanceUtils.ts +310 -0
  94. package/src/core/utils/runtime.ts +190 -0
  95. package/src/core/utils/setOptionUtils.ts +59 -0
  96. package/src/core/version.ts +14 -0
  97. package/src/editor/EnhancedThemeEditor.tsx +362 -540
  98. package/src/editor/ThemeEditor.tsx +55 -321
  99. package/src/editor/components/ThemeBasicSettings.tsx +113 -0
  100. package/src/editor/components/ThemeColorEditor.tsx +105 -0
  101. package/src/editor/components/ThemeSelector.tsx +70 -0
  102. package/src/editor/hooks/useThemeEditorState.ts +201 -0
  103. package/src/editor/index.ts +10 -2
  104. package/src/hooks/__tests__/index.test.tsx +3 -1
  105. package/src/hooks/chartConnectHelpers.ts +341 -0
  106. package/src/hooks/index.ts +55 -660
  107. package/src/hooks/types.ts +189 -0
  108. package/src/hooks/useChartAutoResize.ts +73 -0
  109. package/src/hooks/useChartConnect.ts +92 -238
  110. package/src/hooks/useChartDownload.ts +25 -27
  111. package/src/hooks/useChartHistory.ts +34 -49
  112. package/src/hooks/useChartInit.ts +59 -0
  113. package/src/hooks/useChartOptions.ts +259 -0
  114. package/src/hooks/useChartPerformance.ts +109 -0
  115. package/src/hooks/useChartSelection.ts +52 -49
  116. package/src/hooks/useChartTheme.ts +51 -0
  117. package/src/hooks/useDataTransform.ts +19 -4
  118. package/src/hooks/utils/chartDownloadUtils.ts +40 -53
  119. package/src/hooks/utils/dataTransformUtils.ts +22 -0
  120. package/src/index.ts +48 -34
  121. package/src/main.tsx +4 -9
  122. package/src/react-dom.d.ts +3 -3
  123. package/src/themes/index.ts +30 -855
  124. package/src/themes/palettes/blue-green.ts +13 -0
  125. package/src/themes/palettes/chalk.ts +13 -0
  126. package/src/themes/palettes/cyber.ts +44 -0
  127. package/src/themes/palettes/dark.ts +52 -0
  128. package/src/themes/palettes/default.ts +52 -0
  129. package/src/themes/palettes/elegant.ts +34 -0
  130. package/src/themes/palettes/forest.ts +13 -0
  131. package/src/themes/palettes/glass.ts +49 -0
  132. package/src/themes/palettes/golden.ts +13 -0
  133. package/src/themes/palettes/neon.ts +43 -0
  134. package/src/themes/palettes/ocean.ts +39 -0
  135. package/src/themes/palettes/pastel.ts +37 -0
  136. package/src/themes/palettes/purple-passion.ts +13 -0
  137. package/src/themes/palettes/retro.ts +33 -0
  138. package/src/themes/palettes/sunset.ts +40 -0
  139. package/src/themes/palettes/walden.ts +13 -0
  140. package/src/themes/registry.ts +184 -0
  141. package/src/themes/types.ts +213 -0
  142. package/src/charts/bar/__tests__/index.test.tsx +0 -113
  143. package/src/charts/bar/index.tsx +0 -14
  144. package/src/charts/candlestick/__tests__/index.test.tsx +0 -40
  145. package/src/charts/candlestick/index.tsx +0 -13
  146. package/src/charts/gauge/index.tsx +0 -14
  147. package/src/charts/line/__tests__/index.test.tsx +0 -107
  148. package/src/charts/line/index.tsx +0 -15
  149. package/src/charts/pie/__tests__/index.test.tsx +0 -112
  150. package/src/charts/pie/index.tsx +0 -14
  151. package/src/charts/scatter/index.tsx +0 -14
  152. package/src/charts/sunburst/index.tsx +0 -18
  153. package/src/charts/treemap/index.tsx +0 -18
  154. package/src/core/utils/codeGenerator/CodeGenerator.ts +0 -669
  155. package/src/core/utils/codeGenerator/index.ts +0 -13
  156. package/src/core/utils/codeGenerator/types.ts +0 -198
  157. package/src/core/utils/configGenerator/ConfigGenerator.ts +0 -583
  158. package/src/core/utils/configGenerator/index.ts +0 -13
  159. package/src/core/utils/configGenerator/types.ts +0 -445
  160. package/src/core/utils/debug/DebugPanel.tsx +0 -637
  161. package/src/core/utils/debug/debugger.ts +0 -322
  162. package/src/core/utils/debug/index.ts +0 -21
  163. package/src/core/utils/debug/types.ts +0 -142
  164. package/src/hooks/useDataZoom.ts +0 -323
@@ -1,8 +1,22 @@
1
+ /* eslint-disable @typescript-eslint/no-unused-vars */
1
2
  /**
2
3
  * DrillDown - 数据下钻工具
3
4
  * 支持点击图表数据项时,自动下钻到更细粒度的数据视图
5
+ *
6
+ * @refactor 已拆分为多个辅助函数,详见 drillDownHelpers.ts
4
7
  */
5
- import type { EChartsOption } from 'echarts';
8
+ import type { ECharts, EChartsOption, ECElementEvent } from 'echarts';
9
+ import {
10
+ buildOptionFromSources,
11
+ getDrillDownOption,
12
+ getCurrentLevelSources,
13
+ hasDrillDownData,
14
+ findMatchedSource,
15
+ executeDrillDown,
16
+ executeDrillUp,
17
+ executeReset,
18
+ executeDrillTo,
19
+ } from './drillDownHelpers';
6
20
 
7
21
  // ============================================================================
8
22
  // 类型定义
@@ -56,7 +70,7 @@ export interface DrillDownEventParams {
56
70
  /** 点击的数据项名称 */
57
71
  name: string | number;
58
72
  /** 点击的数据项值 */
59
- value: string | number;
73
+ value: unknown;
60
74
  /** 下钻后的数据源 */
61
75
  sources: DrillDownSource[];
62
76
  /** 下钻后的图表配置 */
@@ -86,7 +100,7 @@ export interface DrillDownReturn {
86
100
  * @param chartInstance ECharts 实例
87
101
  * @param config 下钻配置
88
102
  */
89
- init: (chartInstance: any, config: DrillDownConfig) => void;
103
+ init: (chartInstance: ECharts, config: DrillDownConfig) => void;
90
104
  /**
91
105
  * 返回上一层
92
106
  */
@@ -104,12 +118,12 @@ export interface DrillDownReturn {
104
118
  * 绑定图表点击事件
105
119
  * @param chartInstance ECharts 实例
106
120
  */
107
- bindClick: (chartInstance: any) => void;
121
+ bindClick: (chartInstance: ECharts) => void;
108
122
  /**
109
123
  * 解绑图表点击事件
110
124
  * @param chartInstance ECharts 实例
111
125
  */
112
- unbindClick: (chartInstance: any) => void;
126
+ unbindClick: (chartInstance: ECharts) => void;
113
127
  /**
114
128
  * 手动触发下钻到指定层级
115
129
  * @param level 目标层级
@@ -138,7 +152,7 @@ export interface DrillDownReturn {
138
152
 
139
153
  interface DrillDownState {
140
154
  /** 图表实例 */
141
- chartInstance: any;
155
+ chartInstance: ECharts | null;
142
156
  /** 当前配置 */
143
157
  config: DrillDownConfig;
144
158
  /** 当前层级 */
@@ -148,11 +162,11 @@ interface DrillDownState {
148
162
  /** 当前图表 option */
149
163
  currentOption: EChartsOption;
150
164
  /** 初始 option(用于重置) */
151
- initialOption: EChartsOption;
165
+ initialOption: Record<string, unknown>;
152
166
  /** 是否已初始化 */
153
167
  initialized: boolean;
154
168
  /** 事件处理器引用(用于解绑) */
155
- clickHandler: ((params: any) => void) | null;
169
+ clickHandler: ((params: ECElementEvent) => void) | null;
156
170
  }
157
171
 
158
172
  // ============================================================================
@@ -204,178 +218,11 @@ export function createDrillDown(initialConfig?: Partial<DrillDownConfig>): Drill
204
218
  clickHandler: null,
205
219
  };
206
220
 
207
- // ============================================================
208
- // 内部方法
209
- // ============================================================
210
-
211
- /**
212
- * 根据层级和触发数据项获取下钻后的图表配置
213
- */
214
- const getDrillDownOption = (
215
- level: number,
216
- dataItem: DrillDownSource | undefined,
217
- direction: 'down' | 'up' | 'reset'
218
- ): EChartsOption => {
219
- const { config } = state;
220
- let targetSources: DrillDownSource[] = [];
221
- let targetOption: EChartsOption = {};
222
-
223
- if (direction === 'reset' || level === 0) {
224
- // 重置或回到第一层:使用初始数据
225
- if (config.initialSources) {
226
- targetSources = config.initialSources;
227
- // 从 initialSources 构建图表 option
228
- targetOption = buildOptionFromSources(targetSources);
229
- } else {
230
- // 如果没有 initialSources,返回空 option,让用户重新 setOption
231
- targetOption = {};
232
- }
233
- } else if (direction === 'up') {
234
- // 上钻:从 history 中找到上一层的状态
235
- const prevHistory = state.history[level - 1];
236
- if (prevHistory && prevHistory.dataItem.chartOption) {
237
- targetOption = prevHistory.dataItem.chartOption;
238
- } else {
239
- // 尝试从 children 构建
240
- targetSources = prevHistory?.dataItem.children ?? [];
241
- targetOption = buildOptionFromSources(targetSources);
242
- }
243
- } else if (direction === 'down' && dataItem) {
244
- // 下钻
245
- if (dataItem.chartOption) {
246
- // 优先使用自定义 chartOption
247
- targetOption = dataItem.chartOption;
248
- } else if (dataItem.children && dataItem.children.length > 0) {
249
- // 从 children 构建图表 option
250
- targetSources = dataItem.children;
251
- targetOption = buildOptionFromSources(targetSources);
252
- }
253
- }
254
-
255
- return targetOption;
256
- };
257
-
258
- /**
259
- * 从 DrillDownSource 数组构建 ECharts option
260
- */
261
- const buildOptionFromSources = (sources: DrillDownSource[]): EChartsOption => {
262
- if (!sources || sources.length === 0) return {};
263
-
264
- const names = sources.map((s) => s.name);
265
- const values = sources.map((s) => s.value);
266
-
267
- return {
268
- xAxis: {
269
- type: 'category',
270
- data: names,
271
- },
272
- yAxis: {
273
- type: 'value',
274
- },
275
- series: [
276
- {
277
- type: 'bar',
278
- data: values,
279
- },
280
- ],
281
- };
282
- };
283
-
284
- /**
285
- * 检查是否有下钻数据
286
- */
287
- const hasDrillDownData = (dataItem: DrillDownSource | undefined): boolean => {
288
- if (!dataItem) return false;
289
- return !!(dataItem.children && dataItem.children.length > 0) || !!dataItem.chartOption;
290
- };
291
-
292
- /**
293
- * 执行下钻
294
- */
295
- const executeDrillDown = (params: any) => {
296
- const { config, chartInstance } = state;
297
- if (!chartInstance) return;
298
-
299
- const { name, value } = params;
300
-
301
- // 在当前层级的数据中查找匹配项
302
- let matchedSource: DrillDownSource | undefined;
303
-
304
- // 尝试从 history 中获取当前层级的数据源
305
- const currentLevelSources = getCurrentLevelSources();
306
- matchedSource = currentLevelSources.find(
307
- (s) => String(s.name) === String(name) || s.value === value
308
- );
309
-
310
- // 如果没找到,尝试在 initialSources 中查找
311
- if (!matchedSource && state.currentLevel === 0 && config.initialSources) {
312
- matchedSource = config.initialSources.find(
313
- (s) => String(s.name) === String(name) || s.value === value
314
- );
315
- }
316
-
317
- // 如果是最后一级(不能再下钻)或者找不到匹配项,不执行下钻
318
- if (!hasDrillDownData(matchedSource)) {
319
- console.warn('[DrillDown] No drill-down data available for:', name);
320
- return;
321
- }
322
-
323
- // 记录历史
324
- if (matchedSource) {
325
- state.history.push({ level: state.currentLevel, dataItem: matchedSource });
326
- }
327
-
328
- // 更新层级
329
- state.currentLevel += 1;
330
-
331
- // 获取新的图表配置
332
- const newOption = getDrillDownOption(state.currentLevel, matchedSource, 'down');
333
-
334
- // 更新图表
335
- if (newOption && Object.keys(newOption).length > 0) {
336
- chartInstance.setOption(newOption, true);
337
- state.currentOption = newOption;
338
- }
339
-
340
- // 触发回调
341
- config.onDrillDown?.({
342
- level: state.currentLevel,
343
- name: matchedSource?.name ?? name,
344
- value: matchedSource?.value ?? value,
345
- sources: matchedSource?.children ?? [],
346
- chartOption: newOption,
347
- rawParams: params,
348
- });
349
- };
350
-
351
- /**
352
- * 获取当前层级的数据源列表
353
- */
354
- const getCurrentLevelSources = (): DrillDownSource[] => {
355
- const { config } = state;
356
-
357
- if (state.currentLevel === 0) {
358
- // 第 0 层:使用 initialSources 或从 dimension 匹配
359
- if (config.initialSources) {
360
- return config.initialSources;
361
- }
362
- return [];
363
- }
364
-
365
- // 其他层级:从 history 中找到上一层点击的数据项的 children
366
- const lastHistory = state.history[state.history.length - 1];
367
- if (lastHistory && lastHistory.dataItem.children) {
368
- return lastHistory.dataItem.children;
369
- }
370
-
371
- return [];
372
- };
373
-
374
221
  // ============================================================
375
222
  // 实例方法
376
223
  // ============================================================
377
224
 
378
- const init = (chartInstance: any, config: DrillDownConfig): void => {
225
+ const init = (chartInstance: ECharts, config: DrillDownConfig): void => {
379
226
  if (!chartInstance) {
380
227
  console.error('[DrillDown] Invalid chart instance');
381
228
  return;
@@ -400,69 +247,16 @@ export function createDrillDown(initialConfig?: Partial<DrillDownConfig>): Drill
400
247
  };
401
248
 
402
249
  const drillUp = (): void => {
403
- const { config, chartInstance } = state;
404
- if (!chartInstance || state.currentLevel <= 0) {
405
- console.warn('[DrillDown] Cannot drill up: already at top level');
406
- return;
407
- }
408
-
409
- const previousLevel = state.currentLevel;
410
-
411
- // 弹出历史
412
- state.history.pop();
413
-
414
- // 更新层级
415
- state.currentLevel -= 1;
416
-
417
- // 获取新的图表配置
418
- const newOption = getDrillDownOption(state.currentLevel, undefined, 'up');
419
-
420
- // 更新图表
421
- if (newOption && Object.keys(newOption).length > 0) {
422
- chartInstance.setOption(newOption, true);
423
- state.currentOption = newOption;
424
- } else if (state.currentLevel === 0 && state.initialOption) {
425
- chartInstance.setOption(state.initialOption, true);
426
- state.currentOption = state.initialOption;
427
- }
428
-
429
- // 触发回调
430
- config.onDrillUp?.({
431
- previousLevel,
432
- currentLevel: state.currentLevel,
433
- chartOption: newOption,
434
- });
250
+ executeDrillUp(state, state.config);
435
251
  };
436
252
 
437
253
  const reset = (): void => {
438
- const { config, chartInstance } = state;
439
- if (!chartInstance) return;
440
-
441
- const previousLevel = state.currentLevel;
442
-
443
- // 清空历史
444
- state.history = [];
445
- state.currentLevel = 0;
446
-
447
- // 获取初始配置
448
- const newOption = getDrillDownOption(0, undefined, 'reset');
449
-
450
- // 更新图表
451
- if (newOption && Object.keys(newOption).length > 0) {
452
- chartInstance.setOption(newOption, true);
453
- state.currentOption = newOption;
454
- } else if (state.initialOption && Object.keys(state.initialOption).length > 0) {
455
- chartInstance.setOption(state.initialOption, true);
456
- state.currentOption = state.initialOption;
457
- }
458
-
459
- // 触发回调
460
- config.onReset?.({ level: 0 });
254
+ executeReset(state, state.config);
461
255
  };
462
256
 
463
257
  const getCurrentLevel = (): number => state.currentLevel;
464
258
 
465
- const bindClick = (chartInstance: any): void => {
259
+ const bindClick = (chartInstance: ECharts): void => {
466
260
  const instance = chartInstance || state.chartInstance;
467
261
  if (!instance) {
468
262
  console.error('[DrillDown] No chart instance to bind');
@@ -475,14 +269,14 @@ export function createDrillDown(initialConfig?: Partial<DrillDownConfig>): Drill
475
269
  }
476
270
 
477
271
  // 创建新的点击处理器
478
- state.clickHandler = (params: any) => {
479
- executeDrillDown(params);
272
+ state.clickHandler = (params: ECElementEvent) => {
273
+ executeDrillDown(params, state);
480
274
  };
481
275
 
482
276
  instance.on('click', state.clickHandler);
483
277
  };
484
278
 
485
- const unbindClick = (chartInstance: any): void => {
279
+ const unbindClick = (chartInstance: ECharts): void => {
486
280
  const instance = chartInstance || state.chartInstance;
487
281
  if (!instance || !state.clickHandler) return;
488
282
 
@@ -491,80 +285,26 @@ export function createDrillDown(initialConfig?: Partial<DrillDownConfig>): Drill
491
285
  };
492
286
 
493
287
  const drillTo = (level: number, dataItem?: DrillDownSource): void => {
494
- const { chartInstance, config } = state;
495
- if (!chartInstance) return;
496
-
497
- if (level < 0 || level > state.history.length) {
498
- console.warn('[DrillDown] Invalid drill level:', level);
499
- return;
500
- }
501
-
502
- const previousLevel = state.currentLevel;
503
- state.currentLevel = level;
504
-
505
- if (level === state.history.length) {
506
- // 下钻
507
- if (dataItem) {
508
- state.history.push({ level: level - 1, dataItem });
509
- }
510
- } else if (level < state.history.length) {
511
- // 上钻或跳转:调整 history
512
- state.history = state.history.slice(0, level);
513
- } else {
514
- // level === 0, reset
515
- state.history = [];
516
- }
517
-
518
- const newOption = getDrillDownOption(level, dataItem, level === 0 ? 'reset' : 'down');
519
-
520
- if (newOption && Object.keys(newOption).length > 0) {
521
- chartInstance.setOption(newOption, true);
522
- state.currentOption = newOption;
523
- }
524
-
525
- if (level > previousLevel) {
526
- config.onDrillDown?.({
527
- level,
528
- name: dataItem?.name ?? '',
529
- value: dataItem?.value ?? 0,
530
- sources: dataItem?.children ?? [],
531
- chartOption: newOption,
532
- rawParams: {},
533
- });
534
- } else if (level < previousLevel) {
535
- config.onDrillUp?.({
536
- previousLevel,
537
- currentLevel: level,
538
- chartOption: newOption,
539
- });
540
- } else {
541
- config.onReset?.({ level: 0 });
542
- }
288
+ executeDrillTo(level, dataItem, state, state.config);
543
289
  };
544
290
 
545
291
  const getHistory = (): Array<{ level: number; dataItem: DrillDownSource }> => {
546
292
  return [...state.history];
547
293
  };
548
294
 
549
- const canDrillUp = (): boolean => {
550
- return state.currentLevel > 0;
551
- };
295
+ const canDrillUp = (): boolean => state.currentLevel > 0;
552
296
 
553
297
  const dispose = (): void => {
554
298
  if (state.chartInstance && state.clickHandler) {
555
- unbindClick(state.chartInstance);
299
+ state.chartInstance.off('click', state.clickHandler);
556
300
  }
557
301
  state.chartInstance = null;
558
- state.config = {} as DrillDownConfig;
302
+ state.clickHandler = null;
559
303
  state.history = [];
560
304
  state.currentLevel = 0;
561
305
  state.initialized = false;
562
306
  };
563
307
 
564
- // ============================================================
565
- // 返回公开接口
566
- // ============================================================
567
-
568
308
  return {
569
309
  init,
570
310
  drillUp,
@@ -580,64 +320,5 @@ export function createDrillDown(initialConfig?: Partial<DrillDownConfig>): Drill
580
320
  }
581
321
 
582
322
  // ============================================================================
583
- // 辅助函数
323
+ // 导出
584
324
  // ============================================================================
585
-
586
- /**
587
- * 判断 DrillDownSource 是否有下钻能力
588
- */
589
- export function canDrillDown(source: DrillDownSource): boolean {
590
- return !!(source.children && source.children.length > 0) || !!source.chartOption;
591
- }
592
-
593
- /**
594
- * 从扁平数据构建层级结构(辅助函数)
595
- */
596
- export function buildHierarchy(
597
- data: Array<{ [key: string]: unknown }>,
598
- dimensionKey: string,
599
- valueKey: string,
600
- childrenKey: string = 'children'
601
- ): DrillDownSource[] {
602
- const sourceMap: Record<string, DrillDownSource[]> = {};
603
-
604
- data.forEach((item) => {
605
- const dimValue = String(item[dimensionKey]);
606
- if (!sourceMap[dimValue]) {
607
- sourceMap[dimValue] = [];
608
- }
609
- sourceMap[dimValue].push({
610
- name: item[dimensionKey] as string | number,
611
- value: item[valueKey] as string | number,
612
- children: item[childrenKey]
613
- ? buildHierarchy(item[childrenKey] as Array<{ [key: string]: unknown }>, dimensionKey, valueKey, childrenKey)
614
- : undefined,
615
- });
616
- });
617
-
618
- return Object.values(sourceMap).flat();
619
- }
620
-
621
- /**
622
- * 创建典型的地区下钻示例配置
623
- */
624
- export function createRegionDrillDown(
625
- regionData: Record<string, DrillDownSource[]>
626
- ): DrillDownConfig {
627
- return {
628
- dimension: 'region',
629
- sources: regionData,
630
- };
631
- }
632
-
633
- /**
634
- * 创建典型的分类下钻示例配置
635
- */
636
- export function createCategoryDrillDown(
637
- categoryData: Record<string, DrillDownSource[]>
638
- ): DrillDownConfig {
639
- return {
640
- dimension: 'category',
641
- sources: categoryData,
642
- };
643
- }