Skip to content

Commit

Permalink
Add OrderBySize Rectpacking preprocessor (#1095)
Browse files Browse the repository at this point in the history
* Add OrderBySize Rectpacking preprocessor

Setting OrderBySize to true will order nodes by the sizes of their areas
while preserving any prior ordering in case of ties.

* put node size orderer before interactive orderer
  • Loading branch information
Eddykasp authored Dec 11, 2024
1 parent 5999901 commit 37c7ded
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ algorithm rectpacking(RectPackingLayoutProvider) {
supports currentPosition
supports inNewRow
supports trybox
supports orderBySize
}


Expand Down Expand Up @@ -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
}
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,11 @@ private LayoutProcessorConfiguration<RectPackingLayoutPhases, ElkNode> 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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public enum IntermediateProcessorStrategy implements ILayoutProcessorFactory<Elk
/*
* Before Phase 1
*/
NODE_SIZE_REORDERER,
INTERACTIVE_NODE_REORDERER,
MIN_SIZE_PRE_PROCESSOR,

Expand All @@ -43,6 +44,8 @@ public enum IntermediateProcessorStrategy implements ILayoutProcessorFactory<Elk
@Override
public ILayoutProcessor<ElkNode> create() {
switch (this) {
case NODE_SIZE_REORDERER:
return new NodeSizeReorderer();
case INTERACTIVE_NODE_REORDERER:
return new InteractiveNodeReorderer();
case MIN_SIZE_PRE_PROCESSOR:
Expand Down
Original file line number Diff line number Diff line change
@@ -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<ElkNode> {

/* (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);
}

}
Original file line number Diff line number Diff line change
@@ -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.
*
* <dl>
* <dt>Precondition:</dt>
* <dt>Postcondition:</dt>
* <dd>Children are sorted in descending order from largest to smallest.</dd>
* <dt>Slots:</dt>
* <dd>Before phase 1.</dd>
* <dt>Same-slot dependencies:</dt>
* <dd>Before Interactive Node Reorderer</dd>
* </dl>
*/
public class NodeSizeReorderer implements ILayoutProcessor<ElkNode> {

/* (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());
}

}

0 comments on commit 37c7ded

Please sign in to comment.