use of org.eclipse.elk.graph.ElkLabel in project elk by eclipse.
the class PortLabelPlacementVariantsTest method assertAboveOrLeft.
private void assertAboveOrLeft(final ElkPort port) {
final ElkLabel label = getLabel(port);
// Note that port label positions are relative to the port
double portPosition = 0;
if (PortSide.SIDES_EAST_WEST.contains(port.getProperty(CoreOptions.PORT_SIDE))) {
portPosition = label.getY();
} else if (PortSide.SIDES_NORTH_SOUTH.contains(port.getProperty(CoreOptions.PORT_SIDE))) {
portPosition = label.getX();
} else {
assertTrue(false);
}
assertThat(portPosition, OrderingComparison.lessThan(0.0));
}
use of org.eclipse.elk.graph.ElkLabel in project elk by eclipse.
the class LabelSideSelectorTest method configurator.
@Configurator
public void configurator(final ElkNode graph) {
Deque<ElkNode> nodeQueue = new LinkedList<>();
nodeQueue.add(graph);
Random rand = new Random(RANDOM_SEED);
while (!nodeQueue.isEmpty()) {
ElkNode node = nodeQueue.poll();
for (ElkEdge edge : node.getContainedEdges()) {
if (edge.getLabels().isEmpty()) {
ElkGraphUtil.createLabel(edge.getIdentifier(), edge);
}
ElkLabel label = edge.getLabels().get(0);
double r = rand.nextDouble();
if (r < 0.3) {
label.setProperty(LayeredOptions.EDGE_LABELS_PLACEMENT, EdgeLabelPlacement.HEAD);
} else if (r < 0.7) {
label.setProperty(LayeredOptions.EDGE_LABELS_PLACEMENT, EdgeLabelPlacement.CENTER);
} else {
label.setProperty(LayeredOptions.EDGE_LABELS_PLACEMENT, EdgeLabelPlacement.TAIL);
}
}
}
}
use of org.eclipse.elk.graph.ElkLabel in project elk by eclipse.
the class DotImporter method applyLayout.
/**
* Apply layout to an edge and its labels.
*
* @param edge an edge
* @param offset its offset in the graph
* @param graph the Graphviz graph
*/
private void applyLayout(final ElkEdge edge, final KVector offset, final Graph graph) {
EdgeStatement edgeStatement = (EdgeStatement) edge.getProperty(PROP_STATEMENT);
if (edgeStatement.eContainer() == null) {
// this can happen when an edge with multiple target declarations was found
graph.getStatements().add(edgeStatement);
}
// transfer edge bend points and source / target points
List<Attribute> attributes = edgeStatement.getAttributes();
removeAttributes(attributes, Attributes.POS);
if (!edge.getSections().isEmpty()) {
StringBuilder bendpointString = new StringBuilder("\"");
KVectorChain vectorChain = ElkUtil.createVectorChain(edge.getSections().get(0));
ListIterator<KVector> chainIter = vectorChain.listIterator();
while (chainIter.hasNext()) {
KVector point = chainIter.next().add(offset);
bendpointString.append(point.x);
bendpointString.append(',');
bendpointString.append(point.y);
if (chainIter.hasNext()) {
bendpointString.append(' ');
}
}
bendpointString.append('\"');
attributes.add(DotExporter.createAttribute(Attributes.POS, bendpointString.toString()));
}
// transfer label positions
for (ElkLabel label : edge.getLabels()) {
String attrKey = null;
switch(label.getProperty(CoreOptions.EDGE_LABELS_PLACEMENT)) {
case CENTER:
attrKey = Attributes.LABELPOS;
break;
case HEAD:
attrKey = Attributes.HEADLP;
break;
case TAIL:
attrKey = Attributes.TAILLP;
break;
}
if (attrKey != null) {
removeAttributes(attributes, attrKey);
double xpos = label.getX() + label.getWidth() / 2 + offset.x;
double ypos = label.getY() + label.getHeight() / 2 + offset.y;
String posString = "\"" + Double.toString(xpos) + "," + Double.toString(ypos) + "\"";
attributes.add(DotExporter.createAttribute(attrKey, posString));
}
}
}
use of org.eclipse.elk.graph.ElkLabel in project elk by eclipse.
the class ElkGraphImporter method transformPort.
// /////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Port Transformation
/**
* Transforms the given port. The new port will be added to the given node and will be
* registered with the {@code transformMap}.
*
* @param elkport
* the port to transform.
* @param parentLNode
* the node the port should be added to.
* @param graphProperties
* the graph properties of the graph the transformed port will be part of. The graph
* properties are modified depending on the port's properties.
* @param layoutDirection
* the layout direction in the graph the port will be part of.
* @param portConstraints
* the port constraints of the port's node.
* @return the transformed port.
*/
private LPort transformPort(final ElkPort elkport, final LNode parentLNode, final Set<GraphProperties> graphProperties, final Direction layoutDirection, final PortConstraints portConstraints) {
// create layered port, copying its position
LPort lport = new LPort();
lport.copyProperties(elkport);
lport.setSide(elkport.getProperty(LayeredOptions.PORT_SIDE));
lport.setProperty(InternalProperties.ORIGIN, elkport);
lport.setNode(parentLNode);
KVector portSize = lport.getSize();
portSize.x = elkport.getWidth();
portSize.y = elkport.getHeight();
KVector portPos = lport.getPosition();
portPos.x = elkport.getX();
portPos.y = elkport.getY();
nodeAndPortMap.put(elkport, lport);
// check if the original port has any outgoing connections to descendants of its node
boolean connectionsToDescendants = elkport.getOutgoingEdges().stream().flatMap(edge -> edge.getTargets().stream()).map(ElkGraphUtil::connectableShapeToNode).anyMatch(targetNode -> ElkGraphUtil.isDescendant(targetNode, elkport.getParent()));
// there could be yet incoming connections from descendants
if (!connectionsToDescendants) {
// check if the original port has any incoming connections from descendants of its node
connectionsToDescendants = elkport.getIncomingEdges().stream().flatMap(edge -> edge.getSources().stream()).map(ElkGraphUtil::connectableShapeToNode).anyMatch(sourceNode -> ElkGraphUtil.isDescendant(sourceNode, elkport.getParent()));
}
// if there are still no connections to descendants, there might yet be inside self loops involved
if (!connectionsToDescendants) {
// check if the original port has any incoming connections from descendants of its node
connectionsToDescendants = elkport.getOutgoingEdges().stream().anyMatch(edge -> edge.isSelfloop() && edge.getProperty(LayeredOptions.INSIDE_SELF_LOOPS_YO));
}
// if we have found connections to / from descendants, mark the port accordingly
lport.setProperty(InternalProperties.INSIDE_CONNECTIONS, connectionsToDescendants);
// initialize the port's side, offset, and anchor point
LGraphUtil.initializePort(lport, portConstraints, layoutDirection, elkport.getProperty(LayeredOptions.PORT_ANCHOR));
// create the port's labels
for (ElkLabel elklabel : elkport.getLabels()) {
if (!elklabel.getProperty(LayeredOptions.NO_LAYOUT) && !Strings.isNullOrEmpty(elklabel.getText())) {
lport.getLabels().add(transformLabel(elklabel));
}
}
switch(layoutDirection) {
case LEFT:
case RIGHT:
if (lport.getSide() == PortSide.NORTH || lport.getSide() == PortSide.SOUTH) {
graphProperties.add(GraphProperties.NORTH_SOUTH_PORTS);
}
break;
case UP:
case DOWN:
if (lport.getSide() == PortSide.EAST || lport.getSide() == PortSide.WEST) {
graphProperties.add(GraphProperties.NORTH_SOUTH_PORTS);
}
break;
}
return lport;
}
use of org.eclipse.elk.graph.ElkLabel in project elk by eclipse.
the class ElkGraphImporter method transformExternalPort.
/**
* Transforms the given external port into a dummy node.
*
* @param elkgraph
* the original KGraph
* @param lgraph
* the corresponding layered graph
* @param elkport
* the port to be transformed
*/
private void transformExternalPort(final ElkNode elkgraph, final LGraph lgraph, final ElkPort elkport) {
// We need some information about the port
KVector elkportPosition = new KVector(elkport.getX() + elkport.getWidth() / 2.0, elkport.getY() + elkport.getHeight() / 2.0);
int netFlow = calculateNetFlow(elkport);
PortConstraints portConstraints = elkgraph.getProperty(LayeredOptions.PORT_CONSTRAINTS);
// If we don't have a proper port side, calculate one
PortSide portSide = elkport.getProperty(LayeredOptions.PORT_SIDE);
assert portSide != PortSide.UNDEFINED;
// If we don't have a port offset, infer one
if (!elkport.getAllProperties().containsKey(LayeredOptions.PORT_BORDER_OFFSET)) {
double portOffset;
// if port coordinates are (0,0), we default to port offset 0 to make the common case frustration-free
if (elkport.getX() == 0.0 && elkport.getY() == 0.0) {
portOffset = 0.0;
} else {
portOffset = ElkUtil.calcPortOffset(elkport, portSide);
}
elkport.setProperty(LayeredOptions.PORT_BORDER_OFFSET, portOffset);
}
// Create the external port dummy node
KVector graphSize = new KVector(elkgraph.getWidth(), elkgraph.getHeight());
LNode dummy = LGraphUtil.createExternalPortDummy(elkport, portConstraints, portSide, netFlow, graphSize, elkportPosition, new KVector(elkport.getWidth(), elkport.getHeight()), lgraph.getProperty(LayeredOptions.DIRECTION), lgraph);
dummy.setProperty(InternalProperties.ORIGIN, elkport);
// The dummy only has one port
LPort dummyPort = dummy.getPorts().get(0);
dummyPort.setConnectedToExternalNodes(isConnectedToExternalNodes(elkport));
dummy.setProperty(LayeredOptions.PORT_LABELS_PLACEMENT, PortLabelPlacement.outside());
// If the compound node wants to have its port labels placed on the inside, we need to leave
// enough space for them by creating an LLabel for the KLabels. If the compound node wants to
// have its port labels placed on the outside, we still need to leave enough space for them
// so the port placement does not cause problems on the outside, but we also don't want to waste
// space inside. Thus, for east and west ports, we reduce the label width to zero, otherwise
// we reduce the label height to zero
boolean insidePortLabels = elkgraph.getProperty(LayeredOptions.PORT_LABELS_PLACEMENT).contains(PortLabelPlacement.INSIDE);
// Transform all of the port's labels
for (ElkLabel elklabel : elkport.getLabels()) {
if (!elklabel.getProperty(LayeredOptions.NO_LAYOUT) && !Strings.isNullOrEmpty(elklabel.getText())) {
LLabel llabel = transformLabel(elklabel);
dummyPort.getLabels().add(llabel);
// If the port labels are fixed, we should consider the part that is inside the node and not 0.
if (!insidePortLabels) {
double insidePart = 0;
if (PortLabelPlacement.isFixed(elkgraph.getProperty(LayeredOptions.PORT_LABELS_PLACEMENT))) {
// We use 0 as port border offset here, as we only want the label part that is
// inside the node "after" the port.
insidePart = ElkUtil.computeInsidePart(new KVector(elklabel.getX(), elklabel.getY()), new KVector(elklabel.getWidth(), elklabel.getHeight()), new KVector(elkport.getWidth(), elkport.getHeight()), 0, portSide);
}
switch(portSide) {
case EAST:
case WEST:
llabel.getSize().x = insidePart;
break;
case NORTH:
case SOUTH:
llabel.getSize().y = insidePart;
break;
}
}
}
}
// Remember the relevant spacings that will apply to the labels here. It's not the spacings in the graph, but
// in the parent
dummy.setProperty(LayeredOptions.SPACING_LABEL_PORT, elkgraph.getParent().getProperty(LayeredOptions.SPACING_LABEL_PORT));
dummy.setProperty(LayeredOptions.SPACING_LABEL_LABEL, elkgraph.getParent().getProperty(LayeredOptions.SPACING_LABEL_LABEL));
// Put the external port dummy into our graph and associate it with the original KPort
lgraph.getLayerlessNodes().add(dummy);
nodeAndPortMap.put(elkport, dummy);
}
Aggregations