@agions/taroviz 1.1.1 → 1.2.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/README.md +324 -53
- package/dist/cjs/index.js +1 -0
- package/dist/esm/index.js +82979 -0
- package/package.json +160 -30
- package/src/__tests__/integration.test.tsx +168 -0
- package/src/adapters/__tests__/index.test.ts +91 -0
- package/src/adapters/h5/__tests__/index.test.ts +156 -0
- package/src/adapters/h5/index.ts +301 -0
- package/src/adapters/harmony/index.ts +274 -0
- package/src/adapters/index.ts +166 -0
- package/src/adapters/swan/index.ts +274 -0
- package/src/adapters/tt/index.ts +274 -0
- package/src/adapters/types.ts +162 -0
- package/src/adapters/weapp/index.ts +237 -0
- package/src/charts/bar/__tests__/index.test.tsx +113 -0
- package/src/charts/bar/index.tsx +18 -0
- package/src/charts/common/BaseChartWrapper.tsx +136 -0
- package/src/charts/funnel/index.tsx +18 -0
- package/src/charts/gauge/index.tsx +18 -0
- package/src/charts/heatmap/index.tsx +18 -0
- package/src/charts/index.ts +21 -0
- package/src/charts/line/__tests__/index.test.tsx +107 -0
- package/src/charts/line/index.tsx +18 -0
- package/src/charts/pie/__tests__/index.test.tsx +112 -0
- package/src/charts/pie/index.tsx +19 -0
- package/src/charts/radar/index.tsx +18 -0
- package/src/charts/scatter/index.tsx +18 -0
- package/src/charts/types.ts +619 -0
- package/src/charts/utils.ts +56 -0
- package/src/core/__tests__/platform.test.ts +48 -0
- package/src/core/animation/AnimationManager.ts +391 -0
- package/src/core/animation/index.ts +20 -0
- package/src/core/animation/types.ts +248 -0
- package/src/core/components/BaseChart.tsx +1313 -0
- package/src/core/components/ErrorBoundary.tsx +458 -0
- package/src/core/echarts.ts +58 -0
- package/src/core/index.ts +22 -0
- package/src/core/types/chart.ts +66 -0
- package/src/core/types/common.ts +224 -0
- package/src/core/types/index.ts +281 -0
- package/src/core/types/platform.ts +325 -0
- package/src/core/utils/__tests__/common.test.ts +52 -0
- package/src/core/utils/__tests__/environment.test.ts +94 -0
- package/src/core/utils/__tests__/i18n.test.ts +247 -0
- package/src/core/utils/__tests__/index.test.ts +219 -0
- package/src/core/utils/__tests__/uuid.test.ts +78 -0
- package/src/core/utils/chartInstances.ts +69 -0
- package/src/core/utils/codeGenerator/CodeGenerator.ts +655 -0
- package/src/core/utils/codeGenerator/index.ts +13 -0
- package/src/core/utils/codeGenerator/types.ts +198 -0
- package/src/core/utils/common.ts +58 -0
- package/src/core/utils/configGenerator/ConfigGenerator.ts +583 -0
- package/src/core/utils/configGenerator/index.ts +13 -0
- package/src/core/utils/configGenerator/types.ts +445 -0
- package/src/core/utils/debug/DebugPanel.tsx +637 -0
- package/src/core/utils/debug/debugger.ts +322 -0
- package/src/core/utils/debug/index.ts +21 -0
- package/src/core/utils/debug/types.ts +142 -0
- package/src/core/utils/i18n.ts +452 -0
- package/src/core/utils/index.ts +162 -0
- package/src/core/utils/performance/PerformanceAnalyzer.ts +586 -0
- package/src/core/utils/performance/index.ts +13 -0
- package/src/core/utils/performance/types.ts +180 -0
- package/src/core/utils/uuid.ts +30 -0
- package/src/editor/ThemeEditor.tsx +449 -0
- package/src/editor/index.ts +10 -0
- package/src/hooks/__tests__/index.test.tsx +333 -0
- package/src/hooks/index.ts +594 -0
- package/src/index.ts +75 -0
- package/src/main.tsx +247 -0
- package/src/react-dom.d.ts +7 -0
- package/src/themes/__tests__/index.test.ts +91 -0
- package/src/themes/index.ts +860 -0
- package/dist/389.index.esm.js +0 -1
- package/dist/389.index.js +0 -1
- package/dist/633.index.esm.js +0 -1
- package/dist/633.index.js +0 -1
- package/dist/967.index.esm.js +0 -1
- package/dist/967.index.js +0 -1
- package/dist/index.esm.js +0 -1
- package/dist/index.js +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
|
+
});
|