Search in sources :

Example 6 with AttributeStatement

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

the class DotExporter method applyLayout.

/**
 * Applies layout information from a Graphviz model to the original graph.
 * Note that GraphViz uses cubic B-Splines for edge routing, some generalization of Bezier curves.
 * Edge offsets are given separately, since on some platforms edges seem to have a different
 * reference point than nodes.
 *
 * @param parentNode parent node of the original graph
 * @param statements list of statements to process
 * @param baseOffset offset to be added to edge and subgraph coordinates
 * @param transData transformation data
 */
private void applyLayout(final ElkNode parentNode, final List<Statement> statements, final KVector baseOffset, final ElkPadding outerPadding, final IDotTransformationData<ElkNode, GraphvizModel> transData) {
    // process attributes: determine bounding box of the parent node
    ElkPadding padding = outerPadding;
    KVector nodeOffset = new KVector();
    attr_loop: for (Statement statement : statements) {
        if (statement instanceof AttributeStatement) {
            AttributeStatement attributeStatement = (AttributeStatement) statement;
            if (attributeStatement.getType() == AttributeType.GRAPH) {
                for (Attribute attribute : attributeStatement.getAttributes()) {
                    if (attribute.getName().equals(Attributes.BOUNDINGBOX)) {
                        try {
                            StringTokenizer tokenizer = new StringTokenizer(attribute.getValue(), ATTRIBUTE_DELIM);
                            double leftx = Double.parseDouble(tokenizer.nextToken());
                            double bottomy = Double.parseDouble(tokenizer.nextToken());
                            double rightx = Double.parseDouble(tokenizer.nextToken());
                            double topy = Double.parseDouble(tokenizer.nextToken());
                            // set parent node attributes
                            double width = rightx - leftx;
                            double height = bottomy - topy;
                            if (parentNode == transData.getSourceGraph()) {
                                // the root node, representing the drawing frame
                                width += padding.getHorizontal();
                                height += padding.getVertical();
                                baseOffset.add(-leftx, -topy);
                                nodeOffset.add(-leftx, -topy);
                            } else {
                                // a child or descendant of the root node
                                parentNode.setX(baseOffset.x + leftx + padding.getLeft());
                                parentNode.setY(baseOffset.y + topy + padding.getTop());
                                // since dot uses a 'compound' layout instead of laying out a hierarchical graph,
                                // no padding is supported for children
                                padding = new ElkPadding();
                                // ... and the children's offset must be somewhat adjusted
                                nodeOffset.x = -(baseOffset.x + leftx);
                                nodeOffset.y = -(baseOffset.y + topy);
                            }
                            ElkUtil.resizeNode(parentNode, width, height, false, true);
                            parentNode.setProperty(CoreOptions.NODE_SIZE_CONSTRAINTS, SizeConstraint.fixed());
                            break attr_loop;
                        } catch (NumberFormatException exception) {
                        // ignore exception
                        } catch (NoSuchElementException exception) {
                        // ignore exception
                        }
                    }
                }
            }
        }
    }
    // process nodes and subgraphs to collect all offset data
    for (Statement statement : statements) {
        if (statement instanceof NodeStatement) {
            applyNodeLayout((NodeStatement) statement, nodeOffset, padding, transData);
        } else if (statement instanceof Subgraph) {
            Subgraph subgraph = (Subgraph) statement;
            ElkNode elknode = (ElkNode) transData.getProperty(GRAPH_ELEMS).get(subgraph.getName());
            applyLayout(elknode, subgraph.getStatements(), baseOffset, padding, transData);
            elknode.setX(elknode.getX() + nodeOffset.x);
            elknode.setY(elknode.getY() + nodeOffset.y);
        }
    }
}
Also used : StringTokenizer(java.util.StringTokenizer) ElkNode(org.eclipse.elk.graph.ElkNode) Attribute(org.eclipse.elk.alg.graphviz.dot.dot.Attribute) 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) AttributeStatement(org.eclipse.elk.alg.graphviz.dot.dot.AttributeStatement) NodeStatement(org.eclipse.elk.alg.graphviz.dot.dot.NodeStatement) Subgraph(org.eclipse.elk.alg.graphviz.dot.dot.Subgraph) KVector(org.eclipse.elk.core.math.KVector) ElkPadding(org.eclipse.elk.core.math.ElkPadding) NoSuchElementException(java.util.NoSuchElementException)

Aggregations

Attribute (org.eclipse.elk.alg.graphviz.dot.dot.Attribute)6 AttributeStatement (org.eclipse.elk.alg.graphviz.dot.dot.AttributeStatement)6 EdgeStatement (org.eclipse.elk.alg.graphviz.dot.dot.EdgeStatement)3 NodeStatement (org.eclipse.elk.alg.graphviz.dot.dot.NodeStatement)3 Subgraph (org.eclipse.elk.alg.graphviz.dot.dot.Subgraph)3 Statement (org.eclipse.elk.alg.graphviz.dot.dot.Statement)2 ElkPadding (org.eclipse.elk.core.math.ElkPadding)2 KVector (org.eclipse.elk.core.math.KVector)2 ElkNode (org.eclipse.elk.graph.ElkNode)2 NoSuchElementException (java.util.NoSuchElementException)1 StringTokenizer (java.util.StringTokenizer)1 EdgeTarget (org.eclipse.elk.alg.graphviz.dot.dot.EdgeTarget)1 Graph (org.eclipse.elk.alg.graphviz.dot.dot.Graph)1 GraphvizModel (org.eclipse.elk.alg.graphviz.dot.dot.GraphvizModel)1 Node (org.eclipse.elk.alg.graphviz.dot.dot.Node)1 Port (org.eclipse.elk.alg.graphviz.dot.dot.Port)1 DotSwitch (org.eclipse.elk.alg.graphviz.dot.dot.util.DotSwitch)1 Command (org.eclipse.elk.alg.graphviz.dot.transform.Command)1 NeatoModel (org.eclipse.elk.alg.graphviz.dot.transform.NeatoModel)1 OverlapMode (org.eclipse.elk.alg.graphviz.dot.transform.OverlapMode)1