Search in sources :

Example 96 with KVector

use of org.eclipse.elk.core.math.KVector in project elk by eclipse.

the class SouthToNorthRoutingStrategy method calculateBendPoints.

@Override
public void calculateBendPoints(final HyperEdgeSegment segment, final double startPos, final double edgeSpacing) {
    // We don't do anything with dummy segments; they are dealt with when their partner is processed
    if (segment.isDummy()) {
        return;
    }
    // Calculate coordinates for each port's bend points
    double segmentY = startPos - segment.getRoutingSlot() * edgeSpacing;
    for (LPort port : segment.getPorts()) {
        double sourceX = port.getAbsoluteAnchor().x;
        for (LEdge edge : port.getOutgoingEdges()) {
            if (!edge.isSelfLoop()) {
                LPort target = edge.getTarget();
                double targetX = target.getAbsoluteAnchor().x;
                if (Math.abs(sourceX - targetX) > OrthogonalRoutingGenerator.TOLERANCE) {
                    // We'll update these if we find that the segment was split
                    double currentY = segmentY;
                    HyperEdgeSegment currentSegment = segment;
                    KVector bend = new KVector(sourceX, currentY);
                    edge.getBendPoints().add(bend);
                    addJunctionPointIfNecessary(edge, currentSegment, bend, false);
                    // If this segment was split, we need two additional bend points
                    HyperEdgeSegment splitPartner = segment.getSplitPartner();
                    if (splitPartner != null) {
                        double splitX = splitPartner.getIncomingConnectionCoordinates().get(0);
                        bend = new KVector(splitX, currentY);
                        edge.getBendPoints().add(bend);
                        addJunctionPointIfNecessary(edge, currentSegment, bend, false);
                        // Advance to the split partner's routing slot
                        currentY = startPos - splitPartner.getRoutingSlot() * edgeSpacing;
                        currentSegment = splitPartner;
                        bend = new KVector(splitX, currentY);
                        edge.getBendPoints().add(bend);
                        addJunctionPointIfNecessary(edge, currentSegment, bend, false);
                    }
                    bend = new KVector(targetX, currentY);
                    edge.getBendPoints().add(bend);
                    addJunctionPointIfNecessary(edge, currentSegment, bend, false);
                }
            }
        }
    }
}
Also used : LEdge(org.eclipse.elk.alg.layered.graph.LEdge) LPort(org.eclipse.elk.alg.layered.graph.LPort) HyperEdgeSegment(org.eclipse.elk.alg.layered.p5edges.orthogonal.HyperEdgeSegment) KVector(org.eclipse.elk.core.math.KVector)

Example 97 with KVector

use of org.eclipse.elk.core.math.KVector in project elk by eclipse.

the class PolylineEdgeRouter method processNode.

// //////////////////////////////////////////////////////////////////////////////////////////////////
// Actual Edge Routing Code
/**
 * Inserts bend points for edges incident to this node. The bend points are inserted such that
 * the segments that cross the layer's area are straight or pretty much straight. A bend point
 * is only added if it's necessary: if the bend point to be inserted differs from the edge's end
 * point.
 *
 * @param node
 *            the node whose incident edges to insert bend points for.
 * @param layerLeftXPos
 *            the x position of the node's layer.
 * @param maxAcceptableXDiff
 *            the maximum space between node and layer boundary before bend points need to be inserted.
 */
private void processNode(final LNode node, final double layerLeftXPos, final double maxAcceptableXDiff) {
    // The right side of the layer
    final double layerRightXPos = layerLeftXPos + node.getLayer().getSize().x;
    for (LPort port : node.getPorts()) {
        KVector absolutePortAnchor = port.getAbsoluteAnchor();
        if (node.getType() == NodeType.NORTH_SOUTH_PORT) {
            // North/south ports require special handling (also see #515):
            // The dummy node that represents the north/south port will have been placed at:
            // - the very left x-coordinate of the currently processed layer for incoming edges
            // - the very right x-coordinate for outgoing edges
            // However, the actual x-coordinate of the port itself is very likely to have a different x-coordinate.
            // The code below introduces bendpoints that prevent edge/node overlaps based on a condition that
            // checks that a node's position is "far enough away" from the left-most x-coordinate of the layer.
            // Consequently, we have to use the north/south port's x-coordinate instead of the dummy node's one.
            LPort correspondingPort = (LPort) port.getProperty(InternalProperties.ORIGIN);
            absolutePortAnchor.x = correspondingPort.getAbsoluteAnchor().x;
            // While it makes sense either way, it is important to move the dummy node to the correct location
            // as well. Otherwise the #addBendPoint(...) method won't add the computed bendpoint as it
            // thinks it's superfluous.
            node.getPosition().x = absolutePortAnchor.x;
        }
        KVector bendPoint = new KVector(0, absolutePortAnchor.y);
        if (port.getSide() == PortSide.EAST) {
            bendPoint.x = layerRightXPos;
        } else if (port.getSide() == PortSide.WEST) {
            bendPoint.x = layerLeftXPos;
        } else {
            // We only know what to do with eastern and western ports
            continue;
        }
        // If the port's absolute anchor equals the bend point, we don't want to insert anything
        // (unless the node represents an in-layer dummy)
        double xDistance = Math.abs(absolutePortAnchor.x - bendPoint.x);
        if (xDistance <= maxAcceptableXDiff && !isInLayerDummy(node)) {
            continue;
        }
        // Whether to add a junction point or not
        boolean addJunctionPoint = port.getOutgoingEdges().size() + port.getIncomingEdges().size() > 1;
        // Iterate over the edges and add bend (and possibly junction) points
        for (LEdge e : port.getConnectedEdges()) {
            LPort otherPort = e.getSource() == port ? e.getTarget() : e.getSource();
            if (Math.abs(otherPort.getAbsoluteAnchor().y - bendPoint.y) > MIN_VERT_DIFF) {
                // Insert bend point
                addBendPoint(e, bendPoint, addJunctionPoint, port);
            }
        }
    }
}
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 98 with KVector

use of org.eclipse.elk.core.math.KVector in project elk by eclipse.

the class PolylineEdgeRouter method addBendPoint.

/**
 * Adds a copy of the given bend point to the given edge at the appropriate place in the list of
 * bend points. The appropriate place is determined by the given port: if it's the source port,
 * the bend point is prepended to the list; otherwise is is appended. The bend point is not
 * added to the list at all if it wouldn't have any visual effect; that is, if the port's anchor
 * equals the bend point.
 *
 * @param edge
 *            the edge to add the bend point to.
 * @param bendPoint
 *            the bend point to add.
 * @param addJunctionPoint
 *            if {@code true}, a copy of the bend point will be added to the edge's list of
 *            junction points, if necessary.
 * @param currPort
 *            the port the bend point is near.
 */
private void addBendPoint(final LEdge edge, final KVector bendPoint, final boolean addJunctionPoint, final LPort currPort) {
    // any case
    if ((edge.isInLayerEdge() || !currPort.getAbsoluteAnchor().equals(bendPoint)) && !edge.isSelfLoop()) {
        if (edge.getSource() == currPort) {
            edge.getBendPoints().add(0, new KVector(bendPoint));
        } else {
            edge.getBendPoints().add(new KVector(bendPoint));
        }
        if (addJunctionPoint && !createdJunctionPoints.contains(bendPoint)) {
            // create a new junction point for the edge at the bend point's position
            KVectorChain junctionPoints = edge.getProperty(LayeredOptions.JUNCTION_POINTS);
            if (junctionPoints == null) {
                junctionPoints = new KVectorChain();
                edge.setProperty(LayeredOptions.JUNCTION_POINTS, junctionPoints);
            }
            KVector jpoint = new KVector(bendPoint);
            junctionPoints.add(jpoint);
            createdJunctionPoints.add(jpoint);
        }
    }
}
Also used : KVectorChain(org.eclipse.elk.core.math.KVectorChain) KVector(org.eclipse.elk.core.math.KVector)

Example 99 with KVector

use of org.eclipse.elk.core.math.KVector in project elk by eclipse.

the class NodePositionProcessor method setCoordinates.

/**
 * Set the coordinate for each node in a given level and all underlying levels.
 *
 * @param currentLevel
 *            the list of TNode for which the neighbors should be calculated
 * @param level
 *            the level index
 * @param progressMonitor
 *            the current progress monitor
 */
private void setCoordinates(final LinkedList<TNode> currentLevel, final IElkProgressMonitor progressMonitor) {
    /**
     * if the level is empty there is nothing to do
     */
    if (!currentLevel.isEmpty()) {
        LinkedList<TNode> nextLevel = new LinkedList<TNode>();
        /**
         * set the coordinates for each node in the current level and collect the nodes of the
         * next level
         */
        for (TNode tNode : currentLevel) {
            nextLevel.addAll(tNode.getChildrenCopy());
            KVector pos = tNode.getPosition();
            pos.x = tNode.getProperty(InternalProperties.XCOOR).doubleValue();
            pos.y = tNode.getProperty(InternalProperties.YCOOR).doubleValue();
        }
        /**
         * go to the next level
         */
        setCoordinates(nextLevel, progressMonitor.subTask(nextLevel.size() / numberOfNodes));
    }
}
Also used : TNode(org.eclipse.elk.alg.mrtree.graph.TNode) KVector(org.eclipse.elk.core.math.KVector) LinkedList(java.util.LinkedList)

Example 100 with KVector

use of org.eclipse.elk.core.math.KVector in project elk by eclipse.

the class SimpleNodePlacer method process.

@Override
public void process(final LGraph layeredGraph, final IElkProgressMonitor monitor) {
    monitor.begin("Simple node placement", 1);
    Spacings spacings = layeredGraph.getProperty(InternalProperties.SPACINGS);
    // first iteration: determine the height of each layer
    double maxHeight = 0;
    for (Layer layer : layeredGraph.getLayers()) {
        KVector layerSize = layer.getSize();
        layerSize.y = 0;
        LNode lastNode = null;
        for (LNode node : layer.getNodes()) {
            if (lastNode != null) {
                // use normal spacing as soon as a regular node is involved
                layerSize.y += spacings.getVerticalSpacing(node, lastNode);
            }
            layerSize.y += node.getMargin().top + node.getSize().y + node.getMargin().bottom;
            lastNode = node;
        }
        maxHeight = Math.max(maxHeight, layerSize.y);
    }
    // second iteration: center the nodes of each layer around the tallest layer
    for (Layer layer : layeredGraph.getLayers()) {
        KVector layerSize = layer.getSize();
        double pos = (maxHeight - layerSize.y) / 2;
        LNode lastNode = null;
        for (LNode node : layer.getNodes()) {
            if (lastNode != null) {
                pos += spacings.getVerticalSpacing(node, lastNode);
            }
            pos += node.getMargin().top;
            node.getPosition().y = pos;
            pos += node.getSize().y + node.getMargin().bottom;
            lastNode = node;
        }
    }
    monitor.done();
}
Also used : Spacings(org.eclipse.elk.alg.layered.options.Spacings) LNode(org.eclipse.elk.alg.layered.graph.LNode) KVector(org.eclipse.elk.core.math.KVector) Layer(org.eclipse.elk.alg.layered.graph.Layer)

Aggregations

KVector (org.eclipse.elk.core.math.KVector)292 KVectorChain (org.eclipse.elk.core.math.KVectorChain)52 ElkNode (org.eclipse.elk.graph.ElkNode)49 LNode (org.eclipse.elk.alg.layered.graph.LNode)39 LPort (org.eclipse.elk.alg.layered.graph.LPort)37 ElkRectangle (org.eclipse.elk.core.math.ElkRectangle)36 LEdge (org.eclipse.elk.alg.layered.graph.LEdge)35 Test (org.junit.Test)30 ElkEdge (org.eclipse.elk.graph.ElkEdge)28 ElkLabel (org.eclipse.elk.graph.ElkLabel)27 ElkEdgeSection (org.eclipse.elk.graph.ElkEdgeSection)26 ElkPadding (org.eclipse.elk.core.math.ElkPadding)25 LLabel (org.eclipse.elk.alg.layered.graph.LLabel)20 PortSide (org.eclipse.elk.core.options.PortSide)19 ElkPort (org.eclipse.elk.graph.ElkPort)18 SizeConstraint (org.eclipse.elk.core.options.SizeConstraint)17 LGraph (org.eclipse.elk.alg.layered.graph.LGraph)15 ArrayList (java.util.ArrayList)13 Layer (org.eclipse.elk.alg.layered.graph.Layer)12 LMargin (org.eclipse.elk.alg.layered.graph.LMargin)11