fix: use ELK partitioning to enforce DO_TRY section order
Invisible ordering edges caused horizontal layout. Replace with ELK's partitioning feature which explicitly assigns sections to ordered layers: try_body (partition 0) → doFinally (1) → doCatch (2). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -356,12 +356,6 @@ public class ElkDiagramRenderer implements DiagramRenderer {
|
|||||||
allEdges.addAll(collectAllEdges(hr));
|
allEdges.addAll(collectAllEdges(hr));
|
||||||
}
|
}
|
||||||
for (ElkEdge elkEdge : allEdges) {
|
for (ElkEdge elkEdge : allEdges) {
|
||||||
// Skip invisible ordering edges used only for DO_TRY section layout
|
|
||||||
String edgeId = elkEdge.getIdentifier();
|
|
||||||
if (edgeId != null && edgeId.startsWith("__ordering_")) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
String sourceId = elkEdge.getSources().isEmpty() ? "" : elkEdge.getSources().get(0).getIdentifier();
|
String sourceId = elkEdge.getSources().isEmpty() ? "" : elkEdge.getSources().get(0).getIdentifier();
|
||||||
String targetId = elkEdge.getTargets().isEmpty() ? "" : elkEdge.getTargets().get(0).getIdentifier();
|
String targetId = elkEdge.getTargets().isEmpty() ? "" : elkEdge.getTargets().get(0).getIdentifier();
|
||||||
|
|
||||||
@@ -556,6 +550,7 @@ public class ElkDiagramRenderer implements DiagramRenderer {
|
|||||||
elkNode.setHeight(100);
|
elkNode.setHeight(100);
|
||||||
elkNode.setProperty(CoreOptions.ALGORITHM, "org.eclipse.elk.layered");
|
elkNode.setProperty(CoreOptions.ALGORITHM, "org.eclipse.elk.layered");
|
||||||
elkNode.setProperty(CoreOptions.DIRECTION, Direction.DOWN);
|
elkNode.setProperty(CoreOptions.DIRECTION, Direction.DOWN);
|
||||||
|
elkNode.setProperty(CoreOptions.PARTITIONING_ACTIVATE, true);
|
||||||
elkNode.setProperty(CoreOptions.SPACING_NODE_NODE, NODE_SPACING * 0.4);
|
elkNode.setProperty(CoreOptions.SPACING_NODE_NODE, NODE_SPACING * 0.4);
|
||||||
elkNode.setProperty(CoreOptions.SPACING_EDGE_NODE, EDGE_SPACING * 0.3);
|
elkNode.setProperty(CoreOptions.SPACING_EDGE_NODE, EDGE_SPACING * 0.3);
|
||||||
elkNode.setProperty(CoreOptions.PADDING,
|
elkNode.setProperty(CoreOptions.PADDING,
|
||||||
@@ -573,8 +568,7 @@ public class ElkDiagramRenderer implements DiagramRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Virtual _TRY_BODY wrapper with LR direction for horizontal try body chain
|
// Virtual _TRY_BODY wrapper (partition 0 = top)
|
||||||
// Layer constraint FIRST ensures it stays at the top of the DO_TRY
|
|
||||||
if (!tryBodyChildren.isEmpty()) {
|
if (!tryBodyChildren.isEmpty()) {
|
||||||
String wrapperId = rn.getId() + "._try_body";
|
String wrapperId = rn.getId() + "._try_body";
|
||||||
ElkNode wrapper = factory.createElkNode();
|
ElkNode wrapper = factory.createElkNode();
|
||||||
@@ -588,6 +582,7 @@ public class ElkDiagramRenderer implements DiagramRenderer {
|
|||||||
wrapper.setProperty(CoreOptions.SPACING_EDGE_NODE, EDGE_SPACING * 0.5);
|
wrapper.setProperty(CoreOptions.SPACING_EDGE_NODE, EDGE_SPACING * 0.5);
|
||||||
wrapper.setProperty(CoreOptions.PADDING,
|
wrapper.setProperty(CoreOptions.PADDING,
|
||||||
new org.eclipse.elk.core.math.ElkPadding(8, 8, 8, 8));
|
new org.eclipse.elk.core.math.ElkPadding(8, 8, 8, 8));
|
||||||
|
wrapper.setProperty(CoreOptions.PARTITIONING_PARTITION, 0);
|
||||||
compoundNodeIds.add(wrapperId);
|
compoundNodeIds.add(wrapperId);
|
||||||
elkNodeMap.put(wrapperId, wrapper);
|
elkNodeMap.put(wrapperId, wrapper);
|
||||||
|
|
||||||
@@ -598,12 +593,16 @@ public class ElkDiagramRenderer implements DiagramRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handler children: DO_FINALLY in the middle, DO_CATCH at the bottom
|
// DO_FINALLY in the middle (partition 1), DO_CATCH at the bottom (partition 2)
|
||||||
for (RouteNode child : handlerChildren) {
|
for (RouteNode child : handlerChildren) {
|
||||||
if (child.getType() == NodeType.DO_FINALLY) {
|
if (child.getType() == NodeType.DO_FINALLY) {
|
||||||
childNodeIds.add(child.getId());
|
childNodeIds.add(child.getId());
|
||||||
createElkNodeRecursive(child, elkNode, factory, elkNodeMap, nodeColors,
|
createElkNodeRecursive(child, elkNode, factory, elkNodeMap, nodeColors,
|
||||||
compoundNodeIds, childNodeIds, doTryNodeIds);
|
compoundNodeIds, childNodeIds, doTryNodeIds);
|
||||||
|
ElkNode finallyElk = elkNodeMap.get(child.getId());
|
||||||
|
if (finallyElk != null) {
|
||||||
|
finallyElk.setProperty(CoreOptions.PARTITIONING_PARTITION, 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (RouteNode child : handlerChildren) {
|
for (RouteNode child : handlerChildren) {
|
||||||
@@ -611,31 +610,11 @@ public class ElkDiagramRenderer implements DiagramRenderer {
|
|||||||
childNodeIds.add(child.getId());
|
childNodeIds.add(child.getId());
|
||||||
createElkNodeRecursive(child, elkNode, factory, elkNodeMap, nodeColors,
|
createElkNodeRecursive(child, elkNode, factory, elkNodeMap, nodeColors,
|
||||||
compoundNodeIds, childNodeIds, doTryNodeIds);
|
compoundNodeIds, childNodeIds, doTryNodeIds);
|
||||||
|
ElkNode catchElk = elkNodeMap.get(child.getId());
|
||||||
|
if (catchElk != null) {
|
||||||
|
catchElk.setProperty(CoreOptions.PARTITIONING_PARTITION, 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create invisible ordering edges to enforce top-to-bottom:
|
|
||||||
// try_body → doFinally → doCatch
|
|
||||||
List<ElkNode> orderedSections = new ArrayList<>();
|
|
||||||
if (!tryBodyChildren.isEmpty()) {
|
|
||||||
orderedSections.add(elkNodeMap.get(rn.getId() + "._try_body"));
|
|
||||||
}
|
|
||||||
for (RouteNode child : handlerChildren) {
|
|
||||||
if (child.getType() == NodeType.DO_FINALLY) {
|
|
||||||
orderedSections.add(elkNodeMap.get(child.getId()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (RouteNode child : handlerChildren) {
|
|
||||||
if (child.getType() == NodeType.DO_CATCH) {
|
|
||||||
orderedSections.add(elkNodeMap.get(child.getId()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (int i = 0; i < orderedSections.size() - 1; i++) {
|
|
||||||
ElkEdge orderEdge = factory.createElkEdge();
|
|
||||||
orderEdge.setIdentifier("__ordering_" + rn.getId() + "_" + i);
|
|
||||||
orderEdge.setContainingNode(elkNode);
|
|
||||||
orderEdge.getSources().add(orderedSections.get(i));
|
|
||||||
orderEdge.getTargets().add(orderedSections.get(i + 1));
|
|
||||||
}
|
}
|
||||||
} else if (isCompound) {
|
} else if (isCompound) {
|
||||||
compoundNodeIds.add(rn.getId());
|
compoundNodeIds.add(rn.getId());
|
||||||
|
|||||||
Reference in New Issue
Block a user