use of org.eclipse.elk.core.math.ElkPadding in project elk by eclipse.
the class ElkGraphLayoutTransferrer method applyLayout.
/**
* Applies the layout information contained in the given LGraph to the ElkGraph elements it was
* created from. All source ElkGraph elements are expected to be accessible through their LGraph
* counterparts through the {@link InternalProperties#ORIGIN} property.
*
* @param lgraph the LGraph whose layout information to apply.
*/
public void applyLayout(final LGraph lgraph) {
Object graphOrigin = lgraph.getProperty(InternalProperties.ORIGIN);
if (!(graphOrigin instanceof ElkNode)) {
return;
}
// The ElkNode that represents this graph in the original ElkGraph
ElkNode parentElkNode = (ElkNode) graphOrigin;
// The LNode that represents this graph in the upper hierarchy level, if any
LNode parentLNode = (LNode) lgraph.getParentNode();
// Get the offset to be added to all coordinates
KVector offset = new KVector(lgraph.getOffset());
// Adjust offset (and with it the positions) by the requested padding
LPadding lPadding = lgraph.getPadding();
offset.x += lPadding.left;
offset.y += lPadding.top;
// Set node padding, if it was computed during layout
final EnumSet<SizeOptions> sizeOptions = parentElkNode.getProperty(LayeredOptions.NODE_SIZE_OPTIONS);
if (sizeOptions.contains(SizeOptions.COMPUTE_PADDING)) {
ElkPadding padding = parentElkNode.getProperty(LayeredOptions.PADDING);
padding.setBottom(lPadding.bottom);
padding.setTop(lPadding.top);
padding.setLeft(lPadding.left);
padding.setRight(lPadding.right);
}
// Along the way, we collect the list of edges to be processed later
List<LEdge> edgeList = Lists.newArrayList();
// Process the nodes
for (LNode lnode : lgraph.getLayerlessNodes()) {
if (representsNode(lnode)) {
applyNodeLayout(lnode, offset);
} else if (representsExternalPort(lnode) && parentLNode == null) {
// We have an external port here on the top-most hierarchy level of the current (possibly
// hierarchical) layout run; set its position
ElkPort elkport = (ElkPort) lnode.getProperty(InternalProperties.ORIGIN);
KVector portPosition = LGraphUtil.getExternalPortPosition(lgraph, lnode, elkport.getWidth(), elkport.getHeight());
elkport.setLocation(portPosition.x, portPosition.y);
}
// correctly)
for (LPort port : lnode.getPorts()) {
port.getOutgoingEdges().stream().filter(edge -> !LGraphUtil.isDescendant(edge.getTarget().getNode(), lnode)).forEach(edge -> edgeList.add(edge));
}
}
// Collect edges that go from the current graph's representing LNode down into its descendants
if (parentLNode != null) {
for (LPort port : parentLNode.getPorts()) {
port.getOutgoingEdges().stream().filter(edge -> LGraphUtil.isDescendant(edge.getTarget().getNode(), parentLNode)).forEach(edge -> edgeList.add(edge));
}
}
// Iterate through all edges
EdgeRouting routing = parentElkNode.getProperty(LayeredOptions.EDGE_ROUTING);
for (LEdge ledge : edgeList) {
applyEdgeLayout(ledge, routing, offset, lPadding);
}
// Setup the parent node
applyParentNodeLayout(lgraph);
// Process nested subgraphs
for (LNode lnode : lgraph.getLayerlessNodes()) {
LGraph nestedGraph = lnode.getNestedGraph();
if (nestedGraph != null) {
applyLayout(nestedGraph);
}
}
}
use of org.eclipse.elk.core.math.ElkPadding in project elk by eclipse.
the class ElkGraphImporter method applyLayout.
// /////////////////////////////////////////////////////////////////////////////
// Apply Layout Results
@Override
public void applyLayout(final TGraph tGraph) {
// get the corresponding kGraph
ElkNode elkgraph = (ElkNode) tGraph.getProperty(InternalProperties.ORIGIN);
// calculate the offset from border spacing and node distribution
double minXPos = Integer.MAX_VALUE;
double minYPos = Integer.MAX_VALUE;
double maxXPos = Integer.MIN_VALUE;
double maxYPos = Integer.MIN_VALUE;
for (TNode tNode : tGraph.getNodes()) {
KVector pos = tNode.getPosition();
KVector size = tNode.getSize();
minXPos = Math.min(minXPos, pos.x - size.x / 2);
minYPos = Math.min(minYPos, pos.y - size.y / 2);
maxXPos = Math.max(maxXPos, pos.x + size.x / 2);
maxYPos = Math.max(maxYPos, pos.y + size.y / 2);
}
ElkPadding padding = elkgraph.getProperty(MrTreeOptions.PADDING);
KVector offset = new KVector(padding.getLeft() - minXPos, padding.getTop() - minYPos);
// process the nodes
for (TNode tNode : tGraph.getNodes()) {
Object object = tNode.getProperty(InternalProperties.ORIGIN);
if (object instanceof ElkNode) {
// set the node position
ElkNode elknode = (ElkNode) object;
KVector nodePos = tNode.getPosition().add(offset);
elknode.setLocation(nodePos.x - elknode.getWidth() / 2, nodePos.y - elknode.getHeight() / 2);
}
}
// process the edges
for (TEdge tEdge : tGraph.getEdges()) {
ElkEdge elkedge = (ElkEdge) tEdge.getProperty(InternalProperties.ORIGIN);
if (elkedge != null) {
KVectorChain bendPoints = tEdge.getBendPoints();
// add the source port and target points to the vector chain
KVector sourcePoint = new KVector(tEdge.getSource().getPosition());
bendPoints.addFirst(sourcePoint);
KVector targetPoint = new KVector(tEdge.getTarget().getPosition());
bendPoints.addLast(targetPoint);
// correct the source and target points
toNodeBorder(sourcePoint, bendPoints.get(1), tEdge.getSource().getSize());
toNodeBorder(targetPoint, bendPoints.get(bendPoints.size() - 2), tEdge.getTarget().getSize());
ElkEdgeSection edgeSection = ElkGraphUtil.firstEdgeSection(elkedge, true, true);
ElkUtil.applyVectorChain(bendPoints, edgeSection);
}
}
// set up the graph
double width = maxXPos - minXPos + padding.getHorizontal();
double height = maxYPos - minYPos + padding.getVertical();
ElkUtil.resizeNode(elkgraph, width, height, false, false);
}
use of org.eclipse.elk.core.math.ElkPadding in project elk by eclipse.
the class BoxLayoutProvider method mergeAndPlaceInc.
/**
* In increasing node area order: pick nodes until the next node's half size is larger than
* the current cumulated area. Problematic for certain graphs, where
* the cumulation becomes quite large early.
*/
private List<Group> mergeAndPlaceInc(final List<Group> groups, final double objSpacing, final double minWidth, final double minHeight, final boolean expandNodes, final double aspectRatio) {
// sort increasingly
Collections.sort(groups, (g1, g2) -> Double.compare(g1.area(), g2.area()));
ListIterator<Group> groupIterator = groups.listIterator();
List<Group> toBePlaced = Lists.newArrayList();
double commonArea = 0;
while (groupIterator.hasNext()) {
Group g = groupIterator.next();
if (!toBePlaced.isEmpty() && g.area() > (commonArea * 2)) {
// merge the current set of groups into a common group
Group merged = new Group(toBePlaced);
double innerAspectRatio = g.getWidth() / g.getHeight();
// place the nodes in the group
KVector groupSize = placeInnerBoxes(merged, objSpacing, new ElkPadding(), minWidth, minHeight, expandNodes, innerAspectRatio);
merged.size.reset().add(groupSize);
// reset
toBePlaced.clear();
commonArea = 0;
// add the merged group and the current group to
// the active list
toBePlaced.add(merged);
toBePlaced.add(g);
commonArea = merged.area() + g.area();
} else {
// add the group to the active set
toBePlaced.add(g);
commonArea += g.area();
}
}
return toBePlaced;
}
use of org.eclipse.elk.core.math.ElkPadding in project elk by eclipse.
the class FixedLayoutProvider method layout.
@Override
public void layout(final ElkNode layoutNode, final IElkProgressMonitor progressMonitor) {
progressMonitor.begin("Fixed Layout", 1);
EdgeRouting edgeRouting = layoutNode.getProperty(CoreOptions.EDGE_ROUTING);
double maxx = 0;
double maxy = 0;
for (ElkNode node : layoutNode.getChildren()) {
// set the fixed position of the node, or leave it as it is
KVector pos = node.getProperty(FixedLayouterOptions.POSITION);
if (pos != null) {
node.setLocation(pos.x, pos.y);
// set the fixed size of the node
if (node.getProperty(FixedLayouterOptions.NODE_SIZE_CONSTRAINTS).contains(SizeConstraint.MINIMUM_SIZE)) {
KVector minSize = node.getProperty(FixedLayouterOptions.NODE_SIZE_MINIMUM);
if (minSize.x > 0 && minSize.y > 0) {
ElkUtil.resizeNode(node, minSize.x, minSize.y, true, true);
}
}
}
maxx = Math.max(maxx, node.getX() + node.getWidth());
maxy = Math.max(maxy, node.getY() + node.getHeight());
// set the fixed position of the node labels, or leave them as they are
for (ElkLabel label : node.getLabels()) {
pos = label.getProperty(FixedLayouterOptions.POSITION);
if (pos != null) {
label.setLocation(pos.x, pos.y);
}
maxx = Math.max(maxx, node.getX() + label.getX() + label.getWidth());
maxy = Math.max(maxy, node.getY() + label.getY() + label.getHeight());
}
// set the fixed position of the ports, or leave them as they are
for (ElkPort port : node.getPorts()) {
pos = port.getProperty(FixedLayouterOptions.POSITION);
if (pos != null) {
port.setLocation(pos.x, pos.y);
}
double portx = node.getX() + port.getX();
double porty = node.getY() + port.getY();
maxx = Math.max(maxx, portx + port.getWidth());
maxy = Math.max(maxy, porty + port.getHeight());
// set the fixed position of the port labels, or leave them as they are
for (ElkLabel label : port.getLabels()) {
pos = label.getProperty(FixedLayouterOptions.POSITION);
if (pos != null) {
label.setLocation(pos.x, pos.y);
}
maxx = Math.max(maxx, portx + label.getX() + label.getWidth());
maxy = Math.max(maxy, porty + label.getY() + label.getHeight());
}
}
// set fixed routing for the node's outgoing edges (both simple and hierarchical), or leave them as they are
for (ElkEdge edge : ElkGraphUtil.allOutgoingEdges(node)) {
KVector maxv = processEdge(edge, edgeRouting);
maxx = Math.max(maxx, maxv.x);
maxy = Math.max(maxy, maxv.y);
}
// note that this potentially results in hierarchical edges being handled twice
for (ElkEdge edge : ElkGraphUtil.allIncomingEdges(node)) {
if (ElkGraphUtil.getSourceNode(edge).getParent() != layoutNode) {
KVector maxv = processEdge(edge, edgeRouting);
maxx = Math.max(maxx, maxv.x);
maxy = Math.max(maxy, maxv.y);
}
}
}
// if orthogonal routing is selected, determine the junction points
if (edgeRouting == EdgeRouting.ORTHOGONAL) {
for (ElkNode node : layoutNode.getChildren()) {
for (ElkEdge edge : ElkGraphUtil.allOutgoingEdges(node)) {
generateJunctionPoints(edge);
}
}
}
// set size of the parent node unless its size should be fixed as well
if (!layoutNode.getProperty(FixedLayouterOptions.NODE_SIZE_FIXED_GRAPH_SIZE)) {
ElkPadding padding = layoutNode.getProperty(FixedLayouterOptions.PADDING);
double newWidth = maxx + padding.getLeft() + padding.getRight();
double newHeight = maxy + padding.getTop() + padding.getBottom();
ElkUtil.resizeNode(layoutNode, newWidth, newHeight, true, true);
}
progressMonitor.done();
}
use of org.eclipse.elk.core.math.ElkPadding in project elk by eclipse.
the class RandomLayoutProvider method layout.
@Override
public void layout(final ElkNode parentNode, final IElkProgressMonitor progressMonitor) {
progressMonitor.begin("Random Layout", 1);
if (parentNode.getChildren().isEmpty()) {
progressMonitor.done();
return;
}
// initialize random seed
Random random;
Integer randomSeed = parentNode.getProperty(RandomLayouterOptions.RANDOM_SEED);
if (randomSeed != null && randomSeed != 0) {
random = new Random(randomSeed);
} else {
random = new Random();
}
// retrieve some layout option values
float aspectRatio = parentNode.getProperty(RandomLayouterOptions.ASPECT_RATIO).floatValue();
float spacing = parentNode.getProperty(RandomLayouterOptions.SPACING_NODE_NODE).floatValue();
ElkPadding padding = parentNode.getProperty(RandomLayouterOptions.PADDING);
// randomize the layout
randomize(parentNode, random, aspectRatio, spacing, padding);
progressMonitor.done();
}
Aggregations