Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DF Model Order Fixes #962

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,14 @@ public enum LayeringStrategy implements ILayoutPhaseFactory<LayeredPhases, LGrap
* No node with a higher model order is in a layer before a node with a lower model order.
* Dummy labels are only placed in layers between real nodes.
*/
@ExperimentalPropertyValue
BF_MODEL_ORDER,
/**
* Assumes an intended depth first model order of nodes and creates layers accordingly.
* Nodes are placed in the next layer until a node does not connect the previous layer.
* Dummy labels are only placed in layers between real nodes.
*/
@ExperimentalPropertyValue
DF_MODEL_ORDER;

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,12 @@ public final class DepthFirstModelOrderLayerer implements ILayoutPhase<LayeredPh
*/
private List<LNode> nodesToPlace;

/**
* Saves the maximum layer the nodes that still have to be assigned to a layer will be placed in.
* This is necessary to determine the actual offset of the nodes to place.
*/
private int maxToPlace = 0;

@Override
public LayoutProcessorConfiguration<LayeredPhases, LGraph> getLayoutProcessorConfiguration(final LGraph graph) {
return BASELINE_PROCESSING_CONFIGURATION;
Expand Down Expand Up @@ -123,6 +129,9 @@ public void process(final LGraph thelayeredGraph, final IElkProgressMonitor moni
if (!nodesToPlace.isEmpty()) {
if (layerDiff > 0) {
// Case some dependency to the existing graph was found add all nodes to their layers.
for (LNode toPlace : nodesToPlace) {
toPlace.id += maxLayer - maxToPlace;
}
placeNodesToPlace();
// Remove all nodes since they are now placed correctly.
nodesToPlace.clear();
Expand All @@ -131,6 +140,7 @@ public void process(final LGraph thelayeredGraph, final IElkProgressMonitor moni
// Case nodes cannot be placed without the need to move them later.
nodesToPlace.add(node);
node.id = desiredLayer;
maxToPlace = Math.max(maxToPlace, desiredLayer);
// Add dummy nodes and give them their desired layer id.
for (LEdge edge : node.getIncomingEdges()) {
if (edge.getSource().getNode().getLayer() == null
Expand Down Expand Up @@ -161,6 +171,7 @@ public void process(final LGraph thelayeredGraph, final IElkProgressMonitor moni
// Case no incoming connections, save the node to be placed.
nodesToPlace.add(node);
node.id = 0; // Save the layer the node will be placed in.
maxToPlace = Math.max(maxToPlace, 0);
currentLayer = layeredGraph.getLayers().get(0);
currentLayerId = 0;

Expand Down Expand Up @@ -209,7 +220,7 @@ private boolean isConnectedToCurrentLayer(final LNode node) {
boolean connectedViaLabelDummy;
if (nodesToPlace.isEmpty()) {
// Case the node to check already has a layer.
// TODO this may case an NPE if getLayer is null;
// This may case an NPE if getLayer is null;
directlyConnected = edge.getSource().getNode().getType() == NodeType.NORMAL
&& edge.getSource().getNode().getLayer() != null
&& edge.getSource().getNode().getLayer().id == currentLayerId;
Expand Down Expand Up @@ -289,6 +300,7 @@ private int getMaxConnectedLayer(final int layerId, final LNode node) {
* Places the nodes to place in their desired layer.
*/
public void placeNodesToPlace() {
maxToPlace = 0;
for (LNode nodeToPlace : nodesToPlace) {
if (nodeToPlace.id >= layeredGraph.getLayers().size()) {
// Add a normal and a dummy layer.
Expand Down