From c6f44e8a09d092fb69cb220dd1074f543bee35c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Domr=C3=B6s?= Date: Tue, 13 Feb 2024 09:26:16 +0100 Subject: [PATCH] rectpacking: Fix micro layout for rectpacking including content alignment and label placement. (#997) * rectpacking: Do node micro layout before and after layout. Previously it was only done after because whitespace elimination might change node sizes. However, if the node size cannot fit the label, we need to do this before the layout too. * rectpacking: Corrected comments for minsize processors. * Fixes #989. Content alignment for rectpacking. Translate inner content based on the real width and the width of the parent. --- .../RectPackingLayoutProvider.java | 22 ++++++++++++++++++- .../intermediate/MinSizePostProcessor.java | 2 +- .../intermediate/MinSizePreProcessor.java | 2 +- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/plugins/org.eclipse.elk.alg.rectpacking/src/org/eclipse/elk/alg/rectpacking/RectPackingLayoutProvider.java b/plugins/org.eclipse.elk.alg.rectpacking/src/org/eclipse/elk/alg/rectpacking/RectPackingLayoutProvider.java index 831b867a0..2fb18b557 100644 --- a/plugins/org.eclipse.elk.alg.rectpacking/src/org/eclipse/elk/alg/rectpacking/RectPackingLayoutProvider.java +++ b/plugins/org.eclipse.elk.alg.rectpacking/src/org/eclipse/elk/alg/rectpacking/RectPackingLayoutProvider.java @@ -20,6 +20,7 @@ import org.eclipse.elk.core.alg.ILayoutProcessor; import org.eclipse.elk.core.alg.LayoutProcessorConfiguration; import org.eclipse.elk.core.math.ElkPadding; +import org.eclipse.elk.core.math.KVector; import org.eclipse.elk.core.options.CoreOptions; import org.eclipse.elk.core.util.BasicProgressMonitor; import org.eclipse.elk.core.util.BoxLayoutProvider; @@ -58,6 +59,11 @@ public void layout(final ElkNode layoutGraph, final IElkProgressMonitor progress boolean tryBox = layoutGraph.getProperty(RectPackingOptions.TRYBOX); List rectangles = layoutGraph.getChildren(); + // if requested, compute nodes's dimensions, place node labels, ports, port labels, etc. + if (!layoutGraph.getProperty(RectPackingOptions.OMIT_NODE_MICRO_LAYOUT)) { + NodeMicroLayout.forGraph(layoutGraph).execute(); + } + // Check whether regions are stackable and do box layout instead. boolean stackable = false; if (tryBox && rectangles.size() >= 3) { @@ -119,6 +125,20 @@ public void layout(final ElkNode layoutGraph, final IElkProgressMonitor progress progressMonitor.logGraph(layoutGraph, slotIndex + "-Finished"); } // elkjs-exclude-end + + // Content alignment + double realWidth = 0; + double realHeight = 0; + for (ElkNode rect : rectangles) { + realWidth = Math.max(realWidth, rect.getX() + rect.getWidth()); + realHeight = Math.max(realHeight, rect.getY() + rect.getHeight()); + } + + ElkUtil.translate(layoutGraph, + new KVector( + layoutGraph.getProperty(InternalProperties.DRAWING_WIDTH), + layoutGraph.getProperty(InternalProperties.DRAWING_HEIGHT)), + new KVector(realWidth, realHeight)); // Final touch. applyPadding(rectangles, padding); @@ -129,7 +149,7 @@ public void layout(final ElkNode layoutGraph, final IElkProgressMonitor progress layoutGraph.getProperty(InternalProperties.DRAWING_HEIGHT) + padding.getVertical(), false, true); } - // if requested, compute nodes's dimensions, place node labels, ports, port labels, etc. + // Do micro layout again since the whitspace elimination and other things might have changed node sizes. if (!layoutGraph.getProperty(RectPackingOptions.OMIT_NODE_MICRO_LAYOUT)) { NodeMicroLayout.forGraph(layoutGraph).execute(); } diff --git a/plugins/org.eclipse.elk.alg.rectpacking/src/org/eclipse/elk/alg/rectpacking/intermediate/MinSizePostProcessor.java b/plugins/org.eclipse.elk.alg.rectpacking/src/org/eclipse/elk/alg/rectpacking/intermediate/MinSizePostProcessor.java index 4041718eb..67a372634 100644 --- a/plugins/org.eclipse.elk.alg.rectpacking/src/org/eclipse/elk/alg/rectpacking/intermediate/MinSizePostProcessor.java +++ b/plugins/org.eclipse.elk.alg.rectpacking/src/org/eclipse/elk/alg/rectpacking/intermediate/MinSizePostProcessor.java @@ -15,7 +15,7 @@ import org.eclipse.elk.graph.ElkNode; /** - * Sorts all child nodes by their desired position. + * Sets a target width at least as high as the minimum width of the parent * *
*
Precondition:
diff --git a/plugins/org.eclipse.elk.alg.rectpacking/src/org/eclipse/elk/alg/rectpacking/intermediate/MinSizePreProcessor.java b/plugins/org.eclipse.elk.alg.rectpacking/src/org/eclipse/elk/alg/rectpacking/intermediate/MinSizePreProcessor.java index d2d42558e..8ea289a50 100644 --- a/plugins/org.eclipse.elk.alg.rectpacking/src/org/eclipse/elk/alg/rectpacking/intermediate/MinSizePreProcessor.java +++ b/plugins/org.eclipse.elk.alg.rectpacking/src/org/eclipse/elk/alg/rectpacking/intermediate/MinSizePreProcessor.java @@ -17,7 +17,7 @@ import org.eclipse.elk.graph.ElkNode; /** - * Sorts all child nodes by their desired position. + * Sets the minimum width and height of the parent since this influences decisions based on the aspect ratio. * *
*
Precondition: