use of org.eclipse.elk.alg.layered.graph.LEdge in project elk by eclipse.
the class JsonDebugUtil method writeLayer.
/**
* Writes the given list of nodes and collects their edges.
*
* @param writer
* writer to write to.
* @param layerNumber
* the layer number. {@code -1} for layerless nodes.
* @param nodes
* the nodes in the layer.
* @param indentation
* the indentation level to use.
* @param offset
* the combined offset of the containing LGraph.
* @return list of edges that need to be added to the graph.
*/
private static List<LEdge> writeLayer(final StringWriter writer, final int layerNumber, final List<LNode> nodes, final int indentation, final KVector offset) {
if (nodes.isEmpty()) {
return Lists.newLinkedList();
}
writeNodes(writer, nodes, indentation, layerNumber, offset);
List<LEdge> edges = Lists.newLinkedList();
// Collect the edges
for (LNode node : nodes) {
// Go through all edges and collect those that have this node as their source
for (LPort port : node.getPorts()) {
edges.addAll(port.getOutgoingEdges());
}
}
return edges;
}
use of org.eclipse.elk.alg.layered.graph.LEdge in project elk by eclipse.
the class InteractiveCrossingMinimizer method getPos.
/**
* Determine a vertical position for the given node.
*
* @param node a node
* @param horizPos the horizontal position at which to measure (relevant for edges)
* @return the vertical position used for sorting
*/
private double getPos(final LNode node, final double horizPos) {
switch(node.getType()) {
case LONG_EDGE:
LEdge edge = (LEdge) node.getProperty(InternalProperties.ORIGIN);
// reconstruct the original bend points from the node annotations
KVectorChain bendpoints = edge.getProperty(InternalProperties.ORIGINAL_BENDPOINTS);
if (bendpoints == null) {
bendpoints = new KVectorChain();
} else if (edge.getProperty(InternalProperties.REVERSED)) {
bendpoints = KVectorChain.reverse(bendpoints);
}
// Check if we can determine the position just by using the source point, if we can determine it
LPort source = node.getProperty(InternalProperties.LONG_EDGE_SOURCE);
if (source != null) {
KVector sourcePoint = source.getAbsoluteAnchor();
if (horizPos <= sourcePoint.x) {
return sourcePoint.y;
}
bendpoints.addFirst(sourcePoint);
}
// Check if we can determine the position just by using the target point
LPort target = node.getProperty(InternalProperties.LONG_EDGE_TARGET);
if (target != null) {
KVector targetPoint = target.getAbsoluteAnchor();
if (targetPoint.x <= horizPos) {
return targetPoint.y;
}
bendpoints.addLast(targetPoint);
}
// Find the two points along the edge that the horizontal point lies between
if (bendpoints.size() >= 2) {
Iterator<KVector> pointIter = bendpoints.iterator();
KVector point1 = pointIter.next();
KVector point2 = pointIter.next();
while (point2.x < horizPos && pointIter.hasNext()) {
point1 = point2;
point2 = pointIter.next();
}
return point1.y + (horizPos - point1.x) / (point2.x - point1.x) * (point2.y - point1.y);
}
break;
case NORTH_SOUTH_PORT:
// Get one of the ports the dummy node was created for, and its original node
LPort originPort = (LPort) node.getPorts().get(0).getProperty(InternalProperties.ORIGIN);
LNode originNode = originPort.getNode();
switch(originPort.getSide()) {
case NORTH:
// by respecting node successor constraints.
return originNode.getPosition().y;
case SOUTH:
// Use the position of the node's southern side
return originNode.getPosition().y + originNode.getSize().y;
}
break;
}
// the fallback solution is to take the previous position of the node's anchor point
return node.getInteractiveReferencePoint().y;
}
use of org.eclipse.elk.alg.layered.graph.LEdge in project elk by eclipse.
the class LayerSweepTypeDecider method useBottomUp.
/**
* Decide whether to use bottom up or cross-hierarchical sweep method.
*
* @return decision
*/
public boolean useBottomUp() {
double boundary = graphData.lGraph().getProperty(LayeredOptions.CROSSING_MINIMIZATION_HIERARCHICAL_SWEEPINESS);
if (bottomUpForced(boundary) || rootNode() || fixedPortOrder() || fewerThanTwoInOutEdges()) {
return true;
}
if (graphData.crossMinDeterministic()) {
return false;
}
int pathsToRandom = 0;
int pathsToHierarchical = 0;
List<LNode> nsPortDummies = new ArrayList<>();
for (LNode[] layer : graphData.currentNodeOrder()) {
for (LNode node : layer) {
// We must visit all sources of edges first, so we collect north south dummies for later.
if (isNorthSouthDummy(node)) {
nsPortDummies.add(node);
continue;
}
NodeInfo currentNode = nodeInfoFor(node);
// Check for hierarchical port dummies or random influence.
if (isExternalPortDummy(node)) {
currentNode.hierarchicalInfluence = 1;
if (isEasternDummy(node)) {
pathsToHierarchical += currentNode.connectedEdges;
}
} else if (hasNoWesternPorts(node)) {
currentNode.randomInfluence = 1;
} else if (hasNoEasternPorts(node)) {
pathsToRandom += currentNode.connectedEdges;
}
// and transfer information to targets.
for (LEdge edge : node.getOutgoingEdges()) {
pathsToRandom += currentNode.randomInfluence;
pathsToHierarchical += currentNode.hierarchicalInfluence;
transferInfoToTarget(currentNode, edge);
}
// Do the same for north/south dummies: Increase counts of paths by the number outgoing edges times the
// influence and transfer information to dummies.
Iterable<LPort> northSouthPorts = Iterables.concat(node.getPortSideView(PortSide.NORTH), node.getPortSideView(PortSide.SOUTH));
for (LPort port : northSouthPorts) {
LNode nsDummy = port.getProperty(InternalProperties.PORT_DUMMY);
if (nsDummy != null) {
pathsToRandom += currentNode.randomInfluence;
pathsToHierarchical += currentNode.hierarchicalInfluence;
transferInfoTo(currentNode, nsDummy);
}
}
}
// Now process nsPortDummies
for (LNode node : nsPortDummies) {
NodeInfo currentNode = nodeInfoFor(node);
for (LEdge edge : node.getOutgoingEdges()) {
pathsToRandom += currentNode.randomInfluence;
pathsToHierarchical += currentNode.hierarchicalInfluence;
transferInfoToTarget(currentNode, edge);
}
}
nsPortDummies.clear();
}
double allPaths = pathsToRandom + pathsToHierarchical;
double normalized = allPaths == 0 ? Double.POSITIVE_INFINITY : (pathsToRandom - pathsToHierarchical) / allPaths;
return normalized >= boundary;
}
use of org.eclipse.elk.alg.layered.graph.LEdge in project elk by eclipse.
the class LongestPathLayerer method visit.
/**
* Visit a node: if not already visited, find the longest path to a sink.
*
* @param node node to visit
* @return height of the given node in the layered graph
*/
private int visit(final LNode node) {
int height = nodeHeights[node.id];
if (height >= 0) {
// the node was already visited (the case height == 0 should never occur)
return height;
} else {
int maxHeight = 1;
for (LPort port : node.getPorts()) {
for (LEdge edge : port.getOutgoingEdges()) {
LNode targetNode = edge.getTarget().getNode();
// ignore self-loops
if (node != targetNode) {
int targetHeight = visit(targetNode);
maxHeight = Math.max(maxHeight, targetHeight + 1);
}
}
}
putNode(node, maxHeight);
return maxHeight;
}
}
use of org.eclipse.elk.alg.layered.graph.LEdge in project elk by eclipse.
the class NetworkSimplexLayerer method initialize.
/**
* Helper method for the network simplex layerer. It instantiates all necessary attributes for
* the execution of the network simplex layerer and initializes them with their default values.
* All edges in the connected component given by the input argument will be determined, as well
* as the number of incoming and outgoing edges of each node ( {@code inDegree}, respectively
* {@code outDegree}). All sinks and source nodes in the connected component identified in this
* step will be added to {@code sinks}, respectively {@code sources}.
*
* @param theNodes
* a {@code Collection} containing all nodes of the graph
*/
private NGraph initialize(final List<LNode> theNodes) {
final Map<LNode, NNode> nodeMap = Maps.newHashMap();
// transform nodes
NGraph graph = new NGraph();
for (LNode lNode : theNodes) {
NNode nNode = NNode.of().origin(lNode).create(graph);
nodeMap.put(lNode, nNode);
}
// transform edges
for (LNode lNode : theNodes) {
for (LEdge lEdge : lNode.getOutgoingEdges()) {
// ignore self-loops
if (lEdge.isSelfLoop()) {
continue;
}
NEdge.of(lEdge).weight(1 * Math.max(1, lEdge.getProperty(LayeredOptions.PRIORITY_SHORTNESS))).delta(1).source(nodeMap.get(lEdge.getSource().getNode())).target(nodeMap.get(lEdge.getTarget().getNode())).create();
}
}
return graph;
}
Aggregations