Search in sources :

Example 1 with EdgeStatement

use of org.eclipse.elk.alg.graphviz.dot.dot.EdgeStatement in project elk by eclipse.

the class DotExporter method transferLayout.

/**
 * Applies the layout information attached to the given Dot instance to the KGraph instance
 * using the mapping created by a previous call to {@code transform}. Has to be called after a
 * call to {@code transform}.
 *
 * @param transData the transformation data instance
 */
public void transferLayout(final IDotTransformationData<ElkNode, GraphvizModel> transData) {
    ElkPadding padding = transData.getSourceGraph().getProperty(CoreOptions.PADDING);
    Graph graph = transData.getTargetGraphs().get(0).getGraphs().get(0);
    // process nodes and subgraphs
    KVector baseOffset = new KVector();
    applyLayout(transData.getSourceGraph(), graph.getStatements(), baseOffset, padding, transData);
    // finally process the edges
    LinkedList<Statement> statements = new LinkedList<Statement>(graph.getStatements());
    KVector edgeOffset = baseOffset.add(padding.getLeft(), padding.getTop());
    while (!statements.isEmpty()) {
        Statement statement = statements.removeFirst();
        if (statement instanceof EdgeStatement) {
            applyEdgeLayout((EdgeStatement) statement, edgeOffset, transData);
        } else if (statement instanceof Subgraph) {
            statements.addAll(((Subgraph) statement).getStatements());
        }
    }
}
Also used : Graph(org.eclipse.elk.alg.graphviz.dot.dot.Graph) EdgeStatement(org.eclipse.elk.alg.graphviz.dot.dot.EdgeStatement) NodeStatement(org.eclipse.elk.alg.graphviz.dot.dot.NodeStatement) AttributeStatement(org.eclipse.elk.alg.graphviz.dot.dot.AttributeStatement) Statement(org.eclipse.elk.alg.graphviz.dot.dot.Statement) Subgraph(org.eclipse.elk.alg.graphviz.dot.dot.Subgraph) KVector(org.eclipse.elk.core.math.KVector) ElkPadding(org.eclipse.elk.core.math.ElkPadding) LinkedList(java.util.LinkedList) EdgeStatement(org.eclipse.elk.alg.graphviz.dot.dot.EdgeStatement)

Example 2 with EdgeStatement

use of org.eclipse.elk.alg.graphviz.dot.dot.EdgeStatement 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 3 with EdgeStatement

use of org.eclipse.elk.alg.graphviz.dot.dot.EdgeStatement in project elk by eclipse.

the class DotImporter method transform.

/*---------- Transformation Dot to KGraph ----------*/
/**
 * Transform a Dot graph to a KNode.
 *
 * @param statements
 *            a list of Dot statements
 * @param parent
 *            a KNode
 * @param transData
 *            transformation data instance
 * @param nodeProps
 *            properties that are applied to all nodes
 * @param edgeProps
 *            properties that are applied to all edges
 */
private void transform(final List<Statement> statements, final ElkNode parent, final IDotTransformationData<GraphvizModel, ElkNode> transData, final IPropertyHolder nodeProps, final IPropertyHolder edgeProps) {
    DotSwitch<Object> statementSwitch = new DotSwitch<Object>() {

        public Object caseNodeStatement(final NodeStatement statement) {
            transformNode(statement, parent, transData, nodeProps);
            return null;
        }

        public Object caseEdgeStatement(final EdgeStatement statement) {
            transformEdge(statement, parent, transData, edgeProps);
            return null;
        }

        public Object caseSubgraph(final Subgraph subgraph) {
            ElkNode subElkNode = parent;
            if (subgraph.getName() != null && subgraph.getName().startsWith("cluster")) {
                subElkNode = transformNode(subgraph.getName(), parent, transData);
                if (subElkNode.getProperty(PROP_STATEMENT) != null) {
                    transData.log("Discarding cluster subgraph \"" + subgraph.getName() + "\" since its id is already used.");
                    return null;
                } else {
                    // the subgraph inherits all settings of its parent
                    subElkNode.copyProperties(parent);
                    subElkNode.setProperty(PROP_STATEMENT, subgraph);
                }
            }
            MapPropertyHolder subNodeProps = new MapPropertyHolder();
            subNodeProps.copyProperties(nodeProps);
            MapPropertyHolder subEdgeProps = new MapPropertyHolder();
            subEdgeProps.copyProperties(edgeProps);
            transform(subgraph.getStatements(), subElkNode, transData, subNodeProps, subEdgeProps);
            return null;
        }

        public Object caseAttributeStatement(final AttributeStatement statement) {
            switch(statement.getType()) {
                case GRAPH:
                    for (Attribute attr : statement.getAttributes()) {
                        caseAttribute(attr);
                    }
                    break;
                case NODE:
                    for (Attribute attr : statement.getAttributes()) {
                        transformAttribute(nodeProps, attr, transData);
                    }
                    break;
                case EDGE:
                    for (Attribute attr : statement.getAttributes()) {
                        transformAttribute(edgeProps, attr, transData);
                    }
                    break;
            }
            return null;
        }

        public Object caseAttribute(final Attribute attribute) {
            if (Attributes.MARGIN.equals(attribute.getName())) {
                ElkPadding padding = parent.getProperty(CoreOptions.PADDING);
                if (attribute.getValue().indexOf(',') >= 0) {
                    KVector value = new KVector();
                    try {
                        value.parse(attribute.getValue());
                        padding.setLeft((float) value.x);
                        padding.setRight((float) value.x);
                        padding.setTop((float) value.y);
                        padding.setBottom((float) value.y);
                    } catch (IllegalArgumentException exception) {
                        transData.log("Discarding attribute \"" + attribute.getName() + "\" since its value could not be parsed correctly.");
                    }
                } else {
                    try {
                        float value = Float.parseFloat(trimValue(attribute));
                        padding.setLeft(value);
                        padding.setRight(value);
                        padding.setTop(value);
                        padding.setBottom(value);
                    } catch (NumberFormatException exception) {
                        transData.log("Discarding attribute \"" + attribute.getName() + "\" since its value could not be parsed correctly.");
                    }
                }
            } else {
                transformAttribute(parent, attribute, transData);
            }
            return null;
        }
    };
    for (Statement statement : statements) {
        statementSwitch.doSwitch(statement);
    }
}
Also used : ElkNode(org.eclipse.elk.graph.ElkNode) Attribute(org.eclipse.elk.alg.graphviz.dot.dot.Attribute) NodeStatement(org.eclipse.elk.alg.graphviz.dot.dot.NodeStatement) EdgeStatement(org.eclipse.elk.alg.graphviz.dot.dot.EdgeStatement) NodeStatement(org.eclipse.elk.alg.graphviz.dot.dot.NodeStatement) AttributeStatement(org.eclipse.elk.alg.graphviz.dot.dot.AttributeStatement) Statement(org.eclipse.elk.alg.graphviz.dot.dot.Statement) MapPropertyHolder(org.eclipse.elk.graph.properties.MapPropertyHolder) EdgeStatement(org.eclipse.elk.alg.graphviz.dot.dot.EdgeStatement) AttributeStatement(org.eclipse.elk.alg.graphviz.dot.dot.AttributeStatement) Subgraph(org.eclipse.elk.alg.graphviz.dot.dot.Subgraph) KVector(org.eclipse.elk.core.math.KVector) ElkPadding(org.eclipse.elk.core.math.ElkPadding) DotSwitch(org.eclipse.elk.alg.graphviz.dot.dot.util.DotSwitch)

Example 4 with EdgeStatement

use of org.eclipse.elk.alg.graphviz.dot.dot.EdgeStatement in project elk by eclipse.

the class AbstractGraphvizDotSemanticSequencer method sequence.

@Override
public void sequence(ISerializationContext context, EObject semanticObject) {
    EPackage epackage = semanticObject.eClass().getEPackage();
    ParserRule rule = context.getParserRule();
    Action action = context.getAssignedAction();
    Set<Parameter> parameters = context.getEnabledBooleanParameters();
    if (epackage == DotPackage.eINSTANCE)
        switch(semanticObject.eClass().getClassifierID()) {
            case DotPackage.ATTRIBUTE:
                if (rule == grammarAccess.getStatementRule() || rule == grammarAccess.getAttributeRule()) {
                    sequence_Attribute(context, (Attribute) semanticObject);
                    return;
                } else if (rule == grammarAccess.getListAttributeRule()) {
                    sequence_ListAttribute(context, (Attribute) semanticObject);
                    return;
                } else
                    break;
            case DotPackage.ATTRIBUTE_STATEMENT:
                sequence_AttributeStatement(context, (AttributeStatement) semanticObject);
                return;
            case DotPackage.EDGE_STATEMENT:
                sequence_EdgeStatement(context, (EdgeStatement) semanticObject);
                return;
            case DotPackage.EDGE_TARGET:
                sequence_EdgeTarget(context, (EdgeTarget) semanticObject);
                return;
            case DotPackage.GRAPH:
                sequence_Graph(context, (Graph) semanticObject);
                return;
            case DotPackage.GRAPHVIZ_MODEL:
                sequence_GraphvizModel(context, (GraphvizModel) semanticObject);
                return;
            case DotPackage.NODE:
                sequence_Node(context, (Node) semanticObject);
                return;
            case DotPackage.NODE_STATEMENT:
                sequence_NodeStatement(context, (NodeStatement) semanticObject);
                return;
            case DotPackage.PORT:
                sequence_Port(context, (Port) semanticObject);
                return;
            case DotPackage.SUBGRAPH:
                sequence_Subgraph(context, (Subgraph) semanticObject);
                return;
        }
    if (errorAcceptor != null)
        errorAcceptor.accept(diagnosticProvider.createInvalidContextOrTypeDiagnostic(semanticObject, context));
}
Also used : ParserRule(org.eclipse.xtext.ParserRule) Action(org.eclipse.xtext.Action) Attribute(org.eclipse.elk.alg.graphviz.dot.dot.Attribute) NodeStatement(org.eclipse.elk.alg.graphviz.dot.dot.NodeStatement) Node(org.eclipse.elk.alg.graphviz.dot.dot.Node) Port(org.eclipse.elk.alg.graphviz.dot.dot.Port) EdgeStatement(org.eclipse.elk.alg.graphviz.dot.dot.EdgeStatement) EPackage(org.eclipse.emf.ecore.EPackage) GraphvizModel(org.eclipse.elk.alg.graphviz.dot.dot.GraphvizModel) Graph(org.eclipse.elk.alg.graphviz.dot.dot.Graph) AttributeStatement(org.eclipse.elk.alg.graphviz.dot.dot.AttributeStatement) EdgeTarget(org.eclipse.elk.alg.graphviz.dot.dot.EdgeTarget) Subgraph(org.eclipse.elk.alg.graphviz.dot.dot.Subgraph) Parameter(org.eclipse.xtext.Parameter)

Example 5 with EdgeStatement

use of org.eclipse.elk.alg.graphviz.dot.dot.EdgeStatement in project elk by eclipse.

the class DotExporter method transformEdges.

/**
 * Transform the edges of the given parent node.
 *
 * @param parent a parent node
 * @param statements the list to which new statements are added
 * @param transData transformation data
 */
private void transformEdges(final ElkNode parent, final List<Statement> statements, final IDotTransformationData<ElkNode, GraphvizModel> transData) {
    boolean hierarchy = transData.getProperty(HIERARCHY);
    boolean transformEdgeLayout = transData.getProperty(TRANSFORM_EDGE_LAYOUT);
    Direction direction = parent.getProperty(CoreOptions.DIRECTION);
    boolean vertical = direction == Direction.DOWN || direction == Direction.UP || direction == Direction.UNDEFINED;
    LinkedList<ElkNode> nodes = new LinkedList<>(parent.getChildren());
    BiMap<ElkGraphElement, String> nodeIds = transData.getProperty(GRAPH_ELEMS).inverse();
    while (!nodes.isEmpty()) {
        ElkNode source = nodes.removeFirst();
        for (ElkEdge edge : ElkGraphUtil.allOutgoingEdges(source)) {
            // We don't support hyperedges
            if (edge.isHyperedge()) {
                throw new UnsupportedGraphException("Hyperedges are not supported.");
            }
            ElkNode target = ElkGraphUtil.connectableShapeToNode(edge.getTargets().get(0));
            // cross-hierarchy edges are considered only if hierarchy mode is active
            if (source.getParent() == target.getParent() || hierarchy && isInsideGraph(target, transData.getSourceGraph())) {
                EdgeStatement edgeStatement = DotFactory.eINSTANCE.createEdgeStatement();
                List<Attribute> attributes = edgeStatement.getAttributes();
                // set source node or cluster
                Node sourceNode = DotFactory.eINSTANCE.createNode();
                if (hierarchy && !source.getChildren().isEmpty()) {
                    sourceNode.setName(source.getProperty(CLUSTER_DUMMY));
                    attributes.add(createAttribute(Attributes.LTAIL, nodeIds.get(source)));
                } else {
                    sourceNode.setName(nodeIds.get(source));
                }
                edgeStatement.setSourceNode(sourceNode);
                // set target node or cluster
                EdgeTarget edgeTarget = DotFactory.eINSTANCE.createEdgeTarget();
                Node targetNode = DotFactory.eINSTANCE.createNode();
                if (hierarchy && !target.getChildren().isEmpty()) {
                    targetNode.setName(target.getProperty(CLUSTER_DUMMY));
                    attributes.add(createAttribute(Attributes.LHEAD, nodeIds.get(target)));
                } else {
                    targetNode.setName(nodeIds.get(target));
                }
                edgeTarget.setTargetnode(targetNode);
                edgeStatement.getEdgeTargets().add(edgeTarget);
                // add edge labels at head, tail, and middle position
                setEdgeLabels(edge, attributes, vertical);
                if (transData.getProperty(USE_EDGE_IDS)) {
                    // add comment with edge identifier
                    String edgeID = getEdgeID(edge, transData);
                    attributes.add(createAttribute(Attributes.COMMENT, "\"" + edgeID + "\""));
                }
                // include edge routing for full export, if there is one
                if (!edge.getSections().isEmpty()) {
                    ElkEdgeSection edgeSection = edge.getSections().get(0);
                    if (transformEdgeLayout && (edgeSection.getBendPoints().size() > 0 || edgeSection.getStartX() != 0 || edgeSection.getStartY() != 0 || edgeSection.getEndX() != 0 || edgeSection.getEndY() != 0)) {
                        StringBuilder pos = new StringBuilder();
                        Iterator<KVector> pointIter = ElkUtil.createVectorChain(edgeSection).iterator();
                        while (pointIter.hasNext()) {
                            KVector point = pointIter.next();
                            ElkUtil.toAbsolute(point, edge.getContainingNode());
                            pos.append(point.x);
                            pos.append(",");
                            pos.append(point.y);
                            if (pointIter.hasNext()) {
                                pos.append(" ");
                            }
                        }
                        attributes.add(createAttribute(Attributes.POS, "\"" + pos + "\""));
                    }
                }
                statements.add(edgeStatement);
            }
        }
        if (hierarchy) {
            nodes.addAll(source.getChildren());
        }
    }
}
Also used : UnsupportedGraphException(org.eclipse.elk.core.UnsupportedGraphException) ElkNode(org.eclipse.elk.graph.ElkNode) Attribute(org.eclipse.elk.alg.graphviz.dot.dot.Attribute) ElkNode(org.eclipse.elk.graph.ElkNode) Node(org.eclipse.elk.alg.graphviz.dot.dot.Node) Direction(org.eclipse.elk.core.options.Direction) LinkedList(java.util.LinkedList) EdgeStatement(org.eclipse.elk.alg.graphviz.dot.dot.EdgeStatement) ElkEdgeSection(org.eclipse.elk.graph.ElkEdgeSection) EdgeTarget(org.eclipse.elk.alg.graphviz.dot.dot.EdgeTarget) KVector(org.eclipse.elk.core.math.KVector) ElkGraphElement(org.eclipse.elk.graph.ElkGraphElement) ElkEdge(org.eclipse.elk.graph.ElkEdge)

Aggregations

EdgeStatement (org.eclipse.elk.alg.graphviz.dot.dot.EdgeStatement)6 Attribute (org.eclipse.elk.alg.graphviz.dot.dot.Attribute)5 KVector (org.eclipse.elk.core.math.KVector)4 AttributeStatement (org.eclipse.elk.alg.graphviz.dot.dot.AttributeStatement)3 EdgeTarget (org.eclipse.elk.alg.graphviz.dot.dot.EdgeTarget)3 Node (org.eclipse.elk.alg.graphviz.dot.dot.Node)3 NodeStatement (org.eclipse.elk.alg.graphviz.dot.dot.NodeStatement)3 Subgraph (org.eclipse.elk.alg.graphviz.dot.dot.Subgraph)3 ElkNode (org.eclipse.elk.graph.ElkNode)3 LinkedList (java.util.LinkedList)2 Graph (org.eclipse.elk.alg.graphviz.dot.dot.Graph)2 Statement (org.eclipse.elk.alg.graphviz.dot.dot.Statement)2 ElkPadding (org.eclipse.elk.core.math.ElkPadding)2 ElkEdge (org.eclipse.elk.graph.ElkEdge)2 ElkLabel (org.eclipse.elk.graph.ElkLabel)2 GraphvizModel (org.eclipse.elk.alg.graphviz.dot.dot.GraphvizModel)1 Port (org.eclipse.elk.alg.graphviz.dot.dot.Port)1 DotSwitch (org.eclipse.elk.alg.graphviz.dot.dot.util.DotSwitch)1 UnsupportedGraphException (org.eclipse.elk.core.UnsupportedGraphException)1 KVectorChain (org.eclipse.elk.core.math.KVectorChain)1