135 lines
4.4 KiB
TypeScript
135 lines
4.4 KiB
TypeScript
/**
|
|
* ECharts Download Utilities
|
|
*
|
|
* Provides programmatic chart export functionality for downloading
|
|
* charts as PNG or SVG images. These utilities wrap ECharts' built-in
|
|
* export capabilities with a convenient API and sensible defaults.
|
|
*/
|
|
|
|
import type * as echarts from 'echarts';
|
|
|
|
// ─── Types ───────────────────────────────────────────────────────────────────
|
|
|
|
export type ExportFormat = 'png' | 'svg';
|
|
|
|
export interface DownloadOptions {
|
|
/** The file name (without extension) */
|
|
fileName?: string;
|
|
/** Export format: 'png' or 'svg' */
|
|
format?: ExportFormat;
|
|
/** Pixel ratio for PNG exports (default: 2 for retina quality) */
|
|
pixelRatio?: number;
|
|
/** Background color (default: '#ffffff' for PNG, 'none' for SVG) */
|
|
backgroundColor?: string;
|
|
/** Components to exclude from the export (e.g. ['toolbox']) */
|
|
excludeComponents?: string[];
|
|
}
|
|
|
|
// ─── Defaults ────────────────────────────────────────────────────────────────
|
|
|
|
const DEFAULT_FILE_NAME = 'open-meteo-chart';
|
|
const DEFAULT_PIXEL_RATIO = 2;
|
|
|
|
// ─── Download Functions ──────────────────────────────────────────────────────
|
|
|
|
/**
|
|
* Downloads a single ECharts instance as an image file.
|
|
*
|
|
* @param chart - The ECharts instance to export
|
|
* @param options - Download configuration options
|
|
*/
|
|
export function downloadChart(chart: echarts.ECharts, options: DownloadOptions = {}): void {
|
|
const {
|
|
fileName = DEFAULT_FILE_NAME,
|
|
format = 'png',
|
|
pixelRatio = DEFAULT_PIXEL_RATIO,
|
|
backgroundColor,
|
|
excludeComponents = ['toolbox']
|
|
} = options;
|
|
|
|
const resolvedBg = backgroundColor ?? (format === 'svg' ? 'none' : '#ffffff');
|
|
|
|
// Use ECharts' getDataURL for PNG, getConnectedDataURL for SVG
|
|
const dataUrl = chart.getDataURL({
|
|
type: format === 'svg' ? 'svg' : 'png',
|
|
pixelRatio: format === 'png' ? pixelRatio : 1,
|
|
backgroundColor: resolvedBg,
|
|
excludeComponents
|
|
});
|
|
|
|
triggerDownload(dataUrl, `${fileName}.${format}`);
|
|
}
|
|
|
|
/**
|
|
* Downloads all provided ECharts instances as separate image files.
|
|
* Each file is named with an incrementing suffix (e.g. chart-1.png, chart-2.png).
|
|
*
|
|
* @param charts - Array of ECharts instances to export
|
|
* @param options - Download configuration options (fileName is used as prefix)
|
|
*/
|
|
export function downloadAllCharts(
|
|
charts: echarts.ECharts[],
|
|
options: DownloadOptions = {}
|
|
): void {
|
|
const { fileName = DEFAULT_FILE_NAME, ...rest } = options;
|
|
|
|
charts.forEach((chart, index) => {
|
|
if (chart && !chart.isDisposed()) {
|
|
downloadChart(chart, {
|
|
...rest,
|
|
fileName: charts.length === 1 ? fileName : `${fileName}-${index + 1}`
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Returns the data URL of a chart without triggering a download.
|
|
* Useful for previewing or embedding chart images programmatically.
|
|
*
|
|
* @param chart - The ECharts instance to export
|
|
* @param options - Export configuration options
|
|
* @returns A base64-encoded data URL string
|
|
*/
|
|
export function getChartDataUrl(
|
|
chart: echarts.ECharts,
|
|
options: DownloadOptions = {}
|
|
): string {
|
|
const {
|
|
format = 'png',
|
|
pixelRatio = DEFAULT_PIXEL_RATIO,
|
|
backgroundColor,
|
|
excludeComponents = ['toolbox']
|
|
} = options;
|
|
|
|
const resolvedBg = backgroundColor ?? (format === 'svg' ? 'none' : '#ffffff');
|
|
|
|
return chart.getDataURL({
|
|
type: format === 'svg' ? 'svg' : 'png',
|
|
pixelRatio: format === 'png' ? pixelRatio : 1,
|
|
backgroundColor: resolvedBg,
|
|
excludeComponents
|
|
});
|
|
}
|
|
|
|
// ─── Internal Helpers ────────────────────────────────────────────────────────
|
|
|
|
/**
|
|
* Triggers a browser file download from a data URL.
|
|
* Creates a temporary anchor element, clicks it, and removes it.
|
|
*/
|
|
function triggerDownload(dataUrl: string, fileName: string): void {
|
|
const link = document.createElement('a');
|
|
link.href = dataUrl;
|
|
link.download = fileName;
|
|
link.style.display = 'none';
|
|
|
|
document.body.appendChild(link);
|
|
link.click();
|
|
|
|
// Clean up the DOM after a brief delay to ensure the download starts
|
|
requestAnimationFrame(() => {
|
|
document.body.removeChild(link);
|
|
});
|
|
}
|