Search in sources :

Example 56 with ElkLabel

use of org.eclipse.elk.graph.ElkLabel in project elk by eclipse.

the class Issue682Test method test.

@Test
public void test() {
    Triple<ElkNode, ElkNode, ElkLabel> uut = testGraph();
    new RecursiveGraphLayoutEngine().layout(uut.getFirst(), new NullElkProgressMonitor());
    // Label position
    ElkLabel label = uut.getThird();
    assertThat(label.getX(), closeTo(54.0, EPSILON));
    assertThat(label.getY(), closeTo(21.0, EPSILON));
    // Node dimension
    assertThat(uut.getSecond().getWidth(), closeTo(label.getX() + label.getWidth() + 32, EPSILON));
// TODO the following line fails, it looks like the label's height is applied twice.
// assertThat(uut.getSecond().getHeight(), closeTo(label.getY() + label.getHeight() + 43, EPSILON));
}
Also used : NullElkProgressMonitor(org.eclipse.elk.core.util.NullElkProgressMonitor) ElkNode(org.eclipse.elk.graph.ElkNode) ElkLabel(org.eclipse.elk.graph.ElkLabel) RecursiveGraphLayoutEngine(org.eclipse.elk.core.RecursiveGraphLayoutEngine) Test(org.junit.Test)

Example 57 with ElkLabel

use of org.eclipse.elk.graph.ElkLabel in project elk by eclipse.

the class Issue701Test method assertNodeHeightAccordingToPortHeight.

/**
 * Ensure:
 * <UL>
 * <LI>that the height of the node is as expected according to the port height,</LI>
 * <LI>that the node label location is as expected.</LI>
 * </UL>
 *
 * @param node
 *            the node to check
 * @param port
 *            the port to use
 * @param oppositePort
 *            Optional port on the opposite side, can be null
 * @param eastOrWestSide
 *            true if the port is on EAST or WEST side, false otherwise
 */
private void assertNodeHeightAccordingToPortHeight(ElkNode node, ElkPort port, ElkPort oppositePort, boolean eastOrWestSide) {
    double portLabelHeight = ElkUtil.getLabelsBounds(ElkGraphAdapters.adaptSinglePort(port)).height;
    double oppositePortLabelHeight = oppositePort == null ? 0 : ElkUtil.getLabelsBounds(ElkGraphAdapters.adaptSinglePort(oppositePort)).height;
    double oppositePortHeight = oppositePort == null ? 0 : oppositePort.getHeight();
    ElkPadding nodePadding = node.getProperty(CoreOptions.PADDING);
    ElkLabel nodeLabel = node.getLabels().get(0);
    ElkPadding nodeLabelPadding = node.getProperty(CoreOptions.NODE_LABELS_PADDING);
    double spacingBetweenPort = IndividualSpacings.getIndividualOrInherited(node, CoreOptions.SPACING_PORT_PORT);
    if (eastOrWestSide) {
        // Check node height according to port height (the max of label or port)
        // The spacing between port has added on each side in
        // org.eclipse.elk.alg.common.nodespacing.internal.algorithm.VerticalPortPlacementSizeCalculator.calculateVerticalNodeSizeRequiredByFreePorts(NodeContext,
        // PortSide)
        double portHeightPlusPadding = Math.max(spacingBetweenPort + portLabelHeight + spacingBetweenPort, Math.max(spacingBetweenPort, nodePadding.getTop()) + port.getHeight() + Math.max(spacingBetweenPort, nodePadding.getBottom()));
        double oppositePortHeightPlusPadding = Math.max(spacingBetweenPort + oppositePortLabelHeight + spacingBetweenPort, Math.max(spacingBetweenPort, nodePadding.getTop()) + oppositePortHeight + Math.max(spacingBetweenPort, nodePadding.getBottom()));
        assertEquals("Wrong node height according to port label height.", Math.max(portHeightPlusPadding, oppositePortHeightPlusPadding), node.getHeight(), 0);
        assertEquals("Wrong node label location.", ElkUtil.absolutePosition(node).y + nodeLabelPadding.getTop(), ElkUtil.absolutePosition(nodeLabel).y, 0);
    } else {
        double spacingLabelPort = port.getProperty(CoreOptions.SPACING_LABEL_PORT);
        double spacingLabelOppositePort = oppositePort == null ? 0 : oppositePort.getProperty(CoreOptions.SPACING_LABEL_PORT);
        double portBorderOffset = port.getProperty(CoreOptions.PORT_BORDER_OFFSET);
        double oppositePortBorderOffset = oppositePort == null ? 0 : oppositePort.getProperty(CoreOptions.PORT_BORDER_OFFSET);
        double expectedHeight = -portBorderOffset;
        expectedHeight += -oppositePortBorderOffset;
        // the label size is added twice for the symmetry
        expectedHeight += Math.max((spacingLabelPort + portLabelHeight), (spacingLabelOppositePort + oppositePortLabelHeight)) * 2;
        expectedHeight += nodeLabelPadding.getTop();
        // A free space equals to the node label height is kept.
        expectedHeight += nodeLabel.getHeight() * 2;
        expectedHeight += nodeLabelPadding.getBottom();
        assertEquals("Wrong node height according to port label height.", expectedHeight, node.getHeight(), 0);
        PortSide portSide = port.getProperty(LayeredOptions.PORT_SIDE);
        if (portSide == PortSide.NORTH) {
            // The port is on the north side, the node label is just under the port label
            assertEquals("Wrong node label location.", ElkUtil.absolutePosition(port.getLabels().get(0)).y + portLabelHeight + nodeLabelPadding.getTop(), ElkUtil.absolutePosition(nodeLabel).y, 0);
        } else if (portSide == PortSide.SOUTH) {
            // The port is on the south side, for symmetry a space is let above node label (same as port label)
            assertEquals("Wrong node label location.", ElkUtil.absolutePosition(node).y + portLabelHeight + port.getProperty(CoreOptions.SPACING_LABEL_PORT) + nodeLabelPadding.getTop(), ElkUtil.absolutePosition(nodeLabel).y, 0);
        }
    }
}
Also used : ElkLabel(org.eclipse.elk.graph.ElkLabel) PortSide(org.eclipse.elk.core.options.PortSide) ElkPadding(org.eclipse.elk.core.math.ElkPadding)

Example 58 with ElkLabel

use of org.eclipse.elk.graph.ElkLabel in project elk by eclipse.

the class Issue701Test method testFixedMixInsideAndOutsideLabels.

/**
 * Check behavior for port labels that is fixed, empty {@link PortLabelPlacement) property, located inside or
 * outside the node, with more complex cases that {@link #testFixedInsideLabels(ElkNode)} and
 * {@link #testFixedOutsideLabels(ElkNode)}.
 */
@Test
public void testFixedMixInsideAndOutsideLabels(final ElkNode graph) {
    ElkNode containerForMixInsideOutsideLabels = GraphTestUtils.getChild(graph, "ContainerWithFixedLabels", "Container_SeveralBorderNodes_LabelFixedPartiallyInside");
    // Ensure there is no label overlaps
    if (GraphTestUtils.haveOverlaps(assembleLabels(containerForMixInsideOutsideLabels))) {
        fail("Overlaps between labels detected in \"Container_SeveralBorderNodes_LabelFixedPartiallyInside\"!");
    }
    // Ports on north and on south sides
    ElkNode node1 = GraphTestUtils.getChild(containerForMixInsideOutsideLabels, "MyNode1");
    ElkPort node1Port1 = GraphTestUtils.getPort(node1, "P1");
    ElkPort node1Port2 = GraphTestUtils.getPort(node1, "P2");
    assertNodeWidthAccordingToPortWidth(node1, node1Port1, node1Port2, false);
    // TODO: Probably a bug here (not same result as INSIDE): 12 pixels of difference; padding?
    // assertNodeHeightAccordingToPortHeight(node1, node1Port1, node1Port2, false);
    // Ports on east and on west sides
    ElkNode node2 = GraphTestUtils.getChild(containerForMixInsideOutsideLabels, "MyNode2");
    ElkPort node2Port1 = GraphTestUtils.getPort(node2, "P1");
    ElkPort node2Port2 = GraphTestUtils.getPort(node2, "P2");
    // TODO: Probably a bug here (not same result as INSIDE): 8 pixels of difference; port border offset?
    // assertNodeWidthAccordingToPortWidth(node2, node2Port1, node2Port2, true);
    assertNodeHeightAccordingToPortHeight(node2, node2Port1, node2Port2, true);
    // TODO: Specific case with label centered under the port
    // Ports on east and on west sides with label centered under the port
    ElkNode node2Bis = GraphTestUtils.getChild(containerForMixInsideOutsideLabels, "MyNode2Bis");
    ElkPort node2BisPort1 = GraphTestUtils.getPort(node2, "P1");
    ElkPort node2BisPort2 = GraphTestUtils.getPort(node2, "P2");
    // assertNodeWidthAccordingToPortWidth(node2Bis, node2BisPort1, node2BisPort2, true);
    // assertNodeHeightAccordingToPortHeight(node2, node2BisPort1, node2BisPort2, true);
    // Ports on east and on west sides with a node inside the container without edge
    // TODO: Ignored. The behavior seems KO. Maybe to review for https://github.com/eclipse/elk/issues/638.
    // ElkNode cont2 = GraphTestUtils.getChild(containerForMixInsideOutsideLabels, "MyCont2");
    // Ports on east and on west sides with a node inside the container and linked to the ports, check width of the
    // container
    ElkNode cont3 = GraphTestUtils.getChild(containerForMixInsideOutsideLabels, "MyCont3");
    ElkNode cont3Node2 = GraphTestUtils.getChild(cont3, "MyNode2");
    ElkPort cont3Port1 = GraphTestUtils.getPort(cont3, "P1");
    ElkLabel cont3Port1Label = cont3Port1.getLabels().get(0);
    ElkPort cont3Port2 = GraphTestUtils.getPort(cont3, "P2");
    ElkLabel cont3Port2Label = cont3Port2.getLabels().get(0);
    double spacingLabelCont3Port1 = cont3Port1.getProperty(CoreOptions.SPACING_LABEL_PORT);
    double spacingLabelCont3Port2 = cont3Port2.getProperty(CoreOptions.SPACING_LABEL_PORT);
    double cont3Port1BorderOffset = cont3Port1.getProperty(CoreOptions.PORT_BORDER_OFFSET);
    double cont3Port2BorderOffset = cont3Port2.getProperty(CoreOptions.PORT_BORDER_OFFSET);
    ElkPadding cont3Padding = cont3.getProperty(CoreOptions.PADDING);
    // Compute expected width
    double expectedCont3Width = cont3Padding.getLeft();
    expectedCont3Width -= 8;
    expectedCont3Width += cont3Node2.getWidth();
    expectedCont3Width += -cont3Port2BorderOffset;
    expectedCont3Width += spacingLabelCont3Port2;
    expectedCont3Width += cont3Port2Label.getWidth();
    expectedCont3Width += cont3Port1Label.getWidth();
    expectedCont3Width += spacingLabelCont3Port1;
    expectedCont3Width += -cont3Port1BorderOffset;
    expectedCont3Width += cont3Padding.getRight();
    // TODO: Test to review as the labels are centered under the ports (constant 248 is used instead of above
    // computation)
    expectedCont3Width = 248;
    assertEquals("Wrong node width according to ports label width.", expectedCont3Width, cont3.getWidth(), 0);
    // Port on east side on a node in container, port on west side of the container, and with edge between ports,
    // check width of the container
    ElkNode cont4 = GraphTestUtils.getChild(containerForMixInsideOutsideLabels, "MyCont4");
    ElkNode cont4Node1 = GraphTestUtils.getChild(cont4, "MyNode1");
    ElkPort cont4Node1Port1 = GraphTestUtils.getPort(cont4Node1, "P1");
    ElkLabel cont4Node1Port1Label = cont4Node1Port1.getLabels().get(0);
    ElkPort cont4Port1 = GraphTestUtils.getPort(cont4, "P1");
    ElkLabel cont4Port1Label = cont4Port1.getLabels().get(0);
    double spacingLabelCont4Node1Port1 = cont4Node1Port1.getProperty(CoreOptions.SPACING_LABEL_PORT);
    double spacingLabelCont4Port1 = cont4Port1.getProperty(CoreOptions.SPACING_LABEL_PORT);
    double cont4Node1Port1BorderOffset = cont4Node1Port1.getProperty(CoreOptions.PORT_BORDER_OFFSET);
    double cont4Port1BorderOffset = cont4Port1.getProperty(CoreOptions.PORT_BORDER_OFFSET);
    ElkPadding cont4Padding = cont4.getProperty(CoreOptions.PADDING);
    // Compute expected width
    double expectedCont4Width = cont4Padding.getLeft();
    expectedCont4Width += cont4Node1.getWidth();
    // TODO: ElkUtil.calcPortOffset(cont4Node1Port1, PortSide.EAST); is supposed to do the same computing as below
    // but it is not the case
    expectedCont4Width += cont4Node1Port1.getWidth() + cont4Node1Port1BorderOffset;
    expectedCont4Width += spacingLabelCont4Node1Port1;
    expectedCont4Width += cont4Node1Port1Label.getWidth();
    expectedCont4Width += cont4Port1Label.getWidth();
    expectedCont4Width += spacingLabelCont4Port1;
    expectedCont4Width += -cont4Port1BorderOffset;
    expectedCont4Width += cont4Padding.getRight();
    // TODO: Test to review as the labels are centered under the ports (constant 312.5 is used instead of above
    // computation)
    expectedCont4Width = 312.5;
    assertEquals("Wrong node width according to ports label width.", expectedCont4Width, cont4.getWidth(), 0);
}
Also used : ElkNode(org.eclipse.elk.graph.ElkNode) ElkLabel(org.eclipse.elk.graph.ElkLabel) ElkPort(org.eclipse.elk.graph.ElkPort) ElkPadding(org.eclipse.elk.core.math.ElkPadding) Test(org.junit.Test)

Example 59 with ElkLabel

use of org.eclipse.elk.graph.ElkLabel in project elk by eclipse.

the class Issue701Test method assertNodeWidthAccordingToPortWidth.

/**
 * Ensure that the width of the node is as expected according to the port width.
 *
 * @param node
 *            the node to check
 * @param port
 *            the port to use
 * @param oppositePort
 *            Optional port on the opposite side, can be null
 * @param eastOrWestSide
 *            true if the port is on EAST or WEST side, false otherwise
 */
private void assertNodeWidthAccordingToPortWidth(ElkNode node, ElkPort port, ElkPort oppositePort, boolean eastOrWestSide) {
    double portLabelWidth = port.getLabels().get(0).getWidth();
    double oppositePortLabelWidth = oppositePort == null ? 0 : oppositePort.getLabels().get(0).getWidth();
    double spacingBetweenPort = IndividualSpacings.getIndividualOrInherited(node, CoreOptions.SPACING_PORT_PORT);
    if (!eastOrWestSide) {
        // Check node width according to port label width
        // The spacing between port has added on each side in
        // org.eclipse.elk.alg.common.nodespacing.internal.algorithm.HorizontalPortPlacementSizeCalculator.calculateHorizontalNodeSizeRequiredByFreePorts(NodeContext,
        // PortSide)
        assertEquals("Wrong node width according to port(s) label width.", spacingBetweenPort + Math.max(portLabelWidth, oppositePortLabelWidth) + spacingBetweenPort, node.getWidth(), 0);
    } else {
        double spacingLabelPort = port.getProperty(CoreOptions.SPACING_LABEL_PORT);
        double spacingLabelOppositePort = oppositePort == null ? 0 : oppositePort.getProperty(CoreOptions.SPACING_LABEL_PORT);
        double portBorderOffset = port.getProperty(CoreOptions.PORT_BORDER_OFFSET);
        double oppositePortBorderOffset = oppositePort == null ? 0 : oppositePort.getProperty(CoreOptions.PORT_BORDER_OFFSET);
        ElkLabel nodeLabel = node.getLabels().get(0);
        ElkPadding nodeLabelPadding = node.getProperty(CoreOptions.NODE_LABELS_PADDING);
        // Compute expected width
        double expectedWidth = nodeLabelPadding.getLeft();
        // the label size is added twice for the symmetry
        expectedWidth += Math.max((spacingLabelPort + portLabelWidth), (spacingLabelOppositePort + oppositePortLabelWidth)) * 2;
        expectedWidth += nodeLabel.getWidth();
        expectedWidth += nodeLabelPadding.getRight();
        expectedWidth += -portBorderOffset;
        expectedWidth += -oppositePortBorderOffset;
        assertEquals("Wrong node width according to port(s) label width.", expectedWidth, node.getWidth(), 0);
    }
}
Also used : ElkLabel(org.eclipse.elk.graph.ElkLabel) ElkPadding(org.eclipse.elk.core.math.ElkPadding)

Example 60 with ElkLabel

use of org.eclipse.elk.graph.ElkLabel in project osate2 by osate.

the class ElkGraphBuilder method createElkGraphElementsForConnections.

/**
 * Creates ELK edges for connection diagram nodes which are descendants of the specified node.
 * Even though the results of the ELK edge routing are not used, it is still important because it affects the placements of shapes.
 */
private void createElkGraphElementsForConnections(final DiagramNode dn, final LayoutMapping mapping) {
    for (final DiagramElement de : dn.getChildren()) {
        if (de.getGraphic() instanceof AgeConnection) {
            final AgeConnection connection = (AgeConnection) de.getGraphic();
            // Flow indicators are represented by a node in the container which has a port and an edge connecting that port to the starting element
            final ElkConnectableShape edgeStart = getConnectableShape(de.getStartElement(), mapping);
            ElkConnectableShape edgeEnd = null;
            if (connection.isFlowIndicator) {
                // Find the first undocked ancestor for the flow indicator
                final DiagramElement undockedContainer = DiagramElementUtil.getUndockedDiagramElement(de.getParent());
                if (undockedContainer == null) {
                    // Ignore the flow indicator if unable to find a containing element which isn't docked.
                    continue;
                }
                // Find the ELK shape for the ancestor
                final ElkConnectableShape endContainer = getConnectableShape(undockedContainer, mapping);
                if (!(endContainer instanceof ElkNode)) {
                    // Ignore the flow indicator if the container isn't a node.
                    continue;
                }
                // Create the node for the end of the flow indicator
                final ElkNode endNode = ElkGraphUtil.createNode((ElkNode) endContainer);
                endContainer.setDimensions(0, 0);
                endNode.setProperty(CoreOptions.NODE_SIZE_CONSTRAINTS, EnumSet.noneOf(SizeConstraint.class));
                endNode.setProperty(CoreOptions.NODE_SIZE_OPTIONS, EnumSet.noneOf(SizeOptions.class));
                // Create port
                final ElkPort endPort = ElkGraphUtil.createPort(endNode);
                endPort.setProperty(CoreOptions.PORT_SIDE, PortSide.WEST);
                endPort.setX(0);
                endPort.setY(0);
                endPort.setWidth(0);
                endPort.setHeight(0);
                edgeEnd = endPort;
            } else {
                edgeEnd = getConnectableShape(de.getEndElement(), mapping);
            }
            if (edgeStart != null && edgeEnd != null) {
                final ElkConnectableShape start = edgeStart;
                final ElkConnectableShape end = edgeEnd;
                boolean insideSelfLoopsYo = true;
                // An example of this sort of edge is a steady state state transition in the EMV2
                if (start == end) {
                    insideSelfLoopsYo = false;
                }
                final ElkEdge newEdge = ElkGraphUtil.createSimpleEdge(start, end);
                // Allow edges with the same start and end shape because they layout as intended.
                if (start == end && start instanceof ElkPort) {
                    continue;
                }
                // Ensure the edge has at least one section. Fixes NPE that can occur when laying out connections
                // with the same source and destination port.
                ElkGraphUtil.createEdgeSection(newEdge);
                newEdge.setProperty(CoreOptions.INSIDE_SELF_LOOPS_YO, insideSelfLoopsYo);
                mapping.getGraphMap().put(newEdge, de);
                createElkLabels(de, newEdge, mapping);
                // along with other edges
                if (connection.isFlowIndicator && newEdge.getLabels().isEmpty()) {
                    final ElkLabel spacingLabel = createElkLabel(newEdge, "<Spacing>", new Dimension(10, 10));
                    if (!layoutConnectionLabels) {
                        spacingLabel.setProperty(CoreOptions.NO_LAYOUT, true);
                    }
                }
            }
        }
        createElkGraphElementsForConnections(de, mapping);
    }
}
Also used : DiagramElement(org.osate.ge.internal.diagram.runtime.DiagramElement) AgeConnection(org.osate.ge.graphics.internal.AgeConnection) ElkNode(org.eclipse.elk.graph.ElkNode) SizeOptions(org.eclipse.elk.core.options.SizeOptions) ElkLabel(org.eclipse.elk.graph.ElkLabel) ElkPort(org.eclipse.elk.graph.ElkPort) Dimension(org.osate.ge.graphics.Dimension) ElkConnectableShape(org.eclipse.elk.graph.ElkConnectableShape) SizeConstraint(org.eclipse.elk.core.options.SizeConstraint) ElkEdge(org.eclipse.elk.graph.ElkEdge)

Aggregations

ElkLabel (org.eclipse.elk.graph.ElkLabel)64 ElkNode (org.eclipse.elk.graph.ElkNode)33 KVector (org.eclipse.elk.core.math.KVector)25 ElkPort (org.eclipse.elk.graph.ElkPort)23 ElkEdge (org.eclipse.elk.graph.ElkEdge)20 ElkEdgeSection (org.eclipse.elk.graph.ElkEdgeSection)14 KVectorChain (org.eclipse.elk.core.math.KVectorChain)12 ElkPadding (org.eclipse.elk.core.math.ElkPadding)10 ElkGraphElement (org.eclipse.elk.graph.ElkGraphElement)9 SizeConstraint (org.eclipse.elk.core.options.SizeConstraint)7 PortSide (org.eclipse.elk.core.options.PortSide)6 List (java.util.List)5 LLabel (org.eclipse.elk.alg.layered.graph.LLabel)5 LPort (org.eclipse.elk.alg.layered.graph.LPort)5 ElkBendPoint (org.eclipse.elk.graph.ElkBendPoint)5 ElkConnectableShape (org.eclipse.elk.graph.ElkConnectableShape)5 Test (org.junit.Test)5 Lists (com.google.common.collect.Lists)4 Rectangle (org.eclipse.draw2d.geometry.Rectangle)4 DCElement (org.eclipse.elk.alg.disco.graph.DCElement)4