@@ -82,8 +82,19 @@ function parseChartSpec(content: string): { spec?: ChartSpec; error?: string } {
8282 */
8383function buildOption ( spec : ChartSpec , rows : Array < Record < string , unknown > > | null ) : EChartsOption {
8484 const option = structuredClone ( spec . option )
85- if ( rows && rows . length > 0 && option . dataset === undefined ) {
86- option . dataset = { source : rows }
85+ if ( rows && rows . length > 0 ) {
86+ // The resolved rows become the FIRST dataset (id "table", datasetIndex 0).
87+ // Spec-declared datasets follow it, so filter/sort transform datasets can
88+ // derive from the injected rows (transforms default to fromDatasetIndex 0,
89+ // or name it explicitly with fromDatasetId: "table").
90+ const injected = { id : 'table' , source : rows }
91+ if ( option . dataset === undefined ) {
92+ option . dataset = injected
93+ } else if ( Array . isArray ( option . dataset ) ) {
94+ option . dataset = [ injected , ...option . dataset ]
95+ } else {
96+ option . dataset = [ injected , option . dataset ]
97+ }
8798 }
8899 if ( option . backgroundColor === undefined ) {
89100 option . backgroundColor = 'transparent'
@@ -94,16 +105,16 @@ function buildOption(spec: ChartSpec, rows: Array<Record<string, unknown>> | nul
94105 // Gentle layout defaults — fill in ONLY what the spec leaves unset. A title
95106 // and a legend both default to the top edge and overlap; when both are
96107 // present and the legend declares no position, drop it below the title.
97- const legend = option . legend
98- if (
99- option . title !== undefined &&
100- legend !== null &&
101- typeof legend === 'object' &&
102- ! Array . isArray ( legend )
103- ) {
104- const positioned = legend as Record < string , unknown >
105- if ( positioned . top === undefined && positioned . bottom === undefined ) {
106- positioned . top = 32
108+ if ( option . title !== undefined && option . legend !== null && typeof option . legend === 'object' ) {
109+ const legends = Array . isArray ( option . legend ) ? option . legend : [ option . legend ]
110+ let nextTop = 32
111+ for ( const entry of legends ) {
112+ if ( entry === null || typeof entry !== 'object' ) continue
113+ const positioned = entry as Record < string , unknown >
114+ if ( positioned . top === undefined && positioned . bottom === undefined ) {
115+ positioned . top = nextTop
116+ nextTop += 28
117+ }
107118 }
108119 }
109120 return option as EChartsOption
0 commit comments