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);
}
}
}
Aggregations