use of org.eclipse.elk.core.options.SizeConstraint in project elk by eclipse.
the class ElkUtil method resizeNode.
/**
* Sets the size of a given node, depending on the minimal size, the number of ports
* on each side and the label.
*
* @param node the node that shall be resized
* @return a vector holding the width and height resizing ratio, or {@code null} if the size
* constraint is set to {@code FIXED}
*/
public static KVector resizeNode(final ElkNode node) {
Set<SizeConstraint> sizeConstraint = node.getProperty(CoreOptions.NODE_SIZE_CONSTRAINTS);
if (sizeConstraint.isEmpty()) {
return null;
}
double newWidth = 0, newHeight = 0;
if (sizeConstraint.contains(SizeConstraint.PORTS)) {
PortConstraints portConstraints = node.getProperty(CoreOptions.PORT_CONSTRAINTS);
double minNorth = 2, minEast = 2, minSouth = 2, minWest = 2;
Direction direction = node.getParent() == null ? node.getProperty(CoreOptions.DIRECTION) : node.getParent().getProperty(CoreOptions.DIRECTION);
for (ElkPort port : node.getPorts()) {
PortSide portSide = port.getProperty(CoreOptions.PORT_SIDE);
if (portSide == PortSide.UNDEFINED) {
portSide = calcPortSide(port, direction);
port.setProperty(CoreOptions.PORT_SIDE, portSide);
}
if (portConstraints == PortConstraints.FIXED_POS) {
switch(portSide) {
case NORTH:
minNorth = Math.max(minNorth, port.getX() + port.getWidth());
break;
case EAST:
minEast = Math.max(minEast, port.getY() + port.getHeight());
break;
case SOUTH:
minSouth = Math.max(minSouth, port.getX() + port.getWidth());
break;
case WEST:
minWest = Math.max(minWest, port.getY() + port.getHeight());
break;
}
} else {
switch(portSide) {
case NORTH:
minNorth += port.getWidth() + 2;
break;
case EAST:
minEast += port.getHeight() + 2;
break;
case SOUTH:
minSouth += port.getWidth() + 2;
break;
case WEST:
minWest += port.getHeight() + 2;
break;
}
}
}
newWidth = Math.max(minNorth, minSouth);
newHeight = Math.max(minEast, minWest);
}
return resizeNode(node, newWidth, newHeight, true, true);
}
use of org.eclipse.elk.core.options.SizeConstraint in project osate2 by osate.
the class DiagramElementLayoutUtil method applyProperties.
/**
* Sets the ELK properties of elements in the specified layout mapping based on the layout options.
* @param layoutMapping
*/
private static void applyProperties(final DiagramNode rootDiagramNode, final LayoutMapping layoutMapping) {
// Set the minimum node size based on the ports and their assigned sides.
final IGraphElementVisitor minNodeSizeVisitor = element -> {
if (element instanceof ElkNode) {
final ElkNode n = (ElkNode) element;
final double maxLabelWidth = n.getLabels().stream().mapToDouble(l -> l.getWidth()).max().orElse(0.0);
final double labelHeightSum = n.getLabels().stream().mapToDouble(l -> l.getHeight()).sum();
// Determine max width for ports on the left and right sides
final double maxLeftPortWidth = n.getPorts().stream().filter(p -> p.getProperty(CoreOptions.PORT_SIDE) == PortSide.WEST).mapToDouble(p -> p.getWidth()).max().orElse(0.0);
final double maxRightPortWidth = n.getPorts().stream().filter(p -> p.getProperty(CoreOptions.PORT_SIDE) == PortSide.EAST).mapToDouble(p -> p.getWidth()).max().orElse(0.0);
final DiagramNode dn = (DiagramNode) layoutMapping.getGraphMap().get(n);
double minWidth = 0;
if (n.getProperty(CoreOptions.NODE_LABELS_PLACEMENT).contains(NodeLabelPlacement.H_CENTER)) {
// Ensure the minimum width is such that the label can be centered without overlapping with ports.
// This happens because ports are inside the node due to the PORT_BORDER_OFFSET and ELK centers the labels in the remaining space.
final double widthForPorts = 2 * Math.max(maxLeftPortWidth, maxRightPortWidth);
minWidth = Math.max(40, maxLabelWidth + widthForPorts + PORT_WIDTH_PADDING);
} else {
final double widthForPorts = maxLeftPortWidth + maxRightPortWidth + PORT_WIDTH_PADDING;
minWidth = Math.max(40, Math.max(maxLabelWidth, widthForPorts));
}
double minHeight = Math.max(35, labelHeightSum);
if (dn instanceof DiagramElement) {
final DiagramElement de = ((DiagramElement) dn);
// Special min height handling for initial modes
final Graphic graphic = de.getGraphic();
if (graphic instanceof AgeShape && !((AgeShape) graphic).isResizeable() && de.hasSize()) {
final Dimension dim = de.getSize();
minHeight = dim.height;
minWidth = dim.width;
// Adjust size constraints for fixed sized shapes which do not have contents.
if (n.getChildren().size() == 0 || n.getLabels().size() == 0 && n.getPorts().size() == 0) {
final EnumSet<SizeConstraint> nodeSizeConstraints = EnumSet.of(SizeConstraint.MINIMUM_SIZE);
n.setProperty(CoreOptions.NODE_SIZE_CONSTRAINTS, nodeSizeConstraints);
}
}
if (graphic instanceof ModeGraphic && ((ModeGraphic) graphic).isInitialMode) {
minHeight += ModeGraphic.INITIAL_MODE_AREA_HEIGHT;
}
// Special min size handling for elements shown as image
final Style style = de.getStyle();
if (style != null && Boolean.TRUE.equals(style.getShowAsImage())) {
final Dimension dim = ((DiagramElement) dn).getSize();
minHeight = dim.height;
minWidth = dim.width;
}
}
// Increase min width and min height for top level nodes.
if (dn != null && dn.getParent() instanceof AgeDiagram) {
minWidth = Math.max(minWidth, 200);
minHeight = Math.max(minHeight, 100);
}
n.setProperty(CoreOptions.NODE_SIZE_MINIMUM, new KVector(minWidth, minHeight));
}
};
ElkUtil.applyVisitors(layoutMapping.getLayoutGraph(), minNodeSizeVisitor);
// If the top level element has a size set, don't shrink it.
if (rootDiagramNode instanceof DiagramElement) {
final DiagramElement rootDiagramElement = (DiagramElement) rootDiagramNode;
final ElkGraphElement rootGraphElement = layoutMapping.getGraphMap().inverse().get(rootDiagramNode);
if (rootGraphElement != null && rootDiagramElement.hasSize() && DiagramElementPredicates.isResizeable(rootDiagramElement)) {
final KVector minSize = rootGraphElement.getProperty(CoreOptions.NODE_SIZE_MINIMUM);
final double newMinWidth = Math.max(rootDiagramElement.getWidth(), minSize == null ? 0.0 : minSize.x);
final double newMinHeight = Math.max(rootDiagramElement.getHeight(), minSize == null ? 0.0 : minSize.y);
rootGraphElement.setProperty(CoreOptions.NODE_SIZE_MINIMUM, new KVector(newMinWidth, newMinHeight));
}
}
}
Aggregations