@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,333 @@
1
+ import { renderHook } from '@testing-library/react';
2
+ import React from 'react';
3
+
4
+ import {
5
+ useChart,
6
+ useOption,
7
+ useResize,
8
+ useEvents,
9
+ useLoading,
10
+ useChartTheme,
11
+ useChartData,
12
+ } from '../index';
13
+
14
+ // Mock dependencies
15
+ jest.mock('../../adapters', () => ({
16
+ getAdapter: jest.fn(() => ({
17
+ setComponent: jest.fn(),
18
+ setOption: jest.fn(),
19
+ resize: jest.fn(),
20
+ on: jest.fn(),
21
+ off: jest.fn(),
22
+ showLoading: jest.fn(),
23
+ hideLoading: jest.fn(),
24
+ dispose: jest.fn(),
25
+ })),
26
+ }));
27
+
28
+ describe('React Hooks', () => {
29
+ describe('useChart', () => {
30
+ it('should initialize chart instance when ref is available', () => {
31
+ const chartRef = { current: document.createElement('div') };
32
+
33
+ const { result, rerender } = renderHook(
34
+ (ref: React.RefObject<HTMLElement>) => useChart(ref),
35
+ { initialProps: chartRef }
36
+ );
37
+
38
+ rerender(chartRef);
39
+
40
+ expect(result.current[0]).not.toBeNull();
41
+ });
42
+
43
+ it('should return null when ref is not available', () => {
44
+ const chartRef = { current: null };
45
+
46
+ const { result } = renderHook((ref: React.RefObject<HTMLElement>) => useChart(ref), {
47
+ initialProps: chartRef,
48
+ });
49
+
50
+ expect(result.current[0]).toBeNull();
51
+ });
52
+ });
53
+
54
+ describe('useOption', () => {
55
+ it('should call setOption when instance and option are provided', () => {
56
+ const mockInstance = {
57
+ setOption: jest.fn(),
58
+ };
59
+
60
+ const option = { xAxis: { type: 'category' }, yAxis: { type: 'value' }, series: [] };
61
+
62
+ renderHook(
63
+ ({ instance, option }: { instance: any; option: any }) => useOption(instance, option),
64
+ {
65
+ initialProps: { instance: mockInstance, option },
66
+ }
67
+ );
68
+
69
+ expect(mockInstance.setOption).toHaveBeenCalledWith(option);
70
+ });
71
+
72
+ it('should not call setOption when instance is null', () => {
73
+ const mockInstance = {
74
+ setOption: jest.fn(),
75
+ };
76
+
77
+ const option = { xAxis: { type: 'category' }, yAxis: { type: 'value' }, series: [] };
78
+
79
+ renderHook(
80
+ ({ instance, option }: { instance: any; option: any }) => useOption(instance, option),
81
+ {
82
+ initialProps: { instance: null, option },
83
+ }
84
+ );
85
+
86
+ expect(mockInstance.setOption).not.toHaveBeenCalled();
87
+ });
88
+ });
89
+
90
+ describe('useResize', () => {
91
+ it('should add resize event listener when instance is provided', () => {
92
+ const mockInstance = {
93
+ resize: jest.fn(),
94
+ };
95
+
96
+ // Create spies and save original methods
97
+ const originalAddEventListener = window.addEventListener;
98
+ const originalRemoveEventListener = window.removeEventListener;
99
+ const addEventListenerSpy = jest.spyOn(window, 'addEventListener');
100
+ const removeEventListenerSpy = jest.spyOn(window, 'removeEventListener');
101
+
102
+ const { unmount } = renderHook((instance: any) => useResize(instance), {
103
+ initialProps: mockInstance,
104
+ });
105
+
106
+ expect(addEventListenerSpy).toHaveBeenCalledWith('resize', expect.any(Function));
107
+
108
+ unmount();
109
+
110
+ expect(removeEventListenerSpy).toHaveBeenCalledWith('resize', expect.any(Function));
111
+
112
+ // Restore original methods to ensure test isolation
113
+ window.addEventListener = originalAddEventListener;
114
+ window.removeEventListener = originalRemoveEventListener;
115
+ });
116
+
117
+ it('should not add resize event listener when instance is null', () => {
118
+ // Create spies and save original methods
119
+ const originalAddEventListener = window.addEventListener;
120
+ const addEventListenerSpy = jest.spyOn(window, 'addEventListener');
121
+
122
+ // Render the hook with null instance
123
+ renderHook((instance: any) => useResize(instance), { initialProps: null });
124
+
125
+ // Check that the event listener was not added
126
+ expect(addEventListenerSpy).not.toHaveBeenCalledWith('resize', expect.any(Function));
127
+
128
+ // Restore original method to ensure test isolation
129
+ window.addEventListener = originalAddEventListener;
130
+ });
131
+ });
132
+
133
+ describe('useEvents', () => {
134
+ it('should bind events when instance and events are provided', () => {
135
+ const mockInstance = {
136
+ on: jest.fn(),
137
+ off: jest.fn(),
138
+ };
139
+
140
+ const events = {
141
+ click: jest.fn(),
142
+ mouseover: jest.fn(),
143
+ };
144
+
145
+ const { unmount } = renderHook(
146
+ ({ instance, events }: { instance: any; events: any }) => useEvents(instance, events),
147
+ {
148
+ initialProps: { instance: mockInstance, events },
149
+ }
150
+ );
151
+
152
+ expect(mockInstance.on).toHaveBeenCalledTimes(2);
153
+ expect(mockInstance.on).toHaveBeenCalledWith('click', events.click);
154
+ expect(mockInstance.on).toHaveBeenCalledWith('mouseover', events.mouseover);
155
+
156
+ unmount();
157
+
158
+ expect(mockInstance.off).toHaveBeenCalledTimes(2);
159
+ });
160
+
161
+ it('should not bind events when instance is null', () => {
162
+ const mockInstance = {
163
+ on: jest.fn(),
164
+ };
165
+
166
+ const events = {
167
+ click: jest.fn(),
168
+ };
169
+
170
+ renderHook(
171
+ ({ instance, events }: { instance: any; events: any }) => useEvents(instance, events),
172
+ {
173
+ initialProps: { instance: null, events },
174
+ }
175
+ );
176
+
177
+ expect(mockInstance.on).not.toHaveBeenCalled();
178
+ });
179
+ });
180
+
181
+ describe('useLoading', () => {
182
+ it('should call showLoading when loading is true', () => {
183
+ const mockInstance = {
184
+ showLoading: jest.fn(),
185
+ hideLoading: jest.fn(),
186
+ };
187
+
188
+ renderHook(
189
+ ({ instance, loading }: { instance: any; loading: boolean }) =>
190
+ useLoading(instance, loading),
191
+ {
192
+ initialProps: { instance: mockInstance, loading: true },
193
+ }
194
+ );
195
+
196
+ expect(mockInstance.showLoading).toHaveBeenCalled();
197
+ expect(mockInstance.hideLoading).not.toHaveBeenCalled();
198
+ });
199
+
200
+ it('should call hideLoading when loading is false', () => {
201
+ const mockInstance = {
202
+ showLoading: jest.fn(),
203
+ hideLoading: jest.fn(),
204
+ };
205
+
206
+ renderHook(
207
+ ({ instance, loading }: { instance: any; loading: boolean }) =>
208
+ useLoading(instance, loading),
209
+ {
210
+ initialProps: { instance: mockInstance, loading: false },
211
+ }
212
+ );
213
+
214
+ expect(mockInstance.hideLoading).toHaveBeenCalled();
215
+ expect(mockInstance.showLoading).not.toHaveBeenCalled();
216
+ });
217
+
218
+ it('should not call loading methods when instance is null', () => {
219
+ const mockInstance = {
220
+ showLoading: jest.fn(),
221
+ hideLoading: jest.fn(),
222
+ };
223
+
224
+ renderHook(
225
+ ({ instance, loading }: { instance: any; loading: boolean }) =>
226
+ useLoading(instance, loading),
227
+ {
228
+ initialProps: { instance: null, loading: true },
229
+ }
230
+ );
231
+
232
+ expect(mockInstance.showLoading).not.toHaveBeenCalled();
233
+ expect(mockInstance.hideLoading).not.toHaveBeenCalled();
234
+ });
235
+ });
236
+
237
+ describe('useChartTheme', () => {
238
+ it('should return dark theme when darkMode is true', () => {
239
+ const { result } = renderHook(
240
+ ({ theme, darkMode }: { theme: string; darkMode: boolean }) =>
241
+ useChartTheme(theme, darkMode),
242
+ {
243
+ initialProps: { theme: 'default', darkMode: true },
244
+ }
245
+ );
246
+
247
+ expect(result.current).toBe('dark');
248
+ });
249
+
250
+ it('should return original theme when darkMode is false', () => {
251
+ const { result } = renderHook(
252
+ ({ theme, darkMode }: { theme: string; darkMode: boolean }) =>
253
+ useChartTheme(theme, darkMode),
254
+ {
255
+ initialProps: { theme: 'default', darkMode: false },
256
+ }
257
+ );
258
+
259
+ expect(result.current).toBe('default');
260
+ });
261
+
262
+ it('should return theme object when theme is an object', () => {
263
+ const customTheme = { backgroundColor: '#000' };
264
+
265
+ const { result } = renderHook(
266
+ ({ theme, darkMode }: { theme: Record<string, any>; darkMode: boolean }) =>
267
+ useChartTheme(theme, darkMode),
268
+ {
269
+ initialProps: { theme: customTheme, darkMode: true },
270
+ }
271
+ );
272
+
273
+ expect(result.current).toBe(customTheme);
274
+ });
275
+ });
276
+
277
+ describe('useChartData', () => {
278
+ it('should return transformed data when data is provided', () => {
279
+ const data = [
280
+ { name: 'A', value: 10 },
281
+ { name: 'B', value: 20 },
282
+ ];
283
+ const transformer = jest.fn((d: any[]) => ({
284
+ series: [{ data: d.map((item: any) => item.value) }],
285
+ }));
286
+
287
+ const { result } = renderHook(
288
+ ({ data, transformer }: { data: any[]; transformer: (data: any[]) => any }) =>
289
+ useChartData(data, transformer),
290
+ {
291
+ initialProps: { data, transformer },
292
+ }
293
+ );
294
+
295
+ expect(transformer).toHaveBeenCalledWith(data);
296
+ expect(result.current).toEqual({
297
+ series: [{ data: [10, 20] }],
298
+ });
299
+ });
300
+
301
+ it('should return empty series when data is empty', () => {
302
+ const data: any[] = [];
303
+ const transformer = jest.fn();
304
+
305
+ const { result } = renderHook(
306
+ ({ data, transformer }: { data: any[]; transformer: (data: any[]) => any }) =>
307
+ useChartData(data, transformer),
308
+ {
309
+ initialProps: { data, transformer },
310
+ }
311
+ );
312
+
313
+ expect(transformer).not.toHaveBeenCalled();
314
+ expect(result.current).toEqual({ series: [] });
315
+ });
316
+
317
+ it('should return empty series when data is null', () => {
318
+ const data = null as any;
319
+ const transformer = jest.fn();
320
+
321
+ const { result } = renderHook(
322
+ ({ data, transformer }: { data: any[] | null; transformer: (data: any[]) => any }) =>
323
+ useChartData(data, transformer),
324
+ {
325
+ initialProps: { data, transformer },
326
+ }
327
+ );
328
+
329
+ expect(transformer).not.toHaveBeenCalled();
330
+ expect(result.current).toEqual({ series: [] });
331
+ });
332
+ });
333
+ });
@@ -0,0 +1,214 @@
1
+ /**
2
+ * TaroViz React Hooks
3
+ * 提供与图表相关的React Hooks
4
+ */
5
+ import { useState, useEffect, useMemo } from 'react';
6
+
7
+ import { getAdapter } from '../adapters';
8
+ import { EventHandler } from '../core';
9
+
10
+ // 通用图表配置类型
11
+ interface ChartOptions {
12
+ [key: string]: any;
13
+ }
14
+
15
+ // 通用图表实例类型
16
+ interface ChartInstance {
17
+ setOption: (option: any, notMerge?: boolean) => void;
18
+ resize: () => void;
19
+ on: (event: string, handler: EventHandler) => void;
20
+ off: (event: string, handler?: EventHandler) => void;
21
+ showLoading: (opts?: any) => void;
22
+ hideLoading: () => void;
23
+ dispose: () => void;
24
+ [key: string]: any;
25
+ }
26
+
27
+ /**
28
+ * 使用图表Hook
29
+ * @param chartRef 图表容器的引用
30
+ * @returns [图表实例, setInstance]
31
+ */
32
+ export function useChart(chartRef: React.RefObject<HTMLElement>) {
33
+ const [instance, setInstance] = useState<ChartInstance | null>(null);
34
+
35
+ useEffect(() => {
36
+ if (chartRef.current && !instance) {
37
+ // 使用默认配置初始化适配器
38
+ const adapter = getAdapter({});
39
+
40
+ // 注意:Adapter接口可能没有直接定义setComponent方法
41
+ // 但多数适配器实现中都有这个方法,我们可以通过类型断言使用
42
+ if (typeof (adapter as any).setComponent === 'function') {
43
+ (adapter as any).setComponent(chartRef.current);
44
+ }
45
+
46
+ // 初始化并保存实例
47
+ const chartInstance = adapter as unknown as ChartInstance;
48
+ setInstance(chartInstance);
49
+ }
50
+
51
+ return () => {
52
+ if (instance) {
53
+ try {
54
+ instance.dispose();
55
+ } catch (e) {
56
+ console.warn('Failed to dispose chart instance:', e);
57
+ }
58
+ }
59
+ };
60
+ }, [chartRef, instance]);
61
+
62
+ return [instance, setInstance] as const;
63
+ }
64
+
65
+ /**
66
+ * 设置图表选项Hook
67
+ * @param instance 图表实例
68
+ * @param option 图表选项
69
+ * @param deps 依赖数组
70
+ */
71
+ export function useOption(instance: ChartInstance | null, option: ChartOptions, deps: any[] = []) {
72
+ useEffect(() => {
73
+ if (instance && option) {
74
+ try {
75
+ instance.setOption(option);
76
+ } catch (e) {
77
+ console.warn('Failed to set chart option:', e);
78
+ }
79
+ }
80
+ }, [instance, option, ...deps]);
81
+ }
82
+
83
+ /**
84
+ * 图表自适应Hook
85
+ * @param instance 图表实例
86
+ */
87
+ export function useResize(instance: ChartInstance | null) {
88
+ useEffect(() => {
89
+ if (!instance) {
90
+ return;
91
+ }
92
+
93
+ const handleResize = () => {
94
+ try {
95
+ instance.resize();
96
+ } catch (e) {
97
+ console.warn('Failed to resize chart:', e);
98
+ }
99
+ };
100
+
101
+ window.addEventListener('resize', handleResize);
102
+
103
+ return () => {
104
+ window.removeEventListener('resize', handleResize);
105
+ };
106
+ }, [instance]);
107
+ }
108
+
109
+ /**
110
+ * 图表事件Hook
111
+ * @param instance 图表实例
112
+ * @param events 事件对象
113
+ */
114
+ export function useEvents(instance: ChartInstance | null, events: Record<string, EventHandler>) {
115
+ useEffect(() => {
116
+ if (!instance) {
117
+ return;
118
+ }
119
+
120
+ const eventEntries = Object.entries(events);
121
+
122
+ // 绑定事件
123
+ eventEntries.forEach(([eventName, handler]) => {
124
+ try {
125
+ instance.on(eventName, handler);
126
+ } catch (e) {
127
+ console.warn(`Failed to bind event ${eventName}:`, e);
128
+ }
129
+ });
130
+
131
+ // 清理事件
132
+ return () => {
133
+ eventEntries.forEach(([eventName, handler]) => {
134
+ try {
135
+ instance.off(eventName, handler);
136
+ } catch (e) {
137
+ console.warn(`Failed to unbind event ${eventName}:`, e);
138
+ }
139
+ });
140
+ };
141
+ }, [instance, events]);
142
+ }
143
+
144
+ /**
145
+ * 图表加载状态Hook
146
+ * @param instance 图表实例
147
+ * @param loading 是否加载中
148
+ */
149
+ export function useLoading(instance: ChartInstance | null, loading: boolean) {
150
+ useEffect(() => {
151
+ if (!instance) {
152
+ return;
153
+ }
154
+
155
+ try {
156
+ if (loading) {
157
+ instance.showLoading();
158
+ } else {
159
+ instance.hideLoading();
160
+ }
161
+ } catch (e) {
162
+ console.warn('Failed to set chart loading state:', e);
163
+ }
164
+ }, [instance, loading]);
165
+ }
166
+
167
+ /**
168
+ * 使用图表主题
169
+ * @param theme 主题名称或配置
170
+ * @param darkMode 是否为暗黑模式
171
+ * @returns 处理后的主题
172
+ */
173
+ export function useChartTheme(theme: string | Record<string, any>, darkMode = false) {
174
+ return useMemo(() => {
175
+ if (typeof theme === 'string') {
176
+ return darkMode ? 'dark' : theme;
177
+ }
178
+
179
+ return theme;
180
+ }, [theme, darkMode]);
181
+ }
182
+
183
+ /**
184
+ * 使用图表数据变更
185
+ * @param data 数据源
186
+ * @param transformer 数据转换函数
187
+ * @returns 转换后的图表选项
188
+ */
189
+ export function useChartData<T = any>(data: T[] | null, transformer: (data: T[]) => ChartOptions) {
190
+ return useMemo(() => {
191
+ if (!data || data.length === 0) {
192
+ return { series: [] };
193
+ }
194
+
195
+ return transformer(data);
196
+ }, [data, transformer]);
197
+ }
198
+
199
+ // 导出版本号
200
+ export const version = '1.1.1';
201
+
202
+ // 导出所有hooks到默认导出对象
203
+ const hooks = {
204
+ useChart,
205
+ useOption,
206
+ useResize,
207
+ useEvents,
208
+ useLoading,
209
+ useChartTheme,
210
+ useChartData,
211
+ };
212
+
213
+ // 为了同时支持具名导入和默认导入
214
+ export default hooks;
package/src/index.ts ADDED
@@ -0,0 +1,75 @@
1
+ /**
2
+ * TaroViz - 基于 Taro 和 ECharts 的多端图表组件库
3
+ * @version 1.1.1
4
+ */
5
+
6
+ // 核心组件
7
+ export type { ChartProps } from './core/components/BaseChart';
8
+ export { default as BaseChart } from './core/components/BaseChart';
9
+
10
+ // 核心类型
11
+ export type {
12
+ EChartsType,
13
+ EChartsOption,
14
+ AnimationEasing,
15
+ RendererType,
16
+ ChartEventCallback,
17
+ ChartEventHandlers,
18
+ ThemeType,
19
+ RenderOptimizationConfig,
20
+ Adapter,
21
+ AdapterConfig,
22
+ } from './core/types';
23
+
24
+ // 核心工具函数
25
+ export {
26
+ events,
27
+ deepMerge,
28
+ debounce,
29
+ throttle,
30
+ getEnvironment,
31
+ formatNumber,
32
+ getContrastColor,
33
+ uuid,
34
+ shortId,
35
+ prefixedId,
36
+ } from './core/utils';
37
+
38
+ // 图表组件
39
+ export { default as LineChart } from './charts/line';
40
+ export { default as BarChart } from './charts/bar';
41
+ export { default as PieChart } from './charts/pie';
42
+ export { default as ScatterChart } from './charts/scatter';
43
+ export { default as RadarChart } from './charts/radar';
44
+ export { default as HeatmapChart } from './charts/heatmap';
45
+ export { default as GaugeChart } from './charts/gauge';
46
+ export { default as FunnelChart } from './charts/funnel';
47
+
48
+ // 适配器
49
+ export { getAdapter, detectPlatform, getEnv } from './adapters';
50
+ export { default as H5Adapter } from './adapters/h5';
51
+ export { default as WeappAdapter } from './adapters/weapp';
52
+
53
+ // 主题
54
+ export type { BuiltinTheme, ThemeOptions } from './themes';
55
+ export { defaultTheme, darkTheme, getTheme, registerTheme } from './themes';
56
+
57
+ // 编辑器
58
+ export { ThemeEditor } from './editor';
59
+
60
+ // Hooks
61
+ export {
62
+ useChart,
63
+ useOption,
64
+ useResize,
65
+ useEvents,
66
+ useLoading,
67
+ useChartTheme,
68
+ useChartData,
69
+ } from './hooks';
70
+
71
+ /**
72
+ * 库信息
73
+ */
74
+ export const name = 'taroviz';
75
+ export const version = '1.1.1';