use of org.eclipse.elk.alg.layered.graph.LMargin in project elk by eclipse.
the class HierarchicalPortOrthogonalEdgeRouter method assignAscendingCoordinates.
/**
* Iterates over the given array of dummy nodes, making sure that their x coordinates
* are strictly ascending. Dummy nodes whose coordinates are in violation of this rule
* are moved to the right. Once this method is finished, the coordinates of the dummy
* nodes reflect their order in the array.
*
* @param dummies array of dummy nodes.
* @param graph the layered graph.
*/
private void assignAscendingCoordinates(final LNode[] dummies, final LGraph graph) {
// Find the port-port spacing
double spacing = graph.getProperty(LayeredOptions.SPACING_PORT_PORT);
// Now, iterate over the array, remembering the last assigned position. If we find a
// position that is less than or equal to the last position, assign a new position of
// "lastPosition + edgeSpacing"
double nextValidCoordinate = dummies[0].getPosition().x + dummies[0].getSize().x + dummies[0].getMargin().right + spacing;
for (int index = 1; index < dummies.length; index++) {
KVector currentPosition = dummies[index].getPosition();
KVector currentSize = dummies[index].getSize();
LMargin currentMargin = dummies[index].getMargin();
// Ensure spacings are adhered to
double delta = currentPosition.x - currentMargin.left - nextValidCoordinate;
if (delta < 0) {
currentPosition.x -= delta;
}
// Ensure the graph is large enough for this node
KVector graphSize = graph.getSize();
graphSize.x = Math.max(graphSize.x, currentPosition.x + currentSize.x);
// Compute next valid coordinate
nextValidCoordinate = currentPosition.x + currentSize.x + currentMargin.right + spacing;
}
}
use of org.eclipse.elk.alg.layered.graph.LMargin in project elk by eclipse.
the class ComponentsCompactor method getPortPositionOnMargin.
private KVector getPortPositionOnMargin(final LPort port) {
KVector pos = port.getAbsoluteAnchor().clone();
LMargin margins = port.getNode().getMargin();
switch(port.getSide()) {
case NORTH:
pos.y -= margins.top;
break;
case EAST:
pos.x += margins.right;
break;
case SOUTH:
pos.y += margins.bottom;
break;
case WEST:
pos.x -= margins.left;
break;
}
return pos;
}
use of org.eclipse.elk.alg.layered.graph.LMargin in project elk by eclipse.
the class LabelPlacer method manageLabels.
// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Label Management
private void manageLabels(final SelfHyperLoop slLoop, final ILabelManager labelManager) {
// How much space we have available depends entirely on our alignment since that also determines whether we're
// on the north/south or the east/west sides
SelfHyperLoopLabels slLabels = slLoop.getSLLabels();
SelfLoopPort alignRef = slLabels.getAlignmentReferenceSLPort();
LNode lNode = slLoop.getSLHolder().getLNode();
KVector lNodeSize = lNode.getSize();
LMargin lNodeMargins = slLoop.getSLHolder().getLNode().getMargin();
double targetWidth = 0;
switch(slLabels.getAlignment()) {
case CENTER:
// Clip the label to the extent of the node's bounding box
targetWidth = lNodeMargins.left + lNodeSize.x + lNodeMargins.right;
break;
case LEFT:
targetWidth = lNodeSize.x - alignRef.getLPort().getPosition().x - alignRef.getLPort().getAnchor().x + lNodeMargins.right;
break;
case RIGHT:
targetWidth = lNodeMargins.left + alignRef.getLPort().getPosition().x + alignRef.getLPort().getAnchor().x;
break;
case TOP:
// We have no way of knowing how far to the left / right our self loop will extend on our placement side,
// so we need a default here
targetWidth = LabelManagementProcessor.MIN_WIDTH_EDGE_LABELS;
break;
default:
assert false;
}
slLabels.applyLabelManagement(labelManager, Math.max(targetWidth, LabelManagementProcessor.MIN_WIDTH_EDGE_LABELS));
}
use of org.eclipse.elk.alg.layered.graph.LMargin in project elk by eclipse.
the class OrthogonalSelfLoopRouter method routeSelfLoops.
@Override
public void routeSelfLoops(final SelfLoopHolder slHolder) {
LNode lNode = slHolder.getLNode();
KVector nodeSize = lNode.getSize();
LMargin nodeMargins = lNode.getMargin();
double edgeEdgeDistance = LGraphUtil.getIndividualOrInherited(lNode, LayeredOptions.SPACING_EDGE_EDGE);
double edgeLabelDistance = LGraphUtil.getIndividualOrInherited(lNode, LayeredOptions.SPACING_EDGE_LABEL);
double nodeSLDistance = LGraphUtil.getIndividualOrInherited(lNode, LayeredOptions.SPACING_NODE_SELF_LOOP);
LMargin newNodeMargins = new LMargin();
newNodeMargins.set(nodeMargins);
// Compute how far away from the node each routing slot on each side is (this takes labels into account)
double[][] routingSlotPositions = computeRoutingSlotPositions(slHolder, edgeEdgeDistance, edgeLabelDistance, nodeSLDistance);
for (SelfHyperLoop slLoop : slHolder.getSLHyperLoops()) {
for (SelfLoopEdge slEdge : slLoop.getSLEdges()) {
LEdge lEdge = slEdge.getLEdge();
EdgeRoutingDirection routingDirection = computeEdgeRoutingDirection(slEdge);
// Compute orthogonal bend points and give subclasses a chance to modify them to suit their particular
// routing style. The default implementation in this class won't change the bend points.
KVectorChain bendPoints = computeOrthogonalBendPoints(slEdge, routingDirection, routingSlotPositions);
bendPoints = modifyBendPoints(slEdge, routingDirection, bendPoints);
lEdge.getBendPoints().clear();
lEdge.getBendPoints().addAll(bendPoints);
bendPoints.stream().forEach(bp -> updateNewNodeMargins(nodeSize, newNodeMargins, bp));
}
// Place the self loop's labels (the edges were routed such that there is enough space available)
SelfHyperLoopLabels slLabels = slLoop.getSLLabels();
if (slLabels != null) {
placeLabels(slLoop, slLabels, routingSlotPositions, edgeLabelDistance);
updateNewNodeMargins(nodeSize, newNodeMargins, slLabels);
}
}
// Update the node's margins to include the space required for self loops
nodeMargins.set(newNodeMargins);
}
Aggregations