@agions/taroviz 1.3.1 → 1.6.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 (64) hide show
  1. package/README.md +4 -4
  2. package/dist/cjs/index.js +1 -1
  3. package/dist/esm/index.js +3814 -2724
  4. package/package.json +1 -1
  5. package/src/__tests__/integration.test.tsx +12 -10
  6. package/src/adapters/BaseAdapter.ts +116 -0
  7. package/src/adapters/__tests__/index.test.ts +10 -10
  8. package/src/adapters/index.ts +63 -74
  9. package/src/adapters/swan/index.ts +26 -223
  10. package/src/adapters/tt/index.ts +28 -225
  11. package/src/adapters/types.ts +36 -0
  12. package/src/adapters/weapp/index.ts +29 -189
  13. package/src/charts/bar/index.tsx +5 -9
  14. package/src/charts/boxplot/__tests__/index.test.tsx +130 -0
  15. package/src/charts/boxplot/index.tsx +18 -0
  16. package/src/charts/boxplot/types.ts +46 -0
  17. package/src/charts/candlestick/__tests__/index.test.tsx +37 -0
  18. package/src/charts/candlestick/index.tsx +13 -0
  19. package/src/charts/common/BaseChartWrapper.tsx +47 -38
  20. package/src/charts/funnel/index.tsx +5 -9
  21. package/src/charts/gauge/index.tsx +5 -9
  22. package/src/charts/graph/__tests__/index.test.tsx +41 -0
  23. package/src/charts/graph/index.tsx +13 -0
  24. package/src/charts/heatmap/index.tsx +5 -9
  25. package/src/charts/index.ts +10 -1
  26. package/src/charts/line/index.tsx +4 -7
  27. package/src/charts/parallel/__tests__/index.test.tsx +164 -0
  28. package/src/charts/parallel/index.tsx +18 -0
  29. package/src/charts/parallel/types.ts +73 -0
  30. package/src/charts/pie/index.tsx +5 -10
  31. package/src/charts/radar/index.tsx +5 -9
  32. package/src/charts/scatter/index.tsx +5 -9
  33. package/src/charts/types.ts +48 -4
  34. package/src/charts/wordcloud/__tests__/index.test.tsx +36 -0
  35. package/src/charts/wordcloud/index.tsx +13 -0
  36. package/src/core/animation/AnimationManager.ts +15 -0
  37. package/src/core/components/Annotation.tsx +26 -21
  38. package/src/core/components/BaseChart.tsx +280 -1105
  39. package/src/core/components/ErrorBoundary.tsx +4 -1
  40. package/src/core/components/LazyChart.tsx +42 -55
  41. package/src/core/components/hooks/index.ts +20 -0
  42. package/src/core/components/hooks/useChartEvents.ts +143 -0
  43. package/src/core/components/hooks/useChartInit.ts +80 -0
  44. package/src/core/components/hooks/usePerformance.ts +186 -0
  45. package/src/core/components/hooks/useVirtualScroll.ts +156 -0
  46. package/src/core/echarts.ts +1 -1
  47. package/src/core/themes/ThemeManager.ts +31 -15
  48. package/src/core/types/index.ts +2 -2
  49. package/src/core/utils/chartInstances.ts +10 -3
  50. package/src/core/utils/chartUtils.ts +46 -0
  51. package/src/core/utils/common.ts +14 -1
  52. package/src/core/utils/export/ExportUtils.ts +13 -22
  53. package/src/core/utils/performance/PerformanceAnalyzer.ts +32 -5
  54. package/src/core/utils/uuid.ts +1 -1
  55. package/src/editor/EnhancedThemeEditor.tsx +624 -0
  56. package/src/editor/ThemeEditor.tsx +1 -6
  57. package/src/hooks/__tests__/index.test.tsx +14 -11
  58. package/src/hooks/__tests__/useDataTransform.test.ts +159 -0
  59. package/src/hooks/index.ts +54 -19
  60. package/src/hooks/useDataTransform.ts +503 -0
  61. package/src/index.ts +27 -9
  62. package/src/main.tsx +4 -4
  63. package/src/themes/__tests__/index.test.ts +2 -2
  64. package/src/themes/index.ts +13 -0
@@ -1,92 +1,26 @@
1
1
  /**
2
- * TaroViz 字节跳动小程序适配器
3
- * 基于字节跳动小程序canvas组件实现图表渲染
2
+ * TaroViz 抖音小程序适配器
3
+ * 基于抖音小程序canvas组件实现图表渲染
4
4
  */
5
- import * as React from 'react';
6
5
 
7
- import { Adapter, AdapterOptions } from '../types';
6
+ import { BaseAdapter } from '../BaseAdapter';
7
+ import type { Adapter, TTAdapterOptions } from '../types';
8
8
 
9
- // 扩展 AdapterOptions 类型
10
- interface ExtendedTTAdapterOptions extends AdapterOptions {
11
- /**
12
- * 字节跳动小程序组件实例
13
- */
14
- component?: any;
15
- /**
16
- * 画布ID
17
- */
18
- canvasId?: string;
19
- /**
20
- * 宽度
21
- */
22
- width?: number | string;
23
- /**
24
- * 高度
25
- */
26
- height?: number | string;
27
- /**
28
- * 主题
29
- */
30
- theme?: string | object;
31
- /**
32
- * 图表选项
33
- */
34
- option?: any;
35
- /**
36
- * 初始化回调
37
- */
38
- onInit?: (instance: any) => void;
39
- }
40
-
41
- /**
42
- * 字节跳动小程序环境下的图表适配器
43
- */
44
- class TTAdapter implements Adapter {
45
- /**
46
- * 配置项
47
- */
48
- private config: ExtendedTTAdapterOptions;
49
-
50
- /**
51
- * 图表实例
52
- */
53
- private chartInstance: any | null = null;
54
-
55
- /**
56
- * 组件实例
57
- */
58
- private component: any | null = null;
9
+ export class TTAdapter extends BaseAdapter {
10
+ private component: unknown = null;
59
11
 
60
- /**
61
- * 构造函数
62
- * @param config 适配器配置
63
- */
64
- constructor(config: ExtendedTTAdapterOptions) {
65
- this.config = config;
12
+ constructor(config: TTAdapterOptions) {
13
+ super(config);
66
14
  this.component = config.component;
67
15
  }
68
16
 
69
- /**
70
- * 创建字节跳动小程序适配器实例
71
- * @param options 适配器选项
72
- * @returns 适配器实例
73
- */
74
- static create(options: ExtendedTTAdapterOptions): TTAdapter {
75
- return new TTAdapter(options);
17
+ static create(options: TTAdapterOptions): Adapter {
18
+ return new TTAdapter(options) as unknown as Adapter;
76
19
  }
77
20
 
78
- /**
79
- * 获取图表实例
80
- */
81
- getInstance(): any {
82
- return this.chartInstance;
83
- }
84
-
85
- /**
86
- * 初始化图表
87
- */
88
- init(): any {
89
- const { canvasId, width, height, theme, option } = this.config;
21
+ init(): unknown {
22
+ const config = this.config as TTAdapterOptions & { canvasId?: string };
23
+ const { canvasId, width, height, theme, option } = config;
90
24
 
91
25
  if (!this.component) {
92
26
  console.error('[TaroViz] TTAdapter: component is required');
@@ -98,176 +32,45 @@ class TTAdapter implements Adapter {
98
32
  return null;
99
33
  }
100
34
 
101
- // 创建图表实例
102
- const chart = this.component.createChart({
35
+ const chart = (this.component as { createChart: (config: unknown) => unknown }).createChart({
103
36
  id: canvasId,
104
- width: width,
105
- height: height,
106
- theme: theme,
37
+ width,
38
+ height,
39
+ theme,
107
40
  });
108
41
 
109
- // 设置图表选项
110
42
  if (option) {
111
- chart.setOption(option);
43
+ (chart as { setOption: (o: unknown) => void }).setOption(option);
112
44
  }
113
45
 
114
- // 存储图表实例
115
46
  this.chartInstance = chart;
116
47
 
117
- // 初始化回调
118
- if (this.config.onInit) {
119
- this.config.onInit(chart);
48
+ const onInit = this.config['onInit'] as ((instance: unknown) => void) | undefined;
49
+ if (onInit) {
50
+ onInit(chart);
120
51
  }
121
52
 
122
53
  return chart;
123
54
  }
124
55
 
125
- /**
126
- * 设置图表选项
127
- */
128
- setOption(option: any, opts?: any): void {
129
- if (this.chartInstance) {
130
- this.chartInstance.setOption(option, opts);
131
- } else {
132
- this.config.option = option;
133
- }
134
- }
135
-
136
- /**
137
- * 设置主题
138
- */
139
- setTheme(theme: string | object): void {
140
- this.config.theme = theme;
141
- if (this.chartInstance) {
142
- this.chartInstance.setTheme?.(theme);
143
- }
144
- }
145
-
146
- /**
147
- * 获取图表宽度
148
- */
149
56
  getWidth(): number {
150
- return 0;
57
+ return this.parseSize((this.config as TTAdapterOptions).width, 300);
151
58
  }
152
59
 
153
- /**
154
- * 获取图表高度
155
- */
156
60
  getHeight(): number {
157
- return 0;
158
- }
159
-
160
- /**
161
- * 获取DOM元素
162
- */
163
- getDom(): HTMLElement | null {
164
- return null;
165
- }
166
-
167
- /**
168
- * 转换为DataURL
169
- */
170
- convertToDataURL(opts?: any): string | undefined {
171
- return this.chartInstance?.getDataURL(opts);
172
- }
173
-
174
- /**
175
- * 清空图表
176
- */
177
- clear(): void {
178
- if (this.chartInstance) {
179
- this.chartInstance.clear();
180
- }
181
- }
182
-
183
- /**
184
- * 绑定事件
185
- */
186
- on(event: string, handler: (params: any) => void): void {
187
- if (this.chartInstance) {
188
- this.chartInstance.on(event, handler);
189
- }
190
- }
191
-
192
- /**
193
- * 解绑事件
194
- */
195
- off(event: string, handler?: (params: any) => void): void {
196
- if (this.chartInstance) {
197
- this.chartInstance.off(event, handler);
198
- }
199
- }
200
-
201
- /**
202
- * 显示加载动画
203
- */
204
- showLoading(opts?: object): void {
205
- if (this.chartInstance) {
206
- this.chartInstance.showLoading(opts);
207
- }
208
- }
209
-
210
- /**
211
- * 隐藏加载动画
212
- */
213
- hideLoading(): void {
214
- if (this.chartInstance) {
215
- this.chartInstance.hideLoading();
216
- }
61
+ return this.parseSize((this.config as TTAdapterOptions).height, 300);
217
62
  }
218
63
 
219
- /**
220
- * 销毁图表
221
- */
222
- dispose(): void {
223
- if (this.chartInstance) {
224
- this.chartInstance.dispose();
225
- this.chartInstance = null;
226
- }
227
- }
228
-
229
- /**
230
- * 处理图表大小变化
231
- */
232
- resize(opts?: any): void {
233
- if (this.chartInstance) {
234
- this.chartInstance.resize(opts);
235
- }
236
- }
237
-
238
- /**
239
- * 设置组件实例
240
- */
241
- setComponent(component: any): void {
64
+ setComponent(component: unknown): void {
242
65
  this.component = component;
243
66
  }
244
67
 
245
- /**
246
- * 渲染图表组件
247
- */
248
- render(): JSX.Element {
249
- const { canvasId = 'ec-canvas', width = '100%', height = '300px', style = {} } = this.config;
250
- // 注意:这里需要根据实际使用的Taro版本和组件库来调整
251
- return React.createElement('view', {
252
- id: canvasId,
253
- style: { width, height, ...style },
254
- });
255
- }
256
-
257
- /**
258
- * 触发图表行为
259
- */
260
- dispatchAction(payload: any): void {
261
- if (this.chartInstance) {
262
- this.chartInstance.dispatchAction(payload);
263
- }
68
+ dispatchAction(action: unknown): void {
69
+ (this.chartInstance as { dispatchAction?: (a: unknown) => void })?.dispatchAction?.(action);
264
70
  }
265
71
 
266
- /**
267
- * 获取DataURL
268
- */
269
- getDataURL(opts?: any): string | undefined {
270
- return this.chartInstance?.getDataURL(opts);
72
+ getDataURL(opts?: unknown): string | undefined {
73
+ return (this.chartInstance as { getDataURL?: (o?: unknown) => string })?.getDataURL?.(opts);
271
74
  }
272
75
  }
273
76
 
@@ -134,6 +134,42 @@ export interface DDAdapterOptions extends AdapterOptions {
134
134
  */
135
135
  }
136
136
 
137
+ /**
138
+ * 抖音小程序适配器选项
139
+ */
140
+ export interface TTAdapterOptions extends AdapterOptions {
141
+ /**
142
+ * 抖音小程序特有属性
143
+ */
144
+ }
145
+
146
+ /**
147
+ * QQ小程序适配器选项
148
+ */
149
+ export interface QQAdapterOptions extends AdapterOptions {
150
+ /**
151
+ * QQ小程序特有属性
152
+ */
153
+ }
154
+
155
+ /**
156
+ * 京东小程序适配器选项
157
+ */
158
+ export interface JDAdapterOptions extends AdapterOptions {
159
+ /**
160
+ * 京东小程序特有属性
161
+ */
162
+ }
163
+
164
+ /**
165
+ * 快手小程序适配器选项
166
+ */
167
+ export interface KwaiAdapterOptions extends AdapterOptions {
168
+ /**
169
+ * 快手小程序特有属性
170
+ */
171
+ }
172
+
137
173
  /**
138
174
  * 企业微信小程序适配器选项
139
175
  */
@@ -2,70 +2,25 @@
2
2
  * TaroViz 微信小程序适配器
3
3
  * 基于微信小程序canvas组件实现图表渲染
4
4
  */
5
- import * as React from 'react';
6
-
7
- import { Adapter, WeappAdapterOptions } from '../types';
8
-
9
- // 扩展 WeappAdapterOptions 类型
10
- interface ExtendedWeappAdapterOptions extends WeappAdapterOptions {
11
- component?: any;
12
- canvasId?: string;
13
- width?: number | string;
14
- height?: number | string;
15
- theme?: string | object;
16
- option?: any;
17
- onInit?: (instance: any) => void;
18
- }
19
5
 
20
- /**
21
- * 微信小程序环境下的图表适配器
22
- */
23
- class WeappAdapter implements Adapter {
24
- /**
25
- * 配置项
26
- */
27
- private config: ExtendedWeappAdapterOptions;
28
-
29
- /**
30
- * 图表实例
31
- */
32
- private chartInstance: any | null = null;
33
-
34
- /**
35
- * 组件实例
36
- */
37
- private component: any | null = null;
38
-
39
- /**
40
- * 构造函数
41
- * @param config 适配器配置
42
- */
43
- constructor(config: ExtendedWeappAdapterOptions) {
44
- this.config = config;
45
- this.component = config.component;
46
- }
6
+ import { BaseAdapter } from '../BaseAdapter';
7
+ import type { Adapter, WeappAdapterOptions } from '../types';
47
8
 
48
- /**
49
- * 创建微信小程序适配器实例
50
- * @param options 适配器选项
51
- * @returns 适配器实例
52
- */
53
- static create(options: ExtendedWeappAdapterOptions): WeappAdapter {
54
- return new WeappAdapter(options);
9
+ export class WeappAdapter extends BaseAdapter {
10
+ private component: unknown = null;
11
+
12
+ constructor(config: WeappAdapterOptions) {
13
+ super(config);
14
+ this.component = config.component;
55
15
  }
56
16
 
57
- /**
58
- * 获取图表实例
59
- */
60
- getInstance(): any {
61
- return this.chartInstance;
17
+ static create(options: WeappAdapterOptions): Adapter {
18
+ return new WeappAdapter(options) as unknown as Adapter;
62
19
  }
63
20
 
64
- /**
65
- * 初始化图表
66
- */
67
- init(): any {
68
- const { canvasId, width, height, theme, option } = this.config;
21
+ init(): unknown {
22
+ const config = this.config as WeappAdapterOptions & { canvasId?: string };
23
+ const { canvasId, width, height, theme, option } = config;
69
24
 
70
25
  if (!this.component) {
71
26
  console.error('[TaroViz] WeappAdapter: component is required');
@@ -77,160 +32,45 @@ class WeappAdapter implements Adapter {
77
32
  return null;
78
33
  }
79
34
 
80
- // 创建图表实例
81
- const chart = this.component.createChart({
35
+ const chart = (this.component as { createChart: (config: unknown) => unknown }).createChart({
82
36
  id: canvasId,
83
- width: width,
84
- height: height,
85
- theme: theme,
37
+ width,
38
+ height,
39
+ theme,
86
40
  });
87
41
 
88
- // 设置图表选项
89
42
  if (option) {
90
- chart.setOption(option);
43
+ (chart as { setOption: (o: unknown) => void }).setOption(option);
91
44
  }
92
45
 
93
- // 存储图表实例
94
46
  this.chartInstance = chart;
95
47
 
96
- // 初始化回调
97
- if (this.config.onInit) {
98
- this.config.onInit(chart);
48
+ const onInit = this.config['onInit'] as ((instance: unknown) => void) | undefined;
49
+ if (onInit) {
50
+ onInit(chart);
99
51
  }
100
52
 
101
53
  return chart;
102
54
  }
103
55
 
104
- /**
105
- * 设置图表选项
106
- */
107
- setOption(option: any, opts?: any): void {
108
- if (this.chartInstance) {
109
- this.chartInstance.setOption(option, opts);
110
- } else {
111
- this.config.option = option;
112
- }
113
- }
114
-
115
- /**
116
- * 设置主题
117
- */
118
- setTheme(theme: string | object): void {
119
- this.config.theme = theme;
120
- if (this.chartInstance) {
121
- this.chartInstance.setTheme?.(theme);
122
- }
123
- }
124
-
125
- /**
126
- * 获取图表宽度
127
- */
128
56
  getWidth(): number {
129
- return 0;
57
+ return this.parseSize((this.config as WeappAdapterOptions).width, 300);
130
58
  }
131
59
 
132
- /**
133
- * 获取图表高度
134
- */
135
60
  getHeight(): number {
136
- return 0;
137
- }
138
-
139
- /**
140
- * 获取DOM元素
141
- */
142
- getDom(): HTMLElement | null {
143
- return null;
144
- }
145
-
146
- /**
147
- * 转换为DataURL
148
- */
149
- convertToDataURL(opts?: any): string | undefined {
150
- return this.chartInstance?.getDataURL(opts);
151
- }
152
-
153
- /**
154
- * 清空图表
155
- */
156
- clear(): void {
157
- if (this.chartInstance) {
158
- this.chartInstance.clear();
159
- }
61
+ return this.parseSize((this.config as WeappAdapterOptions).height, 300);
160
62
  }
161
63
 
162
- /**
163
- * 绑定事件
164
- */
165
- on(event: string, handler: (params: any) => void): void {
166
- if (this.chartInstance) {
167
- this.chartInstance.on(event, handler);
168
- }
169
- }
170
-
171
- /**
172
- * 解绑事件
173
- */
174
- off(event: string, handler?: (params: any) => void): void {
175
- if (this.chartInstance) {
176
- this.chartInstance.off(event, handler);
177
- }
178
- }
179
-
180
- /**
181
- * 显示加载动画
182
- */
183
- showLoading(opts?: object): void {
184
- if (this.chartInstance) {
185
- this.chartInstance.showLoading(opts);
186
- }
187
- }
188
-
189
- /**
190
- * 隐藏加载动画
191
- */
192
- hideLoading(): void {
193
- if (this.chartInstance) {
194
- this.chartInstance.hideLoading();
195
- }
196
- }
197
-
198
- /**
199
- * 销毁图表
200
- */
201
- dispose(): void {
202
- if (this.chartInstance) {
203
- this.chartInstance.dispose();
204
- this.chartInstance = null;
205
- }
206
- }
207
-
208
- /**
209
- * 处理图表大小变化
210
- */
211
- resize(opts?: any): void {
212
- if (this.chartInstance) {
213
- this.chartInstance.resize(opts);
214
- }
64
+ setComponent(component: unknown): void {
65
+ this.component = component;
215
66
  }
216
67
 
217
- /**
218
- * 设置组件实例
219
- */
220
- setComponent(component: any): void {
221
- this.component = component;
68
+ dispatchAction(action: unknown): void {
69
+ (this.chartInstance as { dispatchAction?: (a: unknown) => void })?.dispatchAction?.(action);
222
70
  }
223
71
 
224
- /**
225
- * 渲染图表组件
226
- */
227
- render(): JSX.Element {
228
- const { canvasId = 'ec-canvas', width = '100%', height = '300px', style = {} } = this.config;
229
- // 注意:这里需要根据实际使用的Taro版本和组件库来调整
230
- return React.createElement('view', {
231
- id: canvasId,
232
- style: { width, height, ...style },
233
- });
72
+ getDataURL(opts?: unknown): string | undefined {
73
+ return (this.chartInstance as { getDataURL?: (o?: unknown) => string })?.getDataURL?.(opts);
234
74
  }
235
75
  }
236
76
 
@@ -1,18 +1,14 @@
1
1
  /**
2
- * 柱状图组件
2
+ * BarChart组件
3
3
  */
4
- import React from 'react';
5
-
4
+ import React, { memo } from 'react';
6
5
  import BaseChartWrapper from '../common/BaseChartWrapper';
7
6
  import { BarChartProps } from '../types';
8
-
9
7
  import '@/core/echarts';
10
8
 
11
- /**
12
- * 柱状图组件
13
- */
14
- const BarChart: React.FC<BarChartProps> = (props) => (
9
+ const BarChart: React.FC<BarChartProps> = memo((props) => (
15
10
  <BaseChartWrapper {...props} chartType="bar-chart" />
16
- );
11
+ ));
12
+ BarChart.displayName = 'BarChart';
17
13
 
18
14
  export default BarChart;