use of org.eclipse.elk.graph.ElkNode in project sirius-components by eclipse-sirius.
the class ELKDiagramConverter method convertDiagram.
private ElkNode convertDiagram(Diagram diagram) {
ElkNode elkDiagram = ElkGraphFactory.eINSTANCE.createElkNode();
elkDiagram.setIdentifier(diagram.getId());
elkDiagram.setProperty(PROPERTY_TYPE, DEFAULT_DIAGRAM_TYPE);
return elkDiagram;
}
use of org.eclipse.elk.graph.ElkNode 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.ElkNode in project osate2 by osate.
the class DiagramElementLayoutUtil method layout.
private static void layout(final DiagramModification m, final Collection<? extends DiagramNode> nodesToLayout, final StyleProvider styleProvider, final LayoutInfoProvider layoutInfoProvider, final LayoutOptions options) {
Objects.requireNonNull(nodesToLayout, "nodesToLayout must not be null");
try {
// Layout the nodes
final RecursiveGraphLayoutEngine layoutEngine = new RecursiveGraphLayoutEngine();
for (final DiagramNode dn : nodesToLayout) {
LayoutMapping mapping;
ElkNode layoutGraph;
// Perform the first layout. This layout will not include nested ports. This will allow ELK additional flexibility when determining port
// placement.
mapping = ElkGraphBuilder.buildLayoutGraph(dn, styleProvider, layoutInfoProvider, options, !options.layoutPortsOnDefaultSides, ElkGraphBuilder.FixedPortPositionProvider.NO_OP);
layoutGraph = mapping.getLayoutGraph();
layoutGraph.setProperty(CoreOptions.ALGORITHM, LAYOUT_ALGORITHM);
applyProperties(dn, mapping);
LayoutDebugUtil.saveElkGraphToDebugProject(layoutGraph, "pass1");
layoutEngine.layout(layoutGraph, new BasicProgressMonitor());
// nested ports and performing edge routing.
if (layoutGraph.getProperty(AgeLayoutOptions.NESTED_PORTS_WERE_OMITTED)) {
final LayoutMapping initialLayoutMapping = mapping;
mapping = ElkGraphBuilder.buildLayoutGraph(dn, styleProvider, layoutInfoProvider, options, false, new ElkGraphBuilder.FixedPortPositionProvider() {
@Override
public PortSide getPortSide(final DiagramElement de) {
final ElkGraphElement ge = initialLayoutMapping.getGraphMap().inverse().get(de);
if (ge instanceof ElkPort) {
return ge.getProperty(CoreOptions.PORT_SIDE);
}
return null;
}
@Override
public Double getPortPosition(final DiagramElement de) {
final ElkGraphElement ge = initialLayoutMapping.getGraphMap().inverse().get(de);
if (ge instanceof ElkPort) {
final ElkPort port = (ElkPort) ge;
final PortSide ps = port.getProperty(CoreOptions.PORT_SIDE);
if (PortSide.SIDES_EAST_WEST.contains(ps)) {
return port.getY();
} else {
return port.getX();
}
}
return null;
}
});
layoutGraph = mapping.getLayoutGraph();
layoutGraph.setProperty(CoreOptions.ALGORITHM, LAYOUT_ALGORITHM);
applyProperties(dn, mapping);
LayoutDebugUtil.saveElkGraphToDebugProject(layoutGraph, "pass2");
layoutEngine.layout(layoutGraph, new BasicProgressMonitor());
}
LayoutDebugUtil.saveElkGraphToDebugProject(layoutGraph, "final");
applyShapeLayout(mapping, m);
applyConnectionLayout(mapping, m);
// Layout feature self loop connections. These are omitted from the ELK based layout.
dn.getAllDiagramNodes().filter(DiagramElementLayoutUtil::isFeatureSelfLoopConnection).map(DiagramElement.class::cast).forEachOrdered(de -> layoutFeatureSelfLoopConnection(de, m, layoutInfoProvider));
}
} catch (final RuntimeException ex) {
// If a layout error occurs, display the exception but do not rethrow. This is so that the operation that attempted to do the layout will continue.
// This is important because otherwise simple operations such a adding elements to the diagram will completely fail. Suppressing the error will
// degrade performance but allow the user to keep working and should ensure things stay in a valid state.
// It would be best for other parts of the code to handle exceptions properly to avoid entering into an invalid state but this is the best
// workaround.
final Status status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, "A layout error occured.", ex);
StatusManager.getManager().handle(status, StatusManager.SHOW | StatusManager.LOG);
}
}
use of org.eclipse.elk.graph.ElkNode in project osate2 by osate.
the class ElkGraphBuilder method createElkGraphElementForNonLabelAndUndockedShape.
private Optional<ElkGraphElement> createElkGraphElementForNonLabelAndUndockedShape(final DiagramElement de, final ElkNode layoutParent, final LayoutMapping mapping) {
final ElkNode newNode = ElkGraphUtil.createNode(layoutParent);
mapping.getGraphMap().put(newNode, de);
if (de.hasPosition()) {
newNode.setLocation(de.getX(), de.getY());
}
// Setting the size is disabled because setting it causes shapes which have a flow path(along with corresponding ports) to grow.
// if (de.hasSize()) {
// newNode.setDimensions(de.getWidth(), de.getHeight());
// }
final EnumSet<SizeConstraint> nodeSizeConstraints = EnumSet.of(SizeConstraint.PORTS, SizeConstraint.MINIMUM_SIZE, SizeConstraint.NODE_LABELS);
newNode.setProperty(CoreOptions.NODE_SIZE_CONSTRAINTS, nodeSizeConstraints);
newNode.setProperty(CoreOptions.INSIDE_SELF_LOOPS_ACTIVATE, true);
newNode.setProperty(CoreOptions.NODE_SIZE_OPTIONS, EnumSet.of(SizeOptions.DEFAULT_MINIMUM_SIZE, SizeOptions.ASYMMETRICAL));
// Create labels
createElkLabels(de, newNode, mapping);
// Create Children
createElkGraphElementsForNonLabelChildShapes(de, newNode, mapping);
return Optional.of(newNode);
}
use of org.eclipse.elk.graph.ElkNode in project osate2 by osate.
the class ElkGraphBuilder method buildLayoutGraph.
private LayoutMapping buildLayoutGraph(final DiagramNode rootDiagramNode) {
// Create the graph
final LayoutMapping mapping = new LayoutMapping(null);
final ElkNode rootNode = ElkGraphUtil.createGraph();
rootNode.setProperty(CoreOptions.DIRECTION, Direction.RIGHT);
mapping.setLayoutGraph(rootNode);
// As of 2020-04-06, INCLUDE_CHILDREN causes layout issues. In particular, labels can overlap with children
// https://github.com/eclipse/elk/issues/316
// https://github.com/eclipse/elk/issues/412
rootNode.setProperty(CoreOptions.HIERARCHY_HANDLING, HierarchyHandling.SEPARATE_CHILDREN);
if (rootDiagramNode instanceof AgeDiagram) {
final ElkNode diagramElkNode = ElkGraphUtil.createNode(rootNode);
mapping.getGraphMap().put(diagramElkNode, rootDiagramNode);
createElkGraphElementsForNonLabelChildShapes(rootDiagramNode, diagramElkNode, mapping);
} else if (rootDiagramNode instanceof DiagramElement) {
createElkGraphElementsForElements(Collections.singleton((DiagramElement) rootDiagramNode), rootNode, mapping);
}
createElkGraphElementsForConnections(rootDiagramNode, mapping);
return mapping;
}
Aggregations