Search in sources :

Example 21 with LEdge

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;
}
Also used : LEdge(org.eclipse.elk.alg.layered.graph.LEdge) LPort(org.eclipse.elk.alg.layered.graph.LPort) LNode(org.eclipse.elk.alg.layered.graph.LNode)

Example 22 with LEdge

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;
}
Also used : LEdge(org.eclipse.elk.alg.layered.graph.LEdge) KVectorChain(org.eclipse.elk.core.math.KVectorChain) LPort(org.eclipse.elk.alg.layered.graph.LPort) LNode(org.eclipse.elk.alg.layered.graph.LNode) KVector(org.eclipse.elk.core.math.KVector)

Example 23 with LEdge

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;
}
Also used : LEdge(org.eclipse.elk.alg.layered.graph.LEdge) ArrayList(java.util.ArrayList) LPort(org.eclipse.elk.alg.layered.graph.LPort) LNode(org.eclipse.elk.alg.layered.graph.LNode)

Example 24 with LEdge

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;
    }
}
Also used : LEdge(org.eclipse.elk.alg.layered.graph.LEdge) LPort(org.eclipse.elk.alg.layered.graph.LPort) LNode(org.eclipse.elk.alg.layered.graph.LNode)

Example 25 with LEdge

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;
}
Also used : NNode(org.eclipse.elk.alg.common.networksimplex.NNode) LEdge(org.eclipse.elk.alg.layered.graph.LEdge) NGraph(org.eclipse.elk.alg.common.networksimplex.NGraph) LNode(org.eclipse.elk.alg.layered.graph.LNode)

Aggregations

LEdge (org.eclipse.elk.alg.layered.graph.LEdge)148 LNode (org.eclipse.elk.alg.layered.graph.LNode)107 LPort (org.eclipse.elk.alg.layered.graph.LPort)80 Layer (org.eclipse.elk.alg.layered.graph.Layer)41 KVector (org.eclipse.elk.core.math.KVector)34 KVectorChain (org.eclipse.elk.core.math.KVectorChain)20 LLabel (org.eclipse.elk.alg.layered.graph.LLabel)17 LGraph (org.eclipse.elk.alg.layered.graph.LGraph)16 PortSide (org.eclipse.elk.core.options.PortSide)11 ArrayList (java.util.ArrayList)9 List (java.util.List)9 InternalProperties (org.eclipse.elk.alg.layered.options.InternalProperties)8 Set (java.util.Set)7 LayeredOptions (org.eclipse.elk.alg.layered.options.LayeredOptions)7 Map (java.util.Map)6 IElkProgressMonitor (org.eclipse.elk.core.util.IElkProgressMonitor)6 Lists (com.google.common.collect.Lists)5 Iterator (java.util.Iterator)5 ElkRectangle (org.eclipse.elk.core.math.ElkRectangle)5 Pair (org.eclipse.elk.core.util.Pair)5