use of org.eclipse.elk.alg.layered.graph.LPort in project elk by eclipse.
the class HierarchicalPortOrthogonalEdgeRouter method connectNodeToDummy.
/**
* Adds a port to the given node and connects that to the given dummy node.
*
* @param node the node to connect to the dummy.
* @param dummy the external port dummy to connect the node to.
*/
private void connectNodeToDummy(final LGraph layeredGraph, final LNode node, final LNode dummy) {
// First, add a port to the node. The port side depends on the node's hierarchical port side
LPort outPort = new LPort();
outPort.setNode(node);
PortSide extPortSide = node.getProperty(InternalProperties.EXT_PORT_SIDE);
outPort.setSide(extPortSide);
// Find the dummy node's port
LPort inPort = dummy.getPorts().get(0);
// Connect the two nodes
LEdge edge = new LEdge();
edge.setSource(outPort);
edge.setTarget(inPort);
}
use of org.eclipse.elk.alg.layered.graph.LPort in project elk by eclipse.
the class HierarchicalPortOrthogonalEdgeRouter method correctSlantedEdgeSegments.
/**
* Goes over the eastern and western hierarchical dummy nodes in the given layer and checks
* whether their incident edges have slanted segments. Note that only the first and last
* segment needs to be checked.
*
* @param layer the layer.
*/
private void correctSlantedEdgeSegments(final Layer layer) {
for (LNode node : layer) {
if (node.getType() != NodeType.EXTERNAL_PORT) {
// We're only looking for hierarchical port dummies
continue;
}
PortSide extPortSide = node.getProperty(InternalProperties.EXT_PORT_SIDE);
if (extPortSide == PortSide.EAST || extPortSide == PortSide.WEST) {
for (LEdge edge : node.getConnectedEdges()) {
KVectorChain bendPoints = edge.getBendPoints();
if (bendPoints.isEmpty()) {
// TODO: The edge has no bend points yet, but may still be slanted. Handle that!
continue;
}
// Correct a slanted segment connected to the source port if it belongs to our node
LPort sourcePort = edge.getSource();
if (sourcePort.getNode() == node) {
KVector firstBendPoint = bendPoints.getFirst();
firstBendPoint.y = sourcePort.getAbsoluteAnchor().y;
}
// Correct a slanted segment connected to the target port if it belongs to our node
LPort targetPort = edge.getTarget();
if (targetPort.getNode() == node) {
KVector lastBendPoint = bendPoints.getLast();
lastBendPoint.y = targetPort.getAbsoluteAnchor().y;
}
}
}
}
}
use of org.eclipse.elk.alg.layered.graph.LPort in project elk by eclipse.
the class HierarchicalPortOrthogonalEdgeRouter method removeTemporaryNorthSouthDummies.
// /////////////////////////////////////////////////////////////////////////////
// STEP 4: REMOVE TEMPORARY DUMMIES
/**
* Removes the temporary hierarchical port dummies, reconnecting their incoming and outgoing
* edges to the original dummies and setting the appropriate bend points.
*
* @param layeredGraph the layered graph.
*/
private void removeTemporaryNorthSouthDummies(final LGraph layeredGraph) {
List<LNode> nodesToRemove = Lists.newArrayList();
// Iterate through all layers
for (Layer layer : layeredGraph) {
for (LNode node : layer) {
if (node.getType() != NodeType.EXTERNAL_PORT) {
// We're only looking for hierarchical port dummies
continue;
}
if (!node.hasProperty(InternalProperties.EXT_PORT_REPLACED_DUMMY)) {
// We're only looking for temporary north / south dummies
continue;
}
// There must be a port where all edges come in, another port where edges go out, and
// a port with an edge connecting node and origin (that one was added previously by
// this processor)
LPort nodeInPort = null;
LPort nodeOutPort = null;
LPort nodeOriginPort = null;
for (LPort port : node.getPorts()) {
switch(port.getSide()) {
case WEST:
nodeInPort = port;
break;
case EAST:
nodeOutPort = port;
break;
default:
nodeOriginPort = port;
}
}
// Find the edge connecting this dummy to the original external port dummy that we
// restored just a while ago
LEdge nodeToOriginEdge = nodeOriginPort.getOutgoingEdges().get(0);
// Compute bend points for incoming edges
KVectorChain incomingEdgeBendPoints = new KVectorChain(nodeToOriginEdge.getBendPoints());
KVector firstBendPoint = new KVector(nodeOriginPort.getPosition());
firstBendPoint.add(node.getPosition());
incomingEdgeBendPoints.add(0, firstBendPoint);
// Compute bend points for outgoing edges
KVectorChain outgoingEdgeBendPoints = KVectorChain.reverse(nodeToOriginEdge.getBendPoints());
KVector lastBendPoint = new KVector(nodeOriginPort.getPosition());
lastBendPoint.add(node.getPosition());
outgoingEdgeBendPoints.add(lastBendPoint);
// Retrieve the original hierarchical port dummy
LNode replacedDummy = (LNode) node.getProperty(InternalProperties.EXT_PORT_REPLACED_DUMMY);
LPort replacedDummyPort = replacedDummy.getPorts().get(0);
// Reroute all the input port's edges
LEdge[] edges = nodeInPort.getIncomingEdges().toArray(new LEdge[0]);
for (LEdge edge : edges) {
edge.setTarget(replacedDummyPort);
edge.getBendPoints().addAllAsCopies(edge.getBendPoints().size(), incomingEdgeBendPoints);
}
// Reroute all the output port's edges
edges = LGraphUtil.toEdgeArray(nodeOutPort.getOutgoingEdges());
for (LEdge edge : edges) {
edge.setSource(replacedDummyPort);
edge.getBendPoints().addAllAsCopies(0, outgoingEdgeBendPoints);
}
// Remove connection between node and original hierarchical port dummy
nodeToOriginEdge.setSource(null);
nodeToOriginEdge.setTarget(null);
// Remember the temporary node for removal
nodesToRemove.add(node);
}
}
// Remove nodes
for (LNode node : nodesToRemove) {
node.setLayer(null);
}
}
use of org.eclipse.elk.alg.layered.graph.LPort in project elk by eclipse.
the class HierarchicalPortOrthogonalEdgeRouter method restoreDummy.
/**
* Restores the given dummy.
*/
private void restoreDummy(final LNode dummy, final LGraph graph) {
// Depending on the hierarchical port's side, we set the port side of the dummy's ports
// to be able to route properly (northern dummies must have a southern port)
PortSide portSide = dummy.getProperty(InternalProperties.EXT_PORT_SIDE);
LPort dummyPort = dummy.getPorts().get(0);
if (portSide == PortSide.NORTH) {
dummyPort.setSide(PortSide.SOUTH);
} else if (portSide == PortSide.SOUTH) {
dummyPort.setSide(PortSide.NORTH);
}
// are not set acoordingly. That needs to be fixed (if port labels are to be taken into consideration)
if (graph.getProperty(LayeredOptions.NODE_SIZE_CONSTRAINTS).contains(SizeConstraint.PORT_LABELS)) {
// The ElkGraphImporter has set the relevant spacings on the dummy node
double portLabelSpacing = dummy.getProperty(LayeredOptions.SPACING_LABEL_PORT);
double labelLabelSpacing = dummy.getProperty(LayeredOptions.SPACING_LABEL_LABEL);
Set<PortLabelPlacement> portLabelPlacement = graph.getProperty(LayeredOptions.PORT_LABELS_PLACEMENT);
if (portLabelPlacement.contains(PortLabelPlacement.INSIDE)) {
double currentY = portLabelSpacing;
double xCenterRelativeToPort = dummy.getSize().x / 2 - dummyPort.getPosition().x;
for (LLabel label : dummyPort.getLabels()) {
label.getPosition().y = currentY;
label.getPosition().x = xCenterRelativeToPort - label.getSize().x / 2;
currentY += label.getSize().y + labelLabelSpacing;
}
} else if (portLabelPlacement.contains(PortLabelPlacement.OUTSIDE)) {
// Port labels have a vertical size of 0, but we need to set their x coordinate
for (LLabel label : dummyPort.getLabels()) {
label.getPosition().x = portLabelSpacing + dummy.getSize().x - dummyPort.getPosition().x;
}
}
// Calculate margins
NodeDimensionCalculation.getNodeMarginCalculator(LGraphAdapters.adapt(graph, false)).processNode(LGraphAdapters.adapt(dummy, false));
}
}
use of org.eclipse.elk.alg.layered.graph.LPort in project elk by eclipse.
the class InvertedPortProcessor method createEastPortSideDummies.
/**
* Creates the necessary dummy nodes for an input port on the east side of a node, provided that
* the edge connects two different nodes.
*
* @param layeredGraph
* the layered graph.
* @param eastwardPort
* the offending port.
* @param edge
* the edge connected to the port.
* @param layerNodeList
* list of unassigned nodes belonging to the layer of the node the port belongs to.
* The new dummy node is added to this list and must be assigned to the layer later.
*/
private void createEastPortSideDummies(final LGraph layeredGraph, final LPort eastwardPort, final LEdge edge, final List<LNode> layerNodeList) {
assert edge.getTarget() == eastwardPort;
// Ignore self loops
if (edge.getSource().getNode() == eastwardPort.getNode()) {
return;
}
// Dummy node in the same layer
LNode dummy = new LNode(layeredGraph);
dummy.setType(NodeType.LONG_EDGE);
dummy.setProperty(InternalProperties.ORIGIN, edge);
dummy.setProperty(LayeredOptions.PORT_CONSTRAINTS, PortConstraints.FIXED_POS);
layerNodeList.add(dummy);
LPort dummyInput = new LPort();
dummyInput.setNode(dummy);
dummyInput.setSide(PortSide.WEST);
LPort dummyOutput = new LPort();
dummyOutput.setNode(dummy);
dummyOutput.setSide(PortSide.EAST);
// Reroute the original edge
edge.setTarget(dummyInput);
// Connect the dummy with the original port
LEdge dummyEdge = new LEdge();
dummyEdge.copyProperties(edge);
dummyEdge.setProperty(LayeredOptions.JUNCTION_POINTS, null);
dummyEdge.setSource(dummyOutput);
dummyEdge.setTarget(eastwardPort);
// Set LONG_EDGE_SOURCE and LONG_EDGE_TARGET properties on the LONG_EDGE dummy
setLongEdgeSourceAndTarget(dummy, dummyInput, dummyOutput, eastwardPort);
// Move head labels from the old edge over to the new one
ListIterator<LLabel> labelIterator = edge.getLabels().listIterator();
while (labelIterator.hasNext()) {
LLabel label = labelIterator.next();
EdgeLabelPlacement labelPlacement = label.getProperty(LayeredOptions.EDGE_LABELS_PLACEMENT);
if (labelPlacement == EdgeLabelPlacement.HEAD) {
// Remember which edge the label originally belonged to, unless it already knows
if (!label.hasProperty(InternalProperties.END_LABEL_EDGE)) {
label.setProperty(InternalProperties.END_LABEL_EDGE, edge);
}
labelIterator.remove();
dummyEdge.getLabels().add(label);
}
}
}
Aggregations