@@ -192,27 +192,12 @@ function buildPrecomputed(
192192 return { ...d , [ SEGMENT_FIELD ] : segment }
193193 } )
194194
195- // Collect training-base copies BEFORE boundary duplication so they don't
196- // interfere with the sequential boundary-point logic.
197- const trainBaseCopies : Record < string , any > [ ] = [ ]
198- if ( config . trainUnderline ) {
199- for ( const d of tagged ) {
200- if ( d [ SEGMENT_FIELD ] === "training" ) {
201- trainBaseCopies . push ( { ...d , [ SEGMENT_FIELD ] : "training-base" as SegmentType } )
202- }
203- }
204- }
205-
206195 // Duplicate boundary points so adjacent segments share an endpoint (no gap).
207196 // When _groupBy is set (multi-metric data), we must group by metric first
208197 // because the flat data is interleaved by timestamp (A_t1, B_t1, A_t2, B_t2...),
209198 // so adjacent-pair scanning would never find within-group segment transitions.
210199 const groupByField = config . _groupBy
211200 const processedData : Record < string , any > [ ] = [ ]
212- // Prepend training-base copies so they appear first in the data stream —
213- // PipelineStore iterates groups in insertion order, so the solid underline
214- // renders before (beneath) the dashed training line.
215- processedData . push ( ...trainBaseCopies )
216201
217202 if ( groupByField ) {
218203 // Group-aware boundary duplication: collect points per group, find
@@ -254,6 +239,20 @@ function buildPrecomputed(
254239 }
255240 }
256241
242+ // Collect training-base copies AFTER boundary duplication so the solid
243+ // underline includes bridge points and covers the same x-extent as the
244+ // dashed training segment.
245+ if ( config . trainUnderline ) {
246+ const trainBaseCopies : Record < string , any > [ ] = [ ]
247+ for ( const d of processedData ) {
248+ if ( d [ SEGMENT_FIELD ] === "training" ) {
249+ trainBaseCopies . push ( { ...d , [ SEGMENT_FIELD ] : "training-base" as SegmentType } )
250+ }
251+ }
252+ // Prepend so training-base renders first (beneath the dashed training line)
253+ processedData . unshift ( ...trainBaseCopies )
254+ }
255+
257256 const annotations : Record < string , any > [ ] = [ ]
258257
259258 // Envelope from upper/lower bounds
0 commit comments