use of org.eclipse.elk.core.math.KVector 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.core.math.KVector in project elk by eclipse.
the class HierarchicalPortOrthogonalEdgeRouter method removeTemporaryNorthSouthDummies.
// /////////////////////////////////////////////////////////////////////////////
// STEP 4: REMOVE TEMPORARY DUMMIES
/**
* Removes the temporary hierarchical port dummies, reconnecting their incoming and outgoing
* edges to the original dummies and setting the appropriate bend points.
*
* @param layeredGraph the layered graph.
*/
private void removeTemporaryNorthSouthDummies(final LGraph layeredGraph) {
List<LNode> nodesToRemove = Lists.newArrayList();
// Iterate through all layers
for (Layer layer : layeredGraph) {
for (LNode node : layer) {
if (node.getType() != NodeType.EXTERNAL_PORT) {
// We're only looking for hierarchical port dummies
continue;
}
if (!node.hasProperty(InternalProperties.EXT_PORT_REPLACED_DUMMY)) {
// We're only looking for temporary north / south dummies
continue;
}
// There must be a port where all edges come in, another port where edges go out, and
// a port with an edge connecting node and origin (that one was added previously by
// this processor)
LPort nodeInPort = null;
LPort nodeOutPort = null;
LPort nodeOriginPort = null;
for (LPort port : node.getPorts()) {
switch(port.getSide()) {
case WEST:
nodeInPort = port;
break;
case EAST:
nodeOutPort = port;
break;
default:
nodeOriginPort = port;
}
}
// Find the edge connecting this dummy to the original external port dummy that we
// restored just a while ago
LEdge nodeToOriginEdge = nodeOriginPort.getOutgoingEdges().get(0);
// Compute bend points for incoming edges
KVectorChain incomingEdgeBendPoints = new KVectorChain(nodeToOriginEdge.getBendPoints());
KVector firstBendPoint = new KVector(nodeOriginPort.getPosition());
firstBendPoint.add(node.getPosition());
incomingEdgeBendPoints.add(0, firstBendPoint);
// Compute bend points for outgoing edges
KVectorChain outgoingEdgeBendPoints = KVectorChain.reverse(nodeToOriginEdge.getBendPoints());
KVector lastBendPoint = new KVector(nodeOriginPort.getPosition());
lastBendPoint.add(node.getPosition());
outgoingEdgeBendPoints.add(lastBendPoint);
// Retrieve the original hierarchical port dummy
LNode replacedDummy = (LNode) node.getProperty(InternalProperties.EXT_PORT_REPLACED_DUMMY);
LPort replacedDummyPort = replacedDummy.getPorts().get(0);
// Reroute all the input port's edges
LEdge[] edges = nodeInPort.getIncomingEdges().toArray(new LEdge[0]);
for (LEdge edge : edges) {
edge.setTarget(replacedDummyPort);
edge.getBendPoints().addAllAsCopies(edge.getBendPoints().size(), incomingEdgeBendPoints);
}
// Reroute all the output port's edges
edges = LGraphUtil.toEdgeArray(nodeOutPort.getOutgoingEdges());
for (LEdge edge : edges) {
edge.setSource(replacedDummyPort);
edge.getBendPoints().addAllAsCopies(0, outgoingEdgeBendPoints);
}
// Remove connection between node and original hierarchical port dummy
nodeToOriginEdge.setSource(null);
nodeToOriginEdge.setTarget(null);
// Remember the temporary node for removal
nodesToRemove.add(node);
}
}
// Remove nodes
for (LNode node : nodesToRemove) {
node.setLayer(null);
}
}
use of org.eclipse.elk.core.math.KVector in project elk by eclipse.
the class LabelAndNodeSizeProcessor method computePortLabelBox.
/**
* Returns the amount of space required to place the labels later, or {@code null} if there are no labels.
*/
private ElkRectangle computePortLabelBox(final LPort dummyPort, final double labelLabelSpacing) {
if (dummyPort.getLabels().isEmpty()) {
return null;
} else {
ElkRectangle result = new ElkRectangle();
for (LLabel label : dummyPort.getLabels()) {
KVector labelSize = label.getSize();
result.width = Math.max(result.width, labelSize.x);
result.height += labelSize.y;
}
result.height += (dummyPort.getLabels().size() - 1) * labelLabelSpacing;
return result;
}
}
use of org.eclipse.elk.core.math.KVector in project elk by eclipse.
the class LabelManagementProcessor method manageCenterLabels.
// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Center Edge Labels
/**
* Calls label management on all edge center labels.
*/
private void manageCenterLabels(final LGraph lGraph, final ILabelManager labelManager, final double edgeLabelSpacing, final double labelLabelSpacing) {
boolean verticalLayout = lGraph.getProperty(LayeredOptions.DIRECTION).isVertical();
// Iterate over the layers and find label dummy nodes
for (Layer layer : lGraph) {
// The maximum width is used as the target width for center edge labels
double maxWidth = Math.max(MIN_WIDTH_EDGE_LABELS, LGraphUtil.findMaxNonDummyNodeWidth(layer, false));
for (LNode node : layer) {
if (node.getType() == NodeType.LABEL) {
LEdge edge = node.getConnectedEdges().iterator().next();
double edgeThickness = edge.getProperty(LayeredOptions.EDGE_THICKNESS).doubleValue();
// The list of labels should never be empty (otherwise the label dummy wouldn't have been created
// in the first place)
Iterable<LLabel> labels = node.getProperty(InternalProperties.REPRESENTED_LABELS);
KVector spaceRequiredForLabels = doManageLabels(labelManager, labels, maxWidth, labelLabelSpacing, verticalLayout);
// Apply the space required for labels to the dummy node (we don't bother with the ports here since
// they will be meddled with later by the LabelSideSelector anyway)
node.getSize().x = spaceRequiredForLabels.x;
node.getSize().y = spaceRequiredForLabels.y + edgeThickness + edgeLabelSpacing;
}
}
}
}
use of org.eclipse.elk.core.math.KVector in project elk by eclipse.
the class FinalSplineBendpointsCalculator method insertStraighteningControlPoints.
private void insertStraighteningControlPoints(final KVectorChain allCPs, final LPort srcPort, final LPort tgtPort) {
// KVectorChain extends LinkedList, thus the following operations are fast
// Further note that the vector computations are necessary to address adding a straightening gap
// into either of the for cardinal directions (based on the port side)
// beginning
KVector first = allCPs.getFirst();
KVector second = allCPs.get(1);
KVector v = new KVector(SplinesMath.portSideToDirection(srcPort.getSide()));
v.scale(NODE_TO_STRAIGHTENING_CP_GAP);
KVector v2 = second.clone().sub(first);
KVector straightenBeginning = new KVector(absMin(v.x, v2.x), absMin(v.y, v2.y));
straightenBeginning.add(first);
allCPs.add(1, straightenBeginning);
// ending
KVector last = allCPs.getLast();
KVector secondLast = allCPs.get(allCPs.size() - 2);
v = new KVector(SplinesMath.portSideToDirection(tgtPort.getSide()));
v.scale(NODE_TO_STRAIGHTENING_CP_GAP);
v2 = secondLast.clone().sub(last);
KVector straightenEnding = new KVector(absMin(v.x, v2.x), absMin(v.y, v2.y));
straightenEnding.add(last);
allCPs.add(allCPs.size() - 1, straightenEnding);
}
Aggregations