use of org.eclipse.elk.graph.ElkBendPoint in project sirius-components by eclipse-sirius.
the class ELKLayoutedDiagramProvider method getLayoutedEdge.
private Edge getLayoutedEdge(Edge edge, ElkEdge elkEdge, Map<String, ElkGraphElement> id2ElkGraphElements) {
List<Position> routingPoints = new ArrayList<>();
ElkNode containingNode = elkEdge.getContainingNode();
double xOffset = 0;
double yOffset = 0;
if (containingNode != null) {
xOffset = containingNode.getX();
yOffset = containingNode.getY();
ElkNode parent = containingNode.getParent();
while (parent instanceof ElkNode) {
xOffset += parent.getX();
yOffset += parent.getY();
parent = parent.getParent();
}
}
if (!elkEdge.getSections().isEmpty()) {
ElkEdgeSection section = elkEdge.getSections().get(0);
Position startPosition = Position.at(xOffset + section.getStartX(), yOffset + section.getStartY());
routingPoints.add(startPosition);
for (ElkBendPoint bendPoint : section.getBendPoints()) {
Position position = Position.at(xOffset + bendPoint.getX(), yOffset + bendPoint.getY());
routingPoints.add(position);
}
Position endPosition = Position.at(xOffset + section.getEndX(), yOffset + section.getEndY());
routingPoints.add(endPosition);
}
Label beginLabel = edge.getBeginLabel();
if (beginLabel != null) {
beginLabel = this.getLayoutedLabel(beginLabel, id2ElkGraphElements, xOffset, yOffset);
}
Label centerLabel = edge.getCenterLabel();
if (centerLabel != null) {
centerLabel = this.getLayoutedLabel(centerLabel, id2ElkGraphElements, xOffset, yOffset);
}
Label endLabel = edge.getEndLabel();
if (endLabel != null) {
endLabel = this.getLayoutedLabel(endLabel, id2ElkGraphElements, xOffset, yOffset);
}
// @formatter:off
return Edge.newEdge(edge).beginLabel(beginLabel).centerLabel(centerLabel).endLabel(endLabel).routingPoints(routingPoints).build();
// @formatter:on
}
use of org.eclipse.elk.graph.ElkBendPoint in project elk by eclipse.
the class GraphRenderingCanvas method calculateRequiredCanvasSizeAndBaseOffset.
/**
* Sets size of the canvas by looking up the biggest distances between graph elements in x- and y-direction
* and return a KVector with the required offset of the origin coordinates to fit all elements on the canvas.
*
* @param graph to be painted
*/
private KVector calculateRequiredCanvasSizeAndBaseOffset(final ElkNode graph) {
if (graph != null) {
double minX = Double.MAX_VALUE;
double maxX = Double.MIN_VALUE;
double minY = Double.MAX_VALUE;
double maxY = Double.MIN_VALUE;
// check all nodes for their coordinates
for (ElkNode node : graph.getChildren()) {
minX = Math.min(minX, node.getX());
maxX = Math.max(maxX, node.getX() + node.getWidth());
minY = Math.min(minY, node.getY());
maxY = Math.max(maxY, node.getY() + node.getHeight());
// check node labels
for (ElkLabel nodeLabel : node.getLabels()) {
minX = Math.min(minX, node.getX() + nodeLabel.getX());
maxX = Math.max(maxX, node.getX() + nodeLabel.getX() + nodeLabel.getWidth());
minY = Math.min(minY, node.getY() + nodeLabel.getY());
maxY = Math.max(maxY, node.getY() + nodeLabel.getY() + nodeLabel.getHeight());
}
}
for (ElkEdge edge : graph.getContainedEdges()) {
// check all sections of the edges for their coordinates
for (ElkEdgeSection edgeSection : edge.getSections()) {
minX = Math.min(minX, edgeSection.getStartX());
minY = Math.min(minY, edgeSection.getStartY());
maxX = Math.max(maxX, edgeSection.getStartX());
maxY = Math.max(maxY, edgeSection.getStartY());
minX = Math.min(minX, edgeSection.getEndX());
minY = Math.min(minY, edgeSection.getEndY());
maxX = Math.max(maxX, edgeSection.getEndX());
maxY = Math.max(maxY, edgeSection.getEndY());
for (ElkBendPoint bendPoint : edgeSection.getBendPoints()) {
minX = Math.min(minX, bendPoint.getX());
minY = Math.min(minY, bendPoint.getY());
maxX = Math.max(maxX, bendPoint.getX());
maxY = Math.max(maxY, bendPoint.getY());
}
}
// check edge labels
for (ElkLabel edgeLabel : edge.getLabels()) {
minX = Math.min(minX, edgeLabel.getX());
maxX = Math.max(maxX, edgeLabel.getX() + edgeLabel.getWidth());
minY = Math.min(minY, edgeLabel.getY());
maxY = Math.max(maxY, edgeLabel.getY() + edgeLabel.getHeight());
}
}
int x = ((int) (Math.max(graph.getWidth(), maxX) - Math.min(0, minX))) + 1;
int y = ((int) (Math.max(graph.getHeight(), maxY) - Math.min(0, minY))) + 1;
setSize(new Point(x, y));
return new KVector((-Math.min(0, minX)), (-Math.min(0, minY)));
}
return new KVector();
}
use of org.eclipse.elk.graph.ElkBendPoint in project elk by eclipse.
the class RecursiveGraphLayoutEngine method postProcessInsideSelfLoops.
/**
* Post-processes self loops routed inside by offsetting their coordinates by the coordinates of
* their parent node. The post processing is necessary since the self loop coordinates are
* relative to their parent node's upper left corner since, at that point, the parent node's
* final coordinates are not determined yet.
*
* @param insideSelfLoops
* list of inside self loops to post-process.
*/
protected void postProcessInsideSelfLoops(final List<ElkEdge> insideSelfLoops) {
for (final ElkEdge selfLoop : insideSelfLoops) {
// MIGRATE Adapt to hyperedges and make error-safe
final ElkConnectableShape node = ElkGraphUtil.connectableShapeToNode(selfLoop.getSources().get(0));
final double xOffset = node.getX();
final double yOffset = node.getY();
// Offset the edge coordinates by the node's position
// MIGRATE Adapt to hyperedges. Also, what about multiple edge sections?
ElkEdgeSection section = selfLoop.getSections().get(0);
section.setStartLocation(section.getStartX() + xOffset, section.getStartY() + yOffset);
section.setEndLocation(section.getEndX() + xOffset, section.getEndY() + yOffset);
for (final ElkBendPoint bend : section.getBendPoints()) {
bend.set(bend.getX() + xOffset, bend.getY() + yOffset);
}
// Offset junction points by the node position
selfLoop.getProperty(CoreOptions.JUNCTION_POINTS).offset(xOffset, yOffset);
}
}
use of org.eclipse.elk.graph.ElkBendPoint in project elk by eclipse.
the class ElkUtil method applyVectorChain.
/**
* Applies the vector chain's vectors to the given edge section. The first and the last point of the vector chain
* are used as the section's new source and start point, respectively. The remaining points become the section's
* new bend points. The method tries to reuse as many bend points as possible instead of wiping all bend points
* out and creating new ones.
*
* @param vectorChain the vector chain to apply.
* @param section the edge section to apply the chain to.
* @throws IllegalArgumentException if the vector chain contains less than two vectors.
*/
public static void applyVectorChain(final KVectorChain vectorChain, final ElkEdgeSection section) {
// We need at least a start and an end point
if (vectorChain.size() < 2) {
throw new IllegalArgumentException("The vector chain must contain at least a source and a target point.");
}
// Start point
KVector firstPoint = vectorChain.getFirst();
section.setStartLocation(firstPoint.x, firstPoint.y);
// Reuse as many existing bend points as possible
ListIterator<ElkBendPoint> oldPointIter = section.getBendPoints().listIterator();
ListIterator<KVector> newPointIter = vectorChain.listIterator(1);
while (newPointIter.nextIndex() < vectorChain.size() - 1) {
KVector nextPoint = newPointIter.next();
ElkBendPoint bendpoint;
if (oldPointIter.hasNext()) {
bendpoint = oldPointIter.next();
} else {
bendpoint = ElkGraphFactory.eINSTANCE.createElkBendPoint();
oldPointIter.add(bendpoint);
}
bendpoint.set(nextPoint.x, nextPoint.y);
}
// Remove existing bend points that we did not use
while (oldPointIter.hasNext()) {
oldPointIter.next();
oldPointIter.remove();
}
// End point
KVector lastPoint = vectorChain.getLast();
section.setEndLocation(lastPoint.x, lastPoint.y);
}
use of org.eclipse.elk.graph.ElkBendPoint in project elk by eclipse.
the class FixedLayoutProvider method processEdge.
/**
* Process an edge and its labels.
*
* @param edge an edge
* @param edgeRouting the global edge routing setting
*/
private KVector processEdge(final ElkEdge edge, final EdgeRouting edgeRouting) {
// MIGRATE Does this properly support hyperedges?
ElkNode sourceParent = ElkGraphUtil.connectableShapeToNode(edge.getSources().get(0)).getParent();
ElkNode targetParent = ElkGraphUtil.connectableShapeToNode(edge.getTargets().get(0)).getParent();
boolean sameHierarchy = sourceParent == targetParent;
KVector maxv = new KVector();
KVectorChain bendPoints = edge.getProperty(FixedLayouterOptions.BEND_POINTS);
// we need at least two bend points, since the source point and target point must be included
if (bendPoints != null && bendPoints.size() >= 2) {
if (edge.getSections().isEmpty()) {
// We need an edge section to apply the bend points to
ElkEdgeSection edgeSection = ElkGraphFactory.eINSTANCE.createElkEdgeSection();
edge.getSections().add(edgeSection);
} else if (edge.getSections().size() > 1) {
// We can only apply bend points to a single edge section, so throw away all except for the last one
ListIterator<ElkEdgeSection> sections = edge.getSections().listIterator();
while (sections.hasNext()) {
sections.remove();
}
}
ElkUtil.applyVectorChain(bendPoints, edge.getSections().get(0));
}
// determine maximal coordinates
if (sameHierarchy) {
for (ElkEdgeSection edgeSection : edge.getSections()) {
for (ElkBendPoint point : edgeSection.getBendPoints()) {
maxv.x = Math.max(maxv.x, point.getX());
maxv.y = Math.max(maxv.y, point.getY());
}
}
}
// set the fixed position of the edge labels, or leave them as they are
for (ElkLabel label : edge.getLabels()) {
KVector pos = label.getProperty(FixedLayouterOptions.POSITION);
if (pos != null) {
label.setLocation(pos.x, pos.y);
}
if (sameHierarchy) {
maxv.x = Math.max(maxv.x, label.getX() + label.getWidth());
maxv.y = Math.max(maxv.y, label.getY() + label.getHeight());
}
}
return maxv;
}
Aggregations