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));
}
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);
}
}
}
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);
}
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);
}
}
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);
}
}
Aggregations