use of org.eclipse.elk.alg.graphviz.dot.dot.Statement 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());
}
}
}
use of org.eclipse.elk.alg.graphviz.dot.dot.Statement in project elk by eclipse.
the class DotImporter method applyLayout.
/*---------- Layout Transfer KGraph to Dot ----------*/
/**
* Apply layout to a parent node and its children.
*
* @param parent a parent node
* @param offset the node's offset in the graph
* @param graph the Graphviz graph
*/
private void applyLayout(final ElkNode parent, final KVector offset, final Graph graph) {
for (ElkNode elknode : parent.getChildren()) {
Statement statement = elknode.getProperty(PROP_STATEMENT);
if (statement == null) {
// the node was only declared implicitly - create an explicit declaration
NodeStatement stm = DotFactory.eINSTANCE.createNodeStatement();
Node node = DotFactory.eINSTANCE.createNode();
node.setName(elknode.getProperty(PROP_ID));
stm.setNode(node);
graph.getStatements().add(stm);
statement = stm;
}
if (statement instanceof NodeStatement) {
List<Attribute> attributes = ((NodeStatement) statement).getAttributes();
// transfer node position
removeAttributes(attributes, Attributes.POS);
double xpos = elknode.getX() + elknode.getWidth() / 2 + offset.x;
double ypos = elknode.getY() + elknode.getHeight() / 2 + offset.y;
String posString = "\"" + Double.toString(xpos) + "," + Double.toString(ypos) + "\"";
attributes.add(DotExporter.createAttribute(Attributes.POS, posString));
// transfer node size
removeAttributes(attributes, Attributes.WIDTH);
attributes.add(DotExporter.createAttribute(Attributes.WIDTH, elknode.getWidth() / DotExporter.DPI));
removeAttributes(attributes, Attributes.HEIGHT);
attributes.add(DotExporter.createAttribute(Attributes.HEIGHT, elknode.getHeight() / DotExporter.DPI));
} else if (statement instanceof Subgraph) {
applyLayout(elknode, new KVector(offset).add(elknode.getX(), elknode.getY()), graph);
}
for (ElkEdge elkedge : ElkGraphUtil.allOutgoingEdges(elknode)) {
applyLayout(elkedge, offset, graph);
}
}
// transfer graph size to bounding box
List<Statement> statements;
Statement graphStm = parent.getProperty(PROP_STATEMENT);
if (graphStm instanceof Subgraph) {
statements = ((Subgraph) graphStm).getStatements();
} else {
statements = graph.getStatements();
}
removeGraphAttributes(statements, Attributes.BOUNDINGBOX);
String bbString = "\"0,0," + Double.toString(parent.getWidth()) + "," + Double.toString(parent.getHeight()) + "\"";
statements.add(DotExporter.createAttribute(Attributes.BOUNDINGBOX, bbString));
}
use of org.eclipse.elk.alg.graphviz.dot.dot.Statement 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);
}
}
use of org.eclipse.elk.alg.graphviz.dot.dot.Statement 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