diff --git a/plugins/org.eclipse.elk.alg.rectpacking/src/org/eclipse/elk/alg/rectpacking/RectPacking.melk b/plugins/org.eclipse.elk.alg.rectpacking/src/org/eclipse/elk/alg/rectpacking/RectPacking.melk index e6139546c..cde949cc2 100644 --- a/plugins/org.eclipse.elk.alg.rectpacking/src/org/eclipse/elk/alg/rectpacking/RectPacking.melk +++ b/plugins/org.eclipse.elk.alg.rectpacking/src/org/eclipse/elk/alg/rectpacking/RectPacking.melk @@ -59,6 +59,7 @@ algorithm rectpacking(RectPackingLayoutProvider) { supports currentPosition supports inNewRow supports trybox + supports orderBySize } @@ -203,3 +204,12 @@ option inNewRow: boolean { targets nodes default = false } + +option orderBySize: boolean { + label "Order nodes by size" + description + "If set to true the nodes will be sorted by the size of their area before computing the layout. The largest + node will be in the first position." + default = false + targets parents +} 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 2fb18b557..45ca526fc 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 @@ -217,6 +217,11 @@ private LayoutProcessorConfiguration getPhaseI configuration.addBefore(RectPackingLayoutPhases.P2_PACKING, IntermediateProcessorStrategy.MIN_SIZE_POST_PROCESSOR); + if (layoutGraph.getProperty(RectPackingOptions.ORDER_BY_SIZE)) { + configuration.addBefore(RectPackingLayoutPhases.P1_WIDTH_APPROXIMATION, + IntermediateProcessorStrategy.NODE_SIZE_REORDERER); + } + if (layoutGraph.getProperty(RectPackingOptions.INTERACTIVE)) { configuration.addBefore(RectPackingLayoutPhases.P1_WIDTH_APPROXIMATION, IntermediateProcessorStrategy.INTERACTIVE_NODE_REORDERER); diff --git a/plugins/org.eclipse.elk.alg.rectpacking/src/org/eclipse/elk/alg/rectpacking/intermediate/IntermediateProcessorStrategy.java b/plugins/org.eclipse.elk.alg.rectpacking/src/org/eclipse/elk/alg/rectpacking/intermediate/IntermediateProcessorStrategy.java index 8164c56b3..4afa4dbbe 100644 --- a/plugins/org.eclipse.elk.alg.rectpacking/src/org/eclipse/elk/alg/rectpacking/intermediate/IntermediateProcessorStrategy.java +++ b/plugins/org.eclipse.elk.alg.rectpacking/src/org/eclipse/elk/alg/rectpacking/intermediate/IntermediateProcessorStrategy.java @@ -29,6 +29,7 @@ public enum IntermediateProcessorStrategy implements ILayoutProcessorFactory create() { switch (this) { + case NODE_SIZE_REORDERER: + return new NodeSizeReorderer(); case INTERACTIVE_NODE_REORDERER: return new InteractiveNodeReorderer(); case MIN_SIZE_PRE_PROCESSOR: diff --git a/plugins/org.eclipse.elk.alg.rectpacking/src/org/eclipse/elk/alg/rectpacking/intermediate/NodeSizeComparator.java b/plugins/org.eclipse.elk.alg.rectpacking/src/org/eclipse/elk/alg/rectpacking/intermediate/NodeSizeComparator.java new file mode 100644 index 000000000..4466f4aaa --- /dev/null +++ b/plugins/org.eclipse.elk.alg.rectpacking/src/org/eclipse/elk/alg/rectpacking/intermediate/NodeSizeComparator.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2024 Kiel University and others. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + *******************************************************************************/ +package org.eclipse.elk.alg.rectpacking.intermediate; + +import java.util.Comparator; + +import org.eclipse.elk.graph.ElkNode; + +/** + * Node size comparator to compare nodes by their size + * + */ +public class NodeSizeComparator implements Comparator { + + /* (non-Javadoc) + * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object) + */ + @Override + public int compare(ElkNode node0, ElkNode node1) { + double area0 = node0.getWidth() * node0.getHeight(); + double area1 = node1.getWidth() * node1.getHeight(); + + return Double.compare(area1, area0); + } + +} diff --git a/plugins/org.eclipse.elk.alg.rectpacking/src/org/eclipse/elk/alg/rectpacking/intermediate/NodeSizeReorderer.java b/plugins/org.eclipse.elk.alg.rectpacking/src/org/eclipse/elk/alg/rectpacking/intermediate/NodeSizeReorderer.java new file mode 100644 index 000000000..e131e1979 --- /dev/null +++ b/plugins/org.eclipse.elk.alg.rectpacking/src/org/eclipse/elk/alg/rectpacking/intermediate/NodeSizeReorderer.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2024 Kiel University and others. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + *******************************************************************************/ +package org.eclipse.elk.alg.rectpacking.intermediate; + +import org.eclipse.elk.core.alg.ILayoutProcessor; +import org.eclipse.elk.core.util.IElkProgressMonitor; +import org.eclipse.elk.graph.ElkNode; +import org.eclipse.emf.common.util.ECollections; + +/** + * Sorts all child nodes by their sizes from largest to smallest while preserving any existing ordering. + * + *
+ *
Precondition:
+ *
Postcondition:
+ *
Children are sorted in descending order from largest to smallest.
+ *
Slots:
+ *
Before phase 1.
+ *
Same-slot dependencies:
+ *
Before Interactive Node Reorderer
+ *
+ */ +public class NodeSizeReorderer implements ILayoutProcessor { + + /* (non-Javadoc) + * @see org.eclipse.elk.core.alg.ILayoutProcessor#process(java.lang.Object, org.eclipse.elk.core.util.IElkProgressMonitor) + */ + @Override + public void process(ElkNode graph, IElkProgressMonitor progressMonitor) { + + ECollections.sort(graph.getChildren(), new NodeSizeComparator()); + } + +}