Search in sources :

Example 16 with ElkNode

use of org.eclipse.elk.graph.ElkNode in project elk by eclipse.

the class StraightLineEdgeRouter method routeEdges.

/**
 * Route edges from node center to node center. Then clip it, to not cross the node.
 */
public void routeEdges(final ElkNode node) {
    for (ElkEdge edge : ElkGraphUtil.allOutgoingEdges(node)) {
        if (!(edge.getSources().get(0) instanceof ElkPort)) {
            ElkNode target = ElkGraphUtil.connectableShapeToNode(edge.getTargets().get(0));
            if (!edge.isHierarchical()) {
                double sourceX = node.getX() + node.getWidth() / 2;
                double sourceY = node.getY() + node.getHeight() / 2;
                double targetX = target.getX() + target.getWidth() / 2;
                double targetY = target.getY() + target.getHeight() / 2;
                // Clipping
                KVector vector = new KVector();
                vector.x = targetX - sourceX;
                vector.y = targetY - sourceY;
                KVector sourceClip = new KVector(vector.x, vector.y);
                ElkMath.clipVector(sourceClip, node.getWidth(), node.getHeight());
                vector.x -= sourceClip.x;
                vector.y -= sourceClip.y;
                sourceX = targetX - vector.x;
                sourceY = targetY - vector.y;
                KVector targetClip = new KVector(vector.x, vector.y);
                ElkMath.clipVector(targetClip, target.getWidth(), target.getHeight());
                vector.x -= targetClip.x;
                vector.y -= targetClip.y;
                targetX = sourceX + vector.x;
                targetY = sourceY + vector.y;
                ElkEdgeSection section = ElkGraphUtil.firstEdgeSection(edge, true, true);
                section.setStartLocation(sourceX, sourceY);
                section.setEndLocation(targetX, targetY);
                routeEdges(target);
            }
        }
    }
}
Also used : ElkNode(org.eclipse.elk.graph.ElkNode) ElkPort(org.eclipse.elk.graph.ElkPort) KVector(org.eclipse.elk.core.math.KVector) ElkEdgeSection(org.eclipse.elk.graph.ElkEdgeSection) ElkEdge(org.eclipse.elk.graph.ElkEdge)

Example 17 with ElkNode

use of org.eclipse.elk.graph.ElkNode in project elk by eclipse.

the class PolarCoordinateSorter method setIDForNodes.

/**
 * Iterates over the whole graph and assign an order id to each node, depending on its position in the list sorted
 * by polar coordinates.
 *
 * @param nodes
 * @param idOffset
 * @return
 */
private int setIDForNodes(final List<ElkNode> nodes, final int idOffset) {
    int id = idOffset;
    int nextLayerId = 0;
    for (ElkNode node : nodes) {
        node.setProperty(RadialOptions.ORDER_ID, id++);
        List<ElkNode> nodeSuccessors = RadialUtil.getSuccessors(node);
        double arc = Math.atan2(node.getY() + node.getHeight() / 2, node.getX() + node.getWidth() / 2);
        arc += arc < 0 ? 2 * Math.PI : 0;
        // node is right of parent node
        if (arc < DEGREE_45 || arc > DEGREE_315) {
            nodeSuccessors.sort(compLeft);
        } else if (arc <= DEGREE_315 && arc > DEGREE_225) {
            // node is below parent node
            nodeSuccessors.sort(compTop);
        } else if (arc <= DEGREE_225 && arc > DEGREE_135) {
            // node is left
            nodeSuccessors.sort(compRight);
        } else if (arc <= DEGREE_135) {
            // node is top
            nodeSuccessors.sort(compBottom);
        }
        nextLayerId = setIDForNodes(nodeSuccessors, nextLayerId);
    }
    return id;
}
Also used : ElkNode(org.eclipse.elk.graph.ElkNode)

Example 18 with ElkNode

use of org.eclipse.elk.graph.ElkNode in project elk by eclipse.

the class InteractiveRectPackingGraphVisitor method visit.

/* (non-Javadoc)
     * @see org.eclipse.elk.core.util.IGraphElementVisitor#visit(org.eclipse.elk.graph.ElkGraphElement)
     */
@Override
public void visit(final ElkGraphElement element) {
    // Only apply to root of the graph
    if (element instanceof ElkNode) {
        ElkNode root = (ElkNode) element;
        setInteractiveOptions(root);
    }
}
Also used : ElkNode(org.eclipse.elk.graph.ElkNode)

Example 19 with ElkNode

use of org.eclipse.elk.graph.ElkNode in project elk by eclipse.

the class RectPackingLayoutProvider method layout.

/**
 * Calculating and applying layout to the model.
 */
@Override
public void layout(final ElkNode layoutGraph, final IElkProgressMonitor progressMonitor) {
    progressMonitor.begin("Rectangle Packing", 1);
    if (progressMonitor.isLoggingEnabled()) {
        progressMonitor.logGraph(layoutGraph, "Input");
    }
    // The desired aspect ratio.
    double aspectRatio = layoutGraph.getProperty(RectPackingOptions.ASPECT_RATIO);
    // The strategy for the initial width approximation.
    OptimizationGoal goal = layoutGraph.getProperty(RectPackingOptions.OPTIMIZATION_GOAL);
    // Option for better width approximation.
    boolean lastPlaceShift = layoutGraph.getProperty(RectPackingOptions.LAST_PLACE_SHIFT);
    // Option to only do the initial width approximation.
    boolean onlyFirstIteration = layoutGraph.getProperty(RectPackingOptions.ONLY_FIRST_ITERATION);
    // Option whether the nodes should be expanded to fill the bounding rectangle.
    boolean expandNodes = layoutGraph.getProperty(RectPackingOptions.EXPAND_NODES);
    // The padding surrounding the drawing.
    ElkPadding padding = layoutGraph.getProperty(RectPackingOptions.PADDING);
    // The spacing between two nodes.
    double nodeNodeSpacing = layoutGraph.getProperty(RectPackingOptions.SPACING_NODE_NODE);
    // Whether the nodes are compacted after the initial placement.
    boolean compaction = layoutGraph.getProperty(RectPackingOptions.ROW_COMPACTION);
    // Whether the nodes should be expanded to fit the aspect ratio during node expansion.
    // Only effective if nodes are expanded.
    boolean expandToAspectRatio = layoutGraph.getProperty(RectPackingOptions.EXPAND_TO_ASPECT_RATIO);
    // Whether interactive layout is activ.
    boolean interactive = layoutGraph.getProperty(RectPackingOptions.INTERACTIVE);
    // A target width for the algorithm. If this is set the width approximation step is skipped.
    double targetWidth = layoutGraph.getProperty(RectPackingOptions.TARGET_WIDTH);
    List<ElkNode> rectangles = layoutGraph.getChildren();
    DrawingUtil.resetCoordinates(rectangles);
    DrawingData drawing;
    if (interactive) {
        List<ElkNode> fixedNodes = new ArrayList<>();
        for (ElkNode elkNode : rectangles) {
            if (elkNode.hasProperty(RectPackingOptions.DESIRED_POSITION)) {
                fixedNodes.add(elkNode);
            }
        }
        for (ElkNode elkNode : fixedNodes) {
            rectangles.remove(elkNode);
        }
        Collections.sort(fixedNodes, (a, b) -> {
            int positionA = a.getProperty(RectPackingOptions.DESIRED_POSITION);
            int positionB = b.getProperty(RectPackingOptions.DESIRED_POSITION);
            if (positionA == positionB) {
                return -1;
            } else {
                return Integer.compare(positionA, positionB);
            }
        });
        for (ElkNode elkNode : fixedNodes) {
            int position = elkNode.getProperty(RectPackingOptions.DESIRED_POSITION);
            position = Math.min(position, rectangles.size());
            rectangles.add(position, elkNode);
        }
        int index = 0;
        for (ElkNode elkNode : rectangles) {
            elkNode.setProperty(RectPackingOptions.CURRENT_POSITION, index);
            index++;
        }
    }
    // Get minimum size of parent.
    KVector minSize = ElkUtil.effectiveMinSizeConstraintFor(layoutGraph);
    // Remove padding to get the space the algorithm can use.
    minSize.x -= padding.getHorizontal();
    minSize.y -= padding.getVertical();
    double maxWidth = minSize.x;
    if (targetWidth < 0 || targetWidth < minSize.x) {
        // Initial width approximation.
        AreaApproximation firstIt = new AreaApproximation(aspectRatio, goal, lastPlaceShift);
        drawing = firstIt.approxBoundingBox(rectangles, nodeNodeSpacing, padding);
        if (progressMonitor.isLoggingEnabled()) {
            progressMonitor.logGraph(layoutGraph, "After approximation");
        }
    } else {
        drawing = new DrawingData(aspectRatio, targetWidth, 0, DrawingDataDescriptor.WHOLE_DRAWING);
    }
    // Readd padding for next steps.
    minSize.x += padding.getHorizontal();
    minSize.y += padding.getVertical();
    // Placement according to approximated width.
    if (!onlyFirstIteration) {
        DrawingUtil.resetCoordinates(rectangles);
        RowFillingAndCompaction secondIt = new RowFillingAndCompaction(aspectRatio, expandNodes, expandToAspectRatio, compaction, nodeNodeSpacing);
        // Modify the initial approximation if necessary.
        maxWidth = Math.max(minSize.x, drawing.getDrawingWidth());
        // Run placement, compaction, and expansion (if enabled).
        drawing = secondIt.start(rectangles, maxWidth, minSize, progressMonitor, layoutGraph);
    }
    // Final touch.
    applyPadding(rectangles, padding);
    ElkUtil.resizeNode(layoutGraph, drawing.getDrawingWidth() + padding.getHorizontal(), drawing.getDrawingHeight() + padding.getVertical(), false, true);
    // if requested, compute nodes's dimensions, place node labels, ports, port labels, etc.
    if (!layoutGraph.getProperty(RectPackingOptions.OMIT_NODE_MICRO_LAYOUT)) {
        NodeMicroLayout.forGraph(layoutGraph).execute();
    }
    if (progressMonitor.isLoggingEnabled()) {
        progressMonitor.logGraph(layoutGraph, "Output");
    }
    progressMonitor.done();
}
Also used : RowFillingAndCompaction(org.eclipse.elk.alg.rectpacking.seconditeration.RowFillingAndCompaction) ElkNode(org.eclipse.elk.graph.ElkNode) DrawingData(org.eclipse.elk.alg.rectpacking.util.DrawingData) ArrayList(java.util.ArrayList) KVector(org.eclipse.elk.core.math.KVector) ElkPadding(org.eclipse.elk.core.math.ElkPadding) OptimizationGoal(org.eclipse.elk.alg.rectpacking.options.OptimizationGoal) AreaApproximation(org.eclipse.elk.alg.rectpacking.firstiteration.AreaApproximation)

Example 20 with ElkNode

use of org.eclipse.elk.graph.ElkNode in project elk by eclipse.

the class AreaApproximation method approxBoundingBox.

// ////////////////////////////////////////////////////////////////
// Public methods.
/**
 * Calculates a drawing for the given rectangles according options set in the object creation of
 * {@link AreaApproximation}. This method also sets the coordinates for the rectangles.
 *
 * @param rectangles The rectangles to place.
 * @param nodeNodeSpacing The spacing between two nodes.
 * @return A drawing calculated by this methods algorithm.
 */
public DrawingData approxBoundingBox(final List<ElkNode> rectangles, final double nodeNodeSpacing, final ElkPadding padding) {
    // Place first box.
    ElkNode firstRect = rectangles.get(0);
    firstRect.setX(0);
    firstRect.setY(0);
    List<ElkNode> placedRects = new ArrayList<>();
    placedRects.add(firstRect);
    ElkNode lastPlaced = firstRect;
    DrawingData currentValues = new DrawingData(this.aspectRatio, firstRect.getWidth(), firstRect.getHeight(), DrawingDataDescriptor.WHOLE_DRAWING);
    // Place the other boxes.
    for (int rectangleIdx = 1; rectangleIdx < rectangles.size(); rectangleIdx++) {
        ElkNode toPlace = rectangles.get(rectangleIdx);
        // Determine drawing metrics for different candidate positions/placement options
        DrawingData opt1 = calcValuesForOpt(DrawingDataDescriptor.CANDIDATE_POSITION_LAST_PLACED_RIGHT, toPlace, lastPlaced, currentValues, placedRects, nodeNodeSpacing);
        DrawingData opt2 = calcValuesForOpt(DrawingDataDescriptor.CANDIDATE_POSITION_LAST_PLACED_BELOW, toPlace, lastPlaced, currentValues, placedRects, nodeNodeSpacing);
        DrawingData opt3 = calcValuesForOpt(DrawingDataDescriptor.CANDIDATE_POSITION_WHOLE_DRAWING_RIGHT, toPlace, lastPlaced, currentValues, placedRects, nodeNodeSpacing);
        DrawingData opt4 = calcValuesForOpt(DrawingDataDescriptor.CANDIDATE_POSITION_WHOLE_DRAWING_BELOW, toPlace, lastPlaced, currentValues, placedRects, nodeNodeSpacing);
        DrawingData bestOpt = findBestCandidate(opt1, opt2, opt3, opt4, toPlace, lastPlaced, padding);
        toPlace.setX(bestOpt.getNextXcoordinate());
        toPlace.setY(bestOpt.getNextYcoordinate());
        bestOpt.setPlacementOption(DrawingDataDescriptor.WHOLE_DRAWING);
        currentValues = bestOpt;
        lastPlaced = toPlace;
        placedRects.add(toPlace);
    }
    return currentValues;
}
Also used : ElkNode(org.eclipse.elk.graph.ElkNode) DrawingData(org.eclipse.elk.alg.rectpacking.util.DrawingData) ArrayList(java.util.ArrayList)

Aggregations

ElkNode (org.eclipse.elk.graph.ElkNode)267 ElkEdge (org.eclipse.elk.graph.ElkEdge)64 ElkPort (org.eclipse.elk.graph.ElkPort)55 Test (org.junit.Test)52 KVector (org.eclipse.elk.core.math.KVector)51 ElkLabel (org.eclipse.elk.graph.ElkLabel)39 ElkPadding (org.eclipse.elk.core.math.ElkPadding)36 ArrayList (java.util.ArrayList)27 List (java.util.List)25 ElkEdgeSection (org.eclipse.elk.graph.ElkEdgeSection)24 LinkedList (java.util.LinkedList)23 BasicProgressMonitor (org.eclipse.elk.core.util.BasicProgressMonitor)22 ElkGraphElement (org.eclipse.elk.graph.ElkGraphElement)21 ElkConnectableShape (org.eclipse.elk.graph.ElkConnectableShape)17 SizeConstraint (org.eclipse.elk.core.options.SizeConstraint)15 Lists (com.google.common.collect.Lists)12 Collection (java.util.Collection)12 KVectorChain (org.eclipse.elk.core.math.KVectorChain)10 HashMap (java.util.HashMap)9 RecursiveGraphLayoutEngine (org.eclipse.elk.core.RecursiveGraphLayoutEngine)9