Search in sources :

Example 1 with SelfHyperLoopLabels

use of org.eclipse.elk.alg.layered.intermediate.loops.SelfHyperLoopLabels in project elk by eclipse.

the class RoutingSlotAssigner method labelsOverlap.

/**
 * Returns {@code true} if the labels of the two loops would overlap if the loops were assigned to the same routing
 * slot.
 */
private boolean labelsOverlap(final SelfHyperLoop slLoop1, final SelfHyperLoop slLoop2) {
    assert slLoop1 != slLoop2;
    SelfHyperLoopLabels slLabels1 = slLoop1.getSLLabels();
    SelfHyperLoopLabels slLabels2 = slLoop2.getSLLabels();
    // There won't be overlaps unless both loops have labels
    if (slLabels1 == null || slLabels2 == null) {
        return false;
    }
    // The labels must be assigned to the same side, and that side (currently) needs to be either north or south
    if (slLabels1.getSide() != slLabels2.getSide() || slLabels1.getSide() == PortSide.EAST || slLabels1.getSide() == PortSide.WEST) {
        return false;
    }
    // Check if the labels overlap horizontally (remember that at this point, horizontal coordinates of north and
    // south labels have been set by the label placer)
    double start1 = slLabels1.getPosition().x;
    double end1 = start1 + slLabels1.getSize().x;
    double start2 = slLabels2.getPosition().x;
    double end2 = start2 + slLabels2.getSize().x;
    return start1 <= end2 && end1 >= start2;
}
Also used : SelfHyperLoopLabels(org.eclipse.elk.alg.layered.intermediate.loops.SelfHyperLoopLabels)

Example 2 with SelfHyperLoopLabels

use of org.eclipse.elk.alg.layered.intermediate.loops.SelfHyperLoopLabels in project elk by eclipse.

the class LabelPlacer method computeCoordinates.

// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Coordinate Computation
private void computeCoordinates(final SelfHyperLoop slLoop) {
    // The coordinates really only depend on the alignment since LEFT, CENTER and RIGHT are specific to the north
    // and south sides while TOP is specific to the east and west sides
    SelfHyperLoopLabels slLabels = slLoop.getSLLabels();
    SelfLoopPort alignRef = slLabels.getAlignmentReferenceSLPort();
    KVector size = slLabels.getSize();
    KVector pos = slLabels.getPosition();
    switch(slLabels.getAlignment()) {
        case CENTER:
            pos.x = (slLoop.getSLHolder().getLNode().getSize().x - size.x) / 2;
            break;
        case LEFT:
            pos.x = alignRef.getLPort().getPosition().x + alignRef.getLPort().getAnchor().x;
            break;
        case RIGHT:
            pos.x = alignRef.getLPort().getPosition().x + alignRef.getLPort().getAnchor().x - size.x;
            break;
        case TOP:
            pos.y = alignRef.getLPort().getPosition().y + alignRef.getLPort().getAnchor().y;
            break;
        default:
            assert false;
    }
}
Also used : SelfHyperLoopLabels(org.eclipse.elk.alg.layered.intermediate.loops.SelfHyperLoopLabels) SelfLoopPort(org.eclipse.elk.alg.layered.intermediate.loops.SelfLoopPort) KVector(org.eclipse.elk.core.math.KVector)

Example 3 with SelfHyperLoopLabels

use of org.eclipse.elk.alg.layered.intermediate.loops.SelfHyperLoopLabels in project elk by eclipse.

the class LabelPlacer method assignSideAndAlignment.

private void assignSideAndAlignment(final SelfHyperLoop slLoop, final PortSide side, final Alignment alignment, final SelfLoopPort alignmentReference) {
    SelfHyperLoopLabels slLabels = slLoop.getSLLabels();
    slLabels.setSide(side);
    slLabels.setAlignment(alignment);
    slLabels.setAlignmentReferenceSLPort(alignmentReference);
}
Also used : SelfHyperLoopLabels(org.eclipse.elk.alg.layered.intermediate.loops.SelfHyperLoopLabels)

Example 4 with SelfHyperLoopLabels

use of org.eclipse.elk.alg.layered.intermediate.loops.SelfHyperLoopLabels in project elk by eclipse.

the class LabelPlacer method assignSideAndAlignment.

// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Side and Alignment
private void assignSideAndAlignment(final SelfLoopHolder slHolder) {
    // Most loops are straightforward, but the one-sides northern and southern ones may not be. If the loops are
    // stacked, we can simply center their labels. If they are sequenced, we want to go from the outer loops to the
    // inner loops in pairs, and align their labels away from each other. To do so, we need to collect all of them
    // first.
    List<SelfHyperLoop> northernOneSidedSLLoops = null;
    List<SelfHyperLoop> southernOneSidedSLLoops = null;
    SelfLoopOrderingStrategy orderingStrategy = slHolder.getLNode().getProperty(LayeredOptions.EDGE_ROUTING_SELF_LOOP_ORDERING);
    if (orderingStrategy == SelfLoopOrderingStrategy.SEQUENCED) {
        northernOneSidedSLLoops = new ArrayList<>();
        southernOneSidedSLLoops = new ArrayList<>();
    }
    // Assign sides and alignments; how this works differs for the different kinds of labels
    for (SelfHyperLoop slLoop : slHolder.getSLHyperLoops()) {
        // If this loop doesn't have any labels, don't bother
        SelfHyperLoopLabels slLabels = slLoop.getSLLabels();
        if (slLabels == null) {
            continue;
        }
        assert !slLabels.getLLabels().isEmpty();
        // How we place labels largely depends on the self loop type
        switch(slLoop.getSelfLoopType()) {
            case ONE_SIDE:
                PortSide loopSide = slLoop.getOccupiedPortSides().iterator().next();
                if (orderingStrategy == SelfLoopOrderingStrategy.SEQUENCED && (loopSide == PortSide.NORTH)) {
                    // Collect for deferred processing
                    northernOneSidedSLLoops.add(slLoop);
                } else if (orderingStrategy == SelfLoopOrderingStrategy.SEQUENCED && (loopSide == PortSide.SOUTH)) {
                    // Collect for deferred processing
                    southernOneSidedSLLoops.add(slLoop);
                } else {
                    assignOneSidedSimpleSideAndAlignment(slLoop, loopSide);
                }
                break;
            case TWO_SIDES_CORNER:
                assignTwoSidesCornerSideAndAlignment(slLoop);
                break;
            case TWO_SIDES_OPPOSING:
            case THREE_SIDES:
                assignTwoSidesOpposingAndThreeSidesSideAndAlignment(slLoop);
                break;
            case FOUR_SIDES:
                assignFourSidesSideAndAlignment(slLoop);
                break;
            default:
                assert false;
        }
    }
    // Process deferred loops
    if (northernOneSidedSLLoops != null) {
        if (!northernOneSidedSLLoops.isEmpty()) {
            assignOneSidedSequencedSideAndAlignment(northernOneSidedSLLoops, PortSide.NORTH);
        }
        if (!southernOneSidedSLLoops.isEmpty()) {
            assignOneSidedSequencedSideAndAlignment(southernOneSidedSLLoops, PortSide.SOUTH);
        }
    }
}
Also used : SelfLoopOrderingStrategy(org.eclipse.elk.alg.layered.options.SelfLoopOrderingStrategy) SelfHyperLoopLabels(org.eclipse.elk.alg.layered.intermediate.loops.SelfHyperLoopLabels) PortSide(org.eclipse.elk.core.options.PortSide) SelfHyperLoop(org.eclipse.elk.alg.layered.intermediate.loops.SelfHyperLoop)

Example 5 with SelfHyperLoopLabels

use of org.eclipse.elk.alg.layered.intermediate.loops.SelfHyperLoopLabels in project elk by eclipse.

the class LabelPlacer method manageLabels.

// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Label Management
private void manageLabels(final SelfHyperLoop slLoop, final ILabelManager labelManager) {
    // How much space we have available depends entirely on our alignment since that also determines whether we're
    // on the north/south or the east/west sides
    SelfHyperLoopLabels slLabels = slLoop.getSLLabels();
    SelfLoopPort alignRef = slLabels.getAlignmentReferenceSLPort();
    LNode lNode = slLoop.getSLHolder().getLNode();
    KVector lNodeSize = lNode.getSize();
    LMargin lNodeMargins = slLoop.getSLHolder().getLNode().getMargin();
    double targetWidth = 0;
    switch(slLabels.getAlignment()) {
        case CENTER:
            // Clip the label to the extent of the node's bounding box
            targetWidth = lNodeMargins.left + lNodeSize.x + lNodeMargins.right;
            break;
        case LEFT:
            targetWidth = lNodeSize.x - alignRef.getLPort().getPosition().x - alignRef.getLPort().getAnchor().x + lNodeMargins.right;
            break;
        case RIGHT:
            targetWidth = lNodeMargins.left + alignRef.getLPort().getPosition().x + alignRef.getLPort().getAnchor().x;
            break;
        case TOP:
            // We have no way of knowing how far to the left / right our self loop will extend on our placement side,
            // so we need a default here
            targetWidth = LabelManagementProcessor.MIN_WIDTH_EDGE_LABELS;
            break;
        default:
            assert false;
    }
    slLabels.applyLabelManagement(labelManager, Math.max(targetWidth, LabelManagementProcessor.MIN_WIDTH_EDGE_LABELS));
}
Also used : LMargin(org.eclipse.elk.alg.layered.graph.LMargin) SelfHyperLoopLabels(org.eclipse.elk.alg.layered.intermediate.loops.SelfHyperLoopLabels) LNode(org.eclipse.elk.alg.layered.graph.LNode) SelfLoopPort(org.eclipse.elk.alg.layered.intermediate.loops.SelfLoopPort) KVector(org.eclipse.elk.core.math.KVector)

Aggregations

SelfHyperLoopLabels (org.eclipse.elk.alg.layered.intermediate.loops.SelfHyperLoopLabels)7 SelfHyperLoop (org.eclipse.elk.alg.layered.intermediate.loops.SelfHyperLoop)3 KVector (org.eclipse.elk.core.math.KVector)3 LMargin (org.eclipse.elk.alg.layered.graph.LMargin)2 LNode (org.eclipse.elk.alg.layered.graph.LNode)2 SelfLoopPort (org.eclipse.elk.alg.layered.intermediate.loops.SelfLoopPort)2 LEdge (org.eclipse.elk.alg.layered.graph.LEdge)1 SelfLoopEdge (org.eclipse.elk.alg.layered.intermediate.loops.SelfLoopEdge)1 SelfLoopOrderingStrategy (org.eclipse.elk.alg.layered.options.SelfLoopOrderingStrategy)1 KVectorChain (org.eclipse.elk.core.math.KVectorChain)1 PortSide (org.eclipse.elk.core.options.PortSide)1