@agions/taroviz 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/README.md +318 -53
  2. package/dist/index.esm.js +67955 -3318
  3. package/package.json +102 -20
  4. package/src/__tests__/integration.test.tsx +168 -0
  5. package/src/adapters/__tests__/index.test.ts +91 -0
  6. package/src/adapters/h5/__tests__/index.test.ts +156 -0
  7. package/src/adapters/h5/index.ts +301 -0
  8. package/src/adapters/harmony/index.ts +274 -0
  9. package/src/adapters/index.ts +234 -0
  10. package/src/adapters/swan/index.ts +274 -0
  11. package/src/adapters/tt/index.ts +274 -0
  12. package/src/adapters/types.ts +162 -0
  13. package/src/adapters/weapp/index.ts +237 -0
  14. package/src/charts/bar/__tests__/index.test.tsx +113 -0
  15. package/src/charts/bar/index.tsx +27 -0
  16. package/src/charts/common/BaseChartWrapper.tsx +136 -0
  17. package/src/charts/funnel/index.tsx +33 -0
  18. package/src/charts/gauge/index.tsx +33 -0
  19. package/src/charts/heatmap/index.tsx +33 -0
  20. package/src/charts/index.ts +21 -0
  21. package/src/charts/line/__tests__/index.test.tsx +107 -0
  22. package/src/charts/line/index.tsx +27 -0
  23. package/src/charts/pie/__tests__/index.test.tsx +112 -0
  24. package/src/charts/pie/index.tsx +22 -0
  25. package/src/charts/radar/index.tsx +33 -0
  26. package/src/charts/scatter/index.tsx +33 -0
  27. package/src/charts/types.ts +146 -0
  28. package/src/charts/utils.ts +56 -0
  29. package/src/core/__tests__/platform.test.ts +48 -0
  30. package/src/core/animation/AnimationManager.ts +391 -0
  31. package/src/core/animation/index.ts +20 -0
  32. package/src/core/animation/types.ts +248 -0
  33. package/src/core/components/BaseChart.tsx +1319 -0
  34. package/src/core/index.ts +19 -0
  35. package/src/core/types/chart.ts +66 -0
  36. package/src/core/types/common.ts +224 -0
  37. package/src/core/types/index.ts +281 -0
  38. package/src/core/types/platform.ts +325 -0
  39. package/src/core/utils/__tests__/common.test.ts +52 -0
  40. package/src/core/utils/__tests__/environment.test.ts +94 -0
  41. package/src/core/utils/__tests__/i18n.test.ts +247 -0
  42. package/src/core/utils/__tests__/index.test.ts +219 -0
  43. package/src/core/utils/__tests__/uuid.test.ts +78 -0
  44. package/src/core/utils/chartInstances.ts +69 -0
  45. package/src/core/utils/codeGenerator/CodeGenerator.ts +655 -0
  46. package/src/core/utils/codeGenerator/index.ts +13 -0
  47. package/src/core/utils/codeGenerator/types.ts +200 -0
  48. package/src/core/utils/common.ts +58 -0
  49. package/src/core/utils/configGenerator/ConfigGenerator.ts +583 -0
  50. package/src/core/utils/configGenerator/index.ts +13 -0
  51. package/src/core/utils/configGenerator/types.ts +445 -0
  52. package/src/core/utils/debug/DebugPanel.tsx +637 -0
  53. package/src/core/utils/debug/debugger.ts +322 -0
  54. package/src/core/utils/debug/index.ts +21 -0
  55. package/src/core/utils/debug/types.ts +142 -0
  56. package/src/core/utils/i18n.ts +452 -0
  57. package/src/core/utils/index.ts +162 -0
  58. package/src/core/utils/performance/PerformanceAnalyzer.ts +586 -0
  59. package/src/core/utils/performance/index.ts +13 -0
  60. package/src/core/utils/performance/types.ts +180 -0
  61. package/src/core/utils/uuid.ts +30 -0
  62. package/src/editor/ThemeEditor.tsx +449 -0
  63. package/src/editor/index.ts +10 -0
  64. package/src/hooks/__tests__/index.test.tsx +333 -0
  65. package/src/hooks/index.ts +214 -0
  66. package/src/index.ts +75 -0
  67. package/src/main.tsx +247 -0
  68. package/src/react-dom.d.ts +7 -0
  69. package/src/themes/__tests__/index.test.ts +91 -0
  70. package/src/themes/index.ts +465 -0
  71. package/dist/index.esm.js.map +0 -1
  72. package/dist/index.js +0 -4012
  73. package/dist/index.js.map +0 -1
@@ -0,0 +1,33 @@
1
+ /**
2
+ * 雷达图组件
3
+ */
4
+ import { RadarChart as RadarChartComponent } from 'echarts/charts';
5
+ import {
6
+ GridComponent,
7
+ TooltipComponent,
8
+ TitleComponent,
9
+ LegendComponent,
10
+ } from 'echarts/components';
11
+ import * as echarts from 'echarts/core';
12
+ import React from 'react';
13
+
14
+ import BaseChartWrapper from '../common/BaseChartWrapper';
15
+ import { RadarChartProps } from '../types';
16
+
17
+ // 注册必要的组件
18
+ echarts.use([
19
+ RadarChartComponent,
20
+ GridComponent,
21
+ TooltipComponent,
22
+ TitleComponent,
23
+ LegendComponent,
24
+ ]);
25
+
26
+ /**
27
+ * 雷达图组件
28
+ */
29
+ const RadarChart: React.FC<RadarChartProps> = props => (
30
+ <BaseChartWrapper {...props} chartType="radar-chart" />
31
+ );
32
+
33
+ export default RadarChart;
@@ -0,0 +1,33 @@
1
+ /**
2
+ * 散点图组件
3
+ */
4
+ import { ScatterChart as ScatterChartComponent } from 'echarts/charts';
5
+ import {
6
+ GridComponent,
7
+ TooltipComponent,
8
+ TitleComponent,
9
+ LegendComponent,
10
+ } from 'echarts/components';
11
+ import * as echarts from 'echarts/core';
12
+ import React from 'react';
13
+
14
+ import BaseChartWrapper from '../common/BaseChartWrapper';
15
+ import { ScatterChartProps } from '../types';
16
+
17
+ // 注册必要的组件
18
+ echarts.use([
19
+ ScatterChartComponent,
20
+ GridComponent,
21
+ TooltipComponent,
22
+ TitleComponent,
23
+ LegendComponent,
24
+ ]);
25
+
26
+ /**
27
+ * 散点图组件
28
+ */
29
+ const ScatterChart: React.FC<ScatterChartProps> = props => (
30
+ <BaseChartWrapper {...props} chartType="scatter-chart" />
31
+ );
32
+
33
+ export default ScatterChart;
@@ -0,0 +1,146 @@
1
+ /**
2
+ * TaroViz Charts 类型定义
3
+ */
4
+ import * as echarts from 'echarts/core';
5
+
6
+ import { EChartsOption } from '../core';
7
+
8
+ /**
9
+ * 图表组件基本属性
10
+ */
11
+ export interface BaseChartProps {
12
+ /**
13
+ * 图表配置项
14
+ */
15
+ option: EChartsOption;
16
+
17
+ /**
18
+ * 宽度
19
+ */
20
+ width?: number | string;
21
+
22
+ /**
23
+ * 高度
24
+ */
25
+ height?: number | string;
26
+
27
+ /**
28
+ * 主题
29
+ */
30
+ theme?: string | object;
31
+
32
+ /**
33
+ * 样式
34
+ */
35
+ style?: React.CSSProperties;
36
+
37
+ /**
38
+ * 类名
39
+ */
40
+ className?: string;
41
+
42
+ /**
43
+ * 是否自动调整大小
44
+ */
45
+ autoResize?: boolean;
46
+
47
+ /**
48
+ * 是否显示加载动画
49
+ */
50
+ loading?: boolean;
51
+
52
+ /**
53
+ * 加载动画配置
54
+ */
55
+ loadingOption?: object;
56
+
57
+ /**
58
+ * 图表实例初始化回调
59
+ */
60
+ onChartInit?: (chart: echarts.ECharts) => void;
61
+
62
+ /**
63
+ * 图表准备好的回调
64
+ */
65
+ onChartReady?: (chart: echarts.ECharts) => void;
66
+
67
+ /**
68
+ * 渲染器类型
69
+ */
70
+ renderer?: 'canvas' | 'svg';
71
+
72
+ /**
73
+ * 事件回调
74
+ */
75
+ onEvents?: Record<string, (params: any) => void>;
76
+ }
77
+
78
+ /**
79
+ * 折线图属性
80
+ */
81
+ export interface LineChartProps extends BaseChartProps {
82
+ // 折线图特有属性
83
+ }
84
+
85
+ /**
86
+ * 柱状图属性
87
+ */
88
+ export interface BarChartProps extends BaseChartProps {
89
+ // 柱状图特有属性
90
+ }
91
+
92
+ /**
93
+ * 饼图属性
94
+ */
95
+ export interface PieChartProps extends BaseChartProps {
96
+ // 饼图特有属性
97
+ }
98
+
99
+ /**
100
+ * 散点图属性
101
+ */
102
+ export interface ScatterChartProps extends BaseChartProps {
103
+ // 散点图特有属性
104
+ }
105
+
106
+ /**
107
+ * 雷达图属性
108
+ */
109
+ export interface RadarChartProps extends BaseChartProps {
110
+ // 雷达图特有属性
111
+ }
112
+
113
+ /**
114
+ * 漏斗图属性
115
+ */
116
+ export interface FunnelChartProps extends BaseChartProps {
117
+ // 漏斗图特有属性
118
+ }
119
+
120
+ /**
121
+ * 仪表盘属性
122
+ */
123
+ export interface GaugeChartProps extends BaseChartProps {
124
+ // 仪表盘特有属性
125
+ }
126
+
127
+ /**
128
+ * 热力图属性
129
+ */
130
+ export interface HeatmapChartProps extends BaseChartProps {
131
+ // 热力图特有属性
132
+ }
133
+
134
+ /**
135
+ * 树图属性
136
+ */
137
+ export interface TreeChartProps extends BaseChartProps {
138
+ // 树图特有属性
139
+ }
140
+
141
+ /**
142
+ * 旭日图属性
143
+ */
144
+ export interface SunburstChartProps extends BaseChartProps {
145
+ // 旭日图特有属性
146
+ }
@@ -0,0 +1,56 @@
1
+ /**
2
+ * TaroViz 图表工具函数
3
+ */
4
+
5
+ /**
6
+ * 处理适配器配置参数类型
7
+ * 解决类型不匹配问题
8
+ */
9
+ export function processAdapterConfig(config: {
10
+ width?: string | number;
11
+ height?: string | number;
12
+ theme?: string | object;
13
+ autoResize?: boolean;
14
+ canvasId?: string;
15
+ containerRef?: any;
16
+ option?: any;
17
+ renderer?: 'canvas' | 'svg';
18
+ [key: string]: any;
19
+ }): any {
20
+ // 将复杂类型转换为简单类型
21
+ const processedConfig = {
22
+ width: typeof config.width === 'number' ? config.width : undefined,
23
+ height: typeof config.height === 'number' ? config.height : undefined,
24
+ theme: typeof config.theme === 'string' ? config.theme : undefined,
25
+ autoResize: config.autoResize,
26
+ canvasId: config.canvasId,
27
+ containerRef: config.containerRef,
28
+ option: config.option,
29
+ renderer: config.renderer,
30
+ };
31
+
32
+ // 复制其他可能存在的属性
33
+ const result: Record<string, any> = { ...processedConfig };
34
+ Object.keys(config).forEach(key => {
35
+ if (!(key in processedConfig)) {
36
+ result[key] = config[key];
37
+ }
38
+ });
39
+
40
+ return result;
41
+ }
42
+
43
+ /**
44
+ * 安全地调用适配器渲染方法
45
+ * 解决 render 方法可能不存在的问题
46
+ */
47
+ export function safeRenderAdapter(adapter: any): JSX.Element | null {
48
+ if (adapter && typeof adapter.render === 'function') {
49
+ try {
50
+ return adapter.render();
51
+ } catch (error) {
52
+ console.error('[TaroViz] Error rendering adapter:', error);
53
+ }
54
+ }
55
+ return null;
56
+ }
@@ -0,0 +1,48 @@
1
+ import { PlatformType } from '../index';
2
+
3
+ describe('Platform Core Tests', () => {
4
+ describe('PlatformType', () => {
5
+ it('should have correct enum values', () => {
6
+ // 测试PlatformType枚举值
7
+ expect(PlatformType.H5).toBe('h5');
8
+ expect(PlatformType.WEAPP).toBe('weapp');
9
+ expect(PlatformType.ALIPAY).toBe('alipay');
10
+ expect(PlatformType.SWAN).toBe('swan');
11
+ expect(PlatformType.TT).toBe('tt');
12
+ expect(PlatformType.QQ).toBe('qq');
13
+ expect(PlatformType.JD).toBe('jd');
14
+ expect(PlatformType.DD).toBe('dd');
15
+ expect(PlatformType.QYWX).toBe('qywx');
16
+ expect(PlatformType.LARK).toBe('lark');
17
+ expect(PlatformType.HARMONY).toBe('harmony');
18
+ });
19
+
20
+ it('should have all expected platform types', () => {
21
+ // 测试所有预期的平台类型都存在
22
+ const expectedPlatforms = [
23
+ 'h5',
24
+ 'weapp',
25
+ 'alipay',
26
+ 'swan',
27
+ 'tt',
28
+ 'qq',
29
+ 'jd',
30
+ 'dd',
31
+ 'qywx',
32
+ 'lark',
33
+ 'harmony',
34
+ ];
35
+
36
+ const actualPlatforms = Object.values(PlatformType);
37
+ expectedPlatforms.forEach(platform => {
38
+ expect(actualPlatforms).toContain(platform);
39
+ });
40
+ });
41
+
42
+ it('should be usable as a type', () => {
43
+ // 测试PlatformType作为类型的使用
44
+ const platform: PlatformType = PlatformType.H5;
45
+ expect(platform).toBe('h5');
46
+ });
47
+ });
48
+ });
@@ -0,0 +1,391 @@
1
+ /**
2
+ * TaroViz 动画管理器
3
+ * 负责管理图表动画的配置、预设和执行
4
+ */
5
+
6
+ import {
7
+ AnimationConfig,
8
+ AnimationPreset,
9
+ AnimationTemplate,
10
+ AnimationManagerConfig,
11
+ AnimationType,
12
+ AnimationEventType,
13
+ } from './types';
14
+
15
+ /**
16
+ * 动画预设集合
17
+ */
18
+ const DEFAULT_ANIMATION_PRESETS: AnimationPreset[] = [
19
+ {
20
+ name: 'default',
21
+ description: '默认动画配置',
22
+ config: {
23
+ enabled: true,
24
+ duration: 1000,
25
+ easing: 'cubicOut',
26
+ appearDuration: 1200,
27
+ appearEasing: 'cubicOut',
28
+ updateDuration: 800,
29
+ updateEasing: 'cubicOut',
30
+ disappearDuration: 600,
31
+ disappearEasing: 'cubicIn',
32
+ threshold: 1000,
33
+ progressive: true,
34
+ progressiveStep: 500,
35
+ },
36
+ },
37
+ {
38
+ name: 'fast',
39
+ description: '快速动画配置',
40
+ config: {
41
+ enabled: true,
42
+ duration: 500,
43
+ easing: 'linear',
44
+ appearDuration: 600,
45
+ appearEasing: 'linear',
46
+ updateDuration: 400,
47
+ updateEasing: 'linear',
48
+ disappearDuration: 300,
49
+ disappearEasing: 'linear',
50
+ threshold: 2000,
51
+ progressive: true,
52
+ progressiveStep: 1000,
53
+ },
54
+ },
55
+ {
56
+ name: 'slow',
57
+ description: '慢速动画配置',
58
+ config: {
59
+ enabled: true,
60
+ duration: 2000,
61
+ easing: 'cubicInOut',
62
+ appearDuration: 2400,
63
+ appearEasing: 'cubicInOut',
64
+ updateDuration: 1600,
65
+ updateEasing: 'cubicInOut',
66
+ disappearDuration: 1200,
67
+ disappearEasing: 'cubicInOut',
68
+ threshold: 500,
69
+ progressive: true,
70
+ progressiveStep: 250,
71
+ },
72
+ },
73
+ {
74
+ name: 'bounce',
75
+ description: '弹跳动画配置',
76
+ config: {
77
+ enabled: true,
78
+ duration: 1500,
79
+ easing: 'bounceOut',
80
+ appearDuration: 1800,
81
+ appearEasing: 'bounceOut',
82
+ updateDuration: 1200,
83
+ updateEasing: 'bounceOut',
84
+ disappearDuration: 900,
85
+ disappearEasing: 'bounceIn',
86
+ threshold: 500,
87
+ progressive: true,
88
+ progressiveStep: 250,
89
+ },
90
+ },
91
+ {
92
+ name: 'elastic',
93
+ description: '弹性动画配置',
94
+ config: {
95
+ enabled: true,
96
+ duration: 1500,
97
+ easing: 'elasticOut',
98
+ appearDuration: 1800,
99
+ appearEasing: 'elasticOut',
100
+ updateDuration: 1200,
101
+ updateEasing: 'elasticOut',
102
+ disappearDuration: 900,
103
+ disappearEasing: 'elasticIn',
104
+ threshold: 500,
105
+ progressive: true,
106
+ progressiveStep: 250,
107
+ },
108
+ },
109
+ ];
110
+
111
+ /**
112
+ * 动画管理器类
113
+ */
114
+ export class AnimationManager {
115
+ private static instance: AnimationManager;
116
+ private presets: Map<string, AnimationPreset> = new Map();
117
+ private templates: Map<string, AnimationTemplate> = new Map();
118
+ private defaultConfig: AnimationConfig;
119
+ private performanceConfig: AnimationManagerConfig['performance'];
120
+ private eventHandlers: Map<string, Set<(event: any) => void>> = new Map();
121
+
122
+ /**
123
+ * 私有构造函数
124
+ */
125
+ private constructor(config?: AnimationManagerConfig) {
126
+ // 初始化默认配置
127
+ this.defaultConfig = config?.defaultConfig || DEFAULT_ANIMATION_PRESETS[0].config;
128
+ this.performanceConfig = config?.performance || {
129
+ monitor: false,
130
+ frameRate: 60,
131
+ hardwareAcceleration: true,
132
+ };
133
+
134
+ // 注册默认预设
135
+ this.registerPresets(DEFAULT_ANIMATION_PRESETS);
136
+ }
137
+
138
+ /**
139
+ * 获取动画管理器实例
140
+ */
141
+ public static getInstance(config?: AnimationManagerConfig): AnimationManager {
142
+ if (!AnimationManager.instance) {
143
+ AnimationManager.instance = new AnimationManager(config);
144
+ }
145
+ return AnimationManager.instance;
146
+ }
147
+
148
+ /**
149
+ * 注册动画预设
150
+ */
151
+ public registerPreset(preset: AnimationPreset): void {
152
+ this.presets.set(preset.name, preset);
153
+ }
154
+
155
+ /**
156
+ * 批量注册动画预设
157
+ */
158
+ public registerPresets(presets: AnimationPreset[]): void {
159
+ presets.forEach(preset => this.registerPreset(preset));
160
+ }
161
+
162
+ /**
163
+ * 获取动画预设
164
+ */
165
+ public getPreset(name: string): AnimationPreset | undefined {
166
+ return this.presets.get(name);
167
+ }
168
+
169
+ /**
170
+ * 获取所有动画预设
171
+ */
172
+ public getAllPresets(): AnimationPreset[] {
173
+ return Array.from(this.presets.values());
174
+ }
175
+
176
+ /**
177
+ * 注册动画模板
178
+ */
179
+ public registerTemplate(template: AnimationTemplate): void {
180
+ this.templates.set(template.name, template);
181
+ }
182
+
183
+ /**
184
+ * 获取动画模板
185
+ */
186
+ public getTemplate(name: string): AnimationTemplate | undefined {
187
+ return this.templates.get(name);
188
+ }
189
+
190
+ /**
191
+ * 获取所有动画模板
192
+ */
193
+ public getAllTemplates(): AnimationTemplate[] {
194
+ return Array.from(this.templates.values());
195
+ }
196
+
197
+ /**
198
+ * 设置默认动画配置
199
+ */
200
+ public setDefaultConfig(config: AnimationConfig): void {
201
+ this.defaultConfig = config;
202
+ }
203
+
204
+ /**
205
+ * 获取默认动画配置
206
+ */
207
+ public getDefaultConfig(): AnimationConfig {
208
+ return this.defaultConfig;
209
+ }
210
+
211
+ /**
212
+ * 根据数据量和动画类型获取优化后的动画配置
213
+ */
214
+ public getOptimizedConfig(
215
+ config: Partial<AnimationConfig> = {},
216
+ dataLength: number = 0
217
+ ): AnimationConfig {
218
+ // 合并配置:用户配置 > 默认配置
219
+ const mergedConfig: AnimationConfig = {
220
+ ...this.defaultConfig,
221
+ ...config,
222
+ };
223
+
224
+ // 根据数据量优化动画
225
+ if (mergedConfig.threshold && dataLength > mergedConfig.threshold) {
226
+ mergedConfig.enabled = false;
227
+ }
228
+
229
+ return mergedConfig;
230
+ }
231
+
232
+ /**
233
+ * 根据动画类型获取对应的动画配置
234
+ */
235
+ public getAnimationConfigByType(
236
+ config: AnimationConfig,
237
+ animationType: AnimationType
238
+ ): {
239
+ duration: number;
240
+ easing: string;
241
+ } {
242
+ switch (animationType) {
243
+ case 'appear':
244
+ return {
245
+ duration: config.appearDuration || config.duration || 1000,
246
+ easing: config.appearEasing || config.easing || 'cubicOut',
247
+ };
248
+ case 'update':
249
+ return {
250
+ duration: config.updateDuration || config.duration || 800,
251
+ easing: config.updateEasing || config.easing || 'cubicOut',
252
+ };
253
+ case 'disappear':
254
+ return {
255
+ duration: config.disappearDuration || config.duration || 600,
256
+ easing: config.disappearEasing || config.easing || 'cubicIn',
257
+ };
258
+ case 'emphasis':
259
+ return {
260
+ duration: config.duration || 300,
261
+ easing: config.easing || 'cubicOut',
262
+ };
263
+ default:
264
+ return {
265
+ duration: config.duration || 1000,
266
+ easing: config.easing || 'cubicOut',
267
+ };
268
+ }
269
+ }
270
+
271
+ /**
272
+ * 生成ECharts动画配置
273
+ */
274
+ public generateEChartsAnimationConfig(
275
+ config: Partial<AnimationConfig> = {},
276
+ dataLength: number = 0
277
+ ): any {
278
+ const optimizedConfig = this.getOptimizedConfig(config, dataLength);
279
+
280
+ if (!optimizedConfig.enabled) {
281
+ return {
282
+ animation: false,
283
+ };
284
+ }
285
+
286
+ return {
287
+ animation: true,
288
+ animationDuration: optimizedConfig.duration,
289
+ animationEasing: optimizedConfig.easing,
290
+ animationDelay: optimizedConfig.delay,
291
+ animationDurationUpdate: optimizedConfig.updateDuration,
292
+ animationEasingUpdate: optimizedConfig.updateEasing,
293
+ animationDelayUpdate: optimizedConfig.delay,
294
+ animationThreshold: optimizedConfig.threshold,
295
+ progressive: optimizedConfig.progressive,
296
+ progressiveThreshold: optimizedConfig.progressiveStep,
297
+ progressiveChunkMode: 'sequential',
298
+ };
299
+ }
300
+
301
+ /**
302
+ * 绑定动画事件
303
+ */
304
+ public on(eventType: AnimationEventType, handler: (event: any) => void): void {
305
+ if (!this.eventHandlers.has(eventType)) {
306
+ this.eventHandlers.set(eventType, new Set());
307
+ }
308
+ this.eventHandlers.get(eventType)?.add(handler);
309
+ }
310
+
311
+ /**
312
+ * 解绑动画事件
313
+ */
314
+ public off(eventType: AnimationEventType, handler?: (event: any) => void): void {
315
+ if (!handler) {
316
+ this.eventHandlers.delete(eventType);
317
+ return;
318
+ }
319
+ this.eventHandlers.get(eventType)?.delete(handler);
320
+ }
321
+
322
+ /**
323
+ * 触发动画事件
324
+ */
325
+ public emit(eventType: AnimationEventType, data: any): void {
326
+ const handlers = this.eventHandlers.get(eventType);
327
+ if (handlers) {
328
+ handlers.forEach(handler => {
329
+ try {
330
+ handler(data);
331
+ } catch (error) {
332
+ console.error(`Error in animation event handler:`, error);
333
+ }
334
+ });
335
+ }
336
+ }
337
+
338
+ /**
339
+ * 更新性能配置
340
+ */
341
+ public updatePerformanceConfig(config: AnimationManagerConfig['performance']): void {
342
+ this.performanceConfig = {
343
+ ...this.performanceConfig,
344
+ ...config,
345
+ };
346
+ }
347
+
348
+ /**
349
+ * 获取性能配置
350
+ */
351
+ public getPerformanceConfig(): AnimationManagerConfig['performance'] {
352
+ return this.performanceConfig;
353
+ }
354
+
355
+ /**
356
+ * 重置动画管理器
357
+ */
358
+ public reset(): void {
359
+ this.presets.clear();
360
+ this.templates.clear();
361
+ this.eventHandlers.clear();
362
+ this.registerPresets(DEFAULT_ANIMATION_PRESETS);
363
+ }
364
+ }
365
+
366
+ /**
367
+ * 创建动画配置
368
+ */
369
+ export function createAnimationConfig(config: Partial<AnimationConfig> = {}): AnimationConfig {
370
+ const manager = AnimationManager.getInstance();
371
+ return manager.getOptimizedConfig(config);
372
+ }
373
+
374
+ /**
375
+ * 获取动画预设配置
376
+ */
377
+ export function getAnimationPreset(name: string): AnimationPreset | undefined {
378
+ const manager = AnimationManager.getInstance();
379
+ return manager.getPreset(name);
380
+ }
381
+
382
+ /**
383
+ * 生成ECharts动画配置
384
+ */
385
+ export function generateEChartsAnimationConfig(
386
+ config: Partial<AnimationConfig> = {},
387
+ dataLength: number = 0
388
+ ): any {
389
+ const manager = AnimationManager.getInstance();
390
+ return manager.generateEChartsAnimationConfig(config, dataLength);
391
+ }