use of org.eclipse.elk.alg.disco.graph.DCDirection in project elk by eclipse.
the class DCPolyomino method addExtensionsToPoly.
/**
* Adds extenstions to this polyomino taken from a {@link DCElement} of the component it represents.
*
* @param elem
* an element of the component this polyomino represents
*/
private void addExtensionsToPoly(final DCElement elem) {
List<DCExtension> extensions = elem.getExtensions();
KVector compCorner = representee.getMinCorner();
KVector polyoOffset = getOffset();
double baseX = compCorner.x - polyoOffset.x;
double baseY = compCorner.y - polyoOffset.y;
ElkRectangle elemPos = elem.getBounds();
baseX = elemPos.x - baseX;
baseY = elemPos.y - baseY;
for (DCExtension extension : extensions) {
KVector pos = extension.getOffset();
double xe = baseX + pos.x;
double ye = baseY + pos.y;
int xp = (int) (xe / cellSizeX);
int yp = (int) (ye / cellSizeY);
DCDirection dir = extension.getDirection();
Direction polyDir;
switch(dir) {
case NORTH:
polyDir = Direction.NORTH;
break;
case EAST:
polyDir = Direction.EAST;
break;
case SOUTH:
polyDir = Direction.SOUTH;
break;
default:
polyDir = Direction.WEST;
}
if (dir.isHorizontal()) {
int ypPlusWidth = (int) ((ye + extension.getWidth()) / cellSizeY);
addExtension(polyDir, yp, ypPlusWidth);
if (dir.equals(DCDirection.WEST)) {
weaklyBlockArea(0, yp, xp, ypPlusWidth);
} else {
// direction is EAST
weaklyBlockArea(xp, yp, pWidth - 1, ypPlusWidth);
}
} else {
// direction is vertical
int xpPlusWidth = (int) ((xe + extension.getWidth()) / cellSizeX);
addExtension(polyDir, xp, xpPlusWidth);
if (dir.equals(DCDirection.NORTH)) {
weaklyBlockArea(xp, 0, xpPlusWidth, yp);
} else {
// direction is SOUTH
weaklyBlockArea(xp, yp, xpPlusWidth, pHeight - 1);
}
}
}
}
use of org.eclipse.elk.alg.disco.graph.DCDirection in project elk by eclipse.
the class ElkGraphTransformer method nearestSide.
/**
* Computes for a given {@link KVector} relative to the upper left corner of a given node, which of its four sides
* is closest to the point the vector describes.
*
* @param point
* vector to compare
* @param node
* node as reference to the vector
* @return side of the node which is closest to the point
*/
private DCDirection nearestSide(final KVector point, final ElkNode node) {
double distance;
double shortestDistance = Double.MAX_VALUE;
DCDirection result = DCDirection.NORTH;
// NORTHVALUE
shortestDistance = Math.abs(point.y);
// SOUTHVALUE
distance = Math.abs(node.getHeight() - point.y);
if (distance < shortestDistance) {
shortestDistance = distance;
result = DCDirection.SOUTH;
}
// WESTVALUE
distance = Math.abs(point.x);
if (distance < shortestDistance) {
shortestDistance = distance;
result = DCDirection.WEST;
}
// EASTVALUE
distance = Math.abs(node.getWidth() - point.x);
if (distance < shortestDistance) {
shortestDistance = distance;
result = DCDirection.EAST;
}
return result;
}
use of org.eclipse.elk.alg.disco.graph.DCDirection in project elk by eclipse.
the class ElkGraphTransformer method applyLayout.
@Override
public void applyLayout() {
KVector graphDimensions = transformedGraph.getDimensions();
double newWidth = graphDimensions.x;
double newHeight = graphDimensions.y;
double oldWidth = parent.getWidth();
double oldHeight = parent.getHeight();
// Adjust size of layout
parent.setDimensions(graphDimensions.x, graphDimensions.y);
double xFactor = newWidth / oldWidth;
double yFactor = newHeight / oldHeight;
for (ElkLabel label : parent.getLabels()) {
label.setX(label.getX() * xFactor);
label.setY(label.getY() * yFactor);
}
for (ElkPort port : parent.getPorts()) {
double px = port.getX();
double py = port.getY();
if (px > 0) {
port.setX(px * xFactor);
}
if (py > 0) {
port.setY(py * yFactor);
}
}
// Apply offsets, whenever necessary.
elementMapping.forEach(new OffsetApplier());
List<ElkPort> adjustedPorts = Lists.newArrayList();
ElkPort portToAdjust;
for (Entry<ElkEdge, DCExtension> inEntry : incomingExtensionsMapping.entrySet()) {
ElkEdge edge = inEntry.getKey();
DCDirection dir = inEntry.getValue().getDirection();
ElkEdgeSection edgeSection = ElkGraphUtil.firstEdgeSection(edge, false, false);
KVectorChain newPoints = adjustFirstSegment(ElkGraphUtil.getSourceNode(edge), ElkUtil.createVectorChain(edgeSection), dir);
ElkUtil.applyVectorChain(newPoints, edgeSection);
portToAdjust = ElkGraphUtil.getSourcePort(edge);
if (portToAdjust != null && !adjustedPorts.contains(portToAdjust)) {
adjustedPorts.add(portToAdjust);
adjustRelatedPort(portToAdjust, newPoints.getFirst(), dir);
}
}
for (Entry<ElkEdge, DCExtension> outEntry : outgoingExtensionsMapping.entrySet()) {
ElkEdge edge = outEntry.getKey();
DCDirection dir = outEntry.getValue().getDirection();
ElkEdgeSection edgeSection = ElkGraphUtil.firstEdgeSection(edge, false, false);
KVectorChain newPoints = adjustFirstSegment(ElkGraphUtil.getTargetNode(edge), KVectorChain.reverse(ElkUtil.createVectorChain(edgeSection)), dir);
newPoints = KVectorChain.reverse(newPoints);
ElkUtil.applyVectorChain(newPoints, edgeSection);
portToAdjust = ElkGraphUtil.getTargetPort(edge);
if (portToAdjust != null && !adjustedPorts.contains(portToAdjust)) {
adjustedPorts.add(portToAdjust);
adjustRelatedPort(portToAdjust, newPoints.getLast(), dir);
}
}
}
use of org.eclipse.elk.alg.disco.graph.DCDirection in project elk by eclipse.
the class ElkGraphTransformer method importExtension.
/**
* Transforms a {@link ElkEdge} into a {@link DCElement} without destroying it. Edges can have their own
* {@link ElkLabel ElkLabels}, so they will be transformed, too.
*
* @param edge
* Edge to be transformed into a {@link DCElement}
* @param newComponent
* Collection representing the component the edge and its associated labels (if any) belong to. Newly
* generated {@link DCElement DCElements} will be added to it
* @return {@link DCElement} resulting from the transformation
*/
/**
* Transforms a short hierarchical {@link ElkEdge} into a {@link DCExtension} without destroying it. Edges can have
* their own {@link ElkLabel ElkLabels}, so they will be transformed, too.
*
* @param edge
* Edge to be transformed into a {@link DCExtension}
* @param newComponent
* component the extension will belong to
* @param outgoingExtension
* true, if the edge should be handled as an outgoing extension; false, otherwise
*/
private void importExtension(final ElkEdge edge, final Collection<DCElement> newComponent, final boolean outgoingExtension) {
ElkEdgeSection edgeSection = ElkGraphUtil.firstEdgeSection(edge, false, false);
KVectorChain points = ElkUtil.createVectorChain(edgeSection);
if (outgoingExtension) {
points = KVectorChain.reverse(points);
}
// Is going to hold the extension
DCElement shape;
double thickness = edge.getProperty(DisCoOptions.EDGE_THICKNESS);
KVector outerPoint = points.getFirst();
KVector innerPoint = points.get(1);
if (points.size() > 2) {
List<KVector> fixedEdgePoints = Lists.newArrayList();
fixedEdgePoints.addAll(points.subList(1, points.size()));
KVectorChain contour = getContour(fixedEdgePoints, thickness + componentSpacing);
shape = new DCElement(contour);
shape.copyProperties(edge);
newComponent.add(shape);
} else {
if (outgoingExtension) {
shape = elementMapping.get(ElkGraphUtil.getSourceNode(edge));
} else {
shape = elementMapping.get(ElkGraphUtil.getTargetNode(edge));
}
}
// Construct the extension and add to mapping
ElkNode extParent = ElkGraphUtil.getSourceNode(edge);
if (outgoingExtension) {
extParent = ElkGraphUtil.getTargetNode(edge);
}
DCDirection dir = nearestSide(outerPoint, extParent);
double extensionWidth = thickness + componentSpacing;
KVector middlePos;
if (dir.isHorizontal()) {
// West or east extension
extensionWidth += Math.abs(outerPoint.y - innerPoint.y);
middlePos = new KVector(innerPoint.x, (innerPoint.y + outerPoint.y) / 2);
} else {
extensionWidth += Math.abs(outerPoint.x - innerPoint.x);
middlePos = new KVector((innerPoint.x + outerPoint.x) / 2, innerPoint.y);
}
if (outgoingExtension) {
outgoingExtensionsMapping.put(edge, new DCExtension(shape, dir, middlePos, extensionWidth));
} else {
incomingExtensionsMapping.put(edge, new DCExtension(shape, dir, middlePos, extensionWidth));
}
elementMapping.put(edge, shape);
// ElkEdges can have labels, too!
List<ElkLabel> labels = edge.getLabels();
for (ElkLabel label : labels) {
// "true" - ElkLabels belonging to an ElkEdge have absolute coordinates and have to be considered when
// applying
// changes to the DCGraph back to the original graph.
DCElement componentLabel = importElkShape(label, true, 0.0f, 0.0f);
newComponent.add(componentLabel);
}
}
Aggregations