Search in sources :

Example 21 with Node

use of org.knime.workbench.ui.layout.Graph.Node in project knime-core by knime.

the class Layerer method assignLayers.

/**
 * Perform a topological sort to assign layers to nodes. If there are fixed
 * nodes they will be placed on the first or last layer, depending on
 * whether they are sources or sinks.
 *
 * @param g the graph to be layered
 * @param nodeLayer a map storing the layer of each node
 * @param fixedSources a list of sources to fix on the first layer, or null
 *            if none exist
 * @param fixedSinks a list of sinks to fix on the last layer, or null if
 *            none exist
 * @return the list of layers, each layer containing an array list of nodes
 */
static ArrayList<ArrayList<Node>> assignLayers(final Graph g, final Map<Node, Integer> nodeLayer, final ArrayList<Node> fixedSources, final ArrayList<Node> fixedSinks) {
    // initialize residual degrees, and find first sources
    ArrayList<ArrayList<Node>> layers = new ArrayList<ArrayList<Node>>();
    Map<Node, Integer> residualDegree = g.createIntNodeMap();
    ArrayList<Node> sources = new ArrayList<Node>();
    for (Node n : g.nodes()) {
        residualDegree.put(n, n.inDegree());
        if (n.inDegree() == 0) {
            sources.add(n);
        }
    }
    // process each layer:
    int layer = 0;
    // handle fixed sources, if any
    if (fixedSources != null) {
        layers.add(fixedSources);
        for (Node n : fixedSources) {
            sources.remove(n);
            nodeLayer.put(n, layer);
            // check if any of the outgoing neighbors becomes a source
            updateSources(g, n, sources, residualDegree);
        }
        layer++;
    }
    // handle regular nodes
    while (!sources.isEmpty()) {
        ArrayList<Node> nextSources = new ArrayList<Node>();
        // put all of the current sources on the current layer
        layers.add(sources);
        for (Node n : sources) {
            nodeLayer.put(n, layer);
            updateSources(g, n, nextSources, residualDegree);
        }
        // advance to the next layer
        sources = nextSources;
        layer++;
    }
    // handle fixed sinks by putting them on the last layer
    if (fixedSinks != null) {
        // check if there are non-fixed sinks on the current last layer
        boolean lastLayerValid = true;
        int lastlayer = layers.size() - 1;
        for (Node n : layers.get(lastlayer)) {
            if (!fixedSinks.contains(n)) {
                lastLayerValid = false;
            }
        }
        // sinks to this layer, otherwise introduce new last layer
        if (!lastLayerValid) {
            lastlayer++;
            layers.add(new ArrayList<Graph.Node>());
        }
        for (Node n : fixedSinks) {
            layers.get(nodeLayer.get(n)).remove(n);
            nodeLayer.put(n, lastlayer);
            layers.get(lastlayer).add(n);
        }
    }
    return layers;
}
Also used : Node(org.knime.workbench.ui.layout.Graph.Node) ArrayList(java.util.ArrayList)

Aggregations

Node (org.knime.workbench.ui.layout.Graph.Node)21 Edge (org.knime.workbench.ui.layout.Graph.Edge)5 ArrayList (java.util.ArrayList)4 Graph (org.knime.workbench.ui.layout.Graph)3 HashMap (java.util.HashMap)2 Point2D (java.awt.geom.Point2D)1 Point (org.eclipse.draw2d.geometry.Point)1 ConnectionID (org.knime.core.node.workflow.ConnectionID)1 ConnectionUIInformation (org.knime.core.node.workflow.ConnectionUIInformation)1 NodeID (org.knime.core.node.workflow.NodeID)1 NodeUIInformation (org.knime.core.node.workflow.NodeUIInformation)1 ConnectionContainerUI (org.knime.core.ui.node.workflow.ConnectionContainerUI)1 NodeContainerUI (org.knime.core.ui.node.workflow.NodeContainerUI)1 SimpleLayeredLayouter (org.knime.workbench.ui.layout.layeredlayout.SimpleLayeredLayouter)1