use of org.eclipse.elk.core.options.NodeLabelPlacement in project sirius-components by eclipse-sirius.
the class NodeLabelPositionProvider method getVerticalPosition.
private double getVerticalPosition(NodeLayoutData node, LabelLayoutData label) {
double y = 0d;
EnumSet<NodeLabelPlacement> nodeLabelPlacementSet = this.layoutConfigurator.configureByType(node.getNodeType()).getProperty(CoreOptions.NODE_LABELS_PLACEMENT);
ElkPadding nodeLabelsPadding = this.layoutConfigurator.configureByType(node.getNodeType()).getProperty(CoreOptions.NODE_LABELS_PADDING);
boolean outside = this.isOutside(nodeLabelPlacementSet);
double topPadding = 0d;
double bottomPadding = 0d;
if (nodeLabelsPadding == null) {
nodeLabelsPadding = CoreOptions.NODE_LABELS_PADDING.getDefault();
}
topPadding = nodeLabelsPadding.getTop();
bottomPadding = nodeLabelsPadding.getBottom();
for (NodeLabelPlacement nodeLabelPlacement : nodeLabelPlacementSet) {
switch(nodeLabelPlacement) {
case V_TOP:
if (outside) {
y = -(label.getTextBounds().getSize().getHeight()) - topPadding;
} else {
y = topPadding;
}
break;
case V_CENTER:
y = (node.getSize().getHeight() - label.getTextBounds().getSize().getHeight()) / 2;
break;
case V_BOTTOM:
if (outside) {
y = -(label.getTextBounds().getSize().getHeight());
} else {
y = node.getSize().getHeight() - label.getTextBounds().getSize().getHeight() - bottomPadding;
}
break;
default:
break;
}
}
return y;
}
use of org.eclipse.elk.core.options.NodeLabelPlacement in project osate2 by osate.
the class ElkGraphBuilder method getNodeLabelPlacement.
private static EnumSet<NodeLabelPlacement> getNodeLabelPlacement(final Style s) {
// Determine horizontal node label placement
NodeLabelPlacement horizontalNodeLabelPlacement = NodeLabelPlacement.H_CENTER;
if (s.getHorizontalLabelPosition() != null) {
switch(s.getHorizontalLabelPosition()) {
case BEFORE_GRAPHIC:
case GRAPHIC_BEGINNING:
horizontalNodeLabelPlacement = NodeLabelPlacement.H_LEFT;
break;
case GRAPHIC_CENTER:
horizontalNodeLabelPlacement = NodeLabelPlacement.H_CENTER;
break;
case GRAPHIC_END:
case AFTER_GRAPHIC:
horizontalNodeLabelPlacement = NodeLabelPlacement.H_RIGHT;
break;
}
}
// Determine vertical node label placement
NodeLabelPlacement verticalNodeLabelPlacement = NodeLabelPlacement.V_CENTER;
if (s.getVerticalLabelPosition() != null) {
switch(s.getVerticalLabelPosition()) {
case BEFORE_GRAPHIC:
case GRAPHIC_BEGINNING:
verticalNodeLabelPlacement = NodeLabelPlacement.V_TOP;
break;
case GRAPHIC_CENTER:
verticalNodeLabelPlacement = NodeLabelPlacement.V_CENTER;
break;
case GRAPHIC_END:
case AFTER_GRAPHIC:
verticalNodeLabelPlacement = NodeLabelPlacement.V_BOTTOM;
break;
}
}
// However, the ELK graph we build does not contain labels for ports, such labels are considered part of the port itself.
return EnumSet.of(horizontalNodeLabelPlacement, verticalNodeLabelPlacement, NodeLabelPlacement.INSIDE);
}
use of org.eclipse.elk.core.options.NodeLabelPlacement 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.core.options.NodeLabelPlacement in project elk by eclipse.
the class NodeLabelCellCreator method handleNodeLabel.
/**
* Handles the given node label by adding it to the corresponding node label cell. If such a cell doesn't exist
* yet, it is created and added to the correct container cell.
*/
private static void handleNodeLabel(final NodeContext nodeContext, final LabelAdapter<?> label, final boolean onlyInside, final boolean horizontalLayoutMode) {
// Find the effective label location
Set<NodeLabelPlacement> labelPlacement = label.hasProperty(CoreOptions.NODE_LABELS_PLACEMENT) ? label.getProperty(CoreOptions.NODE_LABELS_PLACEMENT) : nodeContext.nodeLabelPlacement;
NodeLabelLocation labelLocation = NodeLabelLocation.fromNodeLabelPlacement(labelPlacement);
// If the label has its location fixed, we will ignore it
if (labelLocation == NodeLabelLocation.UNDEFINED) {
return;
}
// If the label's location is on the node's outside but we only want inside node labels, we will ignore it
if (onlyInside && !labelLocation.isInsideLocation()) {
return;
}
retrieveNodeLabelCell(nodeContext, labelLocation, horizontalLayoutMode).addLabel(label);
}
use of org.eclipse.elk.core.options.NodeLabelPlacement in project sirius-components by eclipse-sirius.
the class NodeLabelPositionProvider method getHorizontalPosition.
private double getHorizontalPosition(NodeLayoutData node, LabelLayoutData label, List<BorderNodesOnSide> borderNodesOnSides) {
double x = 0d;
EnumSet<NodeLabelPlacement> nodeLabelPlacementSet = this.layoutConfigurator.configureByType(node.getNodeType()).getProperty(CoreOptions.NODE_LABELS_PLACEMENT);
ElkPadding nodeLabelsPadding = this.layoutConfigurator.configureByType(node.getNodeType()).getProperty(CoreOptions.NODE_LABELS_PADDING);
boolean outside = this.isOutside(nodeLabelPlacementSet);
double leftPadding = 0d;
double rightPadding = 0d;
if (nodeLabelsPadding == null) {
nodeLabelsPadding = CoreOptions.NODE_LABELS_PADDING.getDefault();
}
leftPadding = nodeLabelsPadding.getLeft();
rightPadding = nodeLabelsPadding.getRight();
for (NodeLabelPlacement nodeLabelPlacement : nodeLabelPlacementSet) {
switch(nodeLabelPlacement) {
case H_LEFT:
if (outside) {
x = -(label.getTextBounds().getSize().getWidth() + leftPadding);
} else {
x = leftPadding;
}
break;
case H_CENTER:
// The label is positioned at the center of the node and the front-end will apply a "'text-anchor':
// 'middle'" property.
int shiftToEast = 0;
int shiftToWest = 0;
for (BorderNodesOnSide borderNodesOnSide : borderNodesOnSides) {
if (RectangleSide.WEST.equals(borderNodesOnSide.getSide())) {
shiftToEast = 1;
} else if (RectangleSide.EAST.equals(borderNodesOnSide.getSide())) {
shiftToWest = 1;
}
}
double portOffset = Optional.ofNullable(this.layoutConfigurator.configureByType(node.getNodeType()).getProperty(CoreOptions.PORT_BORDER_OFFSET)).orElse(0.);
double offSetAccordingToBorderNodes = -portOffset / 2 * (shiftToEast - shiftToWest);
x = node.getSize().getWidth() / 2 + offSetAccordingToBorderNodes;
break;
case H_RIGHT:
if (outside) {
x = node.getSize().getWidth() + rightPadding;
} else {
x = node.getSize().getWidth() - label.getTextBounds().getSize().getWidth() - rightPadding;
}
break;
default:
break;
}
}
return x;
}
Aggregations