All Downloads are FREE. Search and download functionalities are using the official Maven repository.

lphystudio.core.layeredgraph.ProperLayeredGraph Maven / Gradle / Ivy

The newest version!
package lphystudio.core.layeredgraph;

import java.util.ArrayList;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;

/**
 * The SugiyamaLayoutAlgorithm class implements an algorithm to arrange a
 * directed graph in a layered tree-like layout. The final presentation follows
 * five design principles for enhanced readability:
 * 

* - Hierarchical layout of vertices - Least crossings of lines (edges) - * Straightness of lines when ever possible - Close layout of vertices connected * to each other, i.e. short paths - Balanced layout of lines coming into or * going from a vertex *

* For further information see http://dx.doi.org/10.1109/TSMC.1981.4308636 * * @author Rene Kuhlemann * @version 1.2 */ public class ProperLayeredGraph extends LayeredGraph { Layering layering; LayeredGraph wrappedGraph; final Map map = new IdentityHashMap<>(); public ProperLayeredGraph(LayeredGraph wrappedGraph, Layering layering) { this.layering = layering; this.wrappedGraph = wrappedGraph; setup(); } public void setWrappedGraph(LayeredGraph layeredGraph) { this.wrappedGraph = layeredGraph; setup(); } void setup() { makeProper(); } final void makeProper() { layers.clear(); map.clear(); wrappedGraph.applyLayering(layering); int i = 0; for (List layer : wrappedGraph.layers) { addLayer(layer); } updateIndex(); } public List getNodes() { ArrayList nodes = new ArrayList<>(); for (List layer : layers) { nodes.addAll(layer); } return nodes; } /** * Wraps all {@link LayeredNode} objects into an internal presentation * {@link NodeWrapper} and inserts dummy wrappers into the layers between an * object and their predecessing nodes if necessary. Finally, all nodes are * chained over immediate adjacent layers down to their predecessors. * * @param list : List of all {@link LayeredNode} objects within the current * layer */ private void addLayer(List list) { List layer = new ArrayList<>(list.size()); for (LayeredNode node : list) { // wrap each NodeLayout with the internal data object and provide a // corresponding mapping NodeWrapper nw = new NodeWrapper(node, layers.size()); map.put(node, nw); layer.add(nw); // insert dummy nodes if the adjacent layer does not contain the // predecessor for (LayeredNode node_predecessor : node.getPredecessors()) { // for // all // predecessors LayeredNode nw_predecessor = map.get(node_predecessor); if (nw_predecessor == null) { throw new RuntimeException("Node wrapped Predecessor of node " + node + " was null!"); } for (int layerIndex = nw_predecessor.getLayer() + 1; layerIndex < nw.getLayer(); layerIndex++) { // add "virtual" wrappers (dummies) to the layers in between // virtual wrappers are in fact parts of a double linked // list NodeWrapper nw_dummy = new NodeWrapper(layerIndex); nw_dummy.getPredecessors().add(nw_predecessor); nw_predecessor.getSuccessors().add(nw_dummy); nw_predecessor = nw_dummy; layers.get(layerIndex).add(nw_dummy); } nw.getPredecessors().add(nw_predecessor); nw_predecessor.getSuccessors().add(nw); } } layers.add(layer); updateIndex(layers.size()-1); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy