use of org.eclipse.elk.alg.layered.options.FixedAlignment in project elk by eclipse.
the class BKNodePlacer method process.
@Override
public void process(final LGraph layeredGraph, final IElkProgressMonitor monitor) {
monitor.begin("Brandes & Koepf node placement", 1);
this.lGraph = layeredGraph;
// Precalculate some information that we require during the
// following processes.
ni = NeighborhoodInformation.buildFor(layeredGraph);
// a balanced layout is desired if
// a) no specific alignment is set and straight edges are not desired
// b) a balanced alignment is enforced
FixedAlignment align = layeredGraph.getProperty(LayeredOptions.NODE_PLACEMENT_BK_FIXED_ALIGNMENT);
boolean favorStraightEdges = layeredGraph.getProperty(LayeredOptions.NODE_PLACEMENT_FAVOR_STRAIGHT_EDGES);
produceBalancedLayout = (align == FixedAlignment.NONE && !favorStraightEdges) || align == FixedAlignment.BALANCED;
// Phase which marks type 1 conflicts, no difference between the directions so only
// one run is required.
markConflicts(layeredGraph);
// Initialize four layouts which result from the two possible directions respectively.
BKAlignedLayout rightdown = null, rightup = null, leftdown = null, leftup = null;
// SUPPRESS CHECKSTYLE NEXT MagicNumber
List<BKAlignedLayout> layouts = Lists.newArrayListWithCapacity(4);
switch(layeredGraph.getProperty(LayeredOptions.NODE_PLACEMENT_BK_FIXED_ALIGNMENT)) {
case LEFTDOWN:
leftdown = new BKAlignedLayout(layeredGraph, ni.nodeCount, VDirection.DOWN, HDirection.LEFT);
layouts.add(leftdown);
break;
case LEFTUP:
leftup = new BKAlignedLayout(layeredGraph, ni.nodeCount, VDirection.UP, HDirection.LEFT);
layouts.add(leftup);
break;
case RIGHTDOWN:
rightdown = new BKAlignedLayout(layeredGraph, ni.nodeCount, VDirection.DOWN, HDirection.RIGHT);
layouts.add(rightdown);
break;
case RIGHTUP:
rightup = new BKAlignedLayout(layeredGraph, ni.nodeCount, VDirection.UP, HDirection.RIGHT);
layouts.add(rightup);
break;
default:
leftdown = new BKAlignedLayout(layeredGraph, ni.nodeCount, VDirection.DOWN, HDirection.LEFT);
leftup = new BKAlignedLayout(layeredGraph, ni.nodeCount, VDirection.UP, HDirection.LEFT);
rightdown = new BKAlignedLayout(layeredGraph, ni.nodeCount, VDirection.DOWN, HDirection.RIGHT);
rightup = new BKAlignedLayout(layeredGraph, ni.nodeCount, VDirection.UP, HDirection.RIGHT);
layouts.add(rightdown);
layouts.add(rightup);
layouts.add(leftdown);
layouts.add(leftup);
}
BKAligner aligner = new BKAligner(layeredGraph, ni);
for (BKAlignedLayout bal : layouts) {
// Phase which determines the nodes' memberships in blocks. This happens in four different
// ways, either from processing the nodes from the first layer to the last or vice versa.
aligner.verticalAlignment(bal, markedEdges);
// Additional phase which is not included in the original Brandes-Koepf Algorithm.
// It makes sure that the connected ports within a block are aligned to avoid unnecessary
// bend points. Also, the required size of each block is determined.
aligner.insideBlockShift(bal);
}
ICompactor compacter = new BKCompactor(layeredGraph, ni);
for (BKAlignedLayout bal : layouts) {
// This phase determines the y coordinates of the blocks and thus the vertical coordinates
// of all nodes.
compacter.horizontalCompaction(bal);
}
// Debug output
if (monitor.isLoggingEnabled()) {
for (BKAlignedLayout bal : layouts) {
monitor.log(bal + " size is " + bal.layoutSize());
}
}
// Choose a layout from the four calculated layouts. Layouts that contain errors are skipped.
// The layout with the smallest size is selected. If more than one smallest layout exists,
// the first one of the competing layouts is selected.
BKAlignedLayout chosenLayout = null;
// given criteria.
if (produceBalancedLayout) {
BKAlignedLayout balanced = createBalancedLayout(layouts, ni.nodeCount);
if (checkOrderConstraint(layeredGraph, balanced, monitor)) {
chosenLayout = balanced;
}
}
// violates order constraints, pick the one with the smallest height
if (chosenLayout == null) {
for (BKAlignedLayout bal : layouts) {
if (checkOrderConstraint(layeredGraph, bal, monitor)) {
if (chosenLayout == null || chosenLayout.layoutSize() > bal.layoutSize()) {
chosenLayout = bal;
}
}
}
}
// the RIGHTDOWN layout is chosen by default.
if (chosenLayout == null) {
// there has to be at least one layout in the list
chosenLayout = layouts.get(0);
}
// Apply calculated positions to nodes.
for (Layer layer : layeredGraph.getLayers()) {
for (LNode node : layer.getNodes()) {
node.getPosition().y = chosenLayout.y[node.id] + chosenLayout.innerShift[node.id];
}
}
// Debug output
if (monitor.isLoggingEnabled()) {
monitor.log("Chosen node placement: " + chosenLayout);
monitor.log("Blocks: " + getBlocks(chosenLayout));
monitor.log("Classes: " + getClasses(chosenLayout, monitor));
monitor.log("Marked edges: " + markedEdges);
}
// cleanup
for (BKAlignedLayout bal : layouts) {
bal.cleanup();
}
ni.cleanup();
markedEdges.clear();
monitor.done();
}
Aggregations