Search in sources :

Example 11 with PortSide

use of org.eclipse.elk.core.options.PortSide in project elk by eclipse.

the class AbstractBarycenterPortDistributor method distributePortsWhileSweeping.

// /////////////////////////////////////////////////////////////////////////////
// Port Rank Assignment
@Override
public boolean distributePortsWhileSweeping(final LNode[][] nodeOrder, final int currentIndex, final boolean isForwardSweep) {
    updateNodePositions(nodeOrder, currentIndex);
    LNode[] freeLayer = nodeOrder[currentIndex];
    PortSide side = isForwardSweep ? PortSide.WEST : PortSide.EAST;
    if (isNotFirstLayer(nodeOrder.length, currentIndex, isForwardSweep)) {
        LNode[] fixedLayer = nodeOrder[isForwardSweep ? currentIndex - 1 : currentIndex + 1];
        calculatePortRanks(fixedLayer, portTypeFor(isForwardSweep));
        for (LNode node : freeLayer) {
            distributePorts(node, side);
        }
        calculatePortRanks(freeLayer, portTypeFor(!isForwardSweep));
        for (LNode node : fixedLayer) {
            if (!hasNestedGraph(node)) {
                distributePorts(node, side.opposed());
            }
        }
    } else {
        for (LNode node : freeLayer) {
            distributePorts(node, side);
        }
    }
    // which do not need to count.
    return false;
}
Also used : LNode(org.eclipse.elk.alg.layered.graph.LNode) PortSide(org.eclipse.elk.core.options.PortSide)

Example 12 with PortSide

use of org.eclipse.elk.core.options.PortSide in project elk by eclipse.

the class AbstractBarycenterPortDistributor method sortPorts.

/**
 * Sort the ports of a node using the given relative position values. These values are
 * interpreted as a hint for the clockwise order of ports.
 *
 * @param node
 *            a node
 */
private void sortPorts(final LNode node) {
    Collections.sort(node.getPorts(), (port1, port2) -> {
        PortSide side1 = port1.getSide();
        PortSide side2 = port2.getSide();
        if (side1 != side2) {
            // sort according to the node side
            return side1.ordinal() - side2.ordinal();
        } else {
            float port1Bary = portBarycenter[port1.id];
            float port2Bary = portBarycenter[port2.id];
            if (port1Bary == 0 && port2Bary == 0) {
                return 0;
            } else if (port1Bary == 0) {
                return -1;
            } else if (port2Bary == 0) {
                return 1;
            } else {
                // sort according to the position value
                return Float.compare(port1Bary, port2Bary);
            }
        }
    });
}
Also used : PortSide(org.eclipse.elk.core.options.PortSide)

Example 13 with PortSide

use of org.eclipse.elk.core.options.PortSide in project elk by eclipse.

the class ElkGraphImporter method transformExternalPort.

/**
 * Transforms the given external port into a dummy node.
 *
 * @param elkgraph
 *            the original KGraph
 * @param lgraph
 *            the corresponding layered graph
 * @param elkport
 *            the port to be transformed
 */
private void transformExternalPort(final ElkNode elkgraph, final LGraph lgraph, final ElkPort elkport) {
    // We need some information about the port
    KVector elkportPosition = new KVector(elkport.getX() + elkport.getWidth() / 2.0, elkport.getY() + elkport.getHeight() / 2.0);
    int netFlow = calculateNetFlow(elkport);
    PortConstraints portConstraints = elkgraph.getProperty(LayeredOptions.PORT_CONSTRAINTS);
    // If we don't have a proper port side, calculate one
    PortSide portSide = elkport.getProperty(LayeredOptions.PORT_SIDE);
    assert portSide != PortSide.UNDEFINED;
    // If we don't have a port offset, infer one
    if (!elkport.getAllProperties().containsKey(LayeredOptions.PORT_BORDER_OFFSET)) {
        double portOffset;
        // if port coordinates are (0,0), we default to port offset 0 to make the common case frustration-free
        if (elkport.getX() == 0.0 && elkport.getY() == 0.0) {
            portOffset = 0.0;
        } else {
            portOffset = ElkUtil.calcPortOffset(elkport, portSide);
        }
        elkport.setProperty(LayeredOptions.PORT_BORDER_OFFSET, portOffset);
    }
    // Create the external port dummy node
    KVector graphSize = new KVector(elkgraph.getWidth(), elkgraph.getHeight());
    LNode dummy = LGraphUtil.createExternalPortDummy(elkport, portConstraints, portSide, netFlow, graphSize, elkportPosition, new KVector(elkport.getWidth(), elkport.getHeight()), lgraph.getProperty(LayeredOptions.DIRECTION), lgraph);
    dummy.setProperty(InternalProperties.ORIGIN, elkport);
    // The dummy only has one port
    LPort dummyPort = dummy.getPorts().get(0);
    dummyPort.setConnectedToExternalNodes(isConnectedToExternalNodes(elkport));
    dummy.setProperty(LayeredOptions.PORT_LABELS_PLACEMENT, PortLabelPlacement.outside());
    // If the compound node wants to have its port labels placed on the inside, we need to leave
    // enough space for them by creating an LLabel for the KLabels. If the compound node wants to
    // have its port labels placed on the outside, we still need to leave enough space for them
    // so the port placement does not cause problems on the outside, but we also don't want to waste
    // space inside. Thus, for east and west ports, we reduce the label width to zero, otherwise
    // we reduce the label height to zero
    boolean insidePortLabels = elkgraph.getProperty(LayeredOptions.PORT_LABELS_PLACEMENT).contains(PortLabelPlacement.INSIDE);
    // Transform all of the port's labels
    for (ElkLabel elklabel : elkport.getLabels()) {
        if (!elklabel.getProperty(LayeredOptions.NO_LAYOUT) && !Strings.isNullOrEmpty(elklabel.getText())) {
            LLabel llabel = transformLabel(elklabel);
            dummyPort.getLabels().add(llabel);
            // If the port labels are fixed, we should consider the part that is inside the node and not 0.
            if (!insidePortLabels) {
                double insidePart = 0;
                if (PortLabelPlacement.isFixed(elkgraph.getProperty(LayeredOptions.PORT_LABELS_PLACEMENT))) {
                    // We use 0 as port border offset here, as we only want the label part that is
                    // inside the node "after" the port.
                    insidePart = ElkUtil.computeInsidePart(new KVector(elklabel.getX(), elklabel.getY()), new KVector(elklabel.getWidth(), elklabel.getHeight()), new KVector(elkport.getWidth(), elkport.getHeight()), 0, portSide);
                }
                switch(portSide) {
                    case EAST:
                    case WEST:
                        llabel.getSize().x = insidePart;
                        break;
                    case NORTH:
                    case SOUTH:
                        llabel.getSize().y = insidePart;
                        break;
                }
            }
        }
    }
    // Remember the relevant spacings that will apply to the labels here. It's not the spacings in the graph, but
    // in the parent
    dummy.setProperty(LayeredOptions.SPACING_LABEL_PORT, elkgraph.getParent().getProperty(LayeredOptions.SPACING_LABEL_PORT));
    dummy.setProperty(LayeredOptions.SPACING_LABEL_LABEL, elkgraph.getParent().getProperty(LayeredOptions.SPACING_LABEL_LABEL));
    // Put the external port dummy into our graph and associate it with the original KPort
    lgraph.getLayerlessNodes().add(dummy);
    nodeAndPortMap.put(elkport, dummy);
}
Also used : LLabel(org.eclipse.elk.alg.layered.graph.LLabel) ElkLabel(org.eclipse.elk.graph.ElkLabel) LPort(org.eclipse.elk.alg.layered.graph.LPort) LNode(org.eclipse.elk.alg.layered.graph.LNode) KVector(org.eclipse.elk.core.math.KVector) PortSide(org.eclipse.elk.core.options.PortSide) PortConstraints(org.eclipse.elk.core.options.PortConstraints) SizeConstraint(org.eclipse.elk.core.options.SizeConstraint)

Example 14 with PortSide

use of org.eclipse.elk.core.options.PortSide in project elk by eclipse.

the class ElkGraphImporter method ensureDefinedPortSide.

/**
 * Ensures that the given port has a defined port side.
 */
private void ensureDefinedPortSide(final LGraph lgraph, final ElkPort elkport) {
    Direction layoutDirection = lgraph.getProperty(LayeredOptions.DIRECTION);
    PortSide portSide = elkport.getProperty(LayeredOptions.PORT_SIDE);
    PortConstraints portConstraints = lgraph.getProperty(LayeredOptions.PORT_CONSTRAINTS);
    if (!portConstraints.isSideFixed()) {
        // We are free to assign ports to sides, so the port side will depend on the layout direction and the
        // port's net flow
        int netFlow = calculateNetFlow(elkport);
        if (netFlow > 0) {
            portSide = PortSide.fromDirection(layoutDirection);
        } else {
            portSide = PortSide.fromDirection(layoutDirection).opposed();
        }
    } else {
        // We are not free to assign port sides. If none is set, try inferring it from the port's position
        if (portSide == PortSide.UNDEFINED) {
            portSide = ElkUtil.calcPortSide(elkport, layoutDirection);
            // There are cases where ELK may have failed to infer the port side
            if (portSide == PortSide.UNDEFINED) {
                portSide = PortSide.fromDirection(layoutDirection);
            }
        }
    }
    elkport.setProperty(LayeredOptions.PORT_SIDE, portSide);
}
Also used : PortSide(org.eclipse.elk.core.options.PortSide) Direction(org.eclipse.elk.core.options.Direction) PortConstraints(org.eclipse.elk.core.options.PortConstraints) SizeConstraint(org.eclipse.elk.core.options.SizeConstraint)

Example 15 with PortSide

use of org.eclipse.elk.core.options.PortSide in project elk by eclipse.

the class ComponentsCompactor method transformLEdge.

/**
 * Converts an external edge to an external extension. While doing so, the the original edge
 * contributes three things as explained in the code.
 */
private IExternalExtension<LEdge> transformLEdge(final LEdge externalEdge, final Hullpoints hullPoints, final OuterSegments outerSegments) {
    InternalExternalExtension externalExtension = new InternalExternalExtension(externalEdge);
    // #1 convert the edge's path into a set of segments
    Segments segments = edgeToSegments(externalEdge, externalExtension);
    // #2 all 'inner' segments contribute to the hull (consider the edge's thickness)
    double thickness = Math.max(externalEdge.getProperty(LayeredOptions.EDGE_THICKNESS).doubleValue(), 1);
    for (Pair<KVector, KVector> segment : segments.innerSegments) {
        ElkRectangle rect = segmentToRectangle(segment.getFirst(), segment.getSecond(), thickness);
        hullPoints.add(rect);
    }
    // #3 the 'outer' segment, being the segment that actually connects to the external port,
    // contributes to the 'union external segment' that we create
    // for one direction of the component
    PortSide side = externalExtension.externalPortSide;
    ElkRectangle outerSegmentRect = segmentToRectangle(segments.outerSegment.getFirst(), segments.outerSegment.getSecond(), thickness);
    if (side == PortSide.WEST || side == PortSide.EAST) {
        outerSegments.min[side.ordinal()] = Math.min(outerSegments.min[side.ordinal()], outerSegmentRect.y);
        outerSegments.max[side.ordinal()] = Math.max(outerSegments.max[side.ordinal()], outerSegmentRect.y + outerSegmentRect.height);
    } else {
        outerSegments.min[side.ordinal()] = Math.min(outerSegments.min[side.ordinal()], outerSegmentRect.x);
        outerSegments.max[side.ordinal()] = Math.max(outerSegments.max[side.ordinal()], outerSegmentRect.x + outerSegmentRect.width);
    }
    // extent
    double extent = Double.NEGATIVE_INFINITY;
    LMargin margins = externalExtension.externalPort.getNode().getMargin();
    switch(side) {
        case WEST:
            extent = margins.right;
            break;
        case EAST:
            extent = margins.left;
            break;
        case NORTH:
            extent = margins.bottom;
            break;
        case SOUTH:
            extent = margins.top;
            break;
    }
    outerSegments.extent[side.ordinal()] = Math.max(outerSegments.extent[side.ordinal()], extent);
    return externalExtension;
}
Also used : LMargin(org.eclipse.elk.alg.layered.graph.LMargin) KVector(org.eclipse.elk.core.math.KVector) ElkRectangle(org.eclipse.elk.core.math.ElkRectangle) PortSide(org.eclipse.elk.core.options.PortSide)

Aggregations

PortSide (org.eclipse.elk.core.options.PortSide)71 LPort (org.eclipse.elk.alg.layered.graph.LPort)24 LNode (org.eclipse.elk.alg.layered.graph.LNode)23 KVector (org.eclipse.elk.core.math.KVector)16 SelfHyperLoop (org.eclipse.elk.alg.layered.intermediate.loops.SelfHyperLoop)10 Direction (org.eclipse.elk.core.options.Direction)9 PortConstraints (org.eclipse.elk.core.options.PortConstraints)9 ElkPort (org.eclipse.elk.graph.ElkPort)8 List (java.util.List)7 SizeConstraint (org.eclipse.elk.core.options.SizeConstraint)7 ElkLabel (org.eclipse.elk.graph.ElkLabel)7 ArrayList (java.util.ArrayList)6 LEdge (org.eclipse.elk.alg.layered.graph.LEdge)6 Collectors (java.util.stream.Collectors)5 ElkGraphElement (org.eclipse.elk.graph.ElkGraphElement)5 DiagramElement (org.osate.ge.internal.diagram.runtime.DiagramElement)5 EnumSet (java.util.EnumSet)4 HashMap (java.util.HashMap)4 Map (java.util.Map)4 LLabel (org.eclipse.elk.alg.layered.graph.LLabel)4