import { buildCsvDownloadItem, buildPngDownloadItem, type DownloadItem, } from '../actions/download' import type { HistogramWidgetData } from './types' /** * Download menu items for histograms. Always includes a CSV item with * `bin_low, bin_high, series_1_count, series_2_count, …` columns (one row * per bin). When `getCaptureEl` is supplied, prepends a PNG item that * rasterises the captured element via `html2canvas`. */ export function createHistogramDownloadConfig(args: { filename: string getData: () => HistogramWidgetData getTicks: () => readonly number[] seriesNames?: readonly string[] getCaptureEl?: () => HTMLElement | null pngPixelRatio?: number pngBackgroundColor?: string | null }): DownloadItem[] { const items: DownloadItem[] = [] if (args.getCaptureEl) { items.push( buildPngDownloadItem({ filename: args.filename, getCaptureEl: args.getCaptureEl, pixelRatio: args.pngPixelRatio, backgroundColor: args.pngBackgroundColor, }), ) } items.push( buildCsvDownloadItem({ filename: args.filename, getRows: () => { const data = args.getData() const ticks = args.getTicks() const seriesCount = data.length const header: unknown[] = ['bin_low', 'bin_high'] for (let i = 0; i < seriesCount; i++) { header.push(args.seriesNames?.[i] ?? `series_${i + 1}`) } const rows: unknown[][] = [header] for (let bin = 0; bin < Math.max(0, ticks.length - 1); bin++) { const row: unknown[] = [ticks[bin], ticks[bin + 1]] for (let s = 0; s < seriesCount; s++) row.push(data[s]?.[bin] ?? 0) rows.push(row) } return rows }, }), ) return items }