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