use of org.eclipse.elk.alg.common.spore.Node in project elk by eclipse.
the class ElkGraphImporter method updateGraph.
@Override
public void updateGraph(final Graph g) {
Map<KVector, Pair<Node, ElkNode>> updatedNodeMap = Maps.newHashMap();
// reset graph
g.tEdges = null;
g.tree = null;
// update nodes
for (Node n : g.vertices) {
Pair<Node, ElkNode> original = nodeMap.get(n.originalVertex);
n.originalVertex = n.rect.getCenter();
updatedNodeMap.put(n.originalVertex, original);
}
nodeMap = updatedNodeMap;
}
use of org.eclipse.elk.alg.common.spore.Node in project elk by eclipse.
the class ElkGraphImporter method importGraph.
@Override
public Graph importGraph(final ElkNode inputGraph) {
elkGraph = inputGraph;
nodeMap = Maps.newHashMap();
// calculate margins
ElkGraphAdapter adapter = ElkGraphAdapters.adapt(elkGraph);
NodeDimensionCalculation.calculateNodeMargins(adapter);
// retrieve layout options
String preferredRootID = elkGraph.getProperty(SporeCompactionOptions.PROCESSING_ORDER_PREFERRED_ROOT);
SpanningTreeCostFunction costFunctionID = elkGraph.getProperty(SporeCompactionOptions.PROCESSING_ORDER_SPANNING_TREE_COST_FUNCTION);
TreeConstructionStrategy treeConstructionStrategy = elkGraph.getProperty(SporeCompactionOptions.PROCESSING_ORDER_TREE_CONSTRUCTION);
CompactionStrategy compactionStrategy = elkGraph.getProperty(SporeCompactionOptions.COMPACTION_COMPACTION_STRATEGY);
RootSelection rootSelection = elkGraph.getProperty(SporeCompactionOptions.PROCESSING_ORDER_ROOT_SELECTION);
spacingNodeNode = elkGraph.getProperty(SporeCompactionOptions.SPACING_NODE_NODE);
ICostFunction costFunction = centerDistance;
switch(costFunctionID) {
case CENTER_DISTANCE:
costFunction = centerDistance;
break;
case CIRCLE_UNDERLAP:
costFunction = circleUnderlap;
break;
case RECTANGLE_UNDERLAP:
costFunction = rectangleUnderlap;
break;
case INVERTED_OVERLAP:
costFunction = invertedOverlap;
break;
case MINIMUM_ROOT_DISTANCE:
costFunction = minimumRootDistance;
break;
default:
throw new IllegalArgumentException("No implementation available for " + costFunctionID.toString());
}
// instantiate Graph
graph = new Graph(costFunction, treeConstructionStrategy, compactionStrategy);
graph.setProperty(InternalProperties.DEBUG_SVG, elkGraph.getProperty(SporeCompactionOptions.DEBUG_MODE));
graph.orthogonalCompaction = elkGraph.getProperty(SporeCompactionOptions.COMPACTION_ORTHOGONAL);
if (elkGraph.getChildren().isEmpty()) {
// don't bother
return graph;
}
// create Nodes representing the ElkNodes
for (ElkNode elkNode : elkGraph.getChildren()) {
double halfWidth = elkNode.getWidth() / 2;
double halfHeight = elkNode.getHeight() / 2;
KVector vertex = new KVector(elkNode.getX() + halfWidth, elkNode.getY() + halfHeight);
// randomly shift identical points a tiny bit to make them unique
while (nodeMap.containsKey(vertex)) {
// SUPPRESS CHECKSTYLE NEXT 1 MagicNumber
vertex.add((Math.random() - 0.5) * 0.001, (Math.random() - 0.5) * 0.001);
// If two positions were identical, their corresponding edge in the spanning tree would be
// of zero length, had no direction, and couldn't be scaled by anything.
}
ElkMargin margin = elkNode.getProperty(CoreOptions.MARGINS);
Node node = new Node(vertex, new ElkRectangle(vertex.x - halfWidth - spacingNodeNode / 2 - margin.left, vertex.y - halfHeight - spacingNodeNode / 2 - margin.top, elkNode.getWidth() + spacingNodeNode + margin.getHorizontal(), elkNode.getHeight() + spacingNodeNode + margin.getVertical()));
graph.vertices.add(node);
nodeMap.put(vertex, Pair.of(node, elkNode));
}
// spanning tree root selection method
switch(rootSelection) {
case FIXED:
if (preferredRootID == null) {
// get first Node in list if no ID specified
graph.preferredRoot = graph.vertices.get(0);
} else {
// find Node associated with the ElkNode containing the ID
for (Node node : graph.vertices) {
String id = nodeMap.get(node.originalVertex).getSecond().getIdentifier();
if (id != null && id.equals(preferredRootID)) {
graph.preferredRoot = node;
}
}
}
break;
case CENTER_NODE:
// find node that is most central in the drawing
KVector center = new KVector(elkGraph.getWidth(), elkGraph.getHeight());
// CHECKSTYLEOFF MagicNumber
center.scale(0.5);
center.add(elkGraph.getX(), elkGraph.getY());
double closest = Double.POSITIVE_INFINITY;
for (Node node : graph.vertices) {
double distance = node.originalVertex.distance(center);
if (distance < closest) {
closest = distance;
graph.preferredRoot = node;
}
}
break;
default:
throw new IllegalArgumentException("No implementation available for " + rootSelection.toString());
}
return graph;
}
use of org.eclipse.elk.alg.common.spore.Node in project elk by eclipse.
the class UtilsTest method testUnderlapComputation.
private boolean testUnderlapComputation(ElkRectangle r1, ElkRectangle r2) {
Node n1 = new Node(r1.getCenter(), r1);
Node n2 = new Node(r2.getCenter(), r2);
double underlap = n1.underlap(n2);
// Additionally, the underlap should be equal to the distance in the direction
// given by the nodes' centers.
assertTrue(CompareFuzzy.eq(underlap, n1.distance(n2, n1.vertex.clone().sub(n2.vertex))));
// move + check shortest distance
n2.translate(n1.vertex.clone().sub(n2.vertex).scaleToLength(underlap));
return CompareFuzzy.eq(ElkMath.shortestDistance(n1.rect, n2.rect), 0.0);
}
use of org.eclipse.elk.alg.common.spore.Node in project elk by eclipse.
the class ElkGraphImporter method applyPositions.
@Override
public void applyPositions(final Graph g) {
// set new node positions
double minX = Double.POSITIVE_INFINITY;
double minY = Double.POSITIVE_INFINITY;
double maxX = Double.NEGATIVE_INFINITY;
double maxY = Double.NEGATIVE_INFINITY;
for (Node node : g.vertices) {
ElkNode elkNode = nodeMap.get(node.originalVertex).getSecond();
elkNode.setLocation(node.rect.x, node.rect.y);
minX = Math.min(minX, elkNode.getX());
minY = Math.min(minY, elkNode.getY());
maxX = Math.max(maxX, elkNode.getX() + elkNode.getWidth());
maxY = Math.max(maxY, elkNode.getY() + elkNode.getHeight());
}
// set new dimensions of parent node
ElkPadding padding = elkGraph.getProperty(SporeCompactionOptions.PADDING);
ElkUtil.resizeNode(elkGraph, maxX - minX + padding.getHorizontal(), maxY - minY + padding.getVertical(), true, true);
ElkUtil.translate(elkGraph, -minX + padding.left, -minY + padding.top);
// update edges and route them as straight lines
for (ElkEdge e : elkGraph.getContainedEdges()) {
ElkEdgeSection kedgeSection = ElkGraphUtil.firstEdgeSection(e, true, true);
ElkNode source = ElkGraphUtil.getSourceNode(e);
ElkNode target = ElkGraphUtil.getTargetNode(e);
KVector startLocation = new KVector(source.getX() + source.getWidth() / 2, source.getY() + source.getHeight() / 2);
KVector endLocation = new KVector(target.getX() + target.getWidth() / 2, target.getY() + target.getHeight() / 2);
KVector uv = endLocation.clone().sub(startLocation);
ElkMath.clipVector(uv, source.getWidth(), source.getHeight());
startLocation.add(uv);
KVector vu = startLocation.clone().sub(endLocation);
ElkMath.clipVector(vu, target.getWidth(), target.getHeight());
endLocation.add(vu);
kedgeSection.setStartLocation(startLocation.x, startLocation.y);
kedgeSection.setEndLocation(endLocation.x, endLocation.y);
}
}
use of org.eclipse.elk.alg.common.spore.Node in project elk by eclipse.
the class UtilsTest method distanceTest.
/**
* Distance test using different directions.
*/
@Test
public void distanceTest() {
List<Pair<KVector, Boolean>> vectors = Lists.newArrayList();
// true if the nodes should collide
vectors.add(Pair.of(new KVector(-20, 20), true));
vectors.add(Pair.of(new KVector(-80, 0), false));
vectors.add(Pair.of(new KVector(-20, 9), false));
vectors.add(Pair.of(new KVector(0, 50), false));
vectors.add(Pair.of(new KVector(-9.99, 50), false));
vectors.add(Pair.of(new KVector(60, 60), false));
vectors.add(Pair.of(new KVector(-30, 50), true));
vectors.add(Pair.of(new KVector(-20, 130), true));
vectors.add(Pair.of(new KVector(-20, -21), false));
// Arrays.stream(new File(ElkUtil.debugFolderPath("test")).listFiles()).forEach(File::delete);
Node n1 = new Node(r1.getCenter(), r1);
for (Pair<KVector, Boolean> v : vectors) {
Node n2 = new Node(rectangles.get(12).getCenter(), new ElkRectangle(rectangles.get(12)));
double distance = n1.distance(n2, v.getFirst());
// if they should collide, move them, otherwise check whether the returned distance is infinite
if (v.getSecond()) {
// move + check shortest distance
n2.translate(v.getFirst().scaleToLength(distance));
assertTrue(CompareFuzzy.eq(ElkMath.shortestDistance(n1.rect, n2.rect), 0.0));
} else {
assertTrue(Double.isInfinite(distance));
}
}
}
Aggregations