Search in sources :

Example 31 with LPort

use of org.eclipse.elk.alg.layered.graph.LPort in project elk by eclipse.

the class DotDebugUtil method writeLayer.

/**
 * Writes the given list of nodes and 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.
 */
private static void writeLayer(final StringWriter writer, final int layerNumber, final List<LNode> nodes) {
    if (nodes.isEmpty()) {
        return;
    }
    // Go through the layer's nodes
    int nodeNumber = -1;
    for (LNode node : nodes) {
        nodeNumber++;
        // The node's name in the output is its hash code (unique!)
        writer.write("        " + node.hashCode());
        // Options time!
        StringBuffer options = new StringBuffer();
        // Label
        options.append("label=\"");
        if (node.getType() == NodeType.NORMAL) {
            // Normal nodes display their name, if any
            if (node.getDesignation() != null) {
                options.append(node.getDesignation().replace("\"", "\\\"") + " ");
            }
        } else {
            // Dummy nodes show their name (if set), or their node ID
            if (node.getDesignation() != null) {
                options.append(node.getDesignation().replace("\"", "\\\"") + " ");
            } else {
                options.append("n_" + node.id + " ");
            }
            if (node.getType() == NodeType.NORTH_SOUTH_PORT) {
                Object origin = node.getProperty(InternalProperties.ORIGIN);
                if (origin instanceof LNode) {
                    options.append("(" + ((LNode) origin).toString() + ")");
                }
            }
        }
        options.append("(" + layerNumber + "," + nodeNumber + ")\",");
        // Node type
        if (node.getType() == NodeType.NORMAL) {
            options.append("shape=box,");
        } else {
            options.append("style=\"rounded,filled\",");
            String color = node.getType().getColor();
            if (color != null) {
                options.append("color=\"" + color + "\",");
            }
        }
        // Print options, if any
        options.deleteCharAt(options.length() - 1);
        if (options.length() > 0) {
            writer.write("[" + options + "]");
        }
        // End the node line
        writer.write(";\n");
    }
    // Write the edges
    for (LNode node : nodes) {
        // Go through all edges and output those that have this node as their source
        for (LPort port : node.getPorts()) {
            for (LEdge edge : port.getOutgoingEdges()) {
                writer.write("    " + node.hashCode() + " -> " + edge.getTarget().getNode().hashCode());
                writer.write(";\n");
            }
        }
    }
}
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 32 with LPort

use of org.eclipse.elk.alg.layered.graph.LPort in project elk by eclipse.

the class JsonDebugUtil method calculateMinMaxPositions.

/**
 * Inspects the given node, its outgoing edges and its ports for minimal and maximal coordinates
 * and adjusts the given vectors {@code min} and {@code max} if necessary.
 *
 * @param min
 *            the minimal coordinates used by the graph.
 * @param max
 *            the maximal coordinates used by the graph.
 * @param node
 *            the current node to inspect.
 */
private static void calculateMinMaxPositions(final KVector min, final KVector max, final LNode node) {
    min.x = Math.min(min.x, node.getPosition().x - node.getMargin().left);
    max.x = Math.max(max.x, node.getPosition().x + node.getSize().x + node.getMargin().right);
    min.y = Math.min(min.y, node.getPosition().y - node.getMargin().top);
    max.y = Math.max(max.y, node.getPosition().y + node.getSize().y + node.getMargin().bottom);
    for (LPort port : node.getPorts()) {
        min.x = Math.min(min.x, node.getPosition().x + port.getPosition().x - port.getMargin().left);
        max.x = Math.max(max.x, node.getPosition().x + port.getPosition().x + port.getSize().x + port.getMargin().right);
        min.y = Math.min(min.y, node.getPosition().y + port.getPosition().y - port.getMargin().top);
        max.y = Math.max(max.y, node.getPosition().y + port.getPosition().y + port.getSize().y + port.getMargin().bottom);
    }
    for (LEdge edge : node.getOutgoingEdges()) {
        for (KVector bendpoint : edge.getBendPoints()) {
            min.x = Math.min(min.x, bendpoint.x);
            max.x = Math.max(max.x, bendpoint.x);
            min.y = Math.min(min.y, bendpoint.y);
            max.y = Math.max(max.y, bendpoint.y);
        }
    }
}
Also used : LEdge(org.eclipse.elk.alg.layered.graph.LEdge) LPort(org.eclipse.elk.alg.layered.graph.LPort) KVector(org.eclipse.elk.core.math.KVector)

Example 33 with LPort

use of org.eclipse.elk.alg.layered.graph.LPort 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 34 with LPort

use of org.eclipse.elk.alg.layered.graph.LPort 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 35 with LPort

use of org.eclipse.elk.alg.layered.graph.LPort in project elk by eclipse.

the class InteractiveCrossingMinimizer method process.

@Override
public void process(final LGraph layeredGraph, final IElkProgressMonitor monitor) {
    monitor.begin("Interactive crossing minimization", 1);
    // Set ID's for each layer since they will be used by the port distribution code to index into arrays
    int layerIndex = 0;
    for (Layer layer : layeredGraph.getLayers()) {
        layer.id = layerIndex++;
    }
    LNode[][] nodeOrder = layeredGraph.toNodeArray();
    AbstractBarycenterPortDistributor portDistributor = new NodeRelativePortDistributor(nodeOrder.length);
    IInitializable.init(Arrays.asList(portDistributor), nodeOrder);
    int portCount = 0;
    layerIndex = 0;
    for (Layer layer : layeredGraph) {
        // determine a horizontal position for edge bend points comparison
        double horizPos = 0;
        int nodeCount = 0;
        for (LNode node : layer.getNodes()) {
            if (node.getPosition().x > 0) {
                horizPos += node.getPosition().x + node.getSize().x / 2;
                nodeCount++;
            }
            for (LPort port : node.getPorts()) {
                port.id = portCount++;
            }
        }
        if (nodeCount > 0) {
            horizPos /= nodeCount;
        }
        // create an array of vertical node positions
        final double[] pos = new double[layer.getNodes().size()];
        int nextIndex = 0;
        for (LNode node : layer) {
            node.id = nextIndex++;
            pos[node.id] = getPos(node, horizPos);
            // dummies, we haven't calculated meaningful positions)
            if (node.getType() == NodeType.LONG_EDGE) {
                node.setProperty(InternalProperties.ORIGINAL_DUMMY_NODE_POSITION, pos[node.id]);
            }
        }
        // sort the nodes using the position array
        Collections.sort(layer.getNodes(), new Comparator<LNode>() {

            public int compare(final LNode node1, final LNode node2) {
                int compare = Double.compare(pos[node1.id], pos[node2.id]);
                if (compare == 0) {
                    // The two nodes have the same y coordinate. Check for node successor
                    // constraints
                    List<LNode> node1Successors = node1.getProperty(InternalProperties.IN_LAYER_SUCCESSOR_CONSTRAINTS);
                    List<LNode> node2Successors = node2.getProperty(InternalProperties.IN_LAYER_SUCCESSOR_CONSTRAINTS);
                    if (node1Successors.contains(node2)) {
                        return -1;
                    } else if (node2Successors.contains(node1)) {
                        return 1;
                    }
                }
                return compare;
            }
        });
        portDistributor.distributePortsWhileSweeping(nodeOrder, layerIndex, true);
        layerIndex++;
    }
    monitor.done();
}
Also used : LPort(org.eclipse.elk.alg.layered.graph.LPort) LNode(org.eclipse.elk.alg.layered.graph.LNode) List(java.util.List) Layer(org.eclipse.elk.alg.layered.graph.Layer)

Aggregations

LPort (org.eclipse.elk.alg.layered.graph.LPort)270 LNode (org.eclipse.elk.alg.layered.graph.LNode)187 LEdge (org.eclipse.elk.alg.layered.graph.LEdge)78 Test (org.junit.Test)66 Layer (org.eclipse.elk.alg.layered.graph.Layer)62 LGraph (org.eclipse.elk.alg.layered.graph.LGraph)46 KVector (org.eclipse.elk.core.math.KVector)36 PortSide (org.eclipse.elk.core.options.PortSide)29 LLabel (org.eclipse.elk.alg.layered.graph.LLabel)23 KVectorChain (org.eclipse.elk.core.math.KVectorChain)18 GraphInfoHolder (org.eclipse.elk.alg.layered.p3order.GraphInfoHolder)15 List (java.util.List)12 ArrayList (java.util.ArrayList)8 InternalProperties (org.eclipse.elk.alg.layered.options.InternalProperties)8 PortConstraints (org.eclipse.elk.core.options.PortConstraints)7 Set (java.util.Set)6 ElkLabel (org.eclipse.elk.graph.ElkLabel)6 EnumSet (java.util.EnumSet)5 SelfHyperLoop (org.eclipse.elk.alg.layered.intermediate.loops.SelfHyperLoop)5 Lists (com.google.common.collect.Lists)4