use of org.eclipse.elk.alg.layered.graph.LEdge 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.LEdge 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.LEdge in project elk by eclipse.
the class HierarchicalPortOrthogonalEdgeRouter method routeEdges.
// /////////////////////////////////////////////////////////////////////////////
// STEP 3: EDGE ROUTING
/**
* Routes nothern and southern hierarchical port edges and ajusts the graph's height and
* offsets accordingly.
*
* @param monitor the progress monitor we're using.
* @param layeredGraph the layered graph.
* @param northSouthDummies the collection of restored northern and southern port dummies.
*/
private void routeEdges(final IElkProgressMonitor monitor, final LGraph layeredGraph, final Iterable<LNode> northSouthDummies) {
// Prepare south and target layers for northern and southern routing
Set<LNode> northernSourceLayer = Sets.newLinkedHashSet();
Set<LNode> northernTargetLayer = Sets.newLinkedHashSet();
Set<LNode> southernSourceLayer = Sets.newLinkedHashSet();
Set<LNode> southernTargetLayer = Sets.newLinkedHashSet();
// Find some routing parameters
double nodeSpacing = layeredGraph.getProperty(LayeredOptions.SPACING_NODE_NODE).doubleValue();
double edgeSpacing = layeredGraph.getProperty(LayeredOptions.SPACING_EDGE_EDGE).doubleValue();
// connected to
for (LNode hierarchicalPortDummy : northSouthDummies) {
PortSide portSide = hierarchicalPortDummy.getProperty(InternalProperties.EXT_PORT_SIDE);
if (portSide == PortSide.NORTH) {
northernTargetLayer.add(hierarchicalPortDummy);
for (LEdge edge : hierarchicalPortDummy.getIncomingEdges()) {
northernSourceLayer.add(edge.getSource().getNode());
}
} else if (portSide == PortSide.SOUTH) {
southernTargetLayer.add(hierarchicalPortDummy);
for (LEdge edge : hierarchicalPortDummy.getIncomingEdges()) {
southernSourceLayer.add(edge.getSource().getNode());
}
}
}
// Northern routing
if (!northernSourceLayer.isEmpty()) {
// Route the edges using a south-to-north orthogonal edge router
OrthogonalRoutingGenerator routingGenerator = new OrthogonalRoutingGenerator(RoutingDirection.SOUTH_TO_NORTH, edgeSpacing, "extnorth");
int slots = routingGenerator.routeEdges(monitor, layeredGraph, northernSourceLayer, 0, northernTargetLayer, -nodeSpacing - layeredGraph.getOffset().y);
// If anything was routed, adjust the graph's offset and height
if (slots > 0) {
northernExtPortEdgeRoutingHeight = nodeSpacing + (slots - 1) * edgeSpacing;
layeredGraph.getOffset().y += northernExtPortEdgeRoutingHeight;
layeredGraph.getSize().y += northernExtPortEdgeRoutingHeight;
}
}
// Southern routing
if (!southernSourceLayer.isEmpty()) {
// Route the edges using a north-to-south orthogonal edge router
OrthogonalRoutingGenerator routingGenerator = new OrthogonalRoutingGenerator(RoutingDirection.NORTH_TO_SOUTH, edgeSpacing, "extsouth");
int slots = routingGenerator.routeEdges(monitor, layeredGraph, southernSourceLayer, 0, southernTargetLayer, layeredGraph.getSize().y + nodeSpacing - layeredGraph.getOffset().y);
// Adjust graph height.
if (slots > 0) {
layeredGraph.getSize().y += nodeSpacing + (slots - 1) * edgeSpacing;
}
}
}
use of org.eclipse.elk.alg.layered.graph.LEdge 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.LEdge 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