Search in sources :

Example 11 with ElkLabel

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

the class PortLabelPlacementVariantsTest method assertAboveOrLeft.

private void assertAboveOrLeft(final ElkPort port) {
    final ElkLabel label = getLabel(port);
    // Note that port label positions are relative to the port
    double portPosition = 0;
    if (PortSide.SIDES_EAST_WEST.contains(port.getProperty(CoreOptions.PORT_SIDE))) {
        portPosition = label.getY();
    } else if (PortSide.SIDES_NORTH_SOUTH.contains(port.getProperty(CoreOptions.PORT_SIDE))) {
        portPosition = label.getX();
    } else {
        assertTrue(false);
    }
    assertThat(portPosition, OrderingComparison.lessThan(0.0));
}
Also used : ElkLabel(org.eclipse.elk.graph.ElkLabel)

Example 12 with ElkLabel

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

the class LabelSideSelectorTest method configurator.

@Configurator
public void configurator(final ElkNode graph) {
    Deque<ElkNode> nodeQueue = new LinkedList<>();
    nodeQueue.add(graph);
    Random rand = new Random(RANDOM_SEED);
    while (!nodeQueue.isEmpty()) {
        ElkNode node = nodeQueue.poll();
        for (ElkEdge edge : node.getContainedEdges()) {
            if (edge.getLabels().isEmpty()) {
                ElkGraphUtil.createLabel(edge.getIdentifier(), edge);
            }
            ElkLabel label = edge.getLabels().get(0);
            double r = rand.nextDouble();
            if (r < 0.3) {
                label.setProperty(LayeredOptions.EDGE_LABELS_PLACEMENT, EdgeLabelPlacement.HEAD);
            } else if (r < 0.7) {
                label.setProperty(LayeredOptions.EDGE_LABELS_PLACEMENT, EdgeLabelPlacement.CENTER);
            } else {
                label.setProperty(LayeredOptions.EDGE_LABELS_PLACEMENT, EdgeLabelPlacement.TAIL);
            }
        }
    }
}
Also used : ElkNode(org.eclipse.elk.graph.ElkNode) Random(java.util.Random) ElkLabel(org.eclipse.elk.graph.ElkLabel) LinkedList(java.util.LinkedList) ElkEdge(org.eclipse.elk.graph.ElkEdge) Configurator(org.eclipse.elk.alg.test.framework.annotations.Configurator)

Example 13 with ElkLabel

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

the class DotImporter method applyLayout.

/**
 * Apply layout to an edge and its labels.
 *
 * @param edge an edge
 * @param offset its offset in the graph
 * @param graph the Graphviz graph
 */
private void applyLayout(final ElkEdge edge, final KVector offset, final Graph graph) {
    EdgeStatement edgeStatement = (EdgeStatement) edge.getProperty(PROP_STATEMENT);
    if (edgeStatement.eContainer() == null) {
        // this can happen when an edge with multiple target declarations was found
        graph.getStatements().add(edgeStatement);
    }
    // transfer edge bend points and source / target points
    List<Attribute> attributes = edgeStatement.getAttributes();
    removeAttributes(attributes, Attributes.POS);
    if (!edge.getSections().isEmpty()) {
        StringBuilder bendpointString = new StringBuilder("\"");
        KVectorChain vectorChain = ElkUtil.createVectorChain(edge.getSections().get(0));
        ListIterator<KVector> chainIter = vectorChain.listIterator();
        while (chainIter.hasNext()) {
            KVector point = chainIter.next().add(offset);
            bendpointString.append(point.x);
            bendpointString.append(',');
            bendpointString.append(point.y);
            if (chainIter.hasNext()) {
                bendpointString.append(' ');
            }
        }
        bendpointString.append('\"');
        attributes.add(DotExporter.createAttribute(Attributes.POS, bendpointString.toString()));
    }
    // transfer label positions
    for (ElkLabel label : edge.getLabels()) {
        String attrKey = null;
        switch(label.getProperty(CoreOptions.EDGE_LABELS_PLACEMENT)) {
            case CENTER:
                attrKey = Attributes.LABELPOS;
                break;
            case HEAD:
                attrKey = Attributes.HEADLP;
                break;
            case TAIL:
                attrKey = Attributes.TAILLP;
                break;
        }
        if (attrKey != null) {
            removeAttributes(attributes, attrKey);
            double xpos = label.getX() + label.getWidth() / 2 + offset.x;
            double ypos = label.getY() + label.getHeight() / 2 + offset.y;
            String posString = "\"" + Double.toString(xpos) + "," + Double.toString(ypos) + "\"";
            attributes.add(DotExporter.createAttribute(attrKey, posString));
        }
    }
}
Also used : Attribute(org.eclipse.elk.alg.graphviz.dot.dot.Attribute) ElkLabel(org.eclipse.elk.graph.ElkLabel) KVectorChain(org.eclipse.elk.core.math.KVectorChain) KVector(org.eclipse.elk.core.math.KVector) EdgeStatement(org.eclipse.elk.alg.graphviz.dot.dot.EdgeStatement)

Example 14 with ElkLabel

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

the class ElkGraphImporter method transformPort.

// /////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Port Transformation
/**
 * Transforms the given port. The new port will be added to the given node and will be
 * registered with the {@code transformMap}.
 *
 * @param elkport
 *            the port to transform.
 * @param parentLNode
 *            the node the port should be added to.
 * @param graphProperties
 *            the graph properties of the graph the transformed port will be part of. The graph
 *            properties are modified depending on the port's properties.
 * @param layoutDirection
 *            the layout direction in the graph the port will be part of.
 * @param portConstraints
 *            the port constraints of the port's node.
 * @return the transformed port.
 */
private LPort transformPort(final ElkPort elkport, final LNode parentLNode, final Set<GraphProperties> graphProperties, final Direction layoutDirection, final PortConstraints portConstraints) {
    // create layered port, copying its position
    LPort lport = new LPort();
    lport.copyProperties(elkport);
    lport.setSide(elkport.getProperty(LayeredOptions.PORT_SIDE));
    lport.setProperty(InternalProperties.ORIGIN, elkport);
    lport.setNode(parentLNode);
    KVector portSize = lport.getSize();
    portSize.x = elkport.getWidth();
    portSize.y = elkport.getHeight();
    KVector portPos = lport.getPosition();
    portPos.x = elkport.getX();
    portPos.y = elkport.getY();
    nodeAndPortMap.put(elkport, lport);
    // check if the original port has any outgoing connections to descendants of its node
    boolean connectionsToDescendants = elkport.getOutgoingEdges().stream().flatMap(edge -> edge.getTargets().stream()).map(ElkGraphUtil::connectableShapeToNode).anyMatch(targetNode -> ElkGraphUtil.isDescendant(targetNode, elkport.getParent()));
    // there could be yet incoming connections from descendants
    if (!connectionsToDescendants) {
        // check if the original port has any incoming connections from descendants of its node
        connectionsToDescendants = elkport.getIncomingEdges().stream().flatMap(edge -> edge.getSources().stream()).map(ElkGraphUtil::connectableShapeToNode).anyMatch(sourceNode -> ElkGraphUtil.isDescendant(sourceNode, elkport.getParent()));
    }
    // if there are still no connections to descendants, there might yet be inside self loops involved
    if (!connectionsToDescendants) {
        // check if the original port has any incoming connections from descendants of its node
        connectionsToDescendants = elkport.getOutgoingEdges().stream().anyMatch(edge -> edge.isSelfloop() && edge.getProperty(LayeredOptions.INSIDE_SELF_LOOPS_YO));
    }
    // if we have found connections to / from descendants, mark the port accordingly
    lport.setProperty(InternalProperties.INSIDE_CONNECTIONS, connectionsToDescendants);
    // initialize the port's side, offset, and anchor point
    LGraphUtil.initializePort(lport, portConstraints, layoutDirection, elkport.getProperty(LayeredOptions.PORT_ANCHOR));
    // create the port's labels
    for (ElkLabel elklabel : elkport.getLabels()) {
        if (!elklabel.getProperty(LayeredOptions.NO_LAYOUT) && !Strings.isNullOrEmpty(elklabel.getText())) {
            lport.getLabels().add(transformLabel(elklabel));
        }
    }
    switch(layoutDirection) {
        case LEFT:
        case RIGHT:
            if (lport.getSide() == PortSide.NORTH || lport.getSide() == PortSide.SOUTH) {
                graphProperties.add(GraphProperties.NORTH_SOUTH_PORTS);
            }
            break;
        case UP:
        case DOWN:
            if (lport.getSide() == PortSide.EAST || lport.getSide() == PortSide.WEST) {
                graphProperties.add(GraphProperties.NORTH_SOUTH_PORTS);
            }
            break;
    }
    return lport;
}
Also used : CoreOptions(org.eclipse.elk.core.options.CoreOptions) PortSide(org.eclipse.elk.core.options.PortSide) LEdge(org.eclipse.elk.alg.layered.graph.LEdge) UnsupportedGraphException(org.eclipse.elk.core.UnsupportedGraphException) ElkNode(org.eclipse.elk.graph.ElkNode) ElkPort(org.eclipse.elk.graph.ElkPort) LayeredOptions(org.eclipse.elk.alg.layered.options.LayeredOptions) ElkGraphAdapters(org.eclipse.elk.core.util.adapters.ElkGraphAdapters) InternalProperties(org.eclipse.elk.alg.layered.options.InternalProperties) Map(java.util.Map) GraphAdapter(org.eclipse.elk.core.util.adapters.GraphAdapters.GraphAdapter) HierarchyHandling(org.eclipse.elk.core.options.HierarchyHandling) EnumSet(java.util.EnumSet) CycleBreakingStrategy(org.eclipse.elk.alg.layered.options.CycleBreakingStrategy) Set(java.util.Set) SizeConstraint(org.eclipse.elk.core.options.SizeConstraint) CrossingMinimizationStrategy(org.eclipse.elk.alg.layered.options.CrossingMinimizationStrategy) ElkGraphElement(org.eclipse.elk.graph.ElkGraphElement) PortType(org.eclipse.elk.alg.layered.options.PortType) Direction(org.eclipse.elk.core.options.Direction) NodeAdapter(org.eclipse.elk.core.util.adapters.GraphAdapters.NodeAdapter) ElkEdgeSection(org.eclipse.elk.graph.ElkEdgeSection) LPort(org.eclipse.elk.alg.layered.graph.LPort) OrderingStrategy(org.eclipse.elk.alg.layered.options.OrderingStrategy) LNode(org.eclipse.elk.alg.layered.graph.LNode) ElkEdge(org.eclipse.elk.graph.ElkEdge) Queue(java.util.Queue) GraphProperties(org.eclipse.elk.alg.layered.options.GraphProperties) LLabel(org.eclipse.elk.alg.layered.graph.LLabel) NodeLabelAndSizeCalculator(org.eclipse.elk.alg.common.nodespacing.NodeLabelAndSizeCalculator) PortLabelPlacement(org.eclipse.elk.core.options.PortLabelPlacement) KVectorChain(org.eclipse.elk.core.math.KVectorChain) ElkUtil(org.eclipse.elk.core.util.ElkUtil) Strings(com.google.common.base.Strings) Lists(com.google.common.collect.Lists) ElkPadding(org.eclipse.elk.core.math.ElkPadding) LayeredSpacings(org.eclipse.elk.alg.layered.options.LayeredSpacings) NodePlacementStrategy(org.eclipse.elk.alg.layered.options.NodePlacementStrategy) Iterator(java.util.Iterator) PortConstraints(org.eclipse.elk.core.options.PortConstraints) ElkLabel(org.eclipse.elk.graph.ElkLabel) KVector(org.eclipse.elk.core.math.KVector) EcoreUtil(org.eclipse.emf.ecore.util.EcoreUtil) Maps(com.google.common.collect.Maps) ElkConnectableShape(org.eclipse.elk.graph.ElkConnectableShape) LGraphElement(org.eclipse.elk.alg.layered.graph.LGraphElement) LGraphUtil(org.eclipse.elk.alg.layered.graph.LGraphUtil) LPadding(org.eclipse.elk.alg.layered.graph.LPadding) LabelManagementOptions(org.eclipse.elk.core.labels.LabelManagementOptions) LGraph(org.eclipse.elk.alg.layered.graph.LGraph) EdgeLabelPlacement(org.eclipse.elk.core.options.EdgeLabelPlacement) ElkGraphUtil(org.eclipse.elk.graph.util.ElkGraphUtil) ElkGraphUtil(org.eclipse.elk.graph.util.ElkGraphUtil) ElkLabel(org.eclipse.elk.graph.ElkLabel) LPort(org.eclipse.elk.alg.layered.graph.LPort) KVector(org.eclipse.elk.core.math.KVector)

Example 15 with ElkLabel

use of org.eclipse.elk.graph.ElkLabel 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)

Aggregations

ElkLabel (org.eclipse.elk.graph.ElkLabel)64 ElkNode (org.eclipse.elk.graph.ElkNode)33 KVector (org.eclipse.elk.core.math.KVector)25 ElkPort (org.eclipse.elk.graph.ElkPort)23 ElkEdge (org.eclipse.elk.graph.ElkEdge)20 ElkEdgeSection (org.eclipse.elk.graph.ElkEdgeSection)14 KVectorChain (org.eclipse.elk.core.math.KVectorChain)12 ElkPadding (org.eclipse.elk.core.math.ElkPadding)10 ElkGraphElement (org.eclipse.elk.graph.ElkGraphElement)9 SizeConstraint (org.eclipse.elk.core.options.SizeConstraint)7 PortSide (org.eclipse.elk.core.options.PortSide)6 List (java.util.List)5 LLabel (org.eclipse.elk.alg.layered.graph.LLabel)5 LPort (org.eclipse.elk.alg.layered.graph.LPort)5 ElkBendPoint (org.eclipse.elk.graph.ElkBendPoint)5 ElkConnectableShape (org.eclipse.elk.graph.ElkConnectableShape)5 Test (org.junit.Test)5 Lists (com.google.common.collect.Lists)4 Rectangle (org.eclipse.draw2d.geometry.Rectangle)4 DCElement (org.eclipse.elk.alg.disco.graph.DCElement)4