Search in sources :

Example 1 with OverlapRemovalDirection

use of org.eclipse.elk.alg.common.overlaps.RectangleStripOverlapRemover.OverlapRemovalDirection in project elk by eclipse.

the class PortLabelPlacementCalculator method constrainedOutsidePortLabelPlacement.

// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Constrained Outside Port Labels
/**
 * Place the port label cells outside of the node in the knowledge that there might not be enough space to place
 * them without overlaps.
 */
private static void constrainedOutsidePortLabelPlacement(final NodeContext nodeContext, final PortSide portSide) {
    Collection<PortContext> portContexts = nodeContext.portContexts.get(portSide);
    // simply revert to simple port label placement
    if (portContexts.size() <= 2 || portSide == PortSide.EAST || portSide == PortSide.WEST) {
        simpleOutsidePortLabelPlacement(nodeContext, portSide);
        return;
    }
    // If space-efficient port labels are active, the leftmost / topmost port's label must be placed to its left /
    // above it
    boolean portWithSpecialNeeds = nodeContext.portLabelsPlacement.contains(PortLabelPlacement.SPACE_EFFICIENT);
    // Prepare things
    OverlapRemovalDirection overlapRemovalDirection = portSide == PortSide.NORTH ? OverlapRemovalDirection.UP : OverlapRemovalDirection.DOWN;
    VerticalLabelAlignment verticalLabelAlignment = portSide == PortSide.NORTH ? VerticalLabelAlignment.BOTTOM : VerticalLabelAlignment.TOP;
    // Obtain a rectangle strip overlap remover, which will actually do most of the work
    RectangleStripOverlapRemover overlapRemover = RectangleStripOverlapRemover.createForDirection(overlapRemovalDirection).withGap(nodeContext.portLabelSpacing);
    // Iterate over our ports and add rectangles to the overlap remover. Also, calculate the start coordinate
    double startCoordinate = portSide == PortSide.NORTH ? Double.POSITIVE_INFINITY : Double.NEGATIVE_INFINITY;
    for (PortContext portContext : portContexts) {
        if (portContext.portLabelCell == null || !portContext.portLabelCell.hasLabels()) {
            continue;
        }
        KVector portSize = portContext.port.getSize();
        KVector portPosition = portContext.portPosition;
        LabelCell portLabelCell = portContext.portLabelCell;
        ElkRectangle portLabelCellRect = portLabelCell.getCellRectangle();
        // Setup the label cell's cell rectangle
        portLabelCellRect.width = portLabelCell.getMinimumWidth();
        portLabelCellRect.height = portLabelCell.getMinimumHeight();
        if (portWithSpecialNeeds) {
            portLabelCellRect.x = portPosition.x - portLabelCell.getMinimumWidth() - nodeContext.portLabelSpacing;
            portWithSpecialNeeds = false;
        } else {
            portLabelCellRect.x = portPosition.x + portSize.x + nodeContext.portLabelSpacing;
        }
        portLabelCell.setVerticalAlignment(verticalLabelAlignment);
        portLabelCell.setHorizontalAlignment(HorizontalLabelAlignment.RIGHT);
        // Add the rectangle to the overlap remover
        overlapRemover.addRectangle(portLabelCellRect);
        // Update start coordinate
        startCoordinate = portSide == PortSide.NORTH ? Math.min(startCoordinate, portPosition.y) : Math.max(startCoordinate, portPosition.y + portContext.port.getSize().y);
    }
    // The start coordinate needs to be offset by the port-label space
    startCoordinate += portSide == PortSide.NORTH ? -nodeContext.portLabelSpacing : nodeContext.portLabelSpacing;
    // Invoke the overlap remover
    overlapRemover.withStartCoordinate(startCoordinate).removeOverlaps();
    // We need to update the label cell's coordinates to be relative to the ports
    for (PortContext portContext : portContexts) {
        if (portContext.portLabelCell == null || !portContext.portLabelCell.hasLabels()) {
            continue;
        }
        ElkRectangle portLabelCellRect = portContext.portLabelCell.getCellRectangle();
        // Setup the label cell's cell rectangle
        portLabelCellRect.x -= portContext.portPosition.x;
        portLabelCellRect.y -= portContext.portPosition.y;
    }
}
Also used : RectangleStripOverlapRemover(org.eclipse.elk.alg.common.overlaps.RectangleStripOverlapRemover) LabelCell(org.eclipse.elk.alg.common.nodespacing.cellsystem.LabelCell) VerticalLabelAlignment(org.eclipse.elk.alg.common.nodespacing.cellsystem.VerticalLabelAlignment) OverlapRemovalDirection(org.eclipse.elk.alg.common.overlaps.RectangleStripOverlapRemover.OverlapRemovalDirection) KVector(org.eclipse.elk.core.math.KVector) ElkRectangle(org.eclipse.elk.core.math.ElkRectangle) PortContext(org.eclipse.elk.alg.common.nodespacing.internal.PortContext)

Example 2 with OverlapRemovalDirection

use of org.eclipse.elk.alg.common.overlaps.RectangleStripOverlapRemover.OverlapRemovalDirection in project elk by eclipse.

the class PortLabelPlacementCalculator method constrainedInsidePortLabelPlacement.

// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Constrained Inside Port Labels
/**
 * Place the port label cells outside of the node in the knowledge that there might not be enough space to place
 * them without overlaps.
 */
private static void constrainedInsidePortLabelPlacement(final NodeContext nodeContext, final PortSide portSide) {
    Collection<PortContext> portContexts = nodeContext.portContexts.get(portSide);
    // If it's neither the northern nor the southern side, simply revert to simple port label placement
    if (portSide == PortSide.EAST || portSide == PortSide.WEST) {
        simpleInsidePortLabelPlacement(nodeContext, portSide);
        return;
    }
    // Prepare things
    OverlapRemovalDirection overlapRemovalDirection = portSide == PortSide.NORTH ? OverlapRemovalDirection.DOWN : OverlapRemovalDirection.UP;
    VerticalLabelAlignment verticalLabelAlignment = portSide == PortSide.NORTH ? VerticalLabelAlignment.TOP : VerticalLabelAlignment.BOTTOM;
    // To keep labels from extending over the content area of the inside port label container, we need to know
    // where its content area's left and right boundaries are. We also make sure to always keep a bit of space to
    // the node border
    AtomicCell insidePortLabelContainer = nodeContext.insidePortLabelCells.get(portSide);
    ElkRectangle labelContainerRect = insidePortLabelContainer.getCellRectangle();
    double leftBorder = labelContainerRect.x + ElkMath.maxd(insidePortLabelContainer.getPadding().left, nodeContext.surroundingPortMargins.left, nodeContext.nodeLabelSpacing);
    double rightBorder = labelContainerRect.x + labelContainerRect.width - ElkMath.maxd(insidePortLabelContainer.getPadding().right, nodeContext.surroundingPortMargins.right, nodeContext.nodeLabelSpacing);
    // Obtain a rectangle strip overlap remover, which will actually do most of the work
    RectangleStripOverlapRemover overlapRemover = RectangleStripOverlapRemover.createForDirection(overlapRemovalDirection).withGap(nodeContext.portLabelSpacing);
    // Iterate over our ports and add rectangles to the overlap remover. Also, calculate the start coordinate
    double startCoordinate = portSide == PortSide.NORTH ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY;
    for (PortContext portContext : portContexts) {
        if (portContext.portLabelCell == null || !portContext.portLabelCell.hasLabels()) {
            continue;
        }
        KVector portSize = portContext.port.getSize();
        KVector portPosition = portContext.portPosition;
        LabelCell portLabelCell = portContext.portLabelCell;
        ElkRectangle portLabelCellRect = portLabelCell.getCellRectangle();
        // Setup the less interesting cell properties
        portLabelCellRect.width = portLabelCell.getMinimumWidth();
        portLabelCellRect.height = portLabelCell.getMinimumHeight();
        portLabelCell.setVerticalAlignment(verticalLabelAlignment);
        portLabelCell.setHorizontalAlignment(HorizontalLabelAlignment.RIGHT);
        // Center the label, but make sure it doesn't hang over the node boundaries
        centerPortLabel(portLabelCellRect, portPosition, portSize, leftBorder, rightBorder);
        // Add the rectangle to the overlap remover
        overlapRemover.addRectangle(portLabelCellRect);
        // Update start coordinate
        startCoordinate = portSide == PortSide.NORTH ? Math.max(startCoordinate, portPosition.y + portContext.port.getSize().y) : Math.min(startCoordinate, portPosition.y);
    }
    // The start coordinate needs to be offset by the port-label space
    startCoordinate += portSide == PortSide.NORTH ? nodeContext.portLabelSpacing : -nodeContext.portLabelSpacing;
    // Invoke the overlap remover
    double stripHeight = overlapRemover.withStartCoordinate(startCoordinate).removeOverlaps();
    if (stripHeight > 0) {
        nodeContext.insidePortLabelCells.get(portSide).getMinimumContentAreaSize().y = stripHeight;
    }
    // We need to update the label cell's coordinates to be relative to the ports
    for (PortContext portContext : portContexts) {
        if (portContext.portLabelCell == null || !portContext.portLabelCell.hasLabels()) {
            continue;
        }
        ElkRectangle portLabelCellRect = portContext.portLabelCell.getCellRectangle();
        // Setup the label cell's cell rectangle
        portLabelCellRect.x -= portContext.portPosition.x;
        portLabelCellRect.y -= portContext.portPosition.y;
    }
}
Also used : RectangleStripOverlapRemover(org.eclipse.elk.alg.common.overlaps.RectangleStripOverlapRemover) LabelCell(org.eclipse.elk.alg.common.nodespacing.cellsystem.LabelCell) VerticalLabelAlignment(org.eclipse.elk.alg.common.nodespacing.cellsystem.VerticalLabelAlignment) OverlapRemovalDirection(org.eclipse.elk.alg.common.overlaps.RectangleStripOverlapRemover.OverlapRemovalDirection) AtomicCell(org.eclipse.elk.alg.common.nodespacing.cellsystem.AtomicCell) ElkRectangle(org.eclipse.elk.core.math.ElkRectangle) KVector(org.eclipse.elk.core.math.KVector) PortContext(org.eclipse.elk.alg.common.nodespacing.internal.PortContext)

Aggregations

LabelCell (org.eclipse.elk.alg.common.nodespacing.cellsystem.LabelCell)2 VerticalLabelAlignment (org.eclipse.elk.alg.common.nodespacing.cellsystem.VerticalLabelAlignment)2 PortContext (org.eclipse.elk.alg.common.nodespacing.internal.PortContext)2 RectangleStripOverlapRemover (org.eclipse.elk.alg.common.overlaps.RectangleStripOverlapRemover)2 OverlapRemovalDirection (org.eclipse.elk.alg.common.overlaps.RectangleStripOverlapRemover.OverlapRemovalDirection)2 ElkRectangle (org.eclipse.elk.core.math.ElkRectangle)2 KVector (org.eclipse.elk.core.math.KVector)2 AtomicCell (org.eclipse.elk.alg.common.nodespacing.cellsystem.AtomicCell)1