use of org.eclipse.elk.core.options.PortConstraints in project elk by eclipse.
the class ComponentsProcessor method split.
/**
* Split the given graph into its connected components.
*
* @param graph an input graph with layerless nodes
* @return a list of components that can be processed one by one
*/
public List<LGraph> split(final LGraph graph) {
List<LGraph> result;
// Default to the simple graph placer
graphPlacer = simpleRowGraphPlacer;
// Whether separate components processing is requested
Boolean separateProperty = graph.getProperty(LayeredOptions.SEPARATE_CONNECTED_COMPONENTS);
boolean separate = separateProperty == null || separateProperty.booleanValue();
// Whether the graph contains external ports
boolean extPorts = graph.getProperty(InternalProperties.GRAPH_PROPERTIES).contains(GraphProperties.EXTERNAL_PORTS);
// The graph's external port constraints
PortConstraints extPortConstraints = graph.getProperty(LayeredOptions.PORT_CONSTRAINTS);
boolean compatiblePortConstraints = !extPortConstraints.isOrderFixed();
// FREE or FIXED_SIDES.
if (separate && (compatiblePortConstraints || !extPorts)) {
// Set id of all nodes to 0
for (LNode node : graph.getLayerlessNodes()) {
node.id = 0;
}
// Perform DFS starting on each node, collecting connected components
result = Lists.newArrayList();
for (LNode node : graph.getLayerlessNodes()) {
Pair<List<LNode>, Set<PortSide>> componentData = dfs(node, null);
if (componentData != null) {
LGraph newGraph = new LGraph();
newGraph.copyProperties(graph);
newGraph.setProperty(InternalProperties.EXT_PORT_CONNECTIONS, componentData.getSecond());
newGraph.getPadding().copy(graph.getPadding());
// If a minimum size was set on the original graph, setting it on the seperated graphs as well
// might enlarge them although their combined area might not actually have fallen below the minimum
// size; thus, remove the minimum size
newGraph.setProperty(LayeredOptions.NODE_SIZE_MINIMUM, null);
for (LNode n : componentData.getFirst()) {
newGraph.getLayerlessNodes().add(n);
n.setGraph(newGraph);
}
result.add(newGraph);
}
}
if (extPorts) {
// With external port connections, we want to use the more complex components
// placement algorithm
graphPlacer = componentGroupGraphPlacer;
}
} else {
result = Arrays.asList(graph);
}
// The component with the node with the smallest order should be first.
if (graph.getProperty(LayeredOptions.CONSIDER_MODEL_ORDER_STRATEGY) != OrderingStrategy.NONE) {
Collections.sort(result, (g1, g2) -> {
int g1Order = Integer.MAX_VALUE;
for (LNode node : g1.getLayerlessNodes()) {
if (node.hasProperty(InternalProperties.MODEL_ORDER)) {
g1Order = Math.min(g1Order, node.getProperty(InternalProperties.MODEL_ORDER));
}
}
int g2Order = Integer.MAX_VALUE;
for (LNode node : g2.getLayerlessNodes()) {
if (node.hasProperty(InternalProperties.MODEL_ORDER)) {
g2Order = Math.min(g2Order, node.getProperty(InternalProperties.MODEL_ORDER));
}
}
return Integer.compare(g1Order, g2Order);
});
}
return result;
}
use of org.eclipse.elk.core.options.PortConstraints in project elk by eclipse.
the class ElkGraphImporter method transformNode.
// /////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Node Transformation
/**
* Transforms the given node and its contained ports.
*
* @param elknode
* the node to transform
* @param lgraph
* the layered graph into which the transformed node is put
* @return the transformed node
*/
private LNode transformNode(final ElkNode elknode, final LGraph lgraph) {
// add a new node to the layered graph, copying its position
LNode lnode = new LNode(lgraph);
lnode.copyProperties(elknode);
lnode.setProperty(InternalProperties.ORIGIN, elknode);
lnode.getSize().x = elknode.getWidth();
lnode.getSize().y = elknode.getHeight();
lnode.getPosition().x = elknode.getX();
lnode.getPosition().y = elknode.getY();
lgraph.getLayerlessNodes().add(lnode);
nodeAndPortMap.put(elknode, lnode);
// check if the node is a compound node in the original graph
if (!elknode.getChildren().isEmpty() || elknode.getProperty(LayeredOptions.INSIDE_SELF_LOOPS_ACTIVATE)) {
lnode.setProperty(InternalProperties.COMPOUND_NODE, true);
}
Set<GraphProperties> graphProperties = lgraph.getProperty(InternalProperties.GRAPH_PROPERTIES);
// port constraints and sides cannot be undefined
PortConstraints portConstraints = lnode.getProperty(LayeredOptions.PORT_CONSTRAINTS);
if (portConstraints == PortConstraints.UNDEFINED) {
lnode.setProperty(LayeredOptions.PORT_CONSTRAINTS, PortConstraints.FREE);
} else if (portConstraints != PortConstraints.FREE) {
// if the port constraints are not free, set the appropriate graph property
graphProperties.add(GraphProperties.NON_FREE_PORTS);
}
// transform the ports
Direction direction = lgraph.getProperty(LayeredOptions.DIRECTION);
for (ElkPort elkport : elknode.getPorts()) {
if (!elkport.getProperty(LayeredOptions.NO_LAYOUT)) {
transformPort(elkport, lnode, graphProperties, direction, portConstraints);
}
}
// add the node's labels
for (ElkLabel elklabel : elknode.getLabels()) {
if (!elklabel.getProperty(LayeredOptions.NO_LAYOUT) && !Strings.isNullOrEmpty(elklabel.getText())) {
lnode.getLabels().add(transformLabel(elklabel));
}
}
if (lnode.getProperty(LayeredOptions.COMMENT_BOX)) {
graphProperties.add(GraphProperties.COMMENTS);
}
// if we have a hypernode without ports, create a default input and output port
if (lnode.getProperty(LayeredOptions.HYPERNODE)) {
graphProperties.add(GraphProperties.HYPERNODES);
graphProperties.add(GraphProperties.HYPEREDGES);
lnode.setProperty(LayeredOptions.PORT_CONSTRAINTS, PortConstraints.FREE);
}
return lnode;
}
use of org.eclipse.elk.core.options.PortConstraints in project elk by eclipse.
the class NetworkSimplexPlacer method isFlexibleNode.
// ------------------------------------------------------------------------------------------------
// Flexible Ports
// ------------------------------------------------------------------------------------------------
/**
* A node is <em>flexible</em> if
* <ul>
* <li>its port constraints are <b>not</b> {@link PortConstraints#FIXED_POS}, and</li>
* <li>the node's height is large enough to give the ports
* on both sides (WEST and EAST) enough room to potentially alter their position.</li>
* </ul>
*
* The rationale for the latter case is the following:
* if the height of a node is not enough to accommodate all ports
* and we are not allowed to change the node's size,
* we simply use the port positions that have been computed by the {@link LabelAndNodeSizeProcessor}.
* The processor is able to handle this situation properly.
*
* @param lNode a node
* @return whether the node is regarded flexible.
*/
public static boolean isFlexibleNode(final LNode lNode) {
// dummies are not flexible!
if (lNode.getType() != NodeType.NORMAL) {
return false;
}
// at least two ports are required ...
if (lNode.getPorts().size() <= 1) {
return false;
}
// if ports may not be moved there's no use in enlarging the node
PortConstraints pc = lNode.getProperty(LayeredOptions.PORT_CONSTRAINTS);
if (pc.isPosFixed()) {
return false;
}
NodeFlexibility nf = getNodeFlexibility(lNode);
if (nf == NodeFlexibility.NONE) {
return false;
}
// all ports, reuse the existing port positions
if (!nf.isFlexibleSizeWhereSpacePermits()) {
// we are not allowed to increase the node's size
double portSpacing = Spacings.getIndividualOrDefault(lNode, LayeredOptions.SPACING_PORT_PORT);
ElkMargin additionalPortSpacing = lNode.getProperty(LayeredOptions.SPACING_PORTS_SURROUNDING);
if (additionalPortSpacing == null) {
additionalPortSpacing = new ElkMargin(portSpacing, portSpacing, portSpacing, portSpacing);
}
// check west side
List<LPort> westPorts = lNode.getPortSideView(PortSide.WEST);
double requiredWestHeight = additionalPortSpacing.top + additionalPortSpacing.bottom + (westPorts.size() - 1) * portSpacing;
if (requiredWestHeight > lNode.getSize().y) {
return false;
}
// check east side
List<LPort> eastPorts = lNode.getPortSideView(PortSide.EAST);
double requiredEastHeight = additionalPortSpacing.top + additionalPortSpacing.bottom + (eastPorts.size() - 1) * portSpacing;
if (requiredEastHeight > lNode.getSize().y) {
return false;
}
}
return true;
}
use of org.eclipse.elk.core.options.PortConstraints in project elk by eclipse.
the class PortListSorter method process.
@Override
public void process(final LGraph layeredGraph, final IElkProgressMonitor monitor) {
monitor.begin("Port order processing", 1);
PortSortingStrategy pss = layeredGraph.getProperty(LayeredOptions.PORT_SORTING_STRATEGY);
// Iterate through the nodes of all layers
for (Layer layer : layeredGraph) {
for (LNode node : layer) {
PortConstraints portConstraints = node.getProperty(LayeredOptions.PORT_CONSTRAINTS);
List<LPort> ports = node.getPorts();
// We need to sort the port list according to port constraints
if (portConstraints.isOrderFixed()) {
Collections.sort(ports, CMP_COMBINED);
} else if (portConstraints.isSideFixed()) {
// by default try to preserve the input order
Collections.sort(ports, CMP_PORT_SIDE);
reverseWestAndSouthSide(ports);
if (pss == PortSortingStrategy.PORT_DEGREE) {
Collections.sort(ports, CMP_PORT_DEGREE_EAST_WEST);
}
}
node.cachePortSides();
}
}
monitor.done();
}
use of org.eclipse.elk.core.options.PortConstraints in project elk by eclipse.
the class HierarchicalPortOrthogonalEdgeRouter method fixCoordinates.
// /////////////////////////////////////////////////////////////////////////////
// STEP 5: FIX DUMMY COORDINATES
/**
* Fixes all hierarchical port dummy coordinates. For east / west external port dummies, this
* means setting the x coordinate appropriately, and, in case of {@code FIXED_RATIO},
* checking that the ratio is respected. For north / south hierarchical port dummies, this
* means setting the y coordinate appropriately.
*
* @param layeredGraph the layered graph.
*/
private void fixCoordinates(final LGraph layeredGraph) {
PortConstraints constraints = layeredGraph.getProperty(LayeredOptions.PORT_CONSTRAINTS);
// East port dummies are in the first layer; all other dummies are in the last layer
List<Layer> layers = layeredGraph.getLayers();
fixCoordinates(layers.get(0), constraints, layeredGraph);
fixCoordinates(layers.get(layers.size() - 1), constraints, layeredGraph);
}
Aggregations