diff --git a/src/Workflow/__Tests/StellaOps.Workflow.Renderer.Tests/DocumentProcessingWorkflowRenderingTests.Artifacts.cs b/src/Workflow/__Tests/StellaOps.Workflow.Renderer.Tests/DocumentProcessingWorkflowRenderingTests.Artifacts.cs index e722e4ed3..4cbeb51e5 100644 --- a/src/Workflow/__Tests/StellaOps.Workflow.Renderer.Tests/DocumentProcessingWorkflowRenderingTests.Artifacts.cs +++ b/src/Workflow/__Tests/StellaOps.Workflow.Renderer.Tests/DocumentProcessingWorkflowRenderingTests.Artifacts.cs @@ -40,6 +40,7 @@ public partial class DocumentProcessingWorkflowRenderingTests var layout = await engine.LayoutAsync(graph, new WorkflowRenderLayoutRequest { Direction = WorkflowRenderLayoutDirection.LeftToRight, + NodeSpacing = 40, }); var svgRenderer = new WorkflowRenderSvgRenderer(); diff --git a/src/__Libraries/StellaOps.ElkSharp/ElkEdgeRouterIterative.WinnerRefinement.Hybrid.cs b/src/__Libraries/StellaOps.ElkSharp/ElkEdgeRouterIterative.WinnerRefinement.Hybrid.cs index e99ccefbb..25a2d57a5 100644 --- a/src/__Libraries/StellaOps.ElkSharp/ElkEdgeRouterIterative.WinnerRefinement.Hybrid.cs +++ b/src/__Libraries/StellaOps.ElkSharp/ElkEdgeRouterIterative.WinnerRefinement.Hybrid.cs @@ -258,10 +258,21 @@ internal static partial class ElkEdgeRouterIterative ElkLayoutDiagnostics.LogProgress($"Hybrid winner refinement after final boundary-slot snap: {DescribeSolution(current)}"); } + // Eliminate large diagonal segments that may survive through the + // iterative optimization (the hybrid baseline runs EliminateDiagonalSegments + // but subsequent pipeline passes can re-introduce diagonals). + if (current.Score.LongDiagonalViolations > 0) + { + var eliminated = ElkEdgePostProcessor.EliminateDiagonalSegments(current.Edges, nodes); + var elimScore = ElkEdgeRoutingScoring.ComputeScore(eliminated, nodes); + if (elimScore.LongDiagonalViolations < current.Score.LongDiagonalViolations + && elimScore.NodeCrossings <= current.Score.NodeCrossings) + { + current = current with { Score = elimScore, Edges = eliminated }; + } + } + // Straighten short diagonal stubs at gateway boundary vertices. - // The boundary-slot snap and normalization passes may leave small - // diagonal segments (3-8px) at gateway tips. This cosmetic pass - // adjusts the adjacent bend point to make the approach orthogonal. var straightened = ElkEdgePostProcessor.StraightenGatewayCornerDiagonals(current.Edges, nodes); if (!ReferenceEquals(straightened, current.Edges)) {