Search in sources :

Example 6 with FNode

use of org.eclipse.elk.alg.force.graph.FNode in project elk by eclipse.

the class AbstractForceModel method layout.

/**
 * Perform layout on the given force graph.
 *
 * @param fgraph a force graph
 * @param monitor a progress monitor
 */
public void layout(final FGraph fgraph, final IElkProgressMonitor monitor) {
    monitor.begin("Component Layout", 1);
    initialize(fgraph);
    int iterations = 0;
    while (moreIterations(iterations) && !monitor.isCanceled()) {
        // calculate attractive and repulsive forces
        for (FNode v : fgraph.getNodes()) {
            for (FParticle u : fgraph.getParticles()) {
                if (u != v) {
                    KVector displacement = calcDisplacement(u, v);
                    if (displacement != null) {
                        v.getDisplacement().add(displacement);
                    }
                }
            }
        }
        // apply calculated displacement
        for (FNode v : fgraph.getNodes()) {
            KVector d = v.getDisplacement();
            d.bound(-dispBound, -dispBound, dispBound, dispBound);
            v.getPosition().add(d);
            d.reset();
        }
        iterationDone();
        iterations++;
    }
    monitor.done();
}
Also used : FParticle(org.eclipse.elk.alg.force.graph.FParticle) FNode(org.eclipse.elk.alg.force.graph.FNode) KVector(org.eclipse.elk.core.math.KVector) FBendpoint(org.eclipse.elk.alg.force.graph.FBendpoint)

Example 7 with FNode

use of org.eclipse.elk.alg.force.graph.FNode in project elk by eclipse.

the class ComponentsProcessor method recombine.

// ///////////////////////////////////////////////////////////////////////////////////////////
// Recombination
/**
 * Pack the given components into a single graph.
 *
 * @param components a list of components.
 * @return a single graph that contains all components.
 */
public FGraph recombine(final List<FGraph> components) {
    if (components.size() == 1) {
        return components.get(0);
    } else if (components.size() <= 0) {
        return new FGraph();
    }
    // assign priorities and sizes
    for (FGraph graph : components) {
        int priority = 0;
        double minx = Integer.MAX_VALUE, miny = Integer.MAX_VALUE, maxx = Integer.MIN_VALUE, maxy = Integer.MIN_VALUE;
        for (FNode node : graph.getNodes()) {
            priority += node.getProperty(ForceOptions.PRIORITY);
            // careful: the (x,y) of an FNode refers to its center
            minx = Math.min(minx, node.getPosition().x - node.getSize().x / 2);
            miny = Math.min(miny, node.getPosition().y - node.getSize().y / 2);
            maxx = Math.max(maxx, node.getPosition().x + node.getSize().x / 2);
            maxy = Math.max(maxy, node.getPosition().y + node.getSize().y / 2);
        }
        graph.setProperty(ForceOptions.PRIORITY, priority);
        graph.setProperty(InternalProperties.BB_UPLEFT, new KVector(minx, miny));
        graph.setProperty(InternalProperties.BB_LOWRIGHT, new KVector(maxx, maxy));
    }
    // sort the components by their priority and size
    Collections.sort(components, new Comparator<FGraph>() {

        public int compare(final FGraph graph1, final FGraph graph2) {
            int prio = graph2.getProperty(ForceOptions.PRIORITY) - graph1.getProperty(ForceOptions.PRIORITY);
            if (prio == 0) {
                KVector size1 = graph1.getProperty(InternalProperties.BB_LOWRIGHT).clone().sub(graph1.getProperty(InternalProperties.BB_UPLEFT));
                KVector size2 = graph2.getProperty(InternalProperties.BB_LOWRIGHT).clone().sub(graph2.getProperty(InternalProperties.BB_UPLEFT));
                return Double.compare(size1.x * size1.y, size2.x * size2.y);
            }
            return prio;
        }
    });
    FGraph result = new FGraph();
    result.copyProperties(components.get(0));
    // determine the maximal row width by the maximal box width and the total area
    double maxRowWidth = 0.0f;
    double totalArea = 0.0f;
    for (FGraph graph : components) {
        KVector size = graph.getProperty(InternalProperties.BB_LOWRIGHT).clone().sub(graph.getProperty(InternalProperties.BB_UPLEFT));
        maxRowWidth = Math.max(maxRowWidth, size.x);
        totalArea += size.x * size.y;
    }
    maxRowWidth = Math.max(maxRowWidth, (float) Math.sqrt(totalArea) * result.getProperty(ForceOptions.ASPECT_RATIO));
    double spacing = result.getProperty(ForceOptions.SPACING_NODE_NODE).doubleValue();
    // place nodes iteratively into rows
    double xpos = 0, ypos = 0, highestBox = 0, broadestRow = spacing;
    for (FGraph graph : components) {
        KVector size = graph.getProperty(InternalProperties.BB_LOWRIGHT).clone().sub(graph.getProperty(InternalProperties.BB_UPLEFT));
        if (xpos + size.x > maxRowWidth) {
            // place the graph into the next row
            xpos = 0;
            ypos += highestBox + spacing;
            highestBox = 0;
        }
        moveGraph(result, graph, xpos, ypos);
        broadestRow = Math.max(broadestRow, xpos + size.x);
        highestBox = Math.max(highestBox, size.y);
        xpos += size.x + spacing;
    }
    return result;
}
Also used : FNode(org.eclipse.elk.alg.force.graph.FNode) FGraph(org.eclipse.elk.alg.force.graph.FGraph) KVector(org.eclipse.elk.core.math.KVector) FBendpoint(org.eclipse.elk.alg.force.graph.FBendpoint)

Example 8 with FNode

use of org.eclipse.elk.alg.force.graph.FNode in project elk by eclipse.

the class ComponentsProcessor method buildIncidenceLists.

/**
 * Creates and returns the incidence list that for each node lists the incident edges.
 *
 * @param graph a force graph.
 */
@SuppressWarnings("unchecked")
private List<FEdge>[] buildIncidenceLists(final FGraph graph) {
    int n = graph.getNodes().size();
    List<FEdge>[] incidence = new List[n];
    // create incidence lists
    for (FNode node : graph.getNodes()) {
        incidence[node.id] = new LinkedList<FEdge>();
    }
    // add edges to incidence lists
    for (FEdge edge : graph.getEdges()) {
        incidence[edge.getSource().id].add(edge);
        incidence[edge.getTarget().id].add(edge);
    }
    return incidence;
}
Also used : FNode(org.eclipse.elk.alg.force.graph.FNode) FEdge(org.eclipse.elk.alg.force.graph.FEdge) List(java.util.List) LinkedList(java.util.LinkedList) FBendpoint(org.eclipse.elk.alg.force.graph.FBendpoint)

Example 9 with FNode

use of org.eclipse.elk.alg.force.graph.FNode in project elk by eclipse.

the class ComponentsProcessor method split.

// ///////////////////////////////////////////////////////////////////////////////////////////
// Splitting
/**
 * Split the given graph into its connected components.
 *
 * @param graph an input graph.
 * @return a list of components that can be processed one by one.
 */
public List<FGraph> split(final FGraph graph) {
    Boolean separate = graph.getProperty(ForceOptions.SEPARATE_CONNECTED_COMPONENTS);
    if (separate == null || separate.booleanValue()) {
        boolean[] visited = new boolean[graph.getNodes().size()];
        List<FEdge>[] incidence = buildIncidenceLists(graph);
        // perform DFS starting on each node, collecting connected components
        List<FGraph> components = new LinkedList<FGraph>();
        for (FNode node : graph.getNodes()) {
            FGraph comp = dfs(node, null, null, visited, incidence);
            if (comp != null) {
                comp.copyProperties(graph);
                components.add(comp);
            }
        }
        // redistribute identifier numbers to each component
        if (components.size() > 1) {
            for (FGraph comp : components) {
                int id = 0;
                for (FNode node : comp.getNodes()) {
                    node.id = id++;
                }
            }
        }
        return components;
    }
    return Lists.newArrayList(graph);
}
Also used : FNode(org.eclipse.elk.alg.force.graph.FNode) FGraph(org.eclipse.elk.alg.force.graph.FGraph) List(java.util.List) LinkedList(java.util.LinkedList) LinkedList(java.util.LinkedList) FBendpoint(org.eclipse.elk.alg.force.graph.FBendpoint)

Example 10 with FNode

use of org.eclipse.elk.alg.force.graph.FNode in project elk by eclipse.

the class ComponentsProcessor method moveGraph.

/**
 * Move the source graph into the destination graph using a specified offset.
 *
 * @param destGraph the destination graph.
 * @param sourceGraph the source graph.
 * @param offsetx x coordinate offset.
 * @param offsety y coordinate offset.
 */
private void moveGraph(final FGraph destGraph, final FGraph sourceGraph, final double offsetx, final double offsety) {
    KVector graphOffset = new KVector(offsetx, offsety);
    graphOffset.sub(sourceGraph.getProperty(InternalProperties.BB_UPLEFT));
    for (FNode node : sourceGraph.getNodes()) {
        node.getPosition().add(graphOffset);
        destGraph.getNodes().add(node);
    }
    for (FEdge edge : sourceGraph.getEdges()) {
        for (FBendpoint bendpoint : edge.getBendpoints()) {
            bendpoint.getPosition().add(graphOffset);
        }
        destGraph.getEdges().add(edge);
    }
    for (FLabel label : sourceGraph.getLabels()) {
        label.getPosition().add(graphOffset);
        destGraph.getLabels().add(label);
    }
}
Also used : FBendpoint(org.eclipse.elk.alg.force.graph.FBendpoint) FLabel(org.eclipse.elk.alg.force.graph.FLabel) FNode(org.eclipse.elk.alg.force.graph.FNode) FEdge(org.eclipse.elk.alg.force.graph.FEdge) KVector(org.eclipse.elk.core.math.KVector)

Aggregations

FNode (org.eclipse.elk.alg.force.graph.FNode)15 KVector (org.eclipse.elk.core.math.KVector)7 FBendpoint (org.eclipse.elk.alg.force.graph.FBendpoint)6 FEdge (org.eclipse.elk.alg.force.graph.FEdge)6 FGraph (org.eclipse.elk.alg.force.graph.FGraph)3 ElkNode (org.eclipse.elk.graph.ElkNode)3 LinkedList (java.util.LinkedList)2 List (java.util.List)2 FLabel (org.eclipse.elk.alg.force.graph.FLabel)2 HashMap (java.util.HashMap)1 PriorityQueue (java.util.PriorityQueue)1 FParticle (org.eclipse.elk.alg.force.graph.FParticle)1 ElkPadding (org.eclipse.elk.core.math.ElkPadding)1 PortConstraints (org.eclipse.elk.core.options.PortConstraints)1 ElkEdge (org.eclipse.elk.graph.ElkEdge)1 ElkEdgeSection (org.eclipse.elk.graph.ElkEdgeSection)1 ElkLabel (org.eclipse.elk.graph.ElkLabel)1