use of org.eclipse.elk.graph.ElkNode in project osate2 by osate.
the class ElkGraphBuilder method createElkLabels.
private void createElkLabels(final DiagramElement parentElement, final ElkGraphElement parentLayoutElement, final LayoutMapping mapping) {
// Don't create labels for ElkPort. The bounds of the port contain their labels.
if (parentLayoutElement instanceof ElkPort) {
return;
}
final boolean isConnection = parentElement.getGraphic() instanceof AgeConnection;
final Style style = styleProvider.getStyle(parentElement);
if (style.getPrimaryLabelVisible()) {
// Create Primary Label
if (parentElement.getLabelName() != null) {
final ElkLabel elkLabel = createElkLabel(parentLayoutElement, parentElement.getLabelName(), layoutInfoProvider.getPrimaryLabelSize(parentElement));
if (isConnection) {
if (!layoutConnectionLabels) {
elkLabel.setProperty(CoreOptions.NO_LAYOUT, true);
}
mapping.getGraphMap().put(elkLabel, new PrimaryConnectionLabelReference(parentElement));
}
}
}
// Create label for annotations which are part of the graphic configuration. These are only supported by non-connections.
if (!isConnection && parentElement.getGraphicalConfiguration().getAnnotation() != null) {
createElkLabel(parentLayoutElement, parentElement.getGraphicalConfiguration().getAnnotation(), layoutInfoProvider.getAnnotationLabelSize(parentElement));
}
// Create Secondary Labels
parentElement.getChildren().stream().filter(c -> c.getGraphic() instanceof Label).forEachOrdered(labelElement -> {
final ElkLabel elkLabel = createElkLabel(parentLayoutElement, labelElement.getLabelName(), layoutInfoProvider.getPrimaryLabelSize(labelElement));
if (isConnection) {
if (!layoutConnectionLabels) {
elkLabel.setProperty(CoreOptions.NO_LAYOUT, true);
}
mapping.getGraphMap().put(elkLabel, new SecondaryConnectionLabelReference(labelElement));
}
});
if (parentLayoutElement instanceof ElkNode) {
parentLayoutElement.setProperty(CoreOptions.NODE_LABELS_PLACEMENT, getNodeLabelPlacement(style));
}
}
use of org.eclipse.elk.graph.ElkNode in project osate2 by osate.
the class ElkGraphBuilder method createElkPortsForElements.
/**
* Before calling this method, all labels for the parent node should have already been created and the node labels placement property must be set for the parent.
* @param elements
* @param parent
* @param mapping
*/
private void createElkPortsForElements(final Collection<DiagramElement> elements, final ElkNode parent, final LayoutMapping mapping) {
final EnumSet<NodeLabelPlacement> nodeLabelPlacement = parent.getProperty(CoreOptions.NODE_LABELS_PLACEMENT);
final boolean labelsAtTop = nodeLabelPlacement != null && nodeLabelPlacement.contains(NodeLabelPlacement.V_TOP);
final double topPadding = labelsAtTop ? parent.getLabels().stream().mapToDouble(l -> l.getY() + l.getHeight()).sum() : 0.0;
// Group children by the port side to which they should be assigned.
final List<DiagramElement> dockedShapes = elements.stream().filter(dockedShapeFilter).collect(Collectors.toList());
final boolean diagramElementIncludesNestedPorts = dockedShapes.stream().flatMap(de -> de.getChildren().stream()).anyMatch(dockedShapeFilter);
// Set the flag to indicate that there are nested ports which will not be included in the final layout graph
if (omitNestedPorts && diagramElementIncludesNestedPorts) {
mapping.getLayoutGraph().setProperty(AgeLayoutOptions.NESTED_PORTS_WERE_OMITTED, true);
}
// Set port constraints and graph hierarchy handling of the parent based on whether the diagram element actually has nested ports.
final boolean hasNestedPorts = !omitNestedPorts && diagramElementIncludesNestedPorts;
PortConstraints portConstraints;
if (dockedShapes.size() == 0) {
// Don't constrain ports if there aren't any. As of 2017-10-11, some other values can affect the layout even if the node does not contain ports.
portConstraints = PortConstraints.FREE;
} else {
if (hasNestedPorts || options.layoutPortsOnDefaultSides) {
portConstraints = PortConstraints.FIXED_POS;
} else {
portConstraints = PortConstraints.FREE;
}
}
parent.setProperty(CoreOptions.PORT_CONSTRAINTS, portConstraints);
final Map<PortSide, List<DiagramElement>> groupedDockedElements = dockedShapes.stream().collect(Collectors.groupingBy(de -> getPortSide(de, hasNestedPorts), HashMap::new, Collectors.toCollection(ArrayList::new)));
// Determine padding
// Need to pad both left and right sides equally if ELK is determining the side of ports. Otherwise, the space for the
// port may overlap with shapes. This is likely caused by adjusting the border offset of ports
// to lay out ports within the bounds of the containing shape
final boolean padOppositeSides = !portConstraints.isSideFixed();
final ElkPadding parentPadding = new ElkPadding(parent.getParent() == null || parent.getParent().getParent() == null ? 0.0 : portAndContentsPadding);
for (final Entry<PortSide, List<DiagramElement>> entry : groupedDockedElements.entrySet()) {
final PortSide side = entry.getKey();
double maxSize = 0;
for (final DiagramElement de : entry.getValue()) {
maxSize = Math.max(maxSize, getOrthogonalSize(de, side));
}
// Update padding for the side
final double sidePadding = maxSize + portAndContentsPadding;
switch(side) {
case NORTH:
parentPadding.top = Math.max(parentPadding.top, sidePadding);
break;
case SOUTH:
parentPadding.bottom = Math.max(parentPadding.bottom, sidePadding);
break;
case EAST:
parentPadding.right = Math.max(parentPadding.right, sidePadding);
if (padOppositeSides) {
parentPadding.left = Math.max(parentPadding.left, sidePadding);
}
break;
case WEST:
parentPadding.left = Math.max(parentPadding.left, sidePadding);
if (padOppositeSides) {
parentPadding.right = Math.max(parentPadding.right, sidePadding);
}
break;
default:
// Ignore
break;
}
}
// Create and position the ports
for (final Entry<PortSide, List<DiagramElement>> portSideToElementsEntry : groupedDockedElements.entrySet()) {
final PortSide side = portSideToElementsEntry.getKey();
final double additionalPadding;
if (PortSide.SIDES_NORTH_SOUTH.contains(side)) {
additionalPadding = Math.max(parentPadding.left, parentPadding.right);
} else {
additionalPadding = topPadding;
}
createAndPositionPorts(parent, portSideToElementsEntry.getValue(), portSideToElementsEntry.getKey(), additionalPadding, mapping, hasNestedPorts);
}
// Set the padding
parent.setProperty(CoreOptions.PADDING, parentPadding);
}
use of org.eclipse.elk.graph.ElkNode in project elk by eclipse.
the class NGraph method writeDebugGraph.
/**
* Converts this {@link NGraph} to a KGraph and writes it to the specified filed.
*
* @param filePath a path to a file on the filesystem
*/
public void writeDebugGraph(final String filePath) {
ElkNode elkGraph = ElkGraphUtil.createGraph();
elkGraph.setProperty(CoreOptions.DIRECTION, Direction.DOWN);
Map<NNode, ElkNode> nodeMap = Maps.newHashMap();
for (NNode nNode : nodes) {
ElkNode elkNode = ElkGraphUtil.createNode(elkGraph);
nodeMap.put(nNode, elkNode);
ElkGraphUtil.createLabel(nNode.type + " " + nNode.layer, elkNode);
}
for (NNode nNode : nodes) {
for (NEdge nEdge : nNode.getOutgoingEdges()) {
ElkEdge elkEdge = ElkGraphUtil.createSimpleEdge(nodeMap.get(nEdge.source), nodeMap.get(nEdge.target));
ElkGraphUtil.createLabel(nEdge.weight + " " + nEdge.delta, elkEdge);
}
}
ResourceSet rs = new ResourceSetImpl();
Resource r = rs.createResource(URI.createFileURI(filePath));
r.getContents().add(elkGraph);
try {
r.save(Collections.emptyMap());
} catch (IOException e) {
e.printStackTrace();
}
}
use of org.eclipse.elk.graph.ElkNode in project elk by eclipse.
the class GmfDiagramLayoutConnector method processConnections.
/**
* Creates new edges and takes care of the labels for each connection identified in the
* {@code buildLayoutGraphRecursively} method.
*
* @param mapping
* the layout mapping
*/
protected void processConnections(final LayoutMapping mapping) {
Map<EReference, ElkEdge> reference2EdgeMap = new HashMap<>();
for (ConnectionEditPart connection : mapping.getProperty(CONNECTIONS)) {
boolean isOppositeEdge = false;
Optional<EdgeLabelPlacement> edgeLabelPlacement = Optional.empty();
ElkEdge edge;
// Check whether the edge belongs to an Ecore reference, which may have opposites.
// This is required for the layout of Ecore diagrams, since the bend points of
// opposite references are kept synchronized by the editor.
EObject modelObject = connection.getNotationView().getElement();
if (modelObject instanceof EReference) {
EReference reference = (EReference) modelObject;
edge = reference2EdgeMap.get(reference.getEOpposite());
if (edge != null) {
edgeLabelPlacement = Optional.of(EdgeLabelPlacement.TAIL);
isOppositeEdge = true;
} else {
edge = ElkGraphUtil.createEdge(null);
reference2EdgeMap.put(reference, edge);
}
} else {
edge = ElkGraphUtil.createEdge(null);
}
BiMap<Object, ElkGraphElement> inverseGraphMap = mapping.getGraphMap().inverse();
// find a proper source node and source port
ElkGraphElement sourceElem;
EditPart sourceObj = connection.getSource();
if (sourceObj instanceof ConnectionEditPart) {
sourceElem = inverseGraphMap.get(((ConnectionEditPart) sourceObj).getSource());
if (sourceElem == null) {
sourceElem = inverseGraphMap.get(((ConnectionEditPart) sourceObj).getTarget());
}
} else {
sourceElem = inverseGraphMap.get(sourceObj);
}
ElkConnectableShape sourceShape = null;
ElkPort sourcePort = null;
ElkNode sourceNode = null;
if (sourceElem instanceof ElkNode) {
sourceNode = (ElkNode) sourceElem;
sourceShape = sourceNode;
} else if (sourceElem instanceof ElkPort) {
sourcePort = (ElkPort) sourceElem;
sourceNode = sourcePort.getParent();
sourceShape = sourcePort;
} else {
continue;
}
// find a proper target node and target port
ElkGraphElement targetElem;
EditPart targetObj = connection.getTarget();
if (targetObj instanceof ConnectionEditPart) {
targetElem = inverseGraphMap.get(((ConnectionEditPart) targetObj).getTarget());
if (targetElem == null) {
targetElem = inverseGraphMap.get(((ConnectionEditPart) targetObj).getSource());
}
} else {
targetElem = inverseGraphMap.get(targetObj);
}
ElkConnectableShape targetShape = null;
ElkNode targetNode = null;
ElkPort targetPort = null;
if (targetElem instanceof ElkNode) {
targetNode = (ElkNode) targetElem;
targetShape = targetNode;
} else if (targetElem instanceof ElkPort) {
targetPort = (ElkPort) targetElem;
targetNode = targetPort.getParent();
targetShape = targetPort;
} else {
continue;
}
// calculate offset for edge and label coordinates
ElkNode edgeContainment = ElkGraphUtil.findLowestCommonAncestor(sourceNode, targetNode);
KVector offset = new KVector();
ElkUtil.toAbsolute(offset, edgeContainment);
if (!isOppositeEdge) {
// set source and target
edge.getSources().add(sourceShape);
edge.getTargets().add(targetShape);
// now that source and target are set, put the edge into the graph
edgeContainment.getContainedEdges().add(edge);
mapping.getGraphMap().put(edge, connection);
// store the current coordinates of the edge
setEdgeLayout(edge, connection, offset);
}
// process edge labels
processEdgeLabels(mapping, connection, edge, edgeLabelPlacement, offset);
}
}
use of org.eclipse.elk.graph.ElkNode in project elk by eclipse.
the class GmfDiagramLayoutConnector method applyLayout.
@Override
public void applyLayout(final LayoutMapping mapping, final IPropertyHolder settings) {
boolean zoomToFit = settings.getProperty(CoreOptions.ZOOM_TO_FIT);
IWorkbenchPart workbenchPart = mapping.getWorkbenchPart();
int animationTime = calcAnimationTime(mapping, settings, workbenchPart != null && !workbenchPart.getSite().getPage().isPartVisible(workbenchPart));
mapping.setProperty(ANIMATION_TIME, animationTime);
Object layoutGraphObj = mapping.getParentElement();
if (zoomToFit && layoutGraphObj instanceof EditPart) {
// determine pre- or post-layout zoom
DiagramEditPart diagramEditPart = GmfDiagramLayoutConnector.getDiagramEditPart((EditPart) layoutGraphObj);
if (diagramEditPart == null) {
applyLayout(mapping, animationTime);
return;
}
ZoomManager zoomManager = ((RenderedDiagramRootEditPart) diagramEditPart.getRoot()).getZoomManager();
ElkNode parentNode = mapping.getLayoutGraph();
Dimension available = zoomManager.getViewport().getClientArea().getSize();
double desiredWidth = parentNode.getWidth();
double scaleX = Math.min(available.width / desiredWidth, zoomManager.getMaxZoom());
double desiredHeight = parentNode.getHeight();
double scaleY = Math.min(available.height / desiredHeight, zoomManager.getMaxZoom());
final double scale = Math.min(scaleX, scaleY);
final double oldScale = zoomManager.getZoom();
if (scale < oldScale) {
// we're zooming out, so do it before layout is applied
zoomManager.setViewLocation(new Point(0, 0));
zoomManager.setZoom(scale);
zoomManager.setViewLocation(new Point(0, 0));
}
applyLayout(mapping, animationTime);
if (scale > oldScale) {
// we're zooming in, so do it after layout is applied
zoomManager.setViewLocation(new Point(0, 0));
zoomManager.setZoom(scale);
zoomManager.setViewLocation(new Point(0, 0));
}
} else {
applyLayout(mapping, animationTime);
}
}
Aggregations