use of org.eclipse.elk.alg.spore.graph.Graph 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.spore.graph.Graph in project elk by eclipse.
the class MaxSTPhase method process.
@Override
public void process(final Graph graph, final IElkProgressMonitor progressMonitor) {
progressMonitor.begin("Maximum spanning tree construction", 1);
// inverted cost function
ICostFunction invertedCF = e -> {
return -graph.costFunction.cost(e);
};
KVector root;
if (graph.preferredRoot != null) {
root = graph.preferredRoot.vertex;
} else {
root = graph.vertices.get(0).vertex;
}
Tree<KVector> tree;
if (graph.getProperty(InternalProperties.DEBUG_SVG)) {
tree = NaiveMinST.createSpanningTree(graph.tEdges, root, invertedCF, ElkUtil.debugFolderPath("spore") + "20minst");
} else {
tree = NaiveMinST.createSpanningTree(graph.tEdges, root, invertedCF);
}
// convert result to a Tree that can be used in the execution phase
convert(tree, graph);
progressMonitor.done();
}
use of org.eclipse.elk.alg.spore.graph.Graph in project elk by eclipse.
the class OverlapRemovalLayoutProvider method layout.
@Override
public void layout(final ElkNode layoutGraph, final IElkProgressMonitor progressMonitor) {
// If desired, apply a layout algorithm
if (layoutGraph.hasProperty(SporeCompactionOptions.UNDERLYING_LAYOUT_ALGORITHM)) {
String requestedAlgorithm = layoutGraph.getProperty(SporeOverlapRemovalOptions.UNDERLYING_LAYOUT_ALGORITHM);
LayoutAlgorithmData lad = LayoutMetaDataService.getInstance().getAlgorithmDataBySuffix(requestedAlgorithm);
if (lad != null) {
AbstractLayoutProvider layoutProvider = lad.getInstancePool().fetch();
layoutProvider.layout(layoutGraph, progressMonitor.subTask(1));
}
}
// set algorithm properties
layoutGraph.setProperty(SporeCompactionOptions.PROCESSING_ORDER_ROOT_SELECTION, RootSelection.CENTER_NODE);
layoutGraph.setProperty(SporeCompactionOptions.PROCESSING_ORDER_SPANNING_TREE_COST_FUNCTION, SpanningTreeCostFunction.INVERTED_OVERLAP);
layoutGraph.setProperty(SporeCompactionOptions.PROCESSING_ORDER_TREE_CONSTRUCTION, TreeConstructionStrategy.MINIMUM_SPANNING_TREE);
int maxIterations = layoutGraph.getProperty(SporeOverlapRemovalOptions.OVERLAP_REMOVAL_MAX_ITERATIONS);
progressMonitor.begin("Overlap removal", 1);
// initialize debug output
String debugOutputFile = null;
if (layoutGraph.getProperty(SporeOverlapRemovalOptions.DEBUG_MODE)) {
debugOutputFile = ElkUtil.debugFolderPath("spore") + "45scanlineOverlaps";
}
SVGImage svg = new SVGImage(debugOutputFile);
// set overlap handler and import ElkGraph
Set<TEdge> overlapEdges = Sets.newHashSet();
IOverlapHandler overlapHandler = (n1, n2) -> overlapEdges.add(new TEdge(n1.originalVertex, n2.originalVertex));
IGraphImporter<ElkNode> graphImporter = new ElkGraphImporter();
Graph graph = graphImporter.importGraph(layoutGraph);
boolean overlapsExisted = true;
int iteration = 0;
// repeat overlap removal
while (iteration < maxIterations && overlapsExisted) {
// scanline overlap check
if (layoutGraph.getProperty(SporeOverlapRemovalOptions.OVERLAP_REMOVAL_RUN_SCANLINE)) {
overlapEdges.clear();
new ScanlineOverlapCheck(overlapHandler, svg).sweep(graph.vertices);
if (overlapEdges.isEmpty()) {
// don't bother if nothing overlaps
break;
}
graph.tEdges = overlapEdges;
}
// assembling and executing the algorithm
algorithmAssembler.reset();
algorithmAssembler.setPhase(SPOrEPhases.P1_STRUCTURE, StructureExtractionStrategy.DELAUNAY_TRIANGULATION);
algorithmAssembler.setPhase(SPOrEPhases.P2_PROCESSING_ORDER, graph.treeConstructionStrategy);
algorithmAssembler.setPhase(SPOrEPhases.P3_EXECUTION, OverlapRemovalStrategy.GROW_TREE);
algorithm = algorithmAssembler.build(graph);
for (ILayoutProcessor<Graph> processor : algorithm) {
processor.process(graph, progressMonitor.subTask(1));
}
// update node positions
graphImporter.updateGraph(graph);
overlapsExisted = graph.getProperty(InternalProperties.OVERLAPS_EXISTED);
iteration++;
}
// apply node positions to ElkGraph
graphImporter.applyPositions(graph);
progressMonitor.done();
}
use of org.eclipse.elk.alg.spore.graph.Graph in project elk by eclipse.
the class ShrinkTreeLayoutProvider method layout.
@Override
public void layout(final ElkNode layoutGraph, final IElkProgressMonitor progressMonitor) {
// If desired, apply a layout algorithm
if (layoutGraph.hasProperty(SporeCompactionOptions.UNDERLYING_LAYOUT_ALGORITHM)) {
String requestedAlgorithm = layoutGraph.getProperty(SporeCompactionOptions.UNDERLYING_LAYOUT_ALGORITHM);
LayoutAlgorithmData lad = LayoutMetaDataService.getInstance().getAlgorithmDataBySuffix(requestedAlgorithm);
if (lad != null) {
AbstractLayoutProvider layoutProvider = lad.getInstancePool().fetch();
layoutProvider.layout(layoutGraph, progressMonitor.subTask(1));
}
}
IGraphImporter<ElkNode> graphImporter = new ElkGraphImporter();
Graph graph = graphImporter.importGraph(layoutGraph);
shrinktree.shrink(graph, progressMonitor.subTask(1));
graphImporter.applyPositions(graph);
}
Aggregations