@agions/taroviz 1.2.1 → 1.3.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 +23 -17
- package/dist/cjs/index.js +1 -1
- package/dist/esm/index.js +6607 -80493
- package/package.json +36 -6
- package/src/adapters/h5/index.ts +1 -3
- package/src/adapters/index.ts +32 -21
- package/src/charts/common/BaseChartWrapper.tsx +2 -8
- package/src/charts/index.ts +6 -1
- package/src/charts/sankey/index.tsx +18 -0
- package/src/charts/sunburst/index.tsx +18 -0
- package/src/charts/treemap/index.tsx +18 -0
- package/src/charts/types.ts +258 -0
- package/src/core/components/Annotation.tsx +346 -0
- package/src/core/components/ErrorBoundary.tsx +92 -397
- package/src/core/components/LazyChart.tsx +200 -0
- package/src/core/echarts.ts +24 -2
- package/src/core/themes/ThemeManager.ts +628 -0
- package/src/core/utils/chartInstances.ts +9 -0
- package/src/core/utils/codeGenerator/CodeGenerator.ts +19 -5
- package/src/core/utils/export/ExportUtils.ts +385 -0
- package/src/core/utils/uuid.ts +9 -5
- package/src/hooks/index.ts +27 -9
- package/src/index.ts +72 -4
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TaroViz 图表导出工具
|
|
3
|
+
* 支持导出为 PNG、JPEG、SVG、PDF 等格式
|
|
4
|
+
*/
|
|
5
|
+
import type { ECharts } from 'echarts';
|
|
6
|
+
|
|
7
|
+
// ============================================================================
|
|
8
|
+
// 类型定义
|
|
9
|
+
// ============================================================================
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* 图片导出选项
|
|
13
|
+
*/
|
|
14
|
+
export interface ExportImageOptions {
|
|
15
|
+
/** 图片类型 */
|
|
16
|
+
type?: 'png' | 'jpeg' | 'webp';
|
|
17
|
+
/** 设备像素比 */
|
|
18
|
+
pixelRatio?: number;
|
|
19
|
+
/** 背景色 */
|
|
20
|
+
backgroundColor?: string;
|
|
21
|
+
/** 质量 (仅对 jpeg/webp 有效) */
|
|
22
|
+
quality?: number;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* SVG 导出选项
|
|
27
|
+
*/
|
|
28
|
+
export interface ExportSVGOptions {
|
|
29
|
+
/** 是否压缩 */
|
|
30
|
+
compress?: boolean;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* PDF 导出选项
|
|
35
|
+
*/
|
|
36
|
+
export interface ExportPDFOptions {
|
|
37
|
+
/** 页面方向 */
|
|
38
|
+
orientation?: 'portrait' | 'landscape';
|
|
39
|
+
/** 页面大小 */
|
|
40
|
+
pageSize?: 'a4' | 'letter' | 'legal' | 'tabloid';
|
|
41
|
+
/** 标题 */
|
|
42
|
+
title?: string;
|
|
43
|
+
/** 作者 */
|
|
44
|
+
author?: string;
|
|
45
|
+
/** 图表与页面边缘的距离 */
|
|
46
|
+
margin?: {
|
|
47
|
+
top?: number;
|
|
48
|
+
right?: number;
|
|
49
|
+
bottom?: number;
|
|
50
|
+
left?: number;
|
|
51
|
+
};
|
|
52
|
+
/** 是否包含标题 */
|
|
53
|
+
includeTitle?: boolean;
|
|
54
|
+
/** 是否包含图例说明 */
|
|
55
|
+
includeLegend?: boolean;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* 批量导出选项
|
|
60
|
+
*/
|
|
61
|
+
export interface BatchExportOptions {
|
|
62
|
+
/** 导出格式 */
|
|
63
|
+
format: 'png' | 'jpeg' | 'pdf';
|
|
64
|
+
/** 文件名前缀 */
|
|
65
|
+
filenamePrefix?: string;
|
|
66
|
+
/** 是否压缩 */
|
|
67
|
+
compress?: boolean;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* 导出结果
|
|
72
|
+
*/
|
|
73
|
+
export interface ExportResult {
|
|
74
|
+
/** 导出的数据 */
|
|
75
|
+
data: string | Blob;
|
|
76
|
+
/** 文件名 */
|
|
77
|
+
filename: string;
|
|
78
|
+
/** MIME 类型 */
|
|
79
|
+
mimeType: string;
|
|
80
|
+
/** 数据大小 (字节) */
|
|
81
|
+
size?: number;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// ============================================================================
|
|
85
|
+
// 工具函数
|
|
86
|
+
// ============================================================================
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* 将 Data URL 转换为 Blob
|
|
90
|
+
*/
|
|
91
|
+
function dataURLToBlob(dataURL: string): Blob {
|
|
92
|
+
const arr = dataURL.split(',');
|
|
93
|
+
const mime = arr[0].match(/:(.*?);/)?.[1] || 'image/png';
|
|
94
|
+
const bstr = atob(arr[1]);
|
|
95
|
+
let n = bstr.length;
|
|
96
|
+
const u8arr = new Uint8Array(n);
|
|
97
|
+
while (n--) {
|
|
98
|
+
u8arr[n] = bstr.charCodeAt(n);
|
|
99
|
+
}
|
|
100
|
+
return new Blob([u8arr], { type: mime });
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* 下载文件
|
|
105
|
+
*/
|
|
106
|
+
function downloadFile(data: string | Blob, filename: string, mimeType: string): void {
|
|
107
|
+
const blob = typeof data === 'string' ? dataURLToBlob(data) : data;
|
|
108
|
+
const url = URL.createObjectURL(blob);
|
|
109
|
+
|
|
110
|
+
const link = document.createElement('a');
|
|
111
|
+
link.href = url;
|
|
112
|
+
link.download = filename;
|
|
113
|
+
link.style.display = 'none';
|
|
114
|
+
|
|
115
|
+
document.body.appendChild(link);
|
|
116
|
+
link.click();
|
|
117
|
+
|
|
118
|
+
// 清理
|
|
119
|
+
setTimeout(() => {
|
|
120
|
+
document.body.removeChild(link);
|
|
121
|
+
URL.revokeObjectURL(url);
|
|
122
|
+
}, 100);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* 生成文件名
|
|
127
|
+
*/
|
|
128
|
+
function generateFilename(name: string, format: string): string {
|
|
129
|
+
const timestamp = new Date().toISOString().slice(0, 10);
|
|
130
|
+
const sanitizedName = name.replace(/[^a-zA-Z0-9\u4e00-\u9fa5]/g, '_');
|
|
131
|
+
return `${sanitizedName}_${timestamp}.${format}`;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// ============================================================================
|
|
135
|
+
// 导出类
|
|
136
|
+
// ============================================================================
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* 图表导出工具类
|
|
140
|
+
*/
|
|
141
|
+
class ChartExporter {
|
|
142
|
+
/**
|
|
143
|
+
* 导出图表为图片
|
|
144
|
+
*/
|
|
145
|
+
static exportImage(
|
|
146
|
+
chart: ECharts,
|
|
147
|
+
options: ExportImageOptions = {}
|
|
148
|
+
): ExportResult {
|
|
149
|
+
const {
|
|
150
|
+
type = 'png',
|
|
151
|
+
pixelRatio = 2,
|
|
152
|
+
backgroundColor = '#ffffff',
|
|
153
|
+
quality = 0.8,
|
|
154
|
+
} = options;
|
|
155
|
+
|
|
156
|
+
const mimeType = `image/${type}`;
|
|
157
|
+
const data = chart.getDataURL({
|
|
158
|
+
type,
|
|
159
|
+
pixelRatio,
|
|
160
|
+
backgroundColor,
|
|
161
|
+
quality,
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
return {
|
|
165
|
+
data,
|
|
166
|
+
filename: generateFilename('chart', type),
|
|
167
|
+
mimeType,
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* 导出图表为 SVG
|
|
173
|
+
*/
|
|
174
|
+
static exportSVG(chart: ECharts, options: ExportSVGOptions = {}): ExportResult {
|
|
175
|
+
const { compress = false } = options;
|
|
176
|
+
|
|
177
|
+
const svgData = chart.getSvgData();
|
|
178
|
+
if (!svgData) {
|
|
179
|
+
throw new Error('SVG export is not supported. Please use canvas renderer.');
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
let data = svgData;
|
|
183
|
+
let mimeType = 'image/svg+xml';
|
|
184
|
+
|
|
185
|
+
if (compress) {
|
|
186
|
+
// 简单的 SVG 压缩:移除空格和换行
|
|
187
|
+
data = data.replace(/>\s+</g, '><').replace(/\s+/g, ' ');
|
|
188
|
+
mimeType += ';charset=utf-8';
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
return {
|
|
192
|
+
data,
|
|
193
|
+
filename: generateFilename('chart', 'svg'),
|
|
194
|
+
mimeType,
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* 导出图表为 PDF (需要 jspdf 库支持)
|
|
200
|
+
*/
|
|
201
|
+
static async exportPDF(
|
|
202
|
+
chart: ECharts,
|
|
203
|
+
options: ExportPDFOptions = {}
|
|
204
|
+
): Promise<ExportResult> {
|
|
205
|
+
const {
|
|
206
|
+
orientation = 'portrait',
|
|
207
|
+
pageSize = 'a4',
|
|
208
|
+
title = 'Chart Export',
|
|
209
|
+
author = 'TaroViz',
|
|
210
|
+
margin = { top: 40, right: 40, bottom: 40, left: 40 },
|
|
211
|
+
includeTitle = true,
|
|
212
|
+
} = options;
|
|
213
|
+
|
|
214
|
+
// 获取图表图片
|
|
215
|
+
const imageData = chart.getDataURL({
|
|
216
|
+
type: 'png',
|
|
217
|
+
pixelRatio: 2,
|
|
218
|
+
backgroundColor: '#ffffff',
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
// 动态导入 jspdf
|
|
222
|
+
let jsPDF: any;
|
|
223
|
+
try {
|
|
224
|
+
// 尝试使用动态导入,使用 webpackIgnore 注释避免预解析
|
|
225
|
+
// @ts-ignore - 动态导入
|
|
226
|
+
jsPDF = (await import(/* webpackIgnore: true */ 'jspdf')).default;
|
|
227
|
+
} catch {
|
|
228
|
+
// 如果没有 jspdf,提供备选方案
|
|
229
|
+
console.warn('[TaroViz] jspdf not found, falling back to image download');
|
|
230
|
+
return {
|
|
231
|
+
data: imageData,
|
|
232
|
+
filename: generateFilename('chart', 'png'),
|
|
233
|
+
mimeType: 'image/png',
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// 页面尺寸映射 (单位: mm)
|
|
238
|
+
const pageSizes: Record<string, { width: number; height: number }> = {
|
|
239
|
+
a4: { width: 210, height: 297 },
|
|
240
|
+
letter: { width: 216, height: 279 },
|
|
241
|
+
legal: { width: 216, height: 356 },
|
|
242
|
+
tabloid: { width: 279, height: 432 },
|
|
243
|
+
};
|
|
244
|
+
|
|
245
|
+
const size = pageSizes[pageSize];
|
|
246
|
+
const isLandscape = orientation === 'landscape';
|
|
247
|
+
|
|
248
|
+
// 创建 PDF
|
|
249
|
+
const doc = new jsPDF({
|
|
250
|
+
orientation,
|
|
251
|
+
unit: 'mm',
|
|
252
|
+
format: pageSize,
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
// 设置文档属性
|
|
256
|
+
doc.setProperties({
|
|
257
|
+
title,
|
|
258
|
+
author,
|
|
259
|
+
subject: 'Chart Export',
|
|
260
|
+
keywords: 'chart, taroviz, echarts',
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
// 计算图表尺寸和位置
|
|
264
|
+
const chartWidth = isLandscape ? size.height : size.width;
|
|
265
|
+
const chartHeight = chartWidth * 0.6; // 保持 5:3 比例
|
|
266
|
+
const pageWidth = isLandscape ? size.height : size.width;
|
|
267
|
+
const pageHeight = isLandscape ? size.width : size.height;
|
|
268
|
+
|
|
269
|
+
const marginTop = margin.top || 40;
|
|
270
|
+
const marginLeft = margin.left || 40;
|
|
271
|
+
|
|
272
|
+
// 添加标题
|
|
273
|
+
if (includeTitle) {
|
|
274
|
+
doc.setFontSize(16);
|
|
275
|
+
doc.setTextColor(51, 51, 51);
|
|
276
|
+
doc.text(title, marginLeft, marginTop);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// 添加图表
|
|
280
|
+
const chartY = includeTitle ? marginTop + 15 : marginTop;
|
|
281
|
+
const chartX = (pageWidth - chartWidth) / 2;
|
|
282
|
+
|
|
283
|
+
doc.addImage(imageData, 'PNG', chartX, chartY, chartWidth, chartHeight);
|
|
284
|
+
|
|
285
|
+
// 添加页脚
|
|
286
|
+
const footerY = pageHeight - margin.bottom / 2;
|
|
287
|
+
doc.setFontSize(10);
|
|
288
|
+
doc.setTextColor(153, 153, 153);
|
|
289
|
+
doc.text(`Generated by TaroViz on ${new Date().toLocaleDateString()}`, marginLeft, footerY);
|
|
290
|
+
|
|
291
|
+
// 导出为 Blob
|
|
292
|
+
const pdfBlob = doc.output('blob');
|
|
293
|
+
|
|
294
|
+
return {
|
|
295
|
+
data: pdfBlob,
|
|
296
|
+
filename: generateFilename(title.replace(/\s+/g, '_'), 'pdf'),
|
|
297
|
+
mimeType: 'application/pdf',
|
|
298
|
+
size: pdfBlob.size,
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* 批量导出多个图表
|
|
304
|
+
*/
|
|
305
|
+
static async exportBatch(
|
|
306
|
+
charts: Array<{ name: string; chart: ECharts }>,
|
|
307
|
+
options: BatchExportOptions
|
|
308
|
+
): Promise<ExportResult[]> {
|
|
309
|
+
const { format, filenamePrefix = 'chart', compress } = options;
|
|
310
|
+
|
|
311
|
+
const results: ExportResult[] = [];
|
|
312
|
+
|
|
313
|
+
for (const { name, chart } of charts) {
|
|
314
|
+
try {
|
|
315
|
+
let result: ExportResult;
|
|
316
|
+
|
|
317
|
+
if (format === 'pdf') {
|
|
318
|
+
result = await this.exportPDF(chart, { title: name });
|
|
319
|
+
} else {
|
|
320
|
+
result = this.exportImage(chart, { type: format });
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
// 如果需要压缩,重命名文件
|
|
324
|
+
if (compress && result.filename) {
|
|
325
|
+
result.filename = result.filename.replace(/\.(\w+)$/, '.$1');
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
results.push(result);
|
|
329
|
+
} catch (error) {
|
|
330
|
+
console.error(`[TaroViz] Failed to export chart "${name}":`, error);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
return results;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/**
|
|
338
|
+
* 下载导出结果
|
|
339
|
+
*/
|
|
340
|
+
static download(result: ExportResult): void {
|
|
341
|
+
downloadFile(result.data, result.filename, result.mimeType);
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
* 复制到剪贴板
|
|
346
|
+
*/
|
|
347
|
+
static async copyToClipboard(chart: ECharts, options: ExportImageOptions = {}): Promise<boolean> {
|
|
348
|
+
try {
|
|
349
|
+
const result = this.exportImage(chart, { ...options, type: 'png' });
|
|
350
|
+
const blob = dataURLToBlob(result.data);
|
|
351
|
+
|
|
352
|
+
await navigator.clipboard.write([
|
|
353
|
+
new ClipboardItem({
|
|
354
|
+
[blob.type]: blob,
|
|
355
|
+
}),
|
|
356
|
+
]);
|
|
357
|
+
|
|
358
|
+
return true;
|
|
359
|
+
} catch (error) {
|
|
360
|
+
console.error('[TaroViz] Failed to copy to clipboard:', error);
|
|
361
|
+
return false;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
/**
|
|
366
|
+
* 获取导出尺寸 (基于 DPI 计算)
|
|
367
|
+
*/
|
|
368
|
+
static calculateExportSize(
|
|
369
|
+
chart: ECharts,
|
|
370
|
+
targetDPI: number = 300
|
|
371
|
+
): { width: number; height: number } {
|
|
372
|
+
const width = chart.getWidth();
|
|
373
|
+
const height = chart.getHeight();
|
|
374
|
+
const pixelRatio = targetDPI / 96; // 96 DPI 是屏幕默认 DPI
|
|
375
|
+
|
|
376
|
+
return {
|
|
377
|
+
width: Math.round(width * pixelRatio),
|
|
378
|
+
height: Math.round(height * pixelRatio),
|
|
379
|
+
};
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
export const exportChart = ChartExporter;
|
|
384
|
+
|
|
385
|
+
export default ChartExporter;
|
package/src/core/utils/uuid.ts
CHANGED
|
@@ -4,11 +4,15 @@
|
|
|
4
4
|
* @returns 唯一标识符字符串
|
|
5
5
|
*/
|
|
6
6
|
export function uuid(): string {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
// 使用 crypto API 生成加密安全的 UUID
|
|
8
|
+
if (typeof globalThis.crypto?.randomUUID === 'function') {
|
|
9
|
+
return globalThis.crypto.randomUUID();
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// 回退:使用 Math.random() + 时间戳混合
|
|
13
|
+
const timestamp = Date.now().toString(36);
|
|
14
|
+
const randomPart = Math.random().toString(36).substring(2, 15);
|
|
15
|
+
return `${timestamp}-${randomPart}-${Math.random().toString(36).substring(2, 10)}`;
|
|
12
16
|
}
|
|
13
17
|
|
|
14
18
|
/**
|
package/src/hooks/index.ts
CHANGED
|
@@ -410,23 +410,35 @@ export function useDataPolling<T>(
|
|
|
410
410
|
const [data, setData] = useState<T | null>(null);
|
|
411
411
|
const [loading, setLoading] = useState(autoStart);
|
|
412
412
|
const [error, setError] = useState<Error | null>(null);
|
|
413
|
-
|
|
413
|
+
|
|
414
|
+
// 用于取消进行中的请求
|
|
415
|
+
const abortRef = useRef<{ cancelled: boolean }>({ cancelled: false });
|
|
414
416
|
|
|
415
417
|
const fetchData = useCallback(async () => {
|
|
418
|
+
// 取消之前的请求
|
|
419
|
+
abortRef.current.cancelled = true;
|
|
420
|
+
// 创建新的取消标记
|
|
421
|
+
abortRef.current = { cancelled: false };
|
|
422
|
+
const currentAbort = abortRef.current;
|
|
423
|
+
|
|
416
424
|
let retries = retryCount;
|
|
417
425
|
setLoading(true);
|
|
418
426
|
setError(null);
|
|
419
427
|
|
|
420
|
-
while (retries >= 0) {
|
|
428
|
+
while (retries >= 0 && !currentAbort.cancelled) {
|
|
421
429
|
try {
|
|
422
430
|
const result = await fetchFn();
|
|
423
|
-
|
|
424
|
-
|
|
431
|
+
if (!currentAbort.cancelled) {
|
|
432
|
+
setData(result);
|
|
433
|
+
setLoading(false);
|
|
434
|
+
}
|
|
425
435
|
return;
|
|
426
436
|
} catch (e) {
|
|
427
437
|
retries--;
|
|
428
|
-
if (retries < 0) {
|
|
429
|
-
|
|
438
|
+
if (retries < 0 || currentAbort.cancelled) {
|
|
439
|
+
if (!currentAbort.cancelled) {
|
|
440
|
+
setError(e as Error);
|
|
441
|
+
}
|
|
430
442
|
setLoading(false);
|
|
431
443
|
} else {
|
|
432
444
|
await new Promise((resolve) => setTimeout(resolve, retryDelay));
|
|
@@ -442,12 +454,18 @@ export function useDataPolling<T>(
|
|
|
442
454
|
|
|
443
455
|
if (interval > 0) {
|
|
444
456
|
const timer = setInterval(fetchData, interval);
|
|
445
|
-
return () =>
|
|
457
|
+
return () => {
|
|
458
|
+
clearInterval(timer);
|
|
459
|
+
abortRef.current.cancelled = true;
|
|
460
|
+
};
|
|
446
461
|
}
|
|
447
|
-
|
|
462
|
+
|
|
463
|
+
return () => {
|
|
464
|
+
abortRef.current.cancelled = true;
|
|
465
|
+
};
|
|
466
|
+
}, [interval, autoStart, fetchData]);
|
|
448
467
|
|
|
449
468
|
const refresh = useCallback(() => {
|
|
450
|
-
setRefreshIndex((prev) => prev + 1);
|
|
451
469
|
fetchData();
|
|
452
470
|
}, [fetchData]);
|
|
453
471
|
|
package/src/index.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* TaroViz - 基于 Taro 和 ECharts 的多端图表组件库
|
|
3
|
-
* @version 1.
|
|
3
|
+
* @version 1.2.1
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
// 核心组件
|
|
@@ -45,18 +45,80 @@ export { default as HeatmapChart } from './charts/heatmap';
|
|
|
45
45
|
export { default as GaugeChart } from './charts/gauge';
|
|
46
46
|
export { default as FunnelChart } from './charts/funnel';
|
|
47
47
|
|
|
48
|
+
// 扩展图表组件 (新增)
|
|
49
|
+
export { default as TreeMapChart } from './charts/treemap';
|
|
50
|
+
export { default as SunburstChart } from './charts/sunburst';
|
|
51
|
+
export { default as SankeyChart } from './charts/sankey';
|
|
52
|
+
|
|
48
53
|
// 适配器
|
|
49
54
|
export { getAdapter, detectPlatform, getEnv } from './adapters';
|
|
50
55
|
export { default as H5Adapter } from './adapters/h5';
|
|
51
56
|
export { default as WeappAdapter } from './adapters/weapp';
|
|
52
57
|
|
|
53
|
-
//
|
|
58
|
+
// 主题系统
|
|
54
59
|
export type { BuiltinTheme, ThemeOptions } from './themes';
|
|
55
|
-
export {
|
|
60
|
+
export {
|
|
61
|
+
defaultTheme,
|
|
62
|
+
darkTheme,
|
|
63
|
+
getTheme,
|
|
64
|
+
registerTheme,
|
|
65
|
+
switchTheme,
|
|
66
|
+
getRegisteredThemes,
|
|
67
|
+
getThemeByName,
|
|
68
|
+
getLightThemes,
|
|
69
|
+
getDarkThemes,
|
|
70
|
+
getThemesByTag,
|
|
71
|
+
} from './themes';
|
|
72
|
+
|
|
73
|
+
// 主题管理器 (新增)
|
|
74
|
+
export {
|
|
75
|
+
themeManager,
|
|
76
|
+
PRESET_THEMES,
|
|
77
|
+
type ThemeConfig,
|
|
78
|
+
type ThemeVariables,
|
|
79
|
+
type PresetThemeName,
|
|
80
|
+
} from './core/themes/ThemeManager';
|
|
56
81
|
|
|
57
82
|
// 编辑器
|
|
58
83
|
export { ThemeEditor } from './editor';
|
|
59
84
|
|
|
85
|
+
// 错误边界组件 (新增)
|
|
86
|
+
export { ErrorBoundary, withErrorBoundary, type ErrorBoundaryProps } from './core/components/ErrorBoundary';
|
|
87
|
+
|
|
88
|
+
// 懒加载组件 (新增)
|
|
89
|
+
export {
|
|
90
|
+
withLazyLoad,
|
|
91
|
+
preloadChart,
|
|
92
|
+
preloadAllCharts,
|
|
93
|
+
createLazyChart,
|
|
94
|
+
LazyChartRegistry,
|
|
95
|
+
} from './core/components/LazyChart';
|
|
96
|
+
|
|
97
|
+
// 标注系统 (新增)
|
|
98
|
+
export {
|
|
99
|
+
useAnnotation,
|
|
100
|
+
convertAnnotationToMarkLine,
|
|
101
|
+
convertAnnotationToMarkArea,
|
|
102
|
+
convertAnnotationToScatter,
|
|
103
|
+
AnnotationPresets,
|
|
104
|
+
createCompositeAnnotation,
|
|
105
|
+
type AnnotationProps,
|
|
106
|
+
type AnnotationType,
|
|
107
|
+
type MarkLineConfig,
|
|
108
|
+
type MarkAreaConfig,
|
|
109
|
+
type ScatterAnnotationConfig,
|
|
110
|
+
} from './core/components/Annotation';
|
|
111
|
+
|
|
112
|
+
// 导出工具 (新增)
|
|
113
|
+
export {
|
|
114
|
+
exportChart,
|
|
115
|
+
type ExportImageOptions,
|
|
116
|
+
type ExportSVGOptions,
|
|
117
|
+
type ExportPDFOptions,
|
|
118
|
+
type BatchExportOptions,
|
|
119
|
+
type ExportResult,
|
|
120
|
+
} from './core/utils/export/ExportUtils';
|
|
121
|
+
|
|
60
122
|
// Hooks
|
|
61
123
|
export {
|
|
62
124
|
useChart,
|
|
@@ -66,10 +128,16 @@ export {
|
|
|
66
128
|
useLoading,
|
|
67
129
|
useChartTheme,
|
|
68
130
|
useChartData,
|
|
131
|
+
useResponsive,
|
|
132
|
+
useThemeSwitcher,
|
|
133
|
+
useDataPolling,
|
|
134
|
+
useFullscreen,
|
|
135
|
+
useExport,
|
|
136
|
+
useChartTools,
|
|
69
137
|
} from './hooks';
|
|
70
138
|
|
|
71
139
|
/**
|
|
72
140
|
* 库信息
|
|
73
141
|
*/
|
|
74
142
|
export const name = 'taroviz';
|
|
75
|
-
export const version = '1.
|
|
143
|
+
export const version = '1.2.1';
|