import { downloadToCSV, downloadToPNG, type DownloadItem } from '../actions' import type { ConfigProps } from '../loader/types' import type { CategoryWidgetConfig, CategoryWidgetData, CategorySeriesConfig, } from './types' interface CategoryDownloadConfigProps extends ConfigProps { series?: CategorySeriesConfig[] } /** * Creates download configuration for category widgets, supporting PNG (screenshot) and CSV (data) exports. CSV output groups values by category across multiple series. * * @param props - Configuration with `refUI` reference and optional `series` for CSV column headers. * @returns Array of download items for use with the Download action. */ export function categoryDownloadConfig({ refUI, series, }: CategoryDownloadConfigProps): DownloadItem[] { return [ { ...downloadToPNG, modifier: () => downloadToPNG.modifier(refUI), }, { ...downloadToCSV, modifier: async (data) => { if (!data?.length || data[0]?.length === 0) { return downloadToCSV.modifier([]) } // data is CategoryDataItem[][] where data[seriesIndex] contains items for that series const seriesCount = data.length const grouped = new Map() const nameOrder: string[] = [] // Iterate over each series (outer array) for (let seriesIndex = 0; seriesIndex < seriesCount; seriesIndex++) { const seriesData = data[seriesIndex]! for (const item of seriesData) { let values = grouped.get(item.name) if (!values) { values = new Array(seriesCount).fill(0) grouped.set(item.name, values) nameOrder.push(item.name) } values[seriesIndex] = item.value } } // Build rows const rows = nameOrder.map((name) => [name, ...grouped.get(name)!]) const isMulti = seriesCount > 1 const headers = isMulti ? [ 'Category', ...(series?.map((s: CategorySeriesConfig) => s.name) ?? Array.from( { length: seriesCount }, (_, i) => `Series ${i + 1}`, )), ] : ['Category', 'Value'] return downloadToCSV.modifier([headers, ...rows]) }, }, ] } /** * Returns the default configuration for category list widgets, including empty series and a default `maxItems` of 10. * * @returns Default category widget config. */ export function categoryConfig(): CategoryWidgetConfig { return { series: [], maxItems: 10, max: undefined, } }