use of org.eclipse.elk.alg.layered.graph.LPadding in project elk by eclipse.
the class HierarchicalPortOrthogonalEdgeRouter method setNorthSouthDummyCoordinates.
// /////////////////////////////////////////////////////////////////////////////
// STEP 2: SET NORTH / SOUTH DUMMY COORDINATES
/**
* Set coordinates for northern and southern external port dummy nodes.
*
* @param layeredGraph the layered graph.
* @param northSouthDummies dummy nodes whose position to set.
*/
private void setNorthSouthDummyCoordinates(final LGraph layeredGraph, final List<LNode> northSouthDummies) {
PortConstraints constraints = layeredGraph.getProperty(LayeredOptions.PORT_CONSTRAINTS);
KVector graphSize = layeredGraph.getSize();
LPadding graphPadding = layeredGraph.getPadding();
double graphWidth = graphSize.x + graphPadding.left + graphPadding.right;
double northY = 0 - graphPadding.top - layeredGraph.getOffset().y;
double southY = graphSize.y + graphPadding.top + graphPadding.bottom - layeredGraph.getOffset().y;
// Lists of northern and southern external port dummies
List<LNode> northernDummies = Lists.newArrayList();
List<LNode> southernDummies = Lists.newArrayList();
for (LNode dummy : northSouthDummies) {
// Set x coordinate
switch(constraints) {
case FREE:
case FIXED_SIDE:
case FIXED_ORDER:
calculateNorthSouthDummyPositions(dummy);
break;
case FIXED_RATIO:
applyNorthSouthDummyRatio(dummy, graphWidth);
dummy.borderToContentAreaCoordinates(true, false);
break;
case FIXED_POS:
applyNorthSouthDummyPosition(dummy);
dummy.borderToContentAreaCoordinates(true, false);
// Ensure that the graph is wide enough to hold the port
graphSize.x = Math.max(graphSize.x, dummy.getPosition().x + dummy.getSize().x / 2.0);
break;
}
// Set y coordinates and add the dummy to its respective list
switch(dummy.getProperty(InternalProperties.EXT_PORT_SIDE)) {
case NORTH:
dummy.getPosition().y = northY;
northernDummies.add((dummy));
break;
case SOUTH:
dummy.getPosition().y = southY;
southernDummies.add(dummy);
break;
}
}
// have been put on top of one another
switch(constraints) {
case FREE:
case FIXED_SIDE:
ensureUniquePositions(northernDummies, layeredGraph);
ensureUniquePositions(southernDummies, layeredGraph);
break;
case FIXED_ORDER:
restoreProperOrder(northernDummies, layeredGraph);
restoreProperOrder(southernDummies, layeredGraph);
break;
}
}
use of org.eclipse.elk.alg.layered.graph.LPadding in project elk by eclipse.
the class HierarchicalPortOrthogonalEdgeRouter method fixCoordinates.
/**
* Fixes the coordinates of the nodes in the given layer.
*
* @param layer the layer.
* @param constraints external port constraints.
* @param graph the graph.
*/
private void fixCoordinates(final Layer layer, final PortConstraints constraints, final LGraph graph) {
// Get some geometric values from the graph
LPadding padding = graph.getPadding();
KVector offset = graph.getOffset();
KVector graphActualSize = graph.getActualSize();
double newActualGraphHeight = graphActualSize.y;
// of the graph, so we're setting y coordinates of NORTH and SOUTH dummies in a second iteration
for (LNode node : layer) {
if (node.getType() != NodeType.EXTERNAL_PORT) {
// We're only looking for hierarchical port dummies
continue;
}
PortSide extPortSide = node.getProperty(InternalProperties.EXT_PORT_SIDE);
KVector extPortSize = node.getProperty(InternalProperties.EXT_PORT_SIZE);
KVector nodePosition = node.getPosition();
// Set x coordinate
switch(extPortSide) {
case EAST:
nodePosition.x = graph.getSize().x + padding.right - offset.x;
break;
case WEST:
nodePosition.x = -offset.x - padding.left;
break;
}
// Set y coordinate
double requiredActualGraphHeight = 0.0;
switch(extPortSide) {
case EAST:
case WEST:
if (constraints == PortConstraints.FIXED_RATIO) {
double ratio = node.getProperty(InternalProperties.PORT_RATIO_OR_POSITION);
nodePosition.y = graphActualSize.y * ratio - node.getProperty(LayeredOptions.PORT_ANCHOR).y;
requiredActualGraphHeight = nodePosition.y + extPortSize.y;
node.borderToContentAreaCoordinates(false, true);
} else if (constraints == PortConstraints.FIXED_POS) {
nodePosition.y = node.getProperty(InternalProperties.PORT_RATIO_OR_POSITION) - node.getProperty(LayeredOptions.PORT_ANCHOR).y;
requiredActualGraphHeight = nodePosition.y + extPortSize.y;
node.borderToContentAreaCoordinates(false, true);
}
break;
}
newActualGraphHeight = Math.max(newActualGraphHeight, requiredActualGraphHeight);
}
// Make the graph larger, if necessary
graph.getSize().y += newActualGraphHeight - graphActualSize.y;
// Iterate over NORTH and SOUTH dummies now that the graph's height is fixed
for (LNode node : layer) {
if (node.getType() != NodeType.EXTERNAL_PORT) {
// We're only looking for hierarchical port dummies
continue;
}
PortSide extPortSide = node.getProperty(InternalProperties.EXT_PORT_SIDE);
KVector nodePosition = node.getPosition();
// Set y coordinate
switch(extPortSide) {
case NORTH:
nodePosition.y = -offset.y - padding.top;
break;
case SOUTH:
nodePosition.y = graph.getSize().y + padding.bottom - offset.y;
break;
}
}
}
use of org.eclipse.elk.alg.layered.graph.LPadding in project elk by eclipse.
the class HierarchicalNodeResizingProcessor method resizeGraphNoReallyIMeanIt.
/**
* Applies a new effective size to a graph that previously had an old size calculated by the layout algorithm. This
* method takes care of adjusting content alignments as well as external ports that would be misplaced if the new
* size is larger than the old one.
*
* @param lgraph
* the graph to apply the size to.
* @param oldSize
* old size as calculated by the layout algorithm.
* @param newSize
* new size that may be larger than the old one.
*/
private void resizeGraphNoReallyIMeanIt(final LGraph lgraph, final KVector oldSize, final KVector newSize) {
// obey to specified alignment constraints
Set<ContentAlignment> contentAlignment = lgraph.getProperty(LayeredOptions.CONTENT_ALIGNMENT);
// horizontal alignment
if (newSize.x > oldSize.x) {
if (contentAlignment.contains(ContentAlignment.H_CENTER)) {
lgraph.getOffset().x += (newSize.x - oldSize.x) / 2f;
} else if (contentAlignment.contains(ContentAlignment.H_RIGHT)) {
lgraph.getOffset().x += newSize.x - oldSize.x;
}
}
// vertical alignment
if (newSize.y > oldSize.y) {
if (contentAlignment.contains(ContentAlignment.V_CENTER)) {
lgraph.getOffset().y += (newSize.y - oldSize.y) / 2f;
} else if (contentAlignment.contains(ContentAlignment.V_BOTTOM)) {
lgraph.getOffset().y += newSize.y - oldSize.y;
}
}
// correct the position of eastern and southern hierarchical ports, if necessary
if (lgraph.getProperty(InternalProperties.GRAPH_PROPERTIES).contains(GraphProperties.EXTERNAL_PORTS) && (newSize.x > oldSize.x || newSize.y > oldSize.y)) {
// (at this point, the graph's nodes are not divided into layers anymore)
for (LNode node : lgraph.getLayerlessNodes()) {
// we're only looking for external port dummies
if (node.getType() == NodeType.EXTERNAL_PORT) {
// check which side the external port is on
PortSide extPortSide = node.getProperty(InternalProperties.EXT_PORT_SIDE);
if (extPortSide == PortSide.EAST) {
node.getPosition().x += newSize.x - oldSize.x;
} else if (extPortSide == PortSide.SOUTH) {
node.getPosition().y += newSize.y - oldSize.y;
}
}
}
}
// Actually apply the new size
LPadding padding = lgraph.getPadding();
lgraph.getSize().x = newSize.x - padding.left - padding.right;
lgraph.getSize().y = newSize.y - padding.top - padding.bottom;
}
use of org.eclipse.elk.alg.layered.graph.LPadding 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.alg.layered.graph.LPadding in project elk by eclipse.
the class ElkGraphImporter method createLGraph.
// /////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Graph Transformation
/**
* Create an LGraph from the given node.
*
* @param elkgraph
* the parent node from which to create the LGraph
* @return a new LGraph instance
*/
private LGraph createLGraph(final ElkNode elkgraph) {
LGraph lgraph = new LGraph();
// Copy the properties of the KGraph to the layered graph
lgraph.copyProperties(elkgraph);
if (lgraph.getProperty(LayeredOptions.DIRECTION) == Direction.UNDEFINED) {
lgraph.setProperty(LayeredOptions.DIRECTION, LGraphUtil.getDirection(lgraph));
}
// The root may have a label manager installed
if (lgraph.getProperty(LabelManagementOptions.LABEL_MANAGER) == null) {
ElkGraphElement root = (ElkGraphElement) EcoreUtil.getRootContainer(elkgraph);
lgraph.setProperty(LabelManagementOptions.LABEL_MANAGER, root.getProperty(LabelManagementOptions.LABEL_MANAGER));
}
// Remember the KGraph parent the LGraph was created from
lgraph.setProperty(InternalProperties.ORIGIN, elkgraph);
// Initialize the graph properties discovered during the transformations
lgraph.setProperty(InternalProperties.GRAPH_PROPERTIES, EnumSet.noneOf(GraphProperties.class));
// Adjust the padding to respect inside labels (if the graph has a parent, we need to supply that as well
// since size information stored there may apply to the current graph node)
ElkPadding nodeLabelpadding = NodeLabelAndSizeCalculator.computeInsideNodeLabelPadding(elkgraph.getParent() == null ? null : ElkGraphAdapters.adapt(elkgraph.getParent()), ElkGraphAdapters.adaptSingleNode(elkgraph), Direction.RIGHT);
ElkPadding nodePadding = lgraph.getProperty(LayeredOptions.PADDING);
// Setup the graph's padding
LPadding lPadding = lgraph.getPadding();
lPadding.add(nodePadding);
lPadding.add(nodeLabelpadding);
return lgraph;
}
Aggregations