Search in sources :

Example 1 with Graph

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;
}
Also used : ICostFunction(org.eclipse.elk.alg.common.ICostFunction) SpanningTreeCostFunction(org.eclipse.elk.alg.spore.options.SpanningTreeCostFunction) CompactionStrategy(org.eclipse.elk.alg.spore.options.CompactionStrategy) ElkNode(org.eclipse.elk.graph.ElkNode) Node(org.eclipse.elk.alg.common.spore.Node) ElkNode(org.eclipse.elk.graph.ElkNode) ElkMargin(org.eclipse.elk.core.math.ElkMargin) RootSelection(org.eclipse.elk.alg.spore.options.RootSelection) Graph(org.eclipse.elk.alg.spore.graph.Graph) TreeConstructionStrategy(org.eclipse.elk.alg.spore.options.TreeConstructionStrategy) KVector(org.eclipse.elk.core.math.KVector) ElkRectangle(org.eclipse.elk.core.math.ElkRectangle) ElkGraphAdapter(org.eclipse.elk.core.util.adapters.ElkGraphAdapters.ElkGraphAdapter)

Example 2 with 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();
}
Also used : ICostFunction(org.eclipse.elk.alg.common.ICostFunction) ElkUtil(org.eclipse.elk.core.util.ElkUtil) NaiveMinST(org.eclipse.elk.alg.common.NaiveMinST) KVector(org.eclipse.elk.core.math.KVector) IElkProgressMonitor(org.eclipse.elk.core.util.IElkProgressMonitor) ICostFunction(org.eclipse.elk.alg.common.ICostFunction) Tree(org.eclipse.elk.alg.common.Tree) Graph(org.eclipse.elk.alg.spore.graph.Graph) InternalProperties(org.eclipse.elk.alg.common.spore.InternalProperties) KVector(org.eclipse.elk.core.math.KVector)

Example 3 with Graph

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();
}
Also used : TEdge(org.eclipse.elk.alg.common.TEdge) ScanlineOverlapCheck(org.eclipse.elk.alg.common.spore.ScanlineOverlapCheck) RootSelection(org.eclipse.elk.alg.spore.options.RootSelection) AlgorithmAssembler(org.eclipse.elk.core.alg.AlgorithmAssembler) AbstractLayoutProvider(org.eclipse.elk.core.AbstractLayoutProvider) LayoutAlgorithmData(org.eclipse.elk.core.data.LayoutAlgorithmData) IElkProgressMonitor(org.eclipse.elk.core.util.IElkProgressMonitor) Set(java.util.Set) Graph(org.eclipse.elk.alg.spore.graph.Graph) TreeConstructionStrategy(org.eclipse.elk.alg.spore.options.TreeConstructionStrategy) OverlapRemovalStrategy(org.eclipse.elk.alg.spore.options.OverlapRemovalStrategy) ElkNode(org.eclipse.elk.graph.ElkNode) SpanningTreeCostFunction(org.eclipse.elk.alg.spore.options.SpanningTreeCostFunction) ILayoutProcessor(org.eclipse.elk.core.alg.ILayoutProcessor) Sets(com.google.common.collect.Sets) SporeCompactionOptions(org.eclipse.elk.alg.spore.options.SporeCompactionOptions) ElkUtil(org.eclipse.elk.core.util.ElkUtil) SVGImage(org.eclipse.elk.alg.common.utils.SVGImage) List(java.util.List) SporeOverlapRemovalOptions(org.eclipse.elk.alg.spore.options.SporeOverlapRemovalOptions) IOverlapHandler(org.eclipse.elk.alg.common.spore.IOverlapHandler) StructureExtractionStrategy(org.eclipse.elk.alg.spore.options.StructureExtractionStrategy) LayoutMetaDataService(org.eclipse.elk.core.data.LayoutMetaDataService) InternalProperties(org.eclipse.elk.alg.common.spore.InternalProperties) ScanlineOverlapCheck(org.eclipse.elk.alg.common.spore.ScanlineOverlapCheck) ElkNode(org.eclipse.elk.graph.ElkNode) IOverlapHandler(org.eclipse.elk.alg.common.spore.IOverlapHandler) SVGImage(org.eclipse.elk.alg.common.utils.SVGImage) LayoutAlgorithmData(org.eclipse.elk.core.data.LayoutAlgorithmData) TEdge(org.eclipse.elk.alg.common.TEdge) Graph(org.eclipse.elk.alg.spore.graph.Graph) AbstractLayoutProvider(org.eclipse.elk.core.AbstractLayoutProvider)

Example 4 with Graph

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);
}
Also used : LayoutAlgorithmData(org.eclipse.elk.core.data.LayoutAlgorithmData) Graph(org.eclipse.elk.alg.spore.graph.Graph) ElkNode(org.eclipse.elk.graph.ElkNode) AbstractLayoutProvider(org.eclipse.elk.core.AbstractLayoutProvider)

Aggregations

Graph (org.eclipse.elk.alg.spore.graph.Graph)4 ElkNode (org.eclipse.elk.graph.ElkNode)3 ICostFunction (org.eclipse.elk.alg.common.ICostFunction)2 InternalProperties (org.eclipse.elk.alg.common.spore.InternalProperties)2 RootSelection (org.eclipse.elk.alg.spore.options.RootSelection)2 SpanningTreeCostFunction (org.eclipse.elk.alg.spore.options.SpanningTreeCostFunction)2 TreeConstructionStrategy (org.eclipse.elk.alg.spore.options.TreeConstructionStrategy)2 AbstractLayoutProvider (org.eclipse.elk.core.AbstractLayoutProvider)2 LayoutAlgorithmData (org.eclipse.elk.core.data.LayoutAlgorithmData)2 KVector (org.eclipse.elk.core.math.KVector)2 ElkUtil (org.eclipse.elk.core.util.ElkUtil)2 IElkProgressMonitor (org.eclipse.elk.core.util.IElkProgressMonitor)2 Sets (com.google.common.collect.Sets)1 List (java.util.List)1 Set (java.util.Set)1 NaiveMinST (org.eclipse.elk.alg.common.NaiveMinST)1 TEdge (org.eclipse.elk.alg.common.TEdge)1 Tree (org.eclipse.elk.alg.common.Tree)1 IOverlapHandler (org.eclipse.elk.alg.common.spore.IOverlapHandler)1 Node (org.eclipse.elk.alg.common.spore.Node)1