import type { EchartProps, EchartWidgetState, EchartWidgetData, EchartOptionsProps, } from './types' import { EchartUI } from './echart-ui' import { useWidgetSelector } from '../stores/use-widget-selector' import { useMemo } from 'react' /** * Stateful EChart widget component that reads data and options from the widget store and renders an ECharts chart. * * @remarks * Transforms widget data into ECharts dataset format and delegates rendering to {@link EchartUI}. */ export function Echart(props: EchartProps) { // Single consolidated subscription instead of 5 separate ones. const { id, data, widgetOption, onEvents, init } = useWidgetSelector( props.id, (w) => ({ id: w?.id, data: (w as EchartWidgetState | undefined)?.data as | EchartWidgetData | undefined, widgetOption: (w as EchartWidgetState | undefined)?.option, onEvents: (w as EchartWidgetState | undefined)?.onEvents, init: (w as EchartWidgetState | undefined)?.init, }), ) // Memoize dataset transformation to avoid re-computing on every render const dataset = useMemo(() => buildDataset(data), [data]) const option = useMemo( () => ({ ...widgetOption, ...(dataset && { dataset }), }), [widgetOption, dataset], ) if (!id) { return null } return ( ) } /** * Builds the dataset configuration from widget data * @param data - The widget data array * @returns The dataset configuration for ECharts */ function buildDataset( data: EchartWidgetData | undefined, ): EchartOptionsProps['dataset'] { if (!data || data.length === 0) { return undefined } return data.map((d) => ({ source: d, })) }