@@ -349,27 +349,19 @@ fn build_layer_encoding(
349349 ) ;
350350 }
351351
352- // Disable Vega-Lite's automatic stacking - we handle position adjustments ourselves
353- // This prevents Vega-Lite from applying its own stack/dodge logic on top of ours
354- // Set stack: null on both y and y2 channels (pos2 and pos2end in our terminology)
352+ // Disable Vega-Lite's automatic stacking - we handle position adjustments ourselves.
353+ // This prevents Vega-Lite from applying its own stack/dodge logic on top of ours.
354+ // Only set stack: null on primary position channels (y/radius) — Vega-Lite does
355+ // not support 'stack' on secondary channels (y2/radius2) and Altair rejects it.
355356 let y_channel = match coord_kind {
356357 CoordKind :: Cartesian => "y" ,
357358 CoordKind :: Polar => "radius" ,
358359 } ;
359- let y2_channel = match coord_kind {
360- CoordKind :: Cartesian => "y2" ,
361- CoordKind :: Polar => "radius2" ,
362- } ;
363360 if let Some ( y_enc) = encoding. get_mut ( y_channel) {
364361 if let Some ( obj) = y_enc. as_object_mut ( ) {
365362 obj. insert ( "stack" . to_string ( ) , Value :: Null ) ;
366363 }
367364 }
368- if let Some ( y2_enc) = encoding. get_mut ( y2_channel) {
369- if let Some ( obj) = y2_enc. as_object_mut ( ) {
370- obj. insert ( "stack" . to_string ( ) , Value :: Null ) ;
371- }
372- }
373365
374366 // Apply geom-specific encoding modifications via renderer
375367 let renderer = get_renderer ( & layer. geom ) ;
@@ -2703,8 +2695,15 @@ mod tests {
27032695 enc. get( "axis" ) . is_none( ) ,
27042696 "{channel} should not have 'axis': {enc}"
27052697 ) ;
2698+ assert ! (
2699+ enc. get( "stack" ) . is_none( ) ,
2700+ "{channel} should not have 'stack': {enc}"
2701+ ) ;
27062702 }
27072703 }
27082704 }
2705+
2706+ // The spec must also pass Vega-Lite schema validation
2707+ assert_valid_vegalite ( & json_str) ;
27092708 }
27102709}
0 commit comments