use of org.eclipse.elk.alg.layered.graph.LEdge in project elk by eclipse.
the class DummySelfLoopProcessor method process.
@Override
public void process(final LGraph layeredGraph, final IElkProgressMonitor monitor) {
monitor.begin("Self-loop processing", 1);
// Iterate through all nodes
List<LNode> createdDummies = Lists.newArrayList();
for (Layer layer : layeredGraph) {
createdDummies.clear();
for (LNode node : layer) {
for (LPort port : node.getPorts()) {
// Go through the port's outgoing edges
LEdge[] edges = LGraphUtil.toEdgeArray(port.getOutgoingEdges());
for (LEdge edge : edges) {
// We're only interested in edges whose source and target node are identical
if (edge.getSource().getNode() != edge.getTarget().getNode()) {
continue;
}
LPort sourcePort = edge.getSource();
LPort targetPort = edge.getTarget();
PortSide sourcePortSide = sourcePort.getSide();
PortSide targetPortSide = targetPort.getSide();
// First, let's deal with the cases where edges have to be reversed
if ((sourcePortSide == PortSide.NORTH || sourcePortSide == PortSide.SOUTH) && targetPortSide == PortSide.WEST) {
edge.reverse(layeredGraph, false);
} else if (sourcePortSide == PortSide.SOUTH && targetPortSide == PortSide.NORTH) {
edge.reverse(layeredGraph, false);
} else if (sourcePortSide == PortSide.EAST && targetPortSide != PortSide.EAST) {
edge.reverse(layeredGraph, false);
}
// Now, let's see if a dummy has to be inserted
if (sourcePortSide == PortSide.EAST && targetPortSide == PortSide.WEST) {
// Note that the edge was reversed, so source and target port have switched
createdDummies.add(createDummy(layeredGraph, edge, targetPort, sourcePort));
} else if (sourcePortSide == PortSide.WEST && targetPortSide == PortSide.EAST) {
createdDummies.add(createDummy(layeredGraph, edge, sourcePort, targetPort));
}
}
}
}
// Add the dummies, if any
for (LNode dummy : createdDummies) {
dummy.setLayer(layer);
}
}
monitor.done();
}
use of org.eclipse.elk.alg.layered.graph.LEdge in project elk by eclipse.
the class EdgeAndLayerConstraintEdgeReverser method handleInnerNodes.
// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Inner Nodes
/**
* @param remainingNodes
*/
private void handleInnerNodes(final LGraph layeredGraph, final List<LNode> remainingNodes) {
// Iterate over the remaining nodes
for (LNode node : remainingNodes) {
// Check if there is a layer constraint
LayerConstraint layerConstraint = node.getProperty(LayeredOptions.LAYERING_LAYER_CONSTRAINT);
EdgeConstraint edgeConstraint = null;
switch(layerConstraint) {
case FIRST:
case FIRST_SEPARATE:
edgeConstraint = EdgeConstraint.OUTGOING_ONLY;
break;
case LAST:
case LAST_SEPARATE:
edgeConstraint = EdgeConstraint.INCOMING_ONLY;
break;
}
if (edgeConstraint != null) {
// Set the edge constraint on the node
node.setProperty(InternalProperties.EDGE_CONSTRAINT, EdgeConstraint.OUTGOING_ONLY);
if (edgeConstraint == EdgeConstraint.INCOMING_ONLY) {
reverseEdges(layeredGraph, node, layerConstraint, PortType.INPUT);
} else if (edgeConstraint == EdgeConstraint.OUTGOING_ONLY) {
reverseEdges(layeredGraph, node, layerConstraint, PortType.OUTPUT);
}
} else {
// port dummy with FIRST_SEPARATE and an inverted ports on the target node's EAST side.
if (node.getProperty(LayeredOptions.PORT_CONSTRAINTS).isSideFixed() && !node.getPorts().isEmpty()) {
boolean allPortsReversed = true;
for (LPort port : node.getPorts()) {
// reversed.
if (!(port.getSide() == PortSide.EAST && port.getNetFlow() > 0 || port.getSide() == PortSide.WEST && port.getNetFlow() < 0)) {
allPortsReversed = false;
break;
}
// no LAST or LAST_SEPARATE allowed for the target of outgoing edges
for (LEdge e : port.getOutgoingEdges()) {
LayerConstraint lc = e.getTarget().getNode().getProperty(LayeredOptions.LAYERING_LAYER_CONSTRAINT);
if (lc == LayerConstraint.LAST || lc == LayerConstraint.LAST_SEPARATE) {
allPortsReversed = false;
break;
}
}
// no FIRST or FIRST_SEPARATE allowed for the source of incoming edgs
for (LEdge e : port.getIncomingEdges()) {
LayerConstraint lc = e.getSource().getNode().getProperty(LayeredOptions.LAYERING_LAYER_CONSTRAINT);
if (lc == LayerConstraint.FIRST || lc == LayerConstraint.FIRST_SEPARATE) {
allPortsReversed = false;
break;
}
}
}
if (allPortsReversed) {
// Reverse all kinds of edges
reverseEdges(layeredGraph, node, layerConstraint, PortType.UNDEFINED);
}
}
}
}
}
use of org.eclipse.elk.alg.layered.graph.LEdge in project elk by eclipse.
the class FinalSplineBendpointsCalculator method calculateBezierBendPoints.
/**
* Collects all NUB control points computed for a spline segment and converts them to bezier control points.
* Note that additional NUB control points <em>may</em> be added before the conversion is performed.
*/
private void calculateBezierBendPoints(final List<LEdge> edgeChain, final LEdge survivingEdge) {
if (edgeChain.isEmpty()) {
return;
}
// in this chain we will put all NURBS control points.
final KVectorChain allCP = new KVectorChain();
// add the computed bendpoints to the specified edge (default to the first edge in the edge chain)
final LEdge edge = survivingEdge != null ? survivingEdge : edgeChain.get(0);
// Process the source end of the edge-chain.
final LPort sourcePort = edge.getSource();
// edge must be the first edge of a chain of edges
if (!SplineEdgeRouter.isQualifiedAsStartingNode(sourcePort.getNode())) {
throw new IllegalArgumentException("The target node of the edge must be a normal node " + "or a northSouthPort.");
}
// add the source as the very first control point.
allCP.addLast(sourcePort.getAbsoluteAnchor());
// add an additional control point if the source port is a north or south port
if (PortSide.SIDES_NORTH_SOUTH.contains(sourcePort.getSide())) {
double y = sourcePort.getProperty(InternalProperties.SPLINE_NS_PORT_Y_COORD);
KVector northSouthCP = new KVector(sourcePort.getAbsoluteAnchor().x, y);
allCP.addLast(northSouthCP);
}
// copy the calculated control points for all spline segments,
// possibly adding additional control points halfway between computed ones
KVector lastCP = null;
boolean addMidPoint = false;
Iterator<LEdge> edgeIterator = edgeChain.iterator();
while (edgeIterator.hasNext()) {
LEdge currentEdge = edgeIterator.next();
// read the stored bend-points for vertical segments, calculated by calculateNUBSBendPoint.
final KVectorChain currentBendPoints = currentEdge.getBendPoints();
if (!currentBendPoints.isEmpty()) {
// get a more straight horizontal segment
if (addMidPoint) {
KVector halfway = lastCP.add(currentBendPoints.getFirst()).scale(ONE_HALF);
allCP.addLast(halfway);
addMidPoint = false;
} else {
addMidPoint = true;
}
lastCP = currentBendPoints.getLast().clone();
allCP.addAll(currentBendPoints);
currentBendPoints.clear();
}
}
// finalize the spline
LPort targetPort = edge.getTarget();
// again, add an additional control point if the target port is a north or sout port
if (PortSide.SIDES_NORTH_SOUTH.contains(targetPort.getSide())) {
double y = targetPort.getProperty(InternalProperties.SPLINE_NS_PORT_Y_COORD);
KVector northSouthCP = new KVector(targetPort.getAbsoluteAnchor().x, y);
allCP.addLast(northSouthCP);
}
// finish with the target as last control point.
allCP.addLast(targetPort.getAbsoluteAnchor());
// insert straightening control points (if desired)
if (splineRoutingMode == SplineRoutingMode.CONSERVATIVE) {
// Add a control point for a straight segment at the very start and at the very end of a spline to prevent
// the edge from colliding with self-loops or the like inside the margin of the node.
// This also ensures the correct initial direction of the edge
insertStraighteningControlPoints(allCP, sourcePort, targetPort);
}
// convert list of NUB control points to bezier control points
final NubSpline nubSpline = new NubSpline(true, SplineEdgeRouter.SPLINE_DIMENSION, allCP);
// ... and set them as bendpoints of the edge
edge.getBendPoints().addAll(nubSpline.getBezierCP());
}
use of org.eclipse.elk.alg.layered.graph.LEdge in project elk by eclipse.
the class GraphTransformer method transpose.
// /////////////////////////////////////////////////////////////////////////////
// Transpose
/**
* Transpose the x and y coordinates of the given graph.
*
* @param nodes the nodes of the graph to transpose
*/
private void transpose(final List<LNode> nodes) {
// Transpose nodes
for (LNode node : nodes) {
transpose(node.getPosition());
transpose(node.getSize());
transpose(node.getPadding());
transposeNodeLabelPlacement(node);
transposeProperties(node);
// Transpose ports
for (LPort port : node.getPorts()) {
transpose(port.getPosition());
transpose(port.getAnchor());
transpose(port.getSize());
transposePortSide(port);
reverseIndex(port);
// Transpose edges
for (LEdge edge : port.getOutgoingEdges()) {
// Transpose bend points
for (KVector bendPoint : edge.getBendPoints()) {
transpose(bendPoint);
}
// Transpose junction points
KVectorChain junctionPoints = edge.getProperty(LayeredOptions.JUNCTION_POINTS);
if (junctionPoints != null) {
for (KVector jp : junctionPoints) {
transpose(jp);
}
}
// Transpose edge labels
for (LLabel label : edge.getLabels()) {
transpose(label.getPosition());
transpose(label.getSize());
}
}
// Transpose port labels
for (LLabel label : port.getLabels()) {
transpose(label.getPosition());
transpose(label.getSize());
}
}
// External port dummy?
if (node.getType() == NodeType.EXTERNAL_PORT) {
transposeExternalPortSide(node);
transposeLayerConstraint(node);
}
// Transpose node labels
for (LLabel label : node.getLabels()) {
transposeNodeLabelPlacement(label);
transpose(label.getSize());
transpose(label.getPosition());
}
}
}
use of org.eclipse.elk.alg.layered.graph.LEdge in project elk by eclipse.
the class BKAligner method verticalAlignment.
// ///////////////////////////////////////////////////////////////////////////////////////////////////
// Block Building and Inner Shifting
/**
* The graph is traversed in the given directions and nodes a grouped into blocks. The nodes in these
* blocks will later be placed such that the edges connecting them will be straight lines.
*
* <p>Type 1 conflicts are resolved, so that the dummy nodes of a long edge share the same block if
* possible, such that the long edge is drawn straightly.</p>
*
* @param bal One of the four layouts which shall be used in this step
* @param markedEdges List with all edges that were marked as type 1 conflicts
*/
public void verticalAlignment(final BKAlignedLayout bal, final Set<LEdge> markedEdges) {
// Initialize root and align maps
for (Layer layer : layeredGraph.getLayers()) {
for (LNode v : layer.getNodes()) {
bal.root[v.id] = v;
bal.align[v.id] = v;
bal.innerShift[v.id] = 0.0;
}
}
List<Layer> layers = layeredGraph.getLayers();
// right to left, thus a reverse iterator is needed
if (bal.hdir == HDirection.LEFT) {
layers = Lists.reverse(layers);
}
for (Layer layer : layers) {
// r denotes the position in layer order where the last block was found
// It is initialized with -1, since nothing is found and the ordering starts with 0
int r = -1;
List<LNode> nodes = layer.getNodes();
if (bal.vdir == VDirection.UP) {
// If the alignment direction is UP, the nodes in a layer are traversed
// reversely, thus we start at INT_MAX and with the reversed list of nodes.
r = Integer.MAX_VALUE;
nodes = Lists.reverse(nodes);
}
// CHECKSTYLEOFF Local Variable Names
for (LNode v_i_k : nodes) {
List<Pair<LNode, LEdge>> neighbors = null;
if (bal.hdir == HDirection.LEFT) {
neighbors = ni.rightNeighbors.get(v_i_k.id);
} else {
neighbors = ni.leftNeighbors.get(v_i_k.id);
}
if (neighbors.size() > 0) {
// When a node has many upper neighbors, consider only the (two) nodes in the
// middle.
int d = neighbors.size();
int low = ((int) Math.floor(((d + 1.0) / 2.0))) - 1;
int high = ((int) Math.ceil(((d + 1.0) / 2.0))) - 1;
if (bal.vdir == VDirection.UP) {
// Check, whether v_i_k can be added to a block of its upper/lower neighbor(s)
for (int m = high; m >= low; m--) {
if (bal.align[v_i_k.id].equals(v_i_k)) {
Pair<LNode, LEdge> u_m_pair = neighbors.get(m);
LNode u_m = u_m_pair.getFirst();
// ensures that at least one edge exists
if (!markedEdges.contains(u_m_pair.getSecond()) && r > ni.nodeIndex[u_m.id]) {
bal.align[u_m.id] = v_i_k;
bal.root[v_i_k.id] = bal.root[u_m.id];
bal.align[v_i_k.id] = bal.root[v_i_k.id];
bal.od[bal.root[v_i_k.id].id] &= v_i_k.getType() == NodeType.LONG_EDGE;
r = ni.nodeIndex[u_m.id];
}
}
}
} else {
// Check, whether vik can be added to a block of its upper/lower neighbor(s)
for (int m = low; m <= high; m++) {
if (bal.align[v_i_k.id].equals(v_i_k)) {
Pair<LNode, LEdge> um_pair = neighbors.get(m);
LNode um = um_pair.getFirst();
if (!markedEdges.contains(um_pair.getSecond()) && r < ni.nodeIndex[um.id]) {
bal.align[um.id] = v_i_k;
bal.root[v_i_k.id] = bal.root[um.id];
bal.align[v_i_k.id] = bal.root[v_i_k.id];
bal.od[bal.root[v_i_k.id].id] &= v_i_k.getType() == NodeType.LONG_EDGE;
r = ni.nodeIndex[um.id];
}
}
}
}
}
}
// CHECKSTYLEON Local Variable Names
}
}
Aggregations