Skip to content

Commit 1ccfbb1

Browse files
authored
fix incorrect node size calculation in topdown fallback case (#1152)
* fix incorrect node size calculation in topdown fallback case * Extend topdown test for node dimension calculation Check that calculated node dimensions correctly include padding in the fallback case of topdown layout where no approximator is set. * organize imports
1 parent 6ce0e12 commit 1ccfbb1

File tree

2 files changed

+50
-5
lines changed

2 files changed

+50
-5
lines changed

plugins/org.eclipse.elk.core/src/org/eclipse/elk/core/RecursiveGraphLayoutEngine.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,7 @@ protected List<ElkEdge> layoutRecursively(final ElkNode layoutNode, final TestCo
235235
// provider if yes its size needs to be pre-computed before computing the layout
236236
LayoutAlgorithmData localAlgorithmData =
237237
childNode.getProperty(CoreOptions.RESOLVED_ALGORITHM);
238+
ElkPadding padding = childNode.getProperty(CoreOptions.PADDING);
238239
if (childNode.getChildren().size() > 0
239240
&& localAlgorithmData.getInstancePool().fetch() instanceof ITopdownLayoutProvider) {
240241
// topdownlayout providers should not be used on hierarchical nodes
@@ -254,18 +255,17 @@ protected List<ElkEdge> layoutRecursively(final ElkNode layoutNode, final TestCo
254255
ITopdownSizeApproximator approximator =
255256
childNode.getProperty(CoreOptions.TOPDOWN_SIZE_APPROXIMATOR);
256257
KVector size = approximator.getSize(childNode);
257-
ElkPadding padding = childNode.getProperty(CoreOptions.PADDING);
258258
childNode.setDimensions(Math.max(childNode.getWidth(), size.x + padding.left + padding.right),
259259
Math.max(childNode.getHeight(), size.y + padding.top + padding.bottom));
260260
} else {
261261
// If no approximator is set, use the set sizes for atomic nodes and use the properties
262262
// that have been set for nodes containing further children
263263
if (childNode.getChildren().size() != 0) {
264-
childNode.setDimensions(
265-
childNode.getProperty(CoreOptions.TOPDOWN_HIERARCHICAL_NODE_WIDTH),
264+
KVector size = new KVector(childNode.getProperty(CoreOptions.TOPDOWN_HIERARCHICAL_NODE_WIDTH),
266265
childNode.getProperty(CoreOptions.TOPDOWN_HIERARCHICAL_NODE_WIDTH) /
267-
childNode.getProperty(CoreOptions.TOPDOWN_HIERARCHICAL_NODE_ASPECT_RATIO)
268-
);
266+
childNode.getProperty(CoreOptions.TOPDOWN_HIERARCHICAL_NODE_ASPECT_RATIO));
267+
childNode.setDimensions(Math.max(childNode.getWidth(), size.x + padding.left + padding.right),
268+
Math.max(childNode.getHeight(), size.y + padding.top + padding.bottom));
269269
}
270270
}
271271
}

test/org.eclipse.elk.alg.topdown.test/src/org/eclipse/elk/alg/topdown/test/TopdownLayoutTest.java

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,4 +248,49 @@ public void testScaleCapBounded() {
248248
// topdown scale factor of toplevel node
249249
assertEquals(3.0, toplevel.getProperty(CoreOptions.TOPDOWN_SCALE_FACTOR), 0.00001);
250250
}
251+
252+
/**
253+
* Tests that paddings are correctly considered when computing the size of nodes with further children.
254+
*/
255+
@Test
256+
public void testChildDimensionCalculation() {
257+
PlainJavaInitialization.initializePlainJavaLayout();
258+
ElkNode graph = ElkGraphUtil.createGraph();
259+
graph.setProperty(CoreOptions.TOPDOWN_LAYOUT, true);
260+
graph.setProperty(CoreOptions.TOPDOWN_NODE_TYPE, TopdownNodeTypes.ROOT_NODE);
261+
262+
ElkNode toplevel = ElkGraphUtil.createNode(graph);
263+
toplevel.setProperty(CoreOptions.TOPDOWN_LAYOUT, true);
264+
toplevel.setProperty(CoreOptions.TOPDOWN_NODE_TYPE, TopdownNodeTypes.HIERARCHICAL_NODE);
265+
toplevel.setProperty(CoreOptions.NODE_SIZE_FIXED_GRAPH_SIZE, true);
266+
toplevel.setProperty(CoreOptions.ALGORITHM, "org.eclipse.elk.layered");
267+
toplevel.setProperty(CoreOptions.TOPDOWN_HIERARCHICAL_NODE_WIDTH, 20.0);
268+
toplevel.setProperty(CoreOptions.TOPDOWN_HIERARCHICAL_NODE_ASPECT_RATIO, 1.0);
269+
ElkPadding padding = new ElkPadding(10);
270+
toplevel.setProperty(CoreOptions.PADDING, padding);
271+
272+
ElkNode child1 = ElkGraphUtil.createNode(toplevel);
273+
child1.setProperty(CoreOptions.TOPDOWN_LAYOUT, true);
274+
child1.setProperty(CoreOptions.TOPDOWN_NODE_TYPE, TopdownNodeTypes.HIERARCHICAL_NODE);
275+
child1.setProperty(CoreOptions.NODE_SIZE_FIXED_GRAPH_SIZE, true);
276+
child1.setX(0);
277+
child1.setY(0);
278+
child1.setProperty(CoreOptions.TOPDOWN_HIERARCHICAL_NODE_WIDTH, 20.0);
279+
child1.setProperty(CoreOptions.TOPDOWN_HIERARCHICAL_NODE_ASPECT_RATIO, 1.0);
280+
281+
282+
// prepare layout engine
283+
LayoutConfigurator config = new LayoutConfigurator();
284+
ElkUtil.applyVisitors(graph, config, new LayoutAlgorithmResolver());
285+
// call layout with layout engine
286+
try {
287+
new RecursiveGraphLayoutEngine().layout(graph, new BasicProgressMonitor());
288+
} catch (UnsupportedGraphException exception) {
289+
fail(exception.toString());
290+
}
291+
292+
// child dimensions computed in fallback case depend on the paddings and the "topdown size"
293+
assertEquals(20.0 + padding.getHorizontal(), toplevel.getWidth(), 0.00001);
294+
assertEquals(20.0 + padding.getVertical(), toplevel.getHeight(), 0.00001);
295+
}
251296
}

0 commit comments

Comments
 (0)