@@ -152,6 +152,79 @@ export class TrainrunSectionsView {
152152 return atSource ? trainrunSection . getSourceNode ( ) : trainrunSection . getTargetNode ( ) ;
153153 }
154154
155+ /**
156+ * Creates a TrainrunSectionViewObject for collapsed node chains where the visual path
157+ * goes directly from startNode to endNode instead of using the primary section's path.
158+ * This is used when intermediate nodes are collapsed and should not be visible.
159+ */
160+ static createViewObjectForCollapsedChain (
161+ editorView : EditorView ,
162+ primarySection : TrainrunSection ,
163+ allSections : TrainrunSection [ ] ,
164+ startNode : Node ,
165+ endNode : Node ,
166+ isNonStopAtSource : boolean ,
167+ isNonStopAtTarget : boolean ,
168+ isMuted : boolean ,
169+ hiddenTagSource : boolean ,
170+ hiddenTagTarget : boolean ,
171+ hiddenTagTraveltime : boolean ,
172+ hiddenTagTrainrunName : boolean ,
173+ hiddenTagDirectionArrows : boolean ,
174+ ) : TrainrunSectionViewObject {
175+ // Create a standard view object first
176+ const viewObject = new TrainrunSectionViewObject (
177+ editorView ,
178+ primarySection ,
179+ isNonStopAtSource ,
180+ isNonStopAtTarget ,
181+ isMuted ,
182+ hiddenTagSource ,
183+ hiddenTagTarget ,
184+ hiddenTagTraveltime ,
185+ hiddenTagTrainrunName ,
186+ hiddenTagDirectionArrows ,
187+ ) ;
188+
189+ // Override the path calculation to use startNode and endNode
190+ // We need to temporarily modify the primary section's nodes for path calculation
191+ const originalSourceNode = primarySection . getSourceNode ( ) ;
192+ const originalTargetNode = primarySection . getTargetNode ( ) ;
193+ const originalSourcePortId = primarySection . getSourcePortId ( ) ;
194+ const originalTargetPortId = primarySection . getTargetPortId ( ) ;
195+
196+ try {
197+ // Set temporary nodes for path calculation
198+ primarySection . setSourceNode ( startNode ) ;
199+ primarySection . setTargetNode ( endNode ) ;
200+
201+ // Find appropriate ports using the correct sections from the chain
202+ // Source port: from the first section of the chain
203+ // Target port: from the last section of the chain
204+ const firstSection = allSections [ 0 ] ;
205+ const lastSection = allSections [ allSections . length - 1 ] ;
206+
207+ const sourcePort =
208+ startNode . getPortOfTrainrunSection ( firstSection . getId ( ) ) || startNode . getPorts ( ) [ 0 ] ;
209+ const targetPort =
210+ endNode . getPortOfTrainrunSection ( lastSection . getId ( ) ) || endNode . getPorts ( ) [ 0 ] ;
211+
212+ primarySection . setSourcePortId ( sourcePort . getId ( ) ) ;
213+ primarySection . setTargetPortId ( targetPort . getId ( ) ) ;
214+
215+ // Recalculate path with new nodes
216+ primarySection . routeEdgeAndPlaceText ( ) ;
217+ } finally {
218+ // Restore original nodes and ports
219+ primarySection . setSourceNode ( originalSourceNode ) ;
220+ primarySection . setTargetNode ( originalTargetNode ) ;
221+ primarySection . setSourcePortId ( originalSourcePortId ) ;
222+ primarySection . setTargetPortId ( originalTargetPortId ) ;
223+ }
224+
225+ return viewObject ;
226+ }
227+
155228 static hasWarning ( trainrunSection : TrainrunSection , textElement : TrainrunSectionText ) : boolean {
156229 switch ( textElement ) {
157230 case TrainrunSectionText . SourceDeparture :
@@ -1690,9 +1763,12 @@ export class TrainrunSectionsView {
16901763 const primarySection = group . sections [ 0 ] ;
16911764 const lastSection = group . sections [ group . sections . length - 1 ] ;
16921765 viewTrainrunSectionDataObjects . push (
1693- new TrainrunSectionViewObject (
1766+ TrainrunSectionsView . createViewObjectForCollapsedChain (
16941767 editorView ,
16951768 primarySection ,
1769+ group . sections ,
1770+ group . startNode ,
1771+ group . endNode ,
16961772 group . startNode . isNonStop ( primarySection ) ,
16971773 group . endNode . isNonStop ( lastSection ) ,
16981774 TrainrunSectionsView . isMuted ( primarySection , selectedTrainrun , connectedTrainIds ) ,
0 commit comments