Search in sources :

Example 1 with NodeLabelPlacement

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;
}
Also used : NodeLabelPlacement(org.eclipse.elk.core.options.NodeLabelPlacement) ElkPadding(org.eclipse.elk.core.math.ElkPadding)

Example 2 with NodeLabelPlacement

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);
}
Also used : NodeLabelPlacement(org.eclipse.elk.core.options.NodeLabelPlacement)

Example 3 with NodeLabelPlacement

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);
}
Also used : CoreOptions(org.eclipse.elk.core.options.CoreOptions) DiagramElement(org.osate.ge.internal.diagram.runtime.DiagramElement) PortSide(org.eclipse.elk.core.options.PortSide) Dimension(org.osate.ge.graphics.Dimension) HashMap(java.util.HashMap) LayoutMapping(org.eclipse.elk.core.service.LayoutMapping) ElkNode(org.eclipse.elk.graph.ElkNode) ElkPort(org.eclipse.elk.graph.ElkPort) ArrayList(java.util.ArrayList) Style(org.osate.ge.graphics.Style) DockArea(org.osate.ge.internal.diagram.runtime.DockArea) ElkPadding(org.eclipse.elk.core.math.ElkPadding) Map(java.util.Map) AgeShape(org.osate.ge.graphics.internal.AgeShape) DiagramElementPredicates(org.osate.ge.internal.diagram.runtime.DiagramElementPredicates) HierarchyHandling(org.eclipse.elk.core.options.HierarchyHandling) EnumSet(java.util.EnumSet) PortConstraints(org.eclipse.elk.core.options.PortConstraints) ElkLabel(org.eclipse.elk.graph.ElkLabel) Predicate(java.util.function.Predicate) KVector(org.eclipse.elk.core.math.KVector) Collection(java.util.Collection) Label(org.osate.ge.graphics.internal.Label) SizeOptions(org.eclipse.elk.core.options.SizeOptions) EcoreUtil(org.eclipse.emf.ecore.util.EcoreUtil) SizeConstraint(org.eclipse.elk.core.options.SizeConstraint) Collectors(java.util.stream.Collectors) ElkConnectableShape(org.eclipse.elk.graph.ElkConnectableShape) DiagramElementUtil(org.osate.ge.internal.util.DiagramElementUtil) DockingPosition(org.osate.ge.DockingPosition) Objects(java.util.Objects) AgeDiagram(org.osate.ge.internal.diagram.runtime.AgeDiagram) List(java.util.List) ElkGraphElement(org.eclipse.elk.graph.ElkGraphElement) NodeLabelPlacement(org.eclipse.elk.core.options.NodeLabelPlacement) Direction(org.eclipse.elk.core.options.Direction) Entry(java.util.Map.Entry) Optional(java.util.Optional) ElkEdge(org.eclipse.elk.graph.ElkEdge) AgeConnection(org.osate.ge.graphics.internal.AgeConnection) ElkGraphUtil(org.eclipse.elk.graph.util.ElkGraphUtil) StyleProvider(org.osate.ge.internal.diagram.runtime.styling.StyleProvider) Collections(java.util.Collections) DiagramNode(org.osate.ge.internal.diagram.runtime.DiagramNode) ArrayList(java.util.ArrayList) PortConstraints(org.eclipse.elk.core.options.PortConstraints) DiagramElement(org.osate.ge.internal.diagram.runtime.DiagramElement) NodeLabelPlacement(org.eclipse.elk.core.options.NodeLabelPlacement) ArrayList(java.util.ArrayList) List(java.util.List) PortSide(org.eclipse.elk.core.options.PortSide) ElkPadding(org.eclipse.elk.core.math.ElkPadding)

Example 4 with NodeLabelPlacement

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);
}
Also used : NodeLabelPlacement(org.eclipse.elk.core.options.NodeLabelPlacement) NodeLabelLocation(org.eclipse.elk.alg.common.nodespacing.internal.NodeLabelLocation)

Example 5 with NodeLabelPlacement

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;
}
Also used : BorderNodesOnSide(org.eclipse.sirius.components.diagrams.layout.incremental.BorderNodesOnSide) NodeLabelPlacement(org.eclipse.elk.core.options.NodeLabelPlacement) ElkPadding(org.eclipse.elk.core.math.ElkPadding)

Aggregations

NodeLabelPlacement (org.eclipse.elk.core.options.NodeLabelPlacement)5 ElkPadding (org.eclipse.elk.core.math.ElkPadding)3 ArrayList (java.util.ArrayList)1 Collection (java.util.Collection)1 Collections (java.util.Collections)1 EnumSet (java.util.EnumSet)1 HashMap (java.util.HashMap)1 List (java.util.List)1 Map (java.util.Map)1 Entry (java.util.Map.Entry)1 Objects (java.util.Objects)1 Optional (java.util.Optional)1 Predicate (java.util.function.Predicate)1 Collectors (java.util.stream.Collectors)1 NodeLabelLocation (org.eclipse.elk.alg.common.nodespacing.internal.NodeLabelLocation)1 KVector (org.eclipse.elk.core.math.KVector)1 CoreOptions (org.eclipse.elk.core.options.CoreOptions)1 Direction (org.eclipse.elk.core.options.Direction)1 HierarchyHandling (org.eclipse.elk.core.options.HierarchyHandling)1 PortConstraints (org.eclipse.elk.core.options.PortConstraints)1