Export charts as high-quality vector graphics and images
// Create your chart final chart = CristalyseChart() .data(data) .mapping(x: 'month', y: 'revenue') .geomBar() .theme(ChartTheme.defaultTheme()) .build(); // Export as SVG final result = await chart.exportAsSvg( width: 800, height: 600, filename: 'revenue_chart', ); print('Chart exported to: ${result.filePath}');
final exportConfig = ExportConfig( width: 1920, // High resolution for presentations height: 1080, format: ExportFormat.svg, backgroundColor: Colors.white, filename: 'dashboard_chart', quality: 1.0, // Maximum quality transparentBackground: false, ); final result = await chart.export(exportConfig);
// For presentations (16:9 aspect ratio) await chart.exportAsSvg( width: 1920, height: 1080, filename: 'presentation_chart', ); // For print documents (300 DPI equivalent) await chart.exportAsSvg( width: 2400, height: 1800, filename: 'print_chart', ); // For web thumbnails await chart.exportAsSvg( width: 400, height: 300, filename: 'thumbnail_chart', );
class DashboardExporter { static Future<List<ExportResult>> exportDashboard( List<CristalyseChart> charts, ) async { final results = <ExportResult>[]; for (int i = 0; i < charts.length; i++) { final result = await charts[i].exportAsSvg( width: 800, height: 600, filename: 'dashboard_chart_$i', ); results.add(result); } return results; } } // Usage final charts = [revenueChart, usersChart, conversionChart]; final exportResults = await DashboardExporter.exportDashboard(charts); for (final result in exportResults) { print('Exported: ${result.filePath} (${result.fileSizeBytes} bytes)'); }
class BrandedExporter { static final brandTheme = ChartTheme( backgroundColor: const Color(0xFFF8F9FA), primaryColor: const Color(0xFF007ACC), colorPalette: [ const Color(0xFF007ACC), const Color(0xFFFF6B35), const Color(0xFF28A745), const Color(0xFFDC3545), ], // ... other brand properties ); static Future<ExportResult> exportBrandedChart({ required List<Map<String, dynamic>> data, required String xColumn, required String yColumn, required String filename, }) async { final chart = CristalyseChart() .data(data) .mapping(x: xColumn, y: yColumn) .geomBar() .theme(brandTheme) .build(); return await chart.exportAsSvg( width: 1200, height: 800, backgroundColor: brandTheme.backgroundColor, filename: filename, ); } }
class BatchExporter { static Future<void> exportChartVariations({ required List<Map<String, dynamic>> data, required String baseFilename, }) async { final themes = [ ChartTheme.defaultTheme(), ChartTheme.darkTheme(), ChartTheme.solarizedLightTheme(), ]; final themeNames = ['light', 'dark', 'solarized']; for (int i = 0; i < themes.length; i++) { final chart = CristalyseChart() .data(data) .mapping(x: 'month', y: 'value') .geomLine(strokeWidth: 3.0) .geomPoint(size: 6.0) .theme(themes[i]) .build(); await chart.exportAsSvg( width: 800, height: 600, filename: '${baseFilename}_${themeNames[i]}', ); } } }
// Minimal file size for web await chart.exportAsSvg( width: 600, height: 400, filename: 'web_optimized', ); // High quality for print await chart.exportAsSvg( width: 2400, height: 1600, filename: 'print_quality', );
class PerformantExporter { static Future<ExportResult> exportLargeDataset({ required List<Map<String, dynamic>> data, required String filename, }) async { // Simplify data for export if needed final exportData = data.length > 1000 ? _downsampleData(data, 1000) : data; final chart = CristalyseChart() .data(exportData) .mapping(x: 'x', y: 'y') .geomLine(strokeWidth: 2.0) .build(); return await chart.exportAsSvg( width: 1200, height: 800, filename: filename, ); } static List<Map<String, dynamic>> _downsampleData( List<Map<String, dynamic>> data, int targetCount, ) { final step = data.length / targetCount; final result = <Map<String, dynamic>>[]; for (int i = 0; i < data.length; i += step.ceil()) { result.add(data[i]); } return result; } }
class ExportManager { static const String exportDirectory = 'chart_exports'; static Future<Directory> getExportDirectory() async { final documentsDir = await getApplicationDocumentsDirectory(); final exportDir = Directory('${documentsDir.path}/$exportDirectory'); if (!await exportDir.exists()) { await exportDir.create(recursive: true); } return exportDir; } static Future<ExportResult> exportWithTimestamp({ required CristalyseChart chart, required String baseName, }) async { final timestamp = DateTime.now().millisecondsSinceEpoch; final filename = '${baseName}_$timestamp'; final exportDir = await getExportDirectory(); final customPath = '${exportDir.path}/$filename.svg'; return await chart.exportAsSvg( width: 1200, height: 800, filename: filename, customPath: customPath, ); } }
class ShareableExporter { static Future<void> exportAndShare({ required CristalyseChart chart, required String title, required BuildContext context, }) async { try { // Export chart final result = await chart.exportAsSvg( width: 1200, height: 800, filename: 'shared_chart', ); // Share the exported file await Share.shareFiles( [result.filePath], text: title, subject: 'Chart Export', ); } catch (e) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('Export failed: $e'), backgroundColor: Colors.red, ), ); } } }
class CloudExporter { static Future<String> exportToCloud({ required CristalyseChart chart, required String cloudPath, }) async { // Export locally first final result = await chart.exportAsSvg( width: 1200, height: 800, filename: 'temp_export', ); // Upload to cloud storage (example with Firebase) final file = File(result.filePath); final storageRef = FirebaseStorage.instance.ref().child(cloudPath); final uploadTask = await storageRef.putFile(file); final downloadUrl = await uploadTask.ref.getDownloadURL(); // Clean up local file await file.delete(); return downloadUrl; } }
class SafeExporter { static Future<ExportResult?> safeExport({ required CristalyseChart chart, required String filename, required VoidCallback? onSuccess, required Function(String)? onError, }) async { try { final result = await chart.exportAsSvg( width: 1200, height: 800, filename: filename, ); onSuccess?.call(); return result; } on ChartExportException catch (e) { onError?.call('Export failed: ${e.message}'); return null; } catch (e) { onError?.call('Unexpected error: $e'); return null; } } } // Usage await SafeExporter.safeExport( chart: myChart, filename: 'report_chart', onSuccess: () => showSuccessMessage(), onError: (error) => showErrorDialog(error), );
class ExportValidator { static bool validateExportResult(ExportResult result) { // Check file exists final file = File(result.filePath); if (!file.existsSync()) return false; // Check file size is reasonable if (result.fileSizeBytes < 100) return false; // Too small if (result.fileSizeBytes > 10 * 1024 * 1024) return false; // Too large // Check dimensions if (result.dimensions.width <= 0 || result.dimensions.height <= 0) { return false; } return true; } }
File Organization
Quality Control
Performance
User Experience