Search in sources :

Example 1 with GraphProperties

use of org.eclipse.elk.alg.layered.options.GraphProperties in project elk by eclipse.

the class GraphConfigurator method getPhaseIndependentLayoutProcessorConfiguration.

/**
 * Returns an intermediate processing configuration with processors not tied to specific phases.
 *
 * @param lgraph the layered graph to be processed. The configuration may vary depending on certain
 *               properties of the graph.
 * @return intermediate processing configuration. May be {@code null}.
 */
private LayoutProcessorConfiguration<LayeredPhases, LGraph> getPhaseIndependentLayoutProcessorConfiguration(final LGraph lgraph) {
    Set<GraphProperties> graphProperties = lgraph.getProperty(InternalProperties.GRAPH_PROPERTIES);
    // Basic configuration
    LayoutProcessorConfiguration<LayeredPhases, LGraph> configuration = LayoutProcessorConfiguration.createFrom(BASELINE_PROCESSING_CONFIGURATION);
    // Hierarchical layout.
    // Note that the recursive graph layout engine made sure that at this point
    // 'INCLUDE_CHILDREN' has been propagated to all parent nodes with 'INHERIT'.
    // Thus, every lgraph of the hierarchical lgraph structure is configured with the following additions.
    HierarchyHandling hierarchyHandling = lgraph.getProperty(LayeredOptions.HIERARCHY_HANDLING);
    if (hierarchyHandling == HierarchyHandling.INCLUDE_CHILDREN) {
        configuration.addAll(HIERARCHICAL_ADDITIONS);
    }
    // Port side processor, put to first slot only if requested and routing is orthogonal
    if (lgraph.getProperty(LayeredOptions.FEEDBACK_EDGES)) {
        configuration.addBefore(LayeredPhases.P1_CYCLE_BREAKING, IntermediateProcessorStrategy.PORT_SIDE_PROCESSOR);
    } else {
        configuration.addBefore(LayeredPhases.P3_NODE_ORDERING, IntermediateProcessorStrategy.PORT_SIDE_PROCESSOR);
    }
    // If the graph has a label manager, so add label management additions
    if (lgraph.getProperty(LabelManagementOptions.LABEL_MANAGER) != null) {
        configuration.addAll(LABEL_MANAGEMENT_ADDITIONS);
    }
    // If the graph should be laid out interactively, add the layers and positions to the nodes.
    if (lgraph.getProperty(LayeredOptions.INTERACTIVE_LAYOUT)) {
        configuration.addAfter(LayeredPhases.P5_EDGE_ROUTING, IntermediateProcessorStrategy.CONSTRAINTS_POSTPROCESSOR);
    }
    // graph transformations for unusual layout directions
    switch(lgraph.getProperty(LayeredOptions.DIRECTION)) {
        case LEFT:
        case DOWN:
        case UP:
            configuration.addBefore(LayeredPhases.P1_CYCLE_BREAKING, IntermediateProcessorStrategy.DIRECTION_PREPROCESSOR).addAfter(LayeredPhases.P5_EDGE_ROUTING, IntermediateProcessorStrategy.DIRECTION_POSTPROCESSOR);
            break;
        default:
            // don't need any processors here
            break;
    }
    // Additional dependencies
    if (graphProperties.contains(GraphProperties.COMMENTS)) {
        configuration.addBefore(LayeredPhases.P1_CYCLE_BREAKING, IntermediateProcessorStrategy.COMMENT_PREPROCESSOR).addBefore(LayeredPhases.P4_NODE_PLACEMENT, IntermediateProcessorStrategy.COMMENT_NODE_MARGIN_CALCULATOR).addAfter(LayeredPhases.P5_EDGE_ROUTING, IntermediateProcessorStrategy.COMMENT_POSTPROCESSOR);
    }
    // Node-Promotion application for reduction of dummy nodes after layering
    if (lgraph.getProperty(LayeredOptions.LAYERING_NODE_PROMOTION_STRATEGY) != NodePromotionStrategy.NONE) {
        configuration.addBefore(LayeredPhases.P3_NODE_ORDERING, IntermediateProcessorStrategy.NODE_PROMOTION);
    }
    // Preserve certain partitions during layering
    if (graphProperties.contains(GraphProperties.PARTITIONS)) {
        configuration.addBefore(LayeredPhases.P1_CYCLE_BREAKING, IntermediateProcessorStrategy.PARTITION_PREPROCESSOR);
        configuration.addBefore(LayeredPhases.P2_LAYERING, IntermediateProcessorStrategy.PARTITION_MIDPROCESSOR);
        configuration.addBefore(LayeredPhases.P3_NODE_ORDERING, IntermediateProcessorStrategy.PARTITION_POSTPROCESSOR);
    }
    // Additional horizontal compaction depends on orthogonal edge routing
    if (lgraph.getProperty(LayeredOptions.COMPACTION_POST_COMPACTION_STRATEGY) != GraphCompactionStrategy.NONE && lgraph.getProperty(LayeredOptions.EDGE_ROUTING) != EdgeRouting.POLYLINE) {
        configuration.addAfter(LayeredPhases.P5_EDGE_ROUTING, IntermediateProcessorStrategy.HORIZONTAL_COMPACTOR);
    }
    // Move trees of high degree nodes to separate layers
    if (lgraph.getProperty(LayeredOptions.HIGH_DEGREE_NODES_TREATMENT)) {
        configuration.addBefore(LayeredPhases.P3_NODE_ORDERING, IntermediateProcessorStrategy.HIGH_DEGREE_NODE_LAYER_PROCESSOR);
    }
    // Introduce in-layer constraints to preserve the order of regular nodes
    if (lgraph.getProperty(LayeredOptions.CROSSING_MINIMIZATION_SEMI_INTERACTIVE)) {
        configuration.addBefore(LayeredPhases.P3_NODE_ORDERING, IntermediateProcessorStrategy.SEMI_INTERACTIVE_CROSSMIN_PROCESSOR);
    }
    // ElkLayered#reviewAndCorrectHierarchicalProcessors(...)
    if (activateGreedySwitchFor(lgraph)) {
        final GreedySwitchType greedySwitchType;
        if (isHierarchicalLayout(lgraph)) {
            greedySwitchType = lgraph.getProperty(LayeredOptions.CROSSING_MINIMIZATION_GREEDY_SWITCH_HIERARCHICAL_TYPE);
        } else {
            greedySwitchType = lgraph.getProperty(LayeredOptions.CROSSING_MINIMIZATION_GREEDY_SWITCH_TYPE);
        }
        IntermediateProcessorStrategy internalGreedyType = (greedySwitchType == GreedySwitchType.ONE_SIDED) ? IntermediateProcessorStrategy.ONE_SIDED_GREEDY_SWITCH : IntermediateProcessorStrategy.TWO_SIDED_GREEDY_SWITCH;
        configuration.addBefore(LayeredPhases.P4_NODE_PLACEMENT, internalGreedyType);
    }
    // Wrapping of graphs
    switch(lgraph.getProperty(LayeredOptions.WRAPPING_STRATEGY)) {
        case SINGLE_EDGE:
            configuration.addBefore(LayeredPhases.P4_NODE_PLACEMENT, IntermediateProcessorStrategy.SINGLE_EDGE_GRAPH_WRAPPER);
            break;
        case MULTI_EDGE:
            configuration.addBefore(LayeredPhases.P3_NODE_ORDERING, IntermediateProcessorStrategy.BREAKING_POINT_INSERTER).addBefore(LayeredPhases.P4_NODE_PLACEMENT, IntermediateProcessorStrategy.BREAKING_POINT_PROCESSOR).addAfter(LayeredPhases.P5_EDGE_ROUTING, IntermediateProcessorStrategy.BREAKING_POINT_REMOVER);
            break;
        // OFF
        default:
    }
    if (lgraph.getProperty(LayeredOptions.CONSIDER_MODEL_ORDER_STRATEGY) != OrderingStrategy.NONE) {
        configuration.addBefore(LayeredPhases.P3_NODE_ORDERING, IntermediateProcessorStrategy.SORT_BY_INPUT_ORDER_OF_MODEL);
    }
    return configuration;
}
Also used : HierarchyHandling(org.eclipse.elk.core.options.HierarchyHandling) GraphProperties(org.eclipse.elk.alg.layered.options.GraphProperties) GreedySwitchType(org.eclipse.elk.alg.layered.options.GreedySwitchType) IntermediateProcessorStrategy(org.eclipse.elk.alg.layered.intermediate.IntermediateProcessorStrategy) LGraph(org.eclipse.elk.alg.layered.graph.LGraph)

Example 2 with GraphProperties

use of org.eclipse.elk.alg.layered.options.GraphProperties in project elk by eclipse.

the class ElkGraphImporter method importGraph.

// /////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Import Entry Points
/**
 * Imports the given graph.
 *
 * @param elkgraph
 *            the graph to import.
 * @return the transformed graph.
 */
public LGraph importGraph(final ElkNode elkgraph) {
    // Create the layered graph
    final LGraph topLevelGraph = createLGraph(elkgraph);
    // Assign defined port sides to all external ports
    elkgraph.getPorts().stream().forEach(elkport -> ensureDefinedPortSide(topLevelGraph, elkport));
    // Transform the external ports, if any
    Set<GraphProperties> graphProperties = topLevelGraph.getProperty(InternalProperties.GRAPH_PROPERTIES);
    checkExternalPorts(elkgraph, graphProperties);
    if (graphProperties.contains(GraphProperties.EXTERNAL_PORTS)) {
        for (ElkPort elkport : elkgraph.getPorts()) {
            transformExternalPort(elkgraph, topLevelGraph, elkport);
        }
    }
    // Calculate the graph's minimum size
    if (shouldCalculateMinimumGraphSize(elkgraph)) {
        calculateMinimumGraphSize(elkgraph, topLevelGraph);
    }
    // Remember things
    if (topLevelGraph.getProperty(LayeredOptions.PARTITIONING_ACTIVATE)) {
        graphProperties.add(GraphProperties.PARTITIONS);
    }
    // values of the first layout run would be used (explicitly set spacing values are not overwritten).
    if (topLevelGraph.hasProperty(LayeredOptions.SPACING_BASE_VALUE)) {
        LayeredSpacings.withBaseValue(topLevelGraph.getProperty(LayeredOptions.SPACING_BASE_VALUE)).apply(topLevelGraph);
    }
    // Import the graph either with or without multiple nested levels of hierarchy
    if (elkgraph.getProperty(LayeredOptions.HIERARCHY_HANDLING) == HierarchyHandling.INCLUDE_CHILDREN) {
        importHierarchicalGraph(elkgraph, topLevelGraph);
    } else {
        importFlatGraph(elkgraph, topLevelGraph);
    }
    return topLevelGraph;
}
Also used : GraphProperties(org.eclipse.elk.alg.layered.options.GraphProperties) ElkPort(org.eclipse.elk.graph.ElkPort) LGraph(org.eclipse.elk.alg.layered.graph.LGraph)

Example 3 with GraphProperties

use of org.eclipse.elk.alg.layered.options.GraphProperties 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 4 with GraphProperties

use of org.eclipse.elk.alg.layered.options.GraphProperties in project elk by eclipse.

the class ElkGraphImporter method transformEdge.

// /////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Edge Transformation
/**
 * Transforms the given edge if it's not a hyperedge. If it is a hyperedge, throws an exception.
 *
 * @param elkedge the edge to transform
 * @param elkparent the node in the original graph which currently gets transformed into {@code lgraph}
 * @param lgraph the layered graph
 * @return the transformed edge, or {@code null} if it cannot be transformed
 * @throws UnsupportedGraphException if the edge is a hyperedge.
 */
private LEdge transformEdge(final ElkEdge elkedge, final ElkNode elkparent, final LGraph lgraph) {
    checkEdgeValidity(elkedge);
    // Get a few basic information about the edge
    ElkConnectableShape elkSourceShape = elkedge.getSources().get(0);
    ElkConnectableShape elkTargetShape = elkedge.getTargets().get(0);
    ElkNode elkSourceNode = ElkGraphUtil.connectableShapeToNode(elkSourceShape);
    ElkNode elkTargetNode = ElkGraphUtil.connectableShapeToNode(elkTargetShape);
    ElkEdgeSection edgeSection = elkedge.getSections().isEmpty() ? null : elkedge.getSections().get(0);
    // Find the transformed source and target nodes
    LNode sourceLNode = (LNode) nodeAndPortMap.get(elkSourceNode);
    LNode targetLNode = (LNode) nodeAndPortMap.get(elkTargetNode);
    LPort sourceLPort = null;
    LPort targetLPort = null;
    // Find the transformed source port, if any
    if (elkSourceShape instanceof ElkPort) {
        // If the ElkPort is a regular port, it will map to an LPort; if it's an external port, it
        // will map to an LNode
        LGraphElement sourceElem = nodeAndPortMap.get(elkSourceShape);
        if (sourceElem instanceof LPort) {
            sourceLPort = (LPort) sourceElem;
        } else if (sourceElem instanceof LNode) {
            sourceLNode = (LNode) sourceElem;
            sourceLPort = sourceLNode.getPorts().get(0);
        }
    }
    // Find the transformed target port, if any
    if (elkTargetShape instanceof ElkPort) {
        // If the ElkPort is a regular port, it will map to an LPort; if it's an external port, it
        // will map to an LNode
        LGraphElement targetElem = nodeAndPortMap.get(elkTargetShape);
        if (targetElem instanceof LPort) {
            targetLPort = (LPort) targetElem;
        } else if (targetElem instanceof LNode) {
            targetLNode = (LNode) targetElem;
            targetLPort = targetLNode.getPorts().get(0);
        }
    }
    // reason, we back out
    if (sourceLNode == null || targetLNode == null) {
        throw new UnsupportedGraphException("The source or the target of edge " + elkedge + " could not be found. " + "This usually happens when an edge connects a node laid out by ELK Layered to a node in " + "another level of hierarchy laid out by either another instance of ELK Layered or another " + "layout algorithm alltogether. The former can be solved by setting the hierarchyHandling " + "option to INCLUDE_CHILDREN.");
    }
    // Create a layered edge
    LEdge ledge = new LEdge();
    ledge.copyProperties(elkedge);
    ledge.setProperty(InternalProperties.ORIGIN, elkedge);
    // Clear junction points, since they are recomputed from scratch
    ledge.setProperty(LayeredOptions.JUNCTION_POINTS, null);
    // If we have a self-loop, set the appropriate graph property
    Set<GraphProperties> graphProperties = lgraph.getProperty(InternalProperties.GRAPH_PROPERTIES);
    if (sourceLNode == targetLNode) {
        graphProperties.add(GraphProperties.SELF_LOOPS);
    }
    // Create source and target ports if they do not exist yet
    if (sourceLPort == null) {
        PortType portType = PortType.OUTPUT;
        KVector sourcePoint = null;
        if (edgeSection != null && sourceLNode.getProperty(LayeredOptions.PORT_CONSTRAINTS).isSideFixed()) {
            sourcePoint = new KVector(edgeSection.getStartX(), edgeSection.getStartY());
            // The coordinates need to be relative to us
            ElkUtil.toAbsolute(sourcePoint, elkedge.getContainingNode());
            ElkUtil.toRelative(sourcePoint, elkparent);
            // source), we may need to adjust the coordinates
            if (ElkGraphUtil.isDescendant(elkTargetNode, elkSourceNode)) {
                // External source port: put it on the west side
                portType = PortType.INPUT;
                sourcePoint.add(sourceLNode.getPosition());
            }
        }
        sourceLPort = LGraphUtil.createPort(sourceLNode, sourcePoint, portType, lgraph);
    }
    if (targetLPort == null) {
        PortType portType = PortType.INPUT;
        KVector targetPoint = null;
        if (edgeSection != null && targetLNode.getProperty(LayeredOptions.PORT_CONSTRAINTS).isSideFixed()) {
            targetPoint = new KVector(edgeSection.getEndX(), edgeSection.getEndY());
            // Adjust the coordinates
            // MIGRATE Not sure yet if this really does what we want it to do
            ElkUtil.toAbsolute(targetPoint, elkedge.getContainingNode());
            ElkUtil.toRelative(targetPoint, elkparent);
        }
        targetLPort = LGraphUtil.createPort(targetLNode, targetPoint, portType, targetLNode.getGraph());
    }
    // Finally set the source and target of the edge
    ledge.setSource(sourceLPort);
    ledge.setTarget(targetLPort);
    // If the ports have multiple incoming or outgoing edges, the HYPEREDGE property needs to be set
    if (sourceLPort.getIncomingEdges().size() > 1 || sourceLPort.getOutgoingEdges().size() > 1 || targetLPort.getIncomingEdges().size() > 1 || targetLPort.getOutgoingEdges().size() > 1) {
        graphProperties.add(GraphProperties.HYPEREDGES);
    }
    // Transform the edge's labels
    for (ElkLabel elklabel : elkedge.getLabels()) {
        if (!elklabel.getProperty(LayeredOptions.NO_LAYOUT) && !Strings.isNullOrEmpty(elklabel.getText())) {
            LLabel llabel = transformLabel(elklabel);
            ledge.getLabels().add(llabel);
            // edge label placement is actually properly defined
            switch(llabel.getProperty(LayeredOptions.EDGE_LABELS_PLACEMENT)) {
                case HEAD:
                case TAIL:
                    graphProperties.add(GraphProperties.END_LABELS);
                    break;
                case CENTER:
                    graphProperties.add(GraphProperties.CENTER_LABELS);
                    llabel.setProperty(LayeredOptions.EDGE_LABELS_PLACEMENT, EdgeLabelPlacement.CENTER);
            }
        }
    }
    // Copy the original bend points of the edge in case they are required
    CrossingMinimizationStrategy crossMinStrat = lgraph.getProperty(LayeredOptions.CROSSING_MINIMIZATION_STRATEGY);
    NodePlacementStrategy nodePlaceStrat = lgraph.getProperty(LayeredOptions.NODE_PLACEMENT_STRATEGY);
    boolean bendPointsRequired = crossMinStrat == CrossingMinimizationStrategy.INTERACTIVE || nodePlaceStrat == NodePlacementStrategy.INTERACTIVE;
    if (edgeSection != null && !edgeSection.getBendPoints().isEmpty() && bendPointsRequired) {
        KVectorChain originalBendpoints = ElkUtil.createVectorChain(edgeSection);
        KVectorChain importedBendpoints = new KVectorChain();
        // MIGRATE We may have to do some coordinate conversion here
        for (KVector point : originalBendpoints) {
            importedBendpoints.add(new KVector(point));
        }
        ledge.setProperty(InternalProperties.ORIGINAL_BENDPOINTS, importedBendpoints);
    }
    return ledge;
}
Also used : UnsupportedGraphException(org.eclipse.elk.core.UnsupportedGraphException) NodePlacementStrategy(org.eclipse.elk.alg.layered.options.NodePlacementStrategy) ElkNode(org.eclipse.elk.graph.ElkNode) LLabel(org.eclipse.elk.alg.layered.graph.LLabel) GraphProperties(org.eclipse.elk.alg.layered.options.GraphProperties) ElkPort(org.eclipse.elk.graph.ElkPort) LGraphElement(org.eclipse.elk.alg.layered.graph.LGraphElement) LEdge(org.eclipse.elk.alg.layered.graph.LEdge) KVectorChain(org.eclipse.elk.core.math.KVectorChain) ElkConnectableShape(org.eclipse.elk.graph.ElkConnectableShape) ElkEdgeSection(org.eclipse.elk.graph.ElkEdgeSection) ElkLabel(org.eclipse.elk.graph.ElkLabel) LPort(org.eclipse.elk.alg.layered.graph.LPort) CrossingMinimizationStrategy(org.eclipse.elk.alg.layered.options.CrossingMinimizationStrategy) LNode(org.eclipse.elk.alg.layered.graph.LNode) KVector(org.eclipse.elk.core.math.KVector) PortType(org.eclipse.elk.alg.layered.options.PortType)

Example 5 with GraphProperties

use of org.eclipse.elk.alg.layered.options.GraphProperties in project elk by eclipse.

the class LGraphUtil method createPort.

// /////////////////////////////////////////////////////////////////////////////
// Handling of Ports
/**
 * Create a port for an edge that is not connected to a port. This is necessary because ELK
 * Layered wants all edges to have a source port and a target port. The port side is computed
 * from the given absolute end point position of the edge.
 *
 * @param node
 *            the node at which the edge is incident
 * @param endPoint
 *            the absolute point where the edge ends, or {@code null} if unknown
 * @param type
 *            the port type
 * @param layeredGraph
 *            the layered graph
 * @return a new port
 */
public static LPort createPort(final LNode node, final KVector endPoint, final PortType type, final LGraph layeredGraph) {
    LPort port;
    Direction direction = getDirection(layeredGraph);
    boolean mergePorts = layeredGraph.getProperty(LayeredOptions.MERGE_EDGES);
    if ((mergePorts || node.getProperty(LayeredOptions.HYPERNODE)) && !node.getProperty(LayeredOptions.PORT_CONSTRAINTS).isSideFixed()) {
        // Hypernodes have one output port and one input port
        PortSide defaultSide = PortSide.fromDirection(direction);
        port = provideCollectorPort(layeredGraph, node, type, type == PortType.OUTPUT ? defaultSide : defaultSide.opposed());
    } else {
        port = new LPort();
        port.setNode(node);
        if (endPoint != null) {
            KVector pos = port.getPosition();
            pos.x = endPoint.x - node.getPosition().x;
            pos.y = endPoint.y - node.getPosition().y;
            pos.bound(0, 0, node.getSize().x, node.getSize().y);
            port.setSide(calcPortSide(port, direction));
        } else {
            PortSide defaultSide = PortSide.fromDirection(direction);
            port.setSide(type == PortType.OUTPUT ? defaultSide : defaultSide.opposed());
        }
        Set<GraphProperties> graphProperties = layeredGraph.getProperty(InternalProperties.GRAPH_PROPERTIES);
        PortSide portSide = port.getSide();
        switch(direction) {
            case LEFT:
            case RIGHT:
                if (portSide == PortSide.NORTH || portSide == PortSide.SOUTH) {
                    graphProperties.add(GraphProperties.NORTH_SOUTH_PORTS);
                }
                break;
            case UP:
            case DOWN:
                if (portSide == PortSide.EAST || portSide == PortSide.WEST) {
                    graphProperties.add(GraphProperties.NORTH_SOUTH_PORTS);
                }
                break;
        }
    }
    return port;
}
Also used : GraphProperties(org.eclipse.elk.alg.layered.options.GraphProperties) PortSide(org.eclipse.elk.core.options.PortSide) KVector(org.eclipse.elk.core.math.KVector) Direction(org.eclipse.elk.core.options.Direction)

Aggregations

GraphProperties (org.eclipse.elk.alg.layered.options.GraphProperties)9 LNode (org.eclipse.elk.alg.layered.graph.LNode)4 KVector (org.eclipse.elk.core.math.KVector)4 Direction (org.eclipse.elk.core.options.Direction)4 ElkPort (org.eclipse.elk.graph.ElkPort)4 LGraph (org.eclipse.elk.alg.layered.graph.LGraph)3 PortSide (org.eclipse.elk.core.options.PortSide)3 ElkLabel (org.eclipse.elk.graph.ElkLabel)3 ElkNode (org.eclipse.elk.graph.ElkNode)3 LEdge (org.eclipse.elk.alg.layered.graph.LEdge)2 LGraphElement (org.eclipse.elk.alg.layered.graph.LGraphElement)2 LLabel (org.eclipse.elk.alg.layered.graph.LLabel)2 LPort (org.eclipse.elk.alg.layered.graph.LPort)2 CrossingMinimizationStrategy (org.eclipse.elk.alg.layered.options.CrossingMinimizationStrategy)2 NodePlacementStrategy (org.eclipse.elk.alg.layered.options.NodePlacementStrategy)2 PortType (org.eclipse.elk.alg.layered.options.PortType)2 UnsupportedGraphException (org.eclipse.elk.core.UnsupportedGraphException)2 KVectorChain (org.eclipse.elk.core.math.KVectorChain)2 HierarchyHandling (org.eclipse.elk.core.options.HierarchyHandling)2 PortConstraints (org.eclipse.elk.core.options.PortConstraints)2