Kolja Strohm il y a 6 ans
Parent
commit
647beb1ca4

+ 18 - 1
doc/chapter/3progress.tex

@@ -1,9 +1,26 @@
 The following features are either planned (\planned), under construction (\progress) or done (\done):
 The following features are either planned (\planned), under construction (\progress) or done (\done):
 \begin{itemize}
 \begin{itemize}
     \item[\done] Reading from an input file as described in section~\ref{sec:inputFileFormat}.
     \item[\done] Reading from an input file as described in section~\ref{sec:inputFileFormat}.
+    \item[\done] Creating random graphs for testing purposes.
+    \begin{itemize}
+        \item[\done] Saving those randomly created graphs.
+    \end{itemize}
     \item[\done] Drawing a graph with specified node sizes and positions.
     \item[\done] Drawing a graph with specified node sizes and positions.
     \item[\progress] Running the node placement algorithm by Brandes and Köpf~\cite{brandes_fast_2001}.
     \item[\progress] Running the node placement algorithm by Brandes and Köpf~\cite{brandes_fast_2001}.
-    \item[\done] Illustrating the progress while the algorithm is running.
+    \begin{itemize}
+        \item[\done] Calculating the blocks.
+        \item[\progress] Compacting the layout.
+        \item[\planned] Combining the layouts.
+    \end{itemize}
+    \item[\progress] Illustrating the progress while the algorithm is running in the form of
+    \begin{itemize}
+        \item[\done] Drawing the nodes at their current position.
+        \item[\done] Drawing the nodes in the color of their blocks.
+        \item[\done] Drawing a colored circle to show the class assignments.
+        \item[\done] Drawing the edges just as plain straight lines.
+        \item[\progress] Drawing the four extremal layouts and the combined layout separately.
+        \item[\planned] Drawing the edges of the block graph (in a different color than other edges).
+    \end{itemize}
     \item[\done] Running the algorithm step by step manually (by pushing a button labeled \enquote{Step}).
     \item[\done] Running the algorithm step by step manually (by pushing a button labeled \enquote{Step}).
     \item[\progress] Running the algorithm step by step with configurable delay.
     \item[\progress] Running the algorithm step by step with configurable delay.
     \item[\planned] Using debugger-like commands such as \enquote{step into}, \enquote{step over}, \enquote{step out}.
     \item[\planned] Using debugger-like commands such as \enquote{step into}, \enquote{step over}, \enquote{step out}.

+ 2 - 4
doc/doc.bib

@@ -21,11 +21,9 @@
 	copyright = {MIT},
 	copyright = {MIT},
 	shorttitle = {{JSON}-java},
 	shorttitle = {{JSON}-java},
 	url = {https://github.com/stleary/JSON-java},
 	url = {https://github.com/stleary/JSON-java},
-	urldate = {2018-06-09},
 	author = {Leary, Sean and Crockford, Douglas},
 	author = {Leary, Sean and Crockford, Douglas},
 	month = jun,
 	month = jun,
-	year = {2018},
-	note = {original-date: 2010-12-21T17:46:09Z}
+	year = {2018}
 }
 }
 
 
 @article{sugiyama_methods_1981,
 @article{sugiyama_methods_1981,
@@ -39,7 +37,7 @@
 	author = {Sugiyama, K. and Tagawa, S. and Toda, M.},
 	author = {Sugiyama, K. and Tagawa, S. and Toda, M.},
 	month = feb,
 	month = feb,
 	year = {1981},
 	year = {1981},
-	keywords = {Computer displays, Constraint theory, Engineering drawings, Flowcharts, Hierarchical systems, Image recognition, Information science, Processor scheduling, Programming, Testing},
+	keywords = {Testing, Computer displays, Constraint theory, Engineering drawings, Flowcharts, Hierarchical systems, Image recognition, Information science, Processor scheduling, Programming},
 	pages = {109--125}
 	pages = {109--125}
 }
 }
 
 

+ 22 - 5
doc/zotero_backup/NodePlacementAnimation/NodePlacementAnimation.rdf

@@ -88,8 +88,6 @@
         </dc:identifier>
         </dc:identifier>
         <dc:rights>MIT</dc:rights>
         <dc:rights>MIT</dc:rights>
         <dc:date>2018-06-08T16:01:34Z</dc:date>
         <dc:date>2018-06-08T16:01:34Z</dc:date>
-        <dc:description>original-date: 2010-12-21T17:46:09Z</dc:description>
-        <dcterms:dateSubmitted>2018-06-09 01:27:34</dcterms:dateSubmitted>
         <z:libraryCatalog>GitHub</z:libraryCatalog>
         <z:libraryCatalog>GitHub</z:libraryCatalog>
         <z:programmingLanguage>Java</z:programmingLanguage>
         <z:programmingLanguage>Java</z:programmingLanguage>
         <dc:title>JSON-java: A reference implementation of a JSON package in Java</dc:title>
         <dc:title>JSON-java: A reference implementation of a JSON package in Java</dc:title>
@@ -120,6 +118,9 @@
                 </rdf:li>
                 </rdf:li>
             </rdf:Seq>
             </rdf:Seq>
         </bib:authors>
         </bib:authors>
+        <dc:subject>
+           <z:AutomaticTag><rdf:value>Testing</rdf:value></z:AutomaticTag>
+        </dc:subject>
         <dc:subject>
         <dc:subject>
             <z:AutomaticTag>
             <z:AutomaticTag>
                <rdf:value>Computer displays</rdf:value>
                <rdf:value>Computer displays</rdf:value>
@@ -161,9 +162,6 @@
         <dc:subject>
         <dc:subject>
            <z:AutomaticTag><rdf:value>Programming</rdf:value></z:AutomaticTag>
            <z:AutomaticTag><rdf:value>Programming</rdf:value></z:AutomaticTag>
         </dc:subject>
         </dc:subject>
-        <dc:subject>
-           <z:AutomaticTag><rdf:value>Testing</rdf:value></z:AutomaticTag>
-        </dc:subject>
         <bib:pages>109-125</bib:pages>
         <bib:pages>109-125</bib:pages>
         <dc:date>February 1981</dc:date>
         <dc:date>February 1981</dc:date>
         <z:libraryCatalog>IEEE Xplore</z:libraryCatalog>
         <z:libraryCatalog>IEEE Xplore</z:libraryCatalog>
@@ -177,4 +175,23 @@
         <dc:identifier>ISSN 0018-9472</dc:identifier>
         <dc:identifier>ISSN 0018-9472</dc:identifier>
         <dc:identifier>DOI 10.1109/TSMC.1981.4308636</dc:identifier>
         <dc:identifier>DOI 10.1109/TSMC.1981.4308636</dc:identifier>
     </bib:Journal>
     </bib:Journal>
+    <bib:Data rdf:about="https://github.com/eclipse/elk">
+        <z:itemType>computerProgram</z:itemType>
+        <dc:publisher>
+            <foaf:Organization>
+               <foaf:name>Eclipse Foundation</foaf:name>
+            </foaf:Organization>
+        </dc:publisher>
+        <dc:identifier>
+            <dcterms:URI>
+               <rdf:value>https://github.com/eclipse/elk</rdf:value>
+            </dcterms:URI>
+        </dc:identifier>
+        <dc:rights>EPL-1.0</dc:rights>
+        <dc:date>2018-06-09T11:09:35Z</dc:date>
+        <z:libraryCatalog>GitHub</z:libraryCatalog>
+        <z:programmingLanguage>Java</z:programmingLanguage>
+        <dc:title>ELK: Eclipse Layout Kernel - Automatic layout for Java applications</dc:title>
+        <z:shortTitle>ELK</z:shortTitle>
+    </bib:Data>
 </rdf:RDF>
 </rdf:RDF>

+ 1 - 1
save.graph

@@ -1 +1 @@
-{"layers":[[{"layers":[],"edges":[],"name":"0"},{"layers":[],"edges":[],"name":"1"},{"layers":[],"edges":[],"name":"2"},{"layers":[],"edges":[],"name":"3"},{"layers":[],"edges":[],"name":"4"},{"layers":[],"edges":[],"name":"5"},{"layers":[],"edges":[],"name":"6"},{"layers":[],"edges":[],"name":"7"}],[{"layers":[],"edges":[],"name":"8"},{"layers":[],"edges":[],"name":"9"},{"layers":[],"edges":[],"name":"10"},{"layers":[],"edges":[],"name":"11"},{"layers":[],"edges":[],"name":"12"},{"layers":[],"edges":[],"name":"13"},{"layers":[],"edges":[],"name":"14"}],[{"layers":[],"edges":[],"name":"15"},{"layers":[],"edges":[],"name":"16"},{"layers":[],"edges":[],"name":"17"},{"layers":[],"edges":[],"name":"18"},{"layers":[],"edges":[],"name":"19"},{"layers":[],"edges":[],"name":"20"},{"layers":[],"edges":[],"name":"21"},{"layers":[],"edges":[],"name":"22"}],[{"layers":[],"edges":[],"name":"23"},{"layers":[],"edges":[],"name":"24"},{"layers":[],"edges":[],"name":"25"},{"layers":[],"edges":[],"name":"26"},{"layers":[],"edges":[],"name":"27"},{"layers":[],"edges":[],"name":"28"},{"layers":[],"edges":[],"name":"29"},{"layers":[],"edges":[],"name":"30"}],[{"layers":[],"edges":[],"name":"31"},{"layers":[],"edges":[],"name":"32"},{"layers":[],"edges":[],"name":"33"},{"layers":[],"edges":[],"name":"34"},{"layers":[],"edges":[],"name":"35"}],[{"layers":[],"edges":[],"name":"36"},{"layers":[],"edges":[],"name":"37"},{"layers":[],"edges":[],"name":"38"},{"layers":[],"edges":[],"name":"39"},{"layers":[],"edges":[],"name":"40"}],[{"layers":[],"edges":[],"name":"41"},{"layers":[],"edges":[],"name":"42"},{"layers":[],"edges":[],"name":"43"},{"layers":[],"edges":[],"name":"44"},{"layers":[],"edges":[],"name":"45"}],[{"layers":[],"edges":[],"name":"46"},{"layers":[],"edges":[],"name":"47"},{"layers":[],"edges":[],"name":"48"},{"layers":[],"edges":[],"name":"49"},{"layers":[],"edges":[],"name":"50"}],[{"layers":[],"edges":[],"name":"51"},{"layers":[],"edges":[],"name":"52"},{"layers":[],"edges":[],"name":"53"},{"layers":[],"edges":[],"name":"54"},{"layers":[],"edges":[],"name":"55"},{"layers":[],"edges":[],"name":"56"},{"layers":[],"edges":[],"name":"57"}]],"edges":[{"source":"4","target":"9"},{"source":"7","target":"12"},{"source":"5","target":"10"},{"source":"6","target":"11"},{"source":"7","target":"11"},{"source":"11","target":"16"},{"source":"11","target":"18"},{"source":"14","target":"22"},{"source":"13","target":"22"},{"source":"11","target":"19"},{"source":"13","target":"20"},{"source":"10","target":"17"},{"source":"20","target":"26"},{"source":"17","target":"26"},{"source":"15","target":"24"},{"source":"21","target":"27"},{"source":"16","target":"25"},{"source":"24","target":"31"},{"source":"24","target":"32"},{"source":"29","target":"33"},{"source":"34","target":"37"},{"source":"31","target":"36"},{"source":"40","target":"44"},{"source":"37","target":"43"},{"source":"47","target":"54"},{"source":"50","target":"54"}]}
+{"layers":[[{"layers":[],"edges":[],"name":"0"},{"layers":[],"edges":[],"name":"1"},{"layers":[],"edges":[],"name":"2"},{"layers":[],"edges":[],"name":"3"},{"layers":[],"edges":[],"name":"4"}],[{"layers":[],"edges":[],"name":"5"},{"layers":[],"edges":[],"name":"6"},{"layers":[],"edges":[],"name":"7"},{"layers":[],"edges":[],"name":"8"},{"layers":[],"edges":[],"name":"9"}],[{"layers":[],"edges":[],"name":"10"},{"layers":[],"edges":[],"name":"11"},{"layers":[],"edges":[],"name":"12"},{"layers":[],"edges":[],"name":"13"},{"layers":[],"edges":[],"name":"14"}],[{"layers":[],"edges":[],"name":"15"},{"layers":[],"edges":[],"name":"16"},{"layers":[],"edges":[],"name":"17"},{"layers":[],"edges":[],"name":"18"},{"layers":[],"edges":[],"name":"19"}],[{"layers":[],"edges":[],"name":"20"},{"layers":[],"edges":[],"name":"21"},{"layers":[],"edges":[],"name":"22"},{"layers":[],"edges":[],"name":"23"},{"layers":[],"edges":[],"name":"24"}]],"edges":[{"source":"4","target":"6"},{"source":"1","target":"5"},{"source":"8","target":"13"},{"source":"9","target":"13"},{"source":"8","target":"11"},{"source":"8","target":"12"},{"source":"6","target":"10"},{"source":"10","target":"15"},{"source":"12","target":"18"},{"source":"16","target":"21"}]}

+ 67 - 33
src/Algorithms/Animated/BK/BlockCalc.java

@@ -5,6 +5,7 @@ import java.util.ArrayList;
 
 
 import Algorithms.Animated.AlgorithmStage;
 import Algorithms.Animated.AlgorithmStage;
 import Algorithms.Animated.BackwardAction;
 import Algorithms.Animated.BackwardAction;
+import Algorithms.Animated.BK.ExtremalLayoutCalc.LayoutType;
 import Model.LayeredGraphEdge;
 import Model.LayeredGraphEdge;
 import Model.LayeredGraphNode;
 import Model.LayeredGraphNode;
 
 
@@ -21,10 +22,12 @@ public class BlockCalc implements AlgorithmStage {
 	private LayeredGraphNode graph;
 	private LayeredGraphNode graph;
 	private ArrayList< ArrayList< BKNodePlacement > > subgraphAlgs;
 	private ArrayList< ArrayList< BKNodePlacement > > subgraphAlgs;
 	private ArrayList< BackwardAction > backwards;
 	private ArrayList< BackwardAction > backwards;
+	private LayoutType layout;
 	int step;
 	int step;
 	
 	
-	public BlockCalc( LayeredGraphNode graph )
+	public BlockCalc( LayeredGraphNode graph, LayoutType layout )
 	{
 	{
+	    this.layout = layout;
 		step = 0;
 		step = 0;
 		this.graph = graph;
 		this.graph = graph;
 		layerIndex = 0;
 		layerIndex = 0;
@@ -41,18 +44,40 @@ public class BlockCalc implements AlgorithmStage {
 		backwards = new ArrayList<>();
 		backwards = new ArrayList<>();
 	}
 	}
 	
 	
+	private int calcLayerIndex()
+	{
+        if( layout == LayoutType.TOP_BOTTOM_LEFT || layout == LayoutType.TOP_BOTTOM_RIGHT )
+	        return layerIndex;
+        if( layout == LayoutType.BOTTOM_TOP_LEFT || layout == LayoutType.BOTTOM_TOP_RIGHT )
+	        return graph.getContainedLayers().size() - layerIndex - 1;
+	    return -1;
+	}
+	
+	private int calcBeforeLayerIndex()
+	{
+        if( layout == LayoutType.TOP_BOTTOM_LEFT || layout == LayoutType.TOP_BOTTOM_RIGHT )
+            return layerIndex - 1;
+        if( layout == LayoutType.BOTTOM_TOP_LEFT || layout == LayoutType.BOTTOM_TOP_RIGHT )
+            return graph.getContainedLayers().size() - layerIndex;
+        return -1;
+	}
+	
 	@Override
 	@Override
 	public StageStatus forwardStep() {
 	public StageStatus forwardStep() {
-		LayeredGraphNode current = graph.getContainedLayers().get( layerIndex ).get( nodeIndex );
-		current.setSelected();
+		LayeredGraphNode current = graph.getContainedLayers().get( calcLayerIndex() ).get( nodeIndex );
+		current.setSelected( layout );
 		if( current.getContainedNodes().size() > 0 )
 		if( current.getContainedNodes().size() > 0 )
 		{
 		{
-			if( subgraphAlgs.get( layerIndex ).get( nodeIndex ) == null )
-				subgraphAlgs.get( layerIndex ).set( nodeIndex, new BKNodePlacement( null, current ) );
-			if( subgraphAlgs.get( layerIndex ).get( nodeIndex ).forwardStep() == StageStatus.UNFINISHED )
+			if( subgraphAlgs.get( calcLayerIndex() ).get( nodeIndex ) == null )
+				subgraphAlgs.get( calcLayerIndex() ).set( nodeIndex, new BKNodePlacement( null, current ) );
+			if( subgraphAlgs.get( calcLayerIndex() ).get( nodeIndex ).forwardStep() == StageStatus.UNFINISHED )
 				return StageStatus.UNFINISHED;
 				return StageStatus.UNFINISHED;
 		}
 		}
-		ArrayList< LayeredGraphEdge > incommingEdges = current.getSortedIncomingEdges();
+		ArrayList< LayeredGraphEdge > incommingEdges = null;
+        if( layout == LayoutType.TOP_BOTTOM_LEFT || layout == LayoutType.TOP_BOTTOM_RIGHT )
+            incommingEdges = current.getSortedIncomingEdges();
+        if( layout == LayoutType.BOTTOM_TOP_LEFT || layout == LayoutType.BOTTOM_TOP_RIGHT )
+            incommingEdges = current.getSortedOutgoingEdges();
 		if( incommingEdges.size() == 0 )
 		if( incommingEdges.size() == 0 )
 		{
 		{
 			backwards.add( 0, () -> {
 			backwards.add( 0, () -> {
@@ -60,15 +85,23 @@ public class BlockCalc implements AlgorithmStage {
 			});
 			});
 			return calcNextState();
 			return calcNextState();
 		}
 		}
-		int[] ms = {(incommingEdges.size() + 1) / 2, (int)( (incommingEdges.size() + 1) / 2.0 + 0.5 )};
+		int[] ms = null;
+		if( layout == LayoutType.TOP_BOTTOM_LEFT || layout == LayoutType.BOTTOM_TOP_LEFT )
+		    ms = new int[]{(incommingEdges.size() + 1) / 2, (int)( (incommingEdges.size() + 1) / 2.0 + 0.5 )};
+        if( layout == LayoutType.TOP_BOTTOM_RIGHT || layout == LayoutType.BOTTOM_TOP_RIGHT )
+            ms = new int[]{(int)( (incommingEdges.size() + 1) / 2.0 + 0.5 ), (incommingEdges.size() + 1) / 2};
 		boolean backwardsAdded = false;
 		boolean backwardsAdded = false;
 		for( int m : ms )
 		for( int m : ms )
 		{
 		{
-		    if( current.getAlignedTo() == current )
+		    if( current.getAlignedTo( layout ) == current )
 		    {
 		    {
-                LayeredGraphNode u = incommingEdges.get( m - 1 ).getSources().get( 0 );
+                LayeredGraphNode u = null;
+                if( layout == LayoutType.TOP_BOTTOM_LEFT || layout == LayoutType.TOP_BOTTOM_RIGHT )
+                    u = incommingEdges.get( m - 1 ).getSources().get( 0 );
+                if( layout == LayoutType.BOTTOM_TOP_LEFT || layout == LayoutType.BOTTOM_TOP_RIGHT )
+                    u = incommingEdges.get( m - 1 ).getTargets().get( 0 );
                 ArrayList<LayeredGraphEdge> conflicts = incommingEdges.get( m - 1 ).calcConflictedEdges();
                 ArrayList<LayeredGraphEdge> conflicts = incommingEdges.get( m - 1 ).calcConflictedEdges();
-		        if( !incommingEdges.get( m - 1 ).isConflicted() && r < graph.getContainedLayers().get( layerIndex - 1 ).indexOf( u ) + 1 )
+		        if( !incommingEdges.get( m - 1 ).isConflicted() && r < graph.getContainedLayers().get( calcBeforeLayerIndex() ).indexOf( u ) + 1 )
 		        {
 		        {
 		        	System.out.println( "" );
 		        	System.out.println( "" );
 		        	ArrayList< Boolean > oldConflicts = new ArrayList<>();
 		        	ArrayList< Boolean > oldConflicts = new ArrayList<>();
@@ -77,25 +110,26 @@ public class BlockCalc implements AlgorithmStage {
 		        		oldConflicts.add( e.isConflicted() );
 		        		oldConflicts.add( e.isConflicted() );
 		        		e.setConflicted( true );
 		        		e.setConflicted( true );
 		        	}
 		        	}
-		            LayeredGraphNode oldAlignU = u.getAlignedTo();
-		            Color oldColorCurrent = current.getColor();
-		            LayeredGraphNode oldRootCurrent = current.getRoot();
-		            LayeredGraphNode oldAlignCurrent = current.getAlignedTo();
+		            LayeredGraphNode oldAlignU = u.getAlignedTo( layout );
+		            Color oldColorCurrent = current.getColor( layout );
+		            LayeredGraphNode oldRootCurrent = current.getRoot( layout );
+		            LayeredGraphNode oldAlignCurrent = current.getAlignedTo( layout );
 		            int oldR = r;
 		            int oldR = r;
-		            u.setAlignTo( current );
-		            current.setColor( u.getRoot().getColor() );
-		            current.setRoot( u.getRoot() );
-		            current.setAlignTo( current.getRoot() );
-		            r = graph.getContainedLayers().get( layerIndex - 1 ).indexOf( u ) + 1;
+		            u.setAlignTo( current, layout );
+		            current.setColor( u.getRoot( layout ).getColor( layout ), layout );
+		            current.setRoot( u.getRoot( layout ), layout );
+		            current.setAlignTo( current.getRoot( layout ), layout );
+		            r = graph.getContainedLayers().get( calcBeforeLayerIndex() ).indexOf( u ) + 1;
 		            int oldStep = step++;
 		            int oldStep = step++;
+		            final LayeredGraphNode uf = u;
 		            backwards.add( 0, () -> {
 		            backwards.add( 0, () -> {
 		                System.out.println( "Stepping Backwards... (Step " + oldStep + ")" );
 		                System.out.println( "Stepping Backwards... (Step " + oldStep + ")" );
 			        	for( int i = 0; i < conflicts.size(); i++ )
 			        	for( int i = 0; i < conflicts.size(); i++ )
 			        		conflicts.get( i ).setConflicted( oldConflicts.get( i ) );
 			        		conflicts.get( i ).setConflicted( oldConflicts.get( i ) );
-		                u.setAlignTo( oldAlignU );
-		                current.setColor( oldColorCurrent );
-		                current.setRoot( oldRootCurrent );
-		                current.setAlignTo( oldAlignCurrent );
+			        	uf.setAlignTo( oldAlignU, layout );
+		                current.setColor( oldColorCurrent, layout );
+		                current.setRoot( oldRootCurrent, layout );
+		                current.setAlignTo( oldAlignCurrent, layout );
 		                r = oldR;
 		                r = oldR;
 		            });
 		            });
 		            backwardsAdded = true;
 		            backwardsAdded = true;
@@ -116,11 +150,11 @@ public class BlockCalc implements AlgorithmStage {
 	{
 	{
 		if( layerIndex >= graph.getContainedLayers().size() - 1 )
 		if( layerIndex >= graph.getContainedLayers().size() - 1 )
 		{
 		{
-			if( nodeIndex >= graph.getContainedLayers().get( layerIndex ).size() -1 )
+			if( nodeIndex >= graph.getContainedLayers().get( calcLayerIndex() ).size() -1 )
 				return StageStatus.FINISHED;
 				return StageStatus.FINISHED;
 		}
 		}
 		nodeIndex++;
 		nodeIndex++;
-		if( nodeIndex >= graph.getContainedLayers().get( layerIndex ).size() )
+		if( nodeIndex >= graph.getContainedLayers().get( calcLayerIndex() ).size() )
 		{
 		{
 			layerIndex++;
 			layerIndex++;
 			nodeIndex = 0;
 			nodeIndex = 0;
@@ -135,12 +169,12 @@ public class BlockCalc implements AlgorithmStage {
 
 
 	@Override
 	@Override
 	public StageStatus backwardStep() {
 	public StageStatus backwardStep() {
-		if( subgraphAlgs.get( layerIndex ).get( nodeIndex ) != null )
+		if( subgraphAlgs.get( calcLayerIndex() ).get( nodeIndex ) != null )
 		{
 		{
-			if( subgraphAlgs.get( layerIndex ).get( nodeIndex ).backwardStep() == StageStatus.UNFINISHED )
+			if( subgraphAlgs.get( calcLayerIndex() ).get( nodeIndex ).backwardStep() == StageStatus.UNFINISHED )
 			{
 			{
-				LayeredGraphNode current = graph.getContainedLayers().get( layerIndex ).get( nodeIndex );
-				current.setSelected();
+				LayeredGraphNode current = graph.getContainedLayers().get( calcLayerIndex() ).get( nodeIndex );
+				current.setSelected( layout );
 				//current.update();
 				//current.update();
 				return StageStatus.UNFINISHED;
 				return StageStatus.UNFINISHED;
 			}
 			}
@@ -148,8 +182,8 @@ public class BlockCalc implements AlgorithmStage {
 		StageStatus status = calcBeforeState();
 		StageStatus status = calcBeforeState();
 		if( status == StageStatus.FINISHED )
 		if( status == StageStatus.FINISHED )
 			return status;
 			return status;
-		LayeredGraphNode current = graph.getContainedLayers().get( layerIndex ).get( nodeIndex );
-		current.setSelected();
+		LayeredGraphNode current = graph.getContainedLayers().get( calcLayerIndex() ).get( nodeIndex );
+		current.setSelected( layout );
 		//current.update();
 		//current.update();
 		if( !backwards.isEmpty() )
 		if( !backwards.isEmpty() )
 		{
 		{
@@ -172,7 +206,7 @@ public class BlockCalc implements AlgorithmStage {
 			layerIndex--;
 			layerIndex--;
 	        backwards.get( 0 ).reverse();
 	        backwards.get( 0 ).reverse();
 	        backwards.remove( 0 );
 	        backwards.remove( 0 );
-			nodeIndex = graph.getContainedLayers().get( layerIndex ).size() - 1;
+			nodeIndex = graph.getContainedLayers().get( calcLayerIndex() ).size() - 1;
 		}
 		}
 		return StageStatus.UNFINISHED;
 		return StageStatus.UNFINISHED;
 	}
 	}

+ 103 - 74
src/Algorithms/Animated/BK/Compaction.java

@@ -4,6 +4,7 @@ import java.util.ArrayList;
 
 
 import Algorithms.Animated.AlgorithmStage;
 import Algorithms.Animated.AlgorithmStage;
 import Algorithms.Animated.BackwardAction;
 import Algorithms.Animated.BackwardAction;
+import Algorithms.Animated.BK.ExtremalLayoutCalc.LayoutType;
 import Model.LayeredGraphNode;
 import Model.LayeredGraphNode;
 
 
 /**
 /**
@@ -30,14 +31,16 @@ public class Compaction implements AlgorithmStage{
 	private LayeredGraphNode graph;
 	private LayeredGraphNode graph;
 	private int vIndex;
 	private int vIndex;
 	
 	
-	private ArrayList< StackFrame > stack;
-	private ArrayList< BackwardAction > actions;
+	private ArrayList< StackFrame > stack; // TODO: evtl richtigen "Stack" benutzen
+	private ArrayList< BackwardAction > actions; // TODO: evtl richtigen "Stack" benutzen
+	private LayoutType layout;
 	
 	
-	public Compaction( LayeredGraphNode graph )
+	public Compaction( LayeredGraphNode graph, LayoutType layout )
 	{
 	{
+	    this.layout = layout;
 		this.graph = graph;
 		this.graph = graph;
 		state = CompactionState.PLACE_BLOCKS;
 		state = CompactionState.PLACE_BLOCKS;
-		stack = new ArrayList<>();
+		stack = new ArrayList<>(); // der call-stack des rekursiven algorithmus
 		vIndex = 0;
 		vIndex = 0;
 		actions = new ArrayList<>();
 		actions = new ArrayList<>();
 	}
 	}
@@ -46,30 +49,35 @@ public class Compaction implements AlgorithmStage{
 	{
 	{
 		double max = 0;
 		double max = 0;
 		for( LayeredGraphNode n : graph.getContainedNodes() )
 		for( LayeredGraphNode n : graph.getContainedNodes() )
-			max = Math.max( max, n.getWidth() );
+			max = Math.max( max, n.getWidth( layout ) );
 		return max + 50;
 		return max + 50;
 	}
 	}
 	
 	
 	@Override
 	@Override
 	public StageStatus forwardStep() {
 	public StageStatus forwardStep() {
 		int acSize = actions.size();
 		int acSize = actions.size();
-		if( state == CompactionState.PLACE_BLOCKS )
+		if( state == CompactionState.PLACE_BLOCKS ) // blöcke platzieren
 		{
 		{
-			if( stack.size() == 0 )
+			if( stack.size() == 0 ) // äußere schleife, placeblocks bisher nicht aufgerufen
 			{
 			{
 				ArrayList< LayeredGraphNode > nodes = graph.getContainedNodes();
 				ArrayList< LayeredGraphNode > nodes = graph.getContainedNodes();
-				boolean found = false;
-				int oldVIndex = vIndex;
+				boolean found = false; // knoten mit v = root[v] gefunden?
+				int oldVIndex = vIndex; // nötig für "undo"
+				
+				// suche knoten mit v = root[v] und undefiniertem x-Wert
 				for( ; vIndex < nodes.size(); vIndex++ )
 				for( ; vIndex < nodes.size(); vIndex++ )
 				{
 				{
-					if( nodes.get( vIndex ).isXUndefined() && nodes.get( vIndex ) == nodes.get( vIndex ).getRoot() )
+					if( nodes.get( vIndex ).isXUndefined( layout ) && nodes.get( vIndex ) == nodes.get( vIndex ).getRoot( layout ) )
 					{
 					{
 						found = true;
 						found = true;
 						break;
 						break;
 					}
 					}
 				}
 				}
+				
+				// kein knoten gefunden
 				if( !found )
 				if( !found )
 				{
 				{
+				    // wechsele in die phase des Blöckeshiftens
 					state = CompactionState.APPLY_SHIFT;
 					state = CompactionState.APPLY_SHIFT;
 					vIndex = 0;
 					vIndex = 0;
 					actions.add( 0, ()-> {
 					actions.add( 0, ()-> {
@@ -77,118 +85,139 @@ public class Compaction implements AlgorithmStage{
 						state = CompactionState.PLACE_BLOCKS;
 						state = CompactionState.PLACE_BLOCKS;
 					} );
 					} );
 				}
 				}
-				else
+				else // Knoten gefunden
 				{
 				{
-					StackFrame f = new StackFrame();
+					StackFrame f = new StackFrame(); // enthält lokale variablen
 					f.v = nodes.get( vIndex );
 					f.v = nodes.get( vIndex );
-					double oldX = f.v.getX();
-					f.v.setX( 0, true );
-					f.v.setSelected();
+					double oldX = f.v.getX( layout ); // nötig für "undo"
+					f.v.setX( 0, true, layout );
+					f.v.setSelected( layout ); // zeige knoten als aktiven knoten an
 					f.w = f.v;
 					f.w = f.v;
 					stack.add( 0, f );
 					stack.add( 0, f );
+					
+					// die "undo"-action
 					actions.add( 0, ()-> {
 					actions.add( 0, ()-> {
-						stack.get( 0 ).v.setX( oldX, false );
-						stack.get( 0 ).v.setSelected();
+						stack.get( 0 ).v.setX( oldX, false, layout );
+						stack.get( 0 ).v.setSelected( layout );
 						stack.remove( 0 );
 						stack.remove( 0 );
 						vIndex = oldVIndex;
 						vIndex = oldVIndex;
 						state = CompactionState.PLACE_BLOCKS;
 						state = CompactionState.PLACE_BLOCKS;
 					});
 					});
 				}
 				}
 			}
 			}
-			else
+			else // zurzeit innerhalb einer placeblock methode
 			{
 			{
 				StackFrame sf = stack.get( 0 );
 				StackFrame sf = stack.get( 0 );
-				if( sf.u == null )
+				if( sf.u == null ) // zu beginn der placeblock methode
 				{
 				{
-					if( graph.getContainedLayers().get( sf.w.getLayer() ).indexOf( sf.w ) >= 1 )
+					if( graph.getContainedLayers().get( sf.w.getLayer() ).indexOf( sf.w ) >= 1 ) // if pos[w] > 1"
 					{
 					{
-						sf.u = graph.getContainedLayers().get( sf.w.getLayer() ).get( graph.getContainedLayers().get( sf.w.getLayer() ).indexOf( sf.w ) - 1 ).getRoot();
-						if( sf.u.isXUndefined() )
-						{
-							StackFrame nsf = new StackFrame();
+					    
+						sf.u = graph.getContainedLayers().get( sf.w.getLayer() ).get( graph.getContainedLayers().get( sf.w.getLayer() ).indexOf( sf.w ) - 1 ).getRoot( layout );
+						
+						if( sf.u.isXUndefined( layout ) ) // nötig placeblock aufzurufen?
+						{// ja
+							StackFrame nsf = new StackFrame(); // enthält lokale variablen
 							nsf.v = sf.u;
 							nsf.v = sf.u;
-							double oldX = nsf.v.getX();
-							nsf.v.setX( 0, true );
-							nsf.v.setSelected();
+							double oldX = nsf.v.getX( layout ); // nötig für "undo"
+							nsf.v.setX( 0, true, layout );
+							nsf.v.setSelected( layout ); // zeige knoten als aktiven knoten an
 							nsf.w = nsf.v;
 							nsf.w = nsf.v;
 							stack.add( 0, nsf );
 							stack.add( 0, nsf );
+		                    
+		                    // die "undo"-action
 							actions.add( 0, ()-> {
 							actions.add( 0, ()-> {
-								stack.get( 0 ).v.setX( oldX, false );
-								stack.get( 0 ).v.setSelected();
+								stack.get( 0 ).v.setX( oldX, false, layout );
+								stack.get( 0 ).v.setSelected( layout );
 								stack.remove( 0 );
 								stack.remove( 0 );
 								stack.get( 0 ).u = null;
 								stack.get( 0 ).u = null;
 							});
 							});
 						}
 						}
-						else
+						else // nein
 						{
 						{
-							sf.u.setSelected();
+						    // tue nix
+							sf.u.setSelected( layout ); 
 							actions.add( 0, ()-> {
 							actions.add( 0, ()-> {
 								stack.get( 0 ).u = null;
 								stack.get( 0 ).u = null;
 							});
 							});
 						}
 						}
 					}
 					}
-					else
-					{
+					else 
+					{ // w = align[w]
 						LayeredGraphNode oldW = sf.w;
 						LayeredGraphNode oldW = sf.w;
-						sf.v.setSelected();
-						sf.w = sf.w.getAlignedTo();
-						if( sf.w == sf.v )
-						{
+						sf.v.setSelected( layout );
+						sf.w = sf.w.getAlignedTo( layout );
+						
+						if( sf.w == sf.v ) // schleifenabbruchbedingung
+						{ //abbrechen, placeblock beendet
 							stack.remove( 0 );
 							stack.remove( 0 );
 							actions.add( 0, ()-> {
 							actions.add( 0, ()-> {
 								stack.add( 0, sf );
 								stack.add( 0, sf );
-								sf.v.setSelected();
+								sf.v.setSelected( layout );
 								sf.w = oldW;
 								sf.w = oldW;
 							});
 							});
 						}
 						}
 						else
 						else
-						{
+						{ //nur "undo aktion" hinzufügen
 							actions.add( 0, ()-> {
 							actions.add( 0, ()-> {
 								sf.w = oldW;
 								sf.w = oldW;
-								sf.v.setSelected();
+								sf.v.setSelected( layout );
 							});
 							});
 						}
 						}
 					}	
 					}	
 				}
 				}
-				else
+				else // der Teil nach "placeBlock(u)", genannt "absolute coordinates"
 				{
 				{
-					LayeredGraphNode oldSink = sf.v.getSink();
-					if( sf.v.getSink() == sf.v )
-						sf.v.setSink( sf.u.getSink() );
-					LayeredGraphNode sinkOfU = sf.u.getSink();
-					double oldShift = sinkOfU.getShift();
-					double oldX = sf.v.getX();
-					boolean oldDef = !sf.v.isXUndefined();
-					sf.v.setSelected();
-					if( sf.v.getSink() != sf.u.getSink() )
-						sf.u.getSink().setShift( Math.min( sf.u.getSink().getShift(), sf.v.getX() - sf.u.getX() - calcSpacing() ) );
+				    // alte Werte merken für undo
+					LayeredGraphNode oldSink = sf.v.getSink( layout );					
+					LayeredGraphNode sinkOfU = sf.u.getSink( layout );
+					double oldShift = sinkOfU.getShift( layout );
+					double oldX = sf.v.getX( layout );
+					boolean oldDef = !sf.v.isXUndefined( layout );
+					
+					// v für visualisierung markieren
+					sf.v.setSelected( layout );
+                    
+                    if( sf.v.getSink( layout ) == sf.v ) // sink[v] = v?
+                        sf.v.setSink( sf.u.getSink( layout ), layout ); // sink[v] := sink[u]
+
+					if( sf.v.getSink( layout ) != sf.u.getSink( layout ) ) // sink[v] != sink [u]?
+						sf.u.getSink( layout ).setShift( // shift[sink[u]] =
+						  Math.min( sf.u.getSink( layout ).getShift( layout ),  // min(shift[sink[u]]
+						          sf.v.getX( layout ) - sf.u.getX( layout ) - calcSpacing() ), layout ); // y_v - y_u - s
 					else
 					else
-						sf.v.setX( Math.max( sf.v.getX(), sf.u.getX() + calcSpacing() ), true );
+					    // y_v = max {y_v, y_u + s}
+						sf.v.setX( Math.max( sf.v.getX( layout ), sf.u.getX( layout ) + calcSpacing() ), true, layout );
+					
+
+                    // alte Werte merken für undo
 					LayeredGraphNode oldW = sf.w;
 					LayeredGraphNode oldW = sf.w;
-					sf.w = sf.w.getAlignedTo();
-					LayeredGraphNode oldU = sf.u;
-					sf.u = null;
-					if( sf.w == sf.v )
-					{
+                    LayeredGraphNode oldU = sf.u;
+                    
+					sf.w = sf.w.getAlignedTo( layout ); // w = align[w]
+					sf.u = null; // u wird nächsten schleifendurchlauf neu gesetzt
+					
+					if( sf.w == sf.v ) // schleifenabbruchbedingung
+					{ //abbrechen, placeblock beendet  
 						stack.remove( 0 );
 						stack.remove( 0 );
 						actions.add( 0, ()-> {
 						actions.add( 0, ()-> {
 							stack.add( 0, sf );
 							stack.add( 0, sf );
-							stack.get( 0 ).v.setSink(  oldSink );
-							sinkOfU.setShift( oldShift );
+							stack.get( 0 ).v.setSink(  oldSink, layout );
+							sinkOfU.setShift( oldShift, layout );
 							sf.u = oldU;
 							sf.u = oldU;
-							sf.v.setX( oldX, oldDef );
-							sf.v.setSelected();
+							sf.v.setX( oldX, oldDef, layout );
+							sf.v.setSelected( layout );
 							sf.w = oldW;
 							sf.w = oldW;
 						});
 						});
 					}
 					}
 					else
 					else
-					{
+					{ //nur "undo aktion" hinzufügen
 						actions.add( 0, ()-> {
 						actions.add( 0, ()-> {
-							stack.get( 0 ).v.setSink(  oldSink );
-							sinkOfU.setShift( oldShift );
+							stack.get( 0 ).v.setSink(  oldSink, layout );
+							sinkOfU.setShift( oldShift, layout );
 							sf.u = oldU;
 							sf.u = oldU;
-							sf.v.setX( oldX, oldDef );
-							sf.v.setSelected();
+							sf.v.setX( oldX, oldDef, layout );
+							sf.v.setSelected( layout );
 							sf.w = oldW;
 							sf.w = oldW;
 						});
 						});
 					}
 					}
@@ -198,15 +227,15 @@ public class Compaction implements AlgorithmStage{
 		else if( state == CompactionState.APPLY_SHIFT )
 		else if( state == CompactionState.APPLY_SHIFT )
 		{
 		{
 			LayeredGraphNode v = graph.getContainedNodes().get( vIndex );
 			LayeredGraphNode v = graph.getContainedNodes().get( vIndex );
-			double oldX = v.getX();
-			boolean oldDef = !v.isXUndefined();
-			v.setSelected();
-			v.setX( v.getRoot().getX(), true );
-			if( v == v.getRoot() && v.getSink().getShift() < Double.POSITIVE_INFINITY )
-				v.setX( v.getX() + v.getSink().getShift(), true );
+			double oldX = v.getX( layout );
+			boolean oldDef = !v.isXUndefined( layout );
+			v.setSelected( layout );
+			v.setX( v.getRoot( layout ).getX( layout ), true, layout );
+			if( v == v.getRoot( layout ) && v.getSink( layout ).getShift( layout ) < Double.POSITIVE_INFINITY )
+				v.setX( v.getX( layout ) + v.getSink( layout ).getShift( layout ), true, layout );
 			actions.add( 0, ()-> {
 			actions.add( 0, ()-> {
-				v.setX( oldX, oldDef );
-				v.setSelected();
+				v.setX( oldX, oldDef, layout );
+				v.setSelected( layout );
 				vIndex--;
 				vIndex--;
 			} );
 			} );
 			vIndex++;
 			vIndex++;

+ 2 - 4
src/Algorithms/Animated/BK/ExtremalLayoutCalc.java

@@ -23,7 +23,6 @@ public class ExtremalLayoutCalc implements AlgorithmStage {
 		COMPACTION
 		COMPACTION
 	}
 	}
 	
 	
-	private LayoutType typ;
 	private BlockCalc bc;
 	private BlockCalc bc;
 	private Compaction cp;
 	private Compaction cp;
 	private LayoutState status;
 	private LayoutState status;
@@ -32,9 +31,8 @@ public class ExtremalLayoutCalc implements AlgorithmStage {
 	public ExtremalLayoutCalc( LayoutType typ, LayeredGraphNode graph )
 	public ExtremalLayoutCalc( LayoutType typ, LayeredGraphNode graph )
 	{
 	{
 		status = LayoutState.BLOCK_CALCULATION;
 		status = LayoutState.BLOCK_CALCULATION;
-		this.typ = typ;
-		bc = new BlockCalc( graph );
-		cp = new Compaction( graph );
+		bc = new BlockCalc( graph, typ );
+		cp = new Compaction( graph, typ );
 	}
 	}
 	
 	
 	@Override
 	@Override

+ 9 - 8
src/Algorithms/InitializeNodePositions.java

@@ -2,6 +2,7 @@ package Algorithms;
 
 
 import java.util.ArrayList;
 import java.util.ArrayList;
 
 
+import Algorithms.Animated.BK.ExtremalLayoutCalc.LayoutType;
 import Model.LayeredGraphNode;
 import Model.LayeredGraphNode;
 
 
 
 
@@ -21,29 +22,29 @@ public class InitializeNodePositions {
     	RandomColorGenerator cGen = new RandomColorGenerator();
     	RandomColorGenerator cGen = new RandomColorGenerator();
         for( LayeredGraphNode n : graph.getContainedNodes() )
         for( LayeredGraphNode n : graph.getContainedNodes() )
         {
         {
-            n.setWidth( 40 );
-            n.setHeight( 40 );
-            n.setColor( cGen.generateColor() );
+            n.setWidth( 40, null );
+            n.setHeight( 40, null );
+            n.setColor( cGen.generateColor(), null );
             placeNodes( n );
             placeNodes( n );
         }
         }
         int curY = 0;
         int curY = 0;
         double maxWidth = 0, maxHeight = 0;
         double maxWidth = 0, maxHeight = 0;
         
         
         for (LayeredGraphNode node : graph.getContainedNodes()) { // Suche die maximale Knotengröße
         for (LayeredGraphNode node : graph.getContainedNodes()) { // Suche die maximale Knotengröße
-            maxWidth = Math.max(node.getWidth(), maxWidth);
-            maxHeight = Math.max(node.getHeight(), maxHeight);
+            maxWidth = Math.max(node.getWidth( LayoutType.TOP_BOTTOM_LEFT ), maxWidth);
+            maxHeight = Math.max(node.getHeight( LayoutType.TOP_BOTTOM_LEFT ), maxHeight);
         }
         }
         
         
         ArrayList< ArrayList< LayeredGraphNode > > layers = graph.getContainedLayers();
         ArrayList< ArrayList< LayeredGraphNode > > layers = graph.getContainedLayers();
         for (ArrayList<LayeredGraphNode> layer : layers) { // Gehe alle Layer durch
         for (ArrayList<LayeredGraphNode> layer : layers) { // Gehe alle Layer durch
             maxHeight = 0;
             maxHeight = 0;
             for (LayeredGraphNode node : layer) { // Gehe alle Knoten durch
             for (LayeredGraphNode node : layer) { // Gehe alle Knoten durch
-                maxHeight = Math.max(node.getHeight(), maxHeight);
+                maxHeight = Math.max(node.getHeight( LayoutType.TOP_BOTTOM_LEFT ), maxHeight);
             }
             }
             int curX = 0;
             int curX = 0;
             for (LayeredGraphNode node : layer) { // Gehe alle Knoten durch
             for (LayeredGraphNode node : layer) { // Gehe alle Knoten durch
-                node.setX(curX + maxWidth / 2 - node.getWidth() / 2, false);
-                node.setY(curY + maxHeight / 2 - node.getHeight() / 2); // Position setzen
+                node.setX( curX + maxWidth / 2 - node.getWidth( LayoutType.TOP_BOTTOM_LEFT ) / 2, false, null );
+                node.setY( curY + maxHeight / 2 - node.getHeight( LayoutType.TOP_BOTTOM_LEFT ) / 2, null ); // Position setzen
                 curX += maxWidth + 25;
                 curX += maxWidth + 25;
             }
             }
             curY += maxHeight + 25;
             curY += maxHeight + 25;

+ 2 - 2
src/IO/Reader.java

@@ -62,9 +62,9 @@ public class Reader {
             newNode.setName( node.getString( "name" ) );
             newNode.setName( node.getString( "name" ) );
         }
         }
         if( node.has( "width" ) )
         if( node.has( "width" ) )
-            newNode.setWidth( node.getInt( "width" ) );
+            newNode.setWidth( node.getInt( "width" ), null );
         if( node.has( "height" ) )
         if( node.has( "height" ) )
-            newNode.setHeight( node.getInt( "height" ) );
+            newNode.setHeight( node.getInt( "height" ), null );
 		if( node.has( "layers" ) )
 		if( node.has( "layers" ) )
 		{
 		{
 			JSONArray layers = node.getJSONArray( "layers" );
 			JSONArray layers = node.getJSONArray( "layers" );

+ 8 - 7
src/Main.java

@@ -1,6 +1,7 @@
 import Algorithms.InitializeNodePositions;
 import Algorithms.InitializeNodePositions;
 import Algorithms.RandomGraphGenerator;
 import Algorithms.RandomGraphGenerator;
 import Algorithms.SweepCrossingMinimizer;
 import Algorithms.SweepCrossingMinimizer;
+import IO.Reader;
 import Model.LayeredGraphNode;
 import Model.LayeredGraphNode;
 import View.MainView;
 import View.MainView;
 
 
@@ -12,13 +13,13 @@ import View.MainView;
 public class Main {
 public class Main {
 
 
 	public static void main(String[] args) {
 	public static void main(String[] args) {
-		//Reader r = new Reader( "save.graph" );
-		//LayeredGraphNode graph = r.readInputGraph();
-	    RandomGraphGenerator r = new RandomGraphGenerator( 0.1, 0.1, 5,5, 5, 5, 1 );
-	    LayeredGraphNode graph = r.createRandomNode( null, 0 );
-	    SweepCrossingMinimizer cminzer = new SweepCrossingMinimizer();
-	    for( int i = 0; i < 10; i++ )
-	    	cminzer.minimizeCrossings( graph );
+		Reader r = new Reader( "save.graph" );
+		LayeredGraphNode graph = r.readInputGraph();
+	    //RandomGraphGenerator r = new RandomGraphGenerator( 0.1, 0.1, 5,5, 5, 5, 1 );
+	    //LayeredGraphNode graph = r.createRandomNode( null, 0 );
+	    //SweepCrossingMinimizer cminzer = new SweepCrossingMinimizer();
+	    //for( int i = 0; i < 10; i++ )
+	    //	cminzer.minimizeCrossings( graph );
 		InitializeNodePositions.placeNodes( graph );
 		InitializeNodePositions.placeNodes( graph );
 		new MainView( graph );
 		new MainView( graph );
 	}
 	}

+ 72 - 14
src/Model/LayeredEdge.java

@@ -5,6 +5,8 @@ import java.util.ArrayList;
 
 
 import org.eclipse.elk.graph.ElkEdge;
 import org.eclipse.elk.graph.ElkEdge;
 
 
+import Algorithms.Animated.BK.ExtremalLayoutCalc.LayoutType;
+
 /**
 /**
  * Die Implementation einer Kante aus einem Layered Graphen.
  * Die Implementation einer Kante aus einem Layered Graphen.
  * Implementiert {@link LayeredGraphEdge.}
  * Implementiert {@link LayeredGraphEdge.}
@@ -20,9 +22,10 @@ public class LayeredEdge implements LayeredGraphEdge {
     LayeredGraphNode graph;
     LayeredGraphNode graph;
     boolean reversed;
     boolean reversed;
     boolean dummy;
     boolean dummy;
-    ArrayList< Point > bindPoints;
+    ArrayList< Point >[] bindPoints;
     boolean conflicted;
     boolean conflicted;
     
     
+    @SuppressWarnings("unchecked")
     public LayeredEdge( ElkEdge original, ArrayList< LayeredGraphNode > sources, ArrayList< LayeredGraphNode > targets, LayeredGraphNode graph )
     public LayeredEdge( ElkEdge original, ArrayList< LayeredGraphNode > sources, ArrayList< LayeredGraphNode > targets, LayeredGraphNode graph )
     {
     {
         this.original = original;
         this.original = original;
@@ -31,9 +34,14 @@ public class LayeredEdge implements LayeredGraphEdge {
         this.graph = graph;
         this.graph = graph;
         reversed = false;
         reversed = false;
         dummy = false;
         dummy = false;
-        bindPoints = new ArrayList<>();
-        bindPoints.add( null );
-        bindPoints.add( null );
+        bindPoints = new ArrayList[ 4 ];
+        for( int i = 0; i < 4; i++ )
+            bindPoints[ i ] = new ArrayList<>();
+        for( ArrayList<Point> bps : bindPoints )
+        {
+            bps.add( null );
+            bps.add( null );
+        }
         conflicted = false;
         conflicted = false;
     }
     }
 
 
@@ -74,35 +82,85 @@ public class LayeredEdge implements LayeredGraphEdge {
     }
     }
     
     
     @Override
     @Override
-    public void setStartPoint( int x, int y )
+    public void setStartPoint( int x, int y, LayoutType layout )
     {
     {
-        bindPoints.set( 0, new Point( x, y ) );
+        if( layout == null )
+        {
+            bindPoints[ 0 ].set( 0, new Point( x, y ) );
+            bindPoints[ 1 ].set( 0, new Point( x, y ) );
+            bindPoints[ 2 ].set( 0, new Point( x, y ) );
+            bindPoints[ 3 ].set( 0, new Point( x, y ) );
+        }
+        if( layout == LayoutType.TOP_BOTTOM_LEFT )
+            bindPoints[ 0 ].set( 0, new Point( x, y ) );
+        if( layout == LayoutType.TOP_BOTTOM_RIGHT )
+            bindPoints[ 1 ].set( 0, new Point( x, y ) );
+        if( layout == LayoutType.BOTTOM_TOP_LEFT )
+            bindPoints[ 2 ].set( 0, new Point( x, y ) );
+        if( layout == LayoutType.BOTTOM_TOP_RIGHT )
+            bindPoints[ 3 ].set( 0, new Point( x, y ) );
     }
     }
     
     
     @Override
     @Override
-    public void addBindPoint( int x, int y )
+    public void addBindPoint( int x, int y, LayoutType layout )
     {
     {
-        bindPoints.add( bindPoints.size() - 1, new Point( x, y ) );
+        if( layout == null )
+        {
+            bindPoints[ 0 ].add( bindPoints[ 0 ].size() - 1, new Point( x, y ) );
+            bindPoints[ 1 ].add( bindPoints[ 1 ].size() - 1, new Point( x, y ) );
+            bindPoints[ 2 ].add( bindPoints[ 2 ].size() - 1, new Point( x, y ) );
+            bindPoints[ 3 ].add( bindPoints[ 3 ].size() - 1, new Point( x, y ) );
+        }
+        if( layout == LayoutType.TOP_BOTTOM_LEFT )
+            bindPoints[ 0 ].add( bindPoints[ 0 ].size() - 1, new Point( x, y ) );
+        if( layout == LayoutType.TOP_BOTTOM_RIGHT )
+            bindPoints[ 1 ].add( bindPoints[ 1 ].size() - 1, new Point( x, y ) );
+        if( layout == LayoutType.BOTTOM_TOP_LEFT )
+            bindPoints[ 2 ].add( bindPoints[ 2 ].size() - 1, new Point( x, y ) );
+        if( layout == LayoutType.BOTTOM_TOP_RIGHT )
+            bindPoints[ 3 ].add( bindPoints[ 3 ].size() - 1, new Point( x, y ) );
     }
     }
     
     
     @Override
     @Override
-    public void setEndPoint( int x, int y )
+    public void setEndPoint( int x, int y, LayoutType layout )
     {
     {
-        bindPoints.set( bindPoints.size() - 1, new Point( x, y ) );
+        if( layout == null )
+        {
+            bindPoints[ 0 ].set( bindPoints[ 0 ].size() - 1, new Point( x, y ) );
+            bindPoints[ 1 ].set( bindPoints[ 1 ].size() - 1, new Point( x, y ) );
+            bindPoints[ 2 ].set( bindPoints[ 2 ].size() - 1, new Point( x, y ) );
+            bindPoints[ 3 ].set( bindPoints[ 3 ].size() - 1, new Point( x, y ) );
+        }
+        if( layout == LayoutType.TOP_BOTTOM_LEFT )
+            bindPoints[ 0 ].set( bindPoints[ 0 ].size() - 1, new Point( x, y ) );
+        if( layout == LayoutType.TOP_BOTTOM_RIGHT )
+            bindPoints[ 1 ].set( bindPoints[ 1 ].size() - 1, new Point( x, y ) );
+        if( layout == LayoutType.BOTTOM_TOP_LEFT )
+            bindPoints[ 2 ].set( bindPoints[ 2 ].size() - 1, new Point( x, y ) );
+        if( layout == LayoutType.BOTTOM_TOP_RIGHT )
+            bindPoints[ 3 ].set( bindPoints[ 3 ].size() - 1, new Point( x, y ) );
     }
     }
 
 
     @Override
     @Override
-    public ArrayList<Point> getLinePoints()
+    public ArrayList<Point> getLinePoints( LayoutType layout )
     {
     {
         //if( bindPoints.get( 0 ) == null && sources.size() > 0 )
         //if( bindPoints.get( 0 ) == null && sources.size() > 0 )
         //{
         //{
-            setStartPoint( (int)sources.get( 0 ).getX() + (int)sources.get( 0 ).getWidth() / 2, (int)sources.get( 0 ).getY() + (int)sources.get( 0 ).getHeight() );
+            setStartPoint( (int)sources.get( 0 ).getX( layout ) + (int)sources.get( 0 ).getWidth( layout ) / 2, (int)sources.get( 0 ).getY( layout ) + (int)sources.get( 0 ).getHeight( layout ), layout );
         //}
         //}
         //if( bindPoints.get( bindPoints.size() - 1 ) == null && targets.size() > 0 )
         //if( bindPoints.get( bindPoints.size() - 1 ) == null && targets.size() > 0 )
         //{
         //{
-            setEndPoint( (int)targets.get( 0 ).getX() + (int)targets.get( 0 ).getWidth() / 2, (int)targets.get( 0 ).getY() );
+            setEndPoint( (int)targets.get( 0 ).getX( layout ) + (int)targets.get( 0 ).getWidth( layout ) / 2, (int)targets.get( 0 ).getY( layout ), layout );
         //}
         //}
-        return bindPoints;
+        if( layout == LayoutType.TOP_BOTTOM_LEFT )
+            return bindPoints[ 0 ];
+        if( layout == LayoutType.TOP_BOTTOM_RIGHT )
+            return bindPoints[ 1 ];
+        if( layout == LayoutType.BOTTOM_TOP_LEFT )
+            return bindPoints[ 2 ];
+        if( layout == LayoutType.BOTTOM_TOP_RIGHT )
+            return bindPoints[ 3 ];
+        return null;
     }
     }
     
     
     @Override
     @Override

+ 6 - 4
src/Model/LayeredGraphEdge.java

@@ -5,6 +5,8 @@ import java.util.ArrayList;
 
 
 import org.eclipse.elk.graph.ElkEdge;
 import org.eclipse.elk.graph.ElkEdge;
 
 
+import Algorithms.Animated.BK.ExtremalLayoutCalc.LayoutType;
+
 /**
 /**
  * Ein Interface, welches die Methoden einer Kante aus einem gelayerten Graphen beschreibt
  * Ein Interface, welches die Methoden einer Kante aus einem gelayerten Graphen beschreibt
  * @author kolja
  * @author kolja
@@ -51,10 +53,10 @@ public interface LayeredGraphEdge {
      */
      */
     void reverse();
     void reverse();
     
     
-    void setStartPoint( int x, int y );
-    void setEndPoint( int x, int y );
-    void addBindPoint( int x, int y );
-    ArrayList<Point> getLinePoints();
+    void setStartPoint( int x, int y, LayoutType layout );
+    void setEndPoint( int x, int y, LayoutType layout );
+    void addBindPoint( int x, int y, LayoutType layout );
+    ArrayList<Point> getLinePoints( LayoutType layout );
     /**
     /**
      * Pr�ft, ob die Kante umgedreht wurde
      * Pr�ft, ob die Kante umgedreht wurde
      * @return true, falls die Kante umgedreht wurde
      * @return true, falls die Kante umgedreht wurde

+ 27 - 24
src/Model/LayeredGraphNode.java

@@ -3,11 +3,11 @@ package Model;
 import java.awt.Color;
 import java.awt.Color;
 import java.util.ArrayList;
 import java.util.ArrayList;
 
 
-import javax.swing.JPanel;
-
 import org.eclipse.elk.graph.ElkEdge;
 import org.eclipse.elk.graph.ElkEdge;
 import org.eclipse.elk.graph.ElkNode;
 import org.eclipse.elk.graph.ElkNode;
 
 
+import Algorithms.Animated.BK.ExtremalLayoutCalc.LayoutType;
+
 /**
 /**
  * Ein Interface, welches die Methoden eines Knotens aus einem gelayerten Graphen beschreibt (Ein Knoten kann dabei auch einen weiteren Graphen beinhalten)
  * Ein Interface, welches die Methoden eines Knotens aus einem gelayerten Graphen beschreibt (Ein Knoten kann dabei auch einen weiteren Graphen beinhalten)
  * @author kolja
  * @author kolja
@@ -23,23 +23,22 @@ public interface LayeredGraphNode {
      */
      */
     ElkNode getOriginalNode();
     ElkNode getOriginalNode();
 
 
-    public void setShift( double shift );
-    public double getShift();
-    public void setSink( LayeredGraphNode sink );
-    public LayeredGraphNode getSink();
-    public boolean isXUndefined();
-    public void setAlignTo( LayeredGraphNode align );
-    public LayeredGraphNode getAlignedTo();
-    public void setRoot( LayeredGraphNode root );
-    public LayeredGraphNode getRoot();
+    public void setShift( double shift, LayoutType layout );
+    public double getShift( LayoutType layout );
+    public void setSink( LayeredGraphNode sink, LayoutType layout );
+    public LayeredGraphNode getSink( LayoutType layoutType);
+    public boolean isXUndefined( LayoutType layout );
+    public void setAlignTo( LayeredGraphNode align, LayoutType layout );
+    public LayeredGraphNode getAlignedTo( LayoutType layout );
+    public void setRoot( LayeredGraphNode root, LayoutType layout );
+    public LayeredGraphNode getRoot( LayoutType layout );
     public void setName( String n );
     public void setName( String n );
     public String getName();
     public String getName();
-    public void setColor( Color c );
-    public Color getColor();
+    public void setColor( Color c, LayoutType layout );
+    public Color getColor( LayoutType layout );
     public void update();
     public void update();
-    public void setSelected();
-    public boolean isSelected();
-    public void setView( JPanel v );
+    public void setSelected( LayoutType layoutType );
+    public boolean isSelected( LayoutType layout );
     
     
     /**
     /**
      * Setzt den Index des Layers, zu dem der Knoten geh�ren soll
      * Setzt den Index des Layers, zu dem der Knoten geh�ren soll
@@ -89,35 +88,35 @@ public interface LayeredGraphNode {
      * Legt die X Koordinate des Knotens fest
      * Legt die X Koordinate des Knotens fest
      * @param x die X Koordinate in Pixeln
      * @param x die X Koordinate in Pixeln
      */
      */
-    void setX( double x, boolean def );
+    void setX( double x, boolean def, LayoutType layout );
     /**
     /**
      * Legt die Y Koordinate des Knotens Fest
      * Legt die Y Koordinate des Knotens Fest
      * @param y die Y Koordinate in Pixeln
      * @param y die Y Koordinate in Pixeln
      */
      */
-    void setY( double y );
+    void setY( double y, LayoutType layout );
     /**
     /**
      * Gibt die X Koordinate zur�ck
      * Gibt die X Koordinate zur�ck
      * @return die X Koordinate in Pixeln zur�ck
      * @return die X Koordinate in Pixeln zur�ck
      */
      */
-    double getX();
+    double getX( LayoutType layout );
     /**
     /**
      * Gibt die Y Koordinate zur�ck
      * Gibt die Y Koordinate zur�ck
      * @return die Y Koordinate in Pixeln zur�ck
      * @return die Y Koordinate in Pixeln zur�ck
      */
      */
-    double getY();
+    double getY( LayoutType layout );
     /**
     /**
      * Gibt die Breite des Knotens zur�ck
      * Gibt die Breite des Knotens zur�ck
      * @return die Breite in Pixeln
      * @return die Breite in Pixeln
      */
      */
-    double getWidth();
+    double getWidth( LayoutType layout );
     /**
     /**
      * Gibt die H�he des Knotens zur�ck
      * Gibt die H�he des Knotens zur�ck
      * @return die H�he in Pixeln
      * @return die H�he in Pixeln
      */
      */
-    double getHeight();
+    double getHeight( LayoutType layout );
     
     
-    void setWidth( double w );
-    void setHeight( double h );
+    void setWidth( double w, LayoutType layout );
+    void setHeight( double h, LayoutType layout );
     
     
     // for subgraph
     // for subgraph
     
     
@@ -148,6 +147,10 @@ public interface LayeredGraphNode {
      * @return Eine Liste mit allen Knoten des Subgraphen
      * @return Eine Liste mit allen Knoten des Subgraphen
      */
      */
     ArrayList< LayeredGraphNode > getContainedNodes();
     ArrayList< LayeredGraphNode > getContainedNodes();
+    /**
+     * @return Eine Liste mit allen Knoten des Subgraphen sortiert nach Layern und Positionen
+     */
+    ArrayList< LayeredGraphNode > getSortedContainedNodes();
     /**
     /**
      * @return Eine Liste mit allen Layern des Subgraphen
      * @return Eine Liste mit allen Layern des Subgraphen
      */
      */

+ 369 - 93
src/Model/LayeredNode.java

@@ -3,12 +3,12 @@ package Model;
 import java.awt.Color;
 import java.awt.Color;
 import java.util.ArrayList;
 import java.util.ArrayList;
 
 
-import javax.swing.JPanel;
 import javax.swing.SwingUtilities;
 import javax.swing.SwingUtilities;
 
 
 import org.eclipse.elk.graph.ElkEdge;
 import org.eclipse.elk.graph.ElkEdge;
 import org.eclipse.elk.graph.ElkNode;
 import org.eclipse.elk.graph.ElkNode;
 
 
+import Algorithms.Animated.BK.ExtremalLayoutCalc.LayoutType;
 import View.MainView;
 import View.MainView;
 
 
 /**
 /**
@@ -24,23 +24,26 @@ public class LayeredNode implements LayeredGraphNode {
     private ElkNode original;
     private ElkNode original;
     private LayeredGraphNode parent;
     private LayeredGraphNode parent;
     
     
-    double x;
-    double y;
-    double w;
-    double h;
-    Color color;
+    private class LayoutInfo
+    {
+        public double x;
+        public double y;
+        public double w;
+        public double h;
+        public Color color;
+        public boolean selected;
+        public boolean xUndef;
+        
+        // Block Calculation
+        public LayeredGraphNode align;
+        public LayeredGraphNode root;
+        // Compaction
+        public LayeredGraphNode sink;
+        public double shift;
+    }
+    LayoutInfo[] layouts;
     
     
     String name;
     String name;
-    JPanel view;
-    boolean selected;
-    boolean xUndef;
-    
-    // Block Calculation
-    LayeredGraphNode align;
-    LayeredGraphNode root;
-    // Compaction
-    LayeredGraphNode sink;
-    double shift;
     
     
     // for subgraph in this node
     // for subgraph in this node
     private ArrayList< LayeredGraphEdge > edges;
     private ArrayList< LayeredGraphEdge > edges;
@@ -55,72 +58,174 @@ public class LayeredNode implements LayeredGraphNode {
         edges = new ArrayList<>();
         edges = new ArrayList<>();
         nodes = new ArrayList<>();
         nodes = new ArrayList<>();
         layers = new ArrayList<>();
         layers = new ArrayList<>();
-        if( original != null )
+        layouts = new LayoutInfo[ 4 ];
+        for( int i = 0; i < 4; i++ )
+            layouts[ i ] = new LayoutInfo();
+        for( LayoutInfo l : layouts )
         {
         {
-        	x = original.getX();
-        	y = original.getX();
-        	w = original.getWidth();
-        	h = original.getHeight();
+            if( original != null )
+            {
+            	l.x = original.getX();
+            	l.y = original.getX();
+            	l.w = original.getWidth();
+            	l.h = original.getHeight();
+            }
+            l.align = this;
+            l.root = this;
+            l.sink = this;
+            l.shift = Double.POSITIVE_INFINITY;
+            l.xUndef = true;
         }
         }
-        align = this;
-        root = this;
-        sink = this;
-        shift = Double.POSITIVE_INFINITY;
-        xUndef = true;
     }
     }
 
 
     @Override
     @Override
-    public void setShift( double shift )
+    public void setShift( double shift, LayoutType layout )
     {
     {
-    	this.shift = shift;
+        if( layout == null )
+        {
+            this.layouts[ 0 ].shift = shift;
+            this.layouts[ 1 ].shift = shift;
+            this.layouts[ 2 ].shift = shift;
+            this.layouts[ 3 ].shift = shift;
+        }
+        if( layout == LayoutType.TOP_BOTTOM_LEFT )
+            this.layouts[ 0 ].shift = shift;
+        if( layout == LayoutType.TOP_BOTTOM_RIGHT )
+            this.layouts[ 1 ].shift = shift;
+        if( layout == LayoutType.BOTTOM_TOP_LEFT )
+            this.layouts[ 2 ].shift = shift;
+        if( layout == LayoutType.BOTTOM_TOP_RIGHT )
+            this.layouts[ 3 ].shift = shift;
     }
     }
     
     
     @Override
     @Override
-    public double getShift()
+    public double getShift( LayoutType layout )
     {
     {
-    	return shift;
+        if( layout == LayoutType.TOP_BOTTOM_LEFT )
+            return this.layouts[ 0 ].shift;
+        if( layout == LayoutType.TOP_BOTTOM_RIGHT )
+            return this.layouts[ 1 ].shift;
+        if( layout == LayoutType.BOTTOM_TOP_LEFT )
+            return this.layouts[ 2 ].shift;
+        if( layout == LayoutType.BOTTOM_TOP_RIGHT )
+            return this.layouts[ 3 ].shift;
+        return 0;
     }
     }
 
 
     @Override
     @Override
-    public void setSink( LayeredGraphNode sink )
+    public void setSink( LayeredGraphNode sink, LayoutType layout )
     {
     {
-    	this.sink = sink;
+        if( layout == null )
+        {
+            this.layouts[ 0 ].sink = sink;
+            this.layouts[ 1 ].sink = sink;
+            this.layouts[ 2 ].sink = sink;
+            this.layouts[ 3 ].sink = sink;
+        }
+        if( layout == LayoutType.TOP_BOTTOM_LEFT )
+            this.layouts[ 0 ].sink = sink;
+        if( layout == LayoutType.TOP_BOTTOM_RIGHT )
+            this.layouts[ 1 ].sink = sink;
+        if( layout == LayoutType.BOTTOM_TOP_LEFT )
+            this.layouts[ 2 ].sink = sink;
+        if( layout == LayoutType.BOTTOM_TOP_RIGHT )
+            this.layouts[ 3 ].sink = sink;
     }
     }
     
     
     @Override
     @Override
-    public LayeredGraphNode getSink()
+    public LayeredGraphNode getSink( LayoutType layout )
     {
     {
-    	return sink;
+        if( layout == LayoutType.TOP_BOTTOM_LEFT )
+            return this.layouts[ 0 ].sink;
+        if( layout == LayoutType.TOP_BOTTOM_RIGHT )
+            return this.layouts[ 1 ].sink;
+        if( layout == LayoutType.BOTTOM_TOP_LEFT )
+            return this.layouts[ 2 ].sink;
+        if( layout == LayoutType.BOTTOM_TOP_RIGHT )
+            return this.layouts[ 3 ].sink;
+        return null;
     }
     }
     
     
     @Override
     @Override
-    public boolean isXUndefined()
+    public boolean isXUndefined( LayoutType layout )
     {
     {
-    	return xUndef;
+        if( layout == LayoutType.TOP_BOTTOM_LEFT )
+            return this.layouts[ 0 ].xUndef;
+        if( layout == LayoutType.TOP_BOTTOM_RIGHT )
+            return this.layouts[ 1 ].xUndef;
+        if( layout == LayoutType.BOTTOM_TOP_LEFT )
+            return this.layouts[ 2 ].xUndef;
+        if( layout == LayoutType.BOTTOM_TOP_RIGHT )
+            return this.layouts[ 3 ].xUndef;
+        return true;
     }
     }
 
 
     @Override
     @Override
-    public void setAlignTo( LayeredGraphNode align )
+    public void setAlignTo( LayeredGraphNode align, LayoutType layout )
     {
     {
-        this.align = align;
+        if( layout == null )
+        {
+            this.layouts[ 0 ].align = align;
+            this.layouts[ 1 ].align = align;
+            this.layouts[ 2 ].align = align;
+            this.layouts[ 3 ].align = align;
+        }
+        if( layout == LayoutType.TOP_BOTTOM_LEFT )
+            this.layouts[ 0 ].align = align;
+        if( layout == LayoutType.TOP_BOTTOM_RIGHT )
+            this.layouts[ 1 ].align = align;
+        if( layout == LayoutType.BOTTOM_TOP_LEFT )
+            this.layouts[ 2 ].align = align;
+        if( layout == LayoutType.BOTTOM_TOP_RIGHT )
+            this.layouts[ 3 ].align = align;
     }
     }
 
 
     @Override
     @Override
-    public LayeredGraphNode getAlignedTo()
+    public LayeredGraphNode getAlignedTo( LayoutType layout )
     {
     {
-        return align;
+        if( layout == LayoutType.TOP_BOTTOM_LEFT )
+            return this.layouts[ 0 ].align;
+        if( layout == LayoutType.TOP_BOTTOM_RIGHT )
+            return this.layouts[ 1 ].align;
+        if( layout == LayoutType.BOTTOM_TOP_LEFT )
+            return this.layouts[ 2 ].align;
+        if( layout == LayoutType.BOTTOM_TOP_RIGHT )
+            return this.layouts[ 3 ].align;
+        return null;
     }
     }
 
 
     @Override
     @Override
-    public void setRoot( LayeredGraphNode root )
+    public void setRoot( LayeredGraphNode root, LayoutType layout )
     {
     {
-        this.root = root;
+        if( layout == null )
+        {
+            this.layouts[ 0 ].root = root;
+            this.layouts[ 1 ].root = root;
+            this.layouts[ 2 ].root = root;
+            this.layouts[ 3 ].root = root;
+        }
+        if( layout == LayoutType.TOP_BOTTOM_LEFT )
+            this.layouts[ 0 ].root = root;
+        if( layout == LayoutType.TOP_BOTTOM_RIGHT )
+            this.layouts[ 1 ].root = root;
+        if( layout == LayoutType.BOTTOM_TOP_LEFT )
+            this.layouts[ 2 ].root = root;
+        if( layout == LayoutType.BOTTOM_TOP_RIGHT )
+            this.layouts[ 3 ].root = root;
     }
     }
 
 
     @Override
     @Override
-    public LayeredGraphNode getRoot()
+    public LayeredGraphNode getRoot( LayoutType layout )
     {
     {
-        return root;
+        if( layout == LayoutType.TOP_BOTTOM_LEFT )
+            return this.layouts[ 0 ].root;
+        if( layout == LayoutType.TOP_BOTTOM_RIGHT )
+            return this.layouts[ 1 ].root;
+        if( layout == LayoutType.BOTTOM_TOP_LEFT )
+            return this.layouts[ 2 ].root;
+        if( layout == LayoutType.BOTTOM_TOP_RIGHT )
+            return this.layouts[ 3 ].root;
+        return null;
     }
     }
 
 
     @Override
     @Override
@@ -128,43 +233,94 @@ public class LayeredNode implements LayeredGraphNode {
     {
     {
     	SwingUtilities.invokeLater(new Runnable() {
     	SwingUtilities.invokeLater(new Runnable() {
 		    public void run() {
 		    public void run() {
-		        System.out.println( "UPDATE" );
 		        MainView.frame.repaint();
 		        MainView.frame.repaint();
 		    }
 		    }
 		});
 		});
     }
     }
 
 
     @Override
     @Override
-    public void setSelected()
+    public void setSelected( LayoutType layout )
     {
     {
-    	selected = true;
+        if( layout == null )
+        {
+            this.layouts[ 0 ].selected = true;
+            this.layouts[ 1 ].selected = true;
+            this.layouts[ 2 ].selected = true;
+            this.layouts[ 3 ].selected = true;
+        }
+        if( layout == LayoutType.TOP_BOTTOM_LEFT )
+            this.layouts[ 0 ].selected = true;
+        if( layout == LayoutType.TOP_BOTTOM_RIGHT )
+            this.layouts[ 1 ].selected = true;
+        if( layout == LayoutType.BOTTOM_TOP_LEFT )
+            this.layouts[ 2 ].selected = true;
+        if( layout == LayoutType.BOTTOM_TOP_RIGHT )
+            this.layouts[ 3 ].selected = true;
     	update();
     	update();
     }
     }
 
 
     @Override
     @Override
-    public boolean isSelected()
-    {
-    	boolean tmp = selected;
-    	selected = false;
-    	return tmp;
-    }
-
-    @Override
-    public void setView( JPanel v )
+    public boolean isSelected( LayoutType layout )
     {
     {
-    	view = v;
+        if( layout == LayoutType.TOP_BOTTOM_LEFT )
+        {
+            boolean tmp = layouts[ 0 ].selected;
+            layouts[ 0 ].selected = false;
+            return tmp;
+        }
+        if( layout == LayoutType.TOP_BOTTOM_RIGHT )
+        {
+            boolean tmp = layouts[ 1 ].selected;
+            layouts[ 1 ].selected = false;
+            return tmp;
+        }
+        if( layout == LayoutType.BOTTOM_TOP_LEFT )
+        {
+            boolean tmp = layouts[ 2 ].selected;
+            layouts[ 2 ].selected = false;
+            return tmp;
+        }
+        if( layout == LayoutType.BOTTOM_TOP_RIGHT )
+        {
+            boolean tmp = layouts[ 3 ].selected;
+            layouts[ 3 ].selected = false;
+            return tmp;
+        }
+        return false;
     }
     }
     
     
     @Override
     @Override
-    public void setColor( Color c )
+    public void setColor( Color c, LayoutType layout )
     {
     {
-    	color = c;
+        if( layout == null )
+        {
+            this.layouts[ 0 ].color = c;
+            this.layouts[ 1 ].color = c;
+            this.layouts[ 2 ].color = c;
+            this.layouts[ 3 ].color = c;
+        }
+        if( layout == LayoutType.TOP_BOTTOM_LEFT )
+            this.layouts[ 0 ].color = c;
+        if( layout == LayoutType.TOP_BOTTOM_RIGHT )
+            this.layouts[ 1 ].color = c;
+        if( layout == LayoutType.BOTTOM_TOP_LEFT )
+            this.layouts[ 2 ].color = c;
+        if( layout == LayoutType.BOTTOM_TOP_RIGHT )
+            this.layouts[ 3 ].color = c;
     }
     }
     
     
     @Override
     @Override
-    public Color getColor()
+    public Color getColor( LayoutType layout )
     {
     {
-    	return color;
+        if( layout == LayoutType.TOP_BOTTOM_LEFT )
+            return this.layouts[ 0 ].color;
+        if( layout == LayoutType.TOP_BOTTOM_RIGHT )
+            return this.layouts[ 1 ].color;
+        if( layout == LayoutType.BOTTOM_TOP_LEFT )
+            return this.layouts[ 2 ].color;
+        if( layout == LayoutType.BOTTOM_TOP_RIGHT )
+            return this.layouts[ 3 ].color;
+        return null;
     }
     }
     
     
     @Override
     @Override
@@ -204,70 +360,179 @@ public class LayeredNode implements LayeredGraphNode {
     }
     }
 
 
     @Override
     @Override
-    public void setX(double x, boolean def) {
-        if( original != null )
-            original.setX( x );
-        xUndef = !def;
-        this.x = x;
+    public void setX(double x, boolean def, LayoutType layout ) {
+        if( layout == null )
+        {
+            layouts[ 0 ].x = x;
+            layouts[ 1 ].x = x;
+            layouts[ 2 ].x = x;
+            layouts[ 3 ].x = x;
+        }
+        if( layout == LayoutType.TOP_BOTTOM_LEFT )
+        {
+            layouts[ 0 ].xUndef = !def;
+            layouts[ 0 ].x = x;
+        }
+        if( layout == LayoutType.TOP_BOTTOM_RIGHT )
+        {
+            layouts[ 1 ].xUndef = !def;
+            layouts[ 1 ].x = x;
+        }
+        if( layout == LayoutType.BOTTOM_TOP_LEFT )
+        {
+            layouts[ 2 ].xUndef = !def;
+            layouts[ 2 ].x = x;
+        }
+        if( layout == LayoutType.BOTTOM_TOP_RIGHT )
+        {
+            layouts[ 3 ].xUndef = !def;
+            layouts[ 3 ].x = x;
+        }
     }
     }
 
 
     @Override
     @Override
-    public void setY(double y) {
-        if( original != null )
-            original.setY( y );
-        this.y = y;
+    public void setY(double y, LayoutType layout ) {
+        if( layout == null )
+        {
+            layouts[ 0 ].y = y;
+            layouts[ 1 ].y = y;
+            layouts[ 2 ].y = y;
+            layouts[ 3 ].y = y;
+        }
+        if( layout == LayoutType.TOP_BOTTOM_LEFT )
+            layouts[ 0 ].y = y;
+        if( layout == LayoutType.TOP_BOTTOM_RIGHT )
+            layouts[ 1 ].y = y;
+        if( layout == LayoutType.BOTTOM_TOP_LEFT )
+            layouts[ 2 ].y = y;
+        if( layout == LayoutType.BOTTOM_TOP_RIGHT )
+            layouts[ 3 ].y = y;
     }
     }
 
 
     @Override
     @Override
-    public double getX() {
-        return x;
+    public double getX( LayoutType layout ) {
+        if( layout == LayoutType.TOP_BOTTOM_LEFT )
+            return this.layouts[ 0 ].x;
+        if( layout == LayoutType.TOP_BOTTOM_RIGHT )
+            return this.layouts[ 1 ].x;
+        if( layout == LayoutType.BOTTOM_TOP_LEFT )
+            return this.layouts[ 2 ].x;
+        if( layout == LayoutType.BOTTOM_TOP_RIGHT )
+            return this.layouts[ 3 ].x;
+        return 0;
     }
     }
 
 
     @Override
     @Override
-    public double getY() {
-        return y;
+    public double getY( LayoutType layout ) {
+        if( layout == LayoutType.TOP_BOTTOM_LEFT )
+            return this.layouts[ 0 ].y;
+        if( layout == LayoutType.TOP_BOTTOM_RIGHT )
+            return this.layouts[ 1 ].y;
+        if( layout == LayoutType.BOTTOM_TOP_LEFT )
+            return this.layouts[ 2 ].y;
+        if( layout == LayoutType.BOTTOM_TOP_RIGHT )
+            return this.layouts[ 3 ].y;
+        return 0;
     }
     }
 
 
     @Override
     @Override
-    public double getWidth() {
+    public double getWidth( LayoutType layout ) {
         if( nodes.size() > 0 )
         if( nodes.size() > 0 )
         {
         {
-        	double max = 0;
-        	for( LayeredGraphNode n : nodes )
-        	{
-        		if( max < n.getX() + n.getWidth() + 50 )
-        			max = n.getX() + n.getWidth() + 50;
-        	}
-        	return Math.max( max, w );
+            double max = 0;
+            for( LayeredGraphNode n : nodes )
+            {
+                if( max < n.getX(layout) + n.getWidth(layout) + 50 )
+                    max = n.getX(layout) + n.getWidth(layout) + 50;
+            }
+            if( layout == LayoutType.TOP_BOTTOM_LEFT )
+                return Math.max( max, layouts[ 0 ].w );
+            if( layout == LayoutType.TOP_BOTTOM_RIGHT )
+                return Math.max( max, layouts[ 1 ].w );
+            if( layout == LayoutType.BOTTOM_TOP_LEFT )
+                return Math.max( max, layouts[ 2 ].w );
+            if( layout == LayoutType.BOTTOM_TOP_RIGHT )
+                return Math.max( max, layouts[ 3 ].w );
         }
         }
-        return w;
+        if( layout == LayoutType.TOP_BOTTOM_LEFT )
+            return layouts[ 0 ].w;
+        if( layout == LayoutType.TOP_BOTTOM_RIGHT )
+            return layouts[ 1 ].w;
+        if( layout == LayoutType.BOTTOM_TOP_LEFT )
+            return layouts[ 2 ].w;
+        if( layout == LayoutType.BOTTOM_TOP_RIGHT )
+            return layouts[ 3 ].w;
+        return 0;
     }
     }
 
 
     @Override
     @Override
-    public double getHeight() {
+    public double getHeight( LayoutType layout ) {
         if( nodes.size() > 0 )
         if( nodes.size() > 0 )
         {
         {
         	double max = 0;
         	double max = 0;
         	for( LayeredGraphNode n : nodes )
         	for( LayeredGraphNode n : nodes )
         	{
         	{
-        		if( max < n.getY() + n.getHeight() + 50 )
-        			max = n.getY() + n.getHeight() + 50;
+        		if( max < n.getY(layout) + n.getHeight(layout) + 50 )
+        			max = n.getY(layout) + n.getHeight(layout) + 50;
         	}
         	}
-        	return Math.max( max, h );
+            if( layout == LayoutType.TOP_BOTTOM_LEFT )
+                return Math.max( max, layouts[ 0 ].h );
+            if( layout == LayoutType.TOP_BOTTOM_RIGHT )
+                return Math.max( max, layouts[ 1 ].h );
+            if( layout == LayoutType.BOTTOM_TOP_LEFT )
+                return Math.max( max, layouts[ 2 ].h );
+            if( layout == LayoutType.BOTTOM_TOP_RIGHT )
+                return Math.max( max, layouts[ 3 ].h );
         }
         }
-        return h;
+        if( layout == LayoutType.TOP_BOTTOM_LEFT )
+            return layouts[ 0 ].h;
+        if( layout == LayoutType.TOP_BOTTOM_RIGHT )
+            return layouts[ 1 ].h;
+        if( layout == LayoutType.BOTTOM_TOP_LEFT )
+            return layouts[ 2 ].h;
+        if( layout == LayoutType.BOTTOM_TOP_RIGHT )
+            return layouts[ 3 ].h;
+        return 0;
     }
     }
     
     
     @Override
     @Override
-    public void setWidth( double w )
+    public void setWidth( double w, LayoutType layout )
     {
     {
-        this.w = w;
+        if( layout == null )
+        {
+            this.layouts[ 0 ].w = w;
+            this.layouts[ 1 ].w = w;
+            this.layouts[ 2 ].w = w;
+            this.layouts[ 3 ].w = w;
+        }
+        if( layout == LayoutType.TOP_BOTTOM_LEFT )
+            this.layouts[ 0 ].w = w;
+        if( layout == LayoutType.TOP_BOTTOM_RIGHT )
+            this.layouts[ 1 ].w = w;
+        if( layout == LayoutType.BOTTOM_TOP_LEFT )
+            this.layouts[ 2 ].w = w;
+        if( layout == LayoutType.BOTTOM_TOP_RIGHT )
+            this.layouts[ 3 ].w = w;
     }
     }
     
     
     @Override
     @Override
-    public void setHeight( double h )
+    public void setHeight( double h, LayoutType layout )
     {
     {
-        this.h = h;
+        if( layout == null )
+        {
+            this.layouts[ 0 ].h = h;
+            this.layouts[ 1 ].h = h;
+            this.layouts[ 2 ].h = h;
+            this.layouts[ 3 ].h = h;
+        }
+        if( layout == LayoutType.TOP_BOTTOM_LEFT )
+            this.layouts[ 0 ].h = h;
+        if( layout == LayoutType.TOP_BOTTOM_RIGHT )
+            this.layouts[ 1 ].h = h;
+        if( layout == LayoutType.BOTTOM_TOP_LEFT )
+            this.layouts[ 2 ].h = h;
+        if( layout == LayoutType.BOTTOM_TOP_RIGHT )
+            this.layouts[ 3 ].h = h;
     }
     }
 
 
     @Override
     @Override
@@ -350,6 +615,17 @@ public class LayeredNode implements LayeredGraphNode {
     public ArrayList<LayeredGraphNode> getContainedNodes() {
     public ArrayList<LayeredGraphNode> getContainedNodes() {
         return nodes;
         return nodes;
     }
     }
+    
+    @Override
+    public ArrayList< LayeredGraphNode > getSortedContainedNodes()
+    {
+        ArrayList< LayeredGraphNode > result = new ArrayList<>();
+        for( ArrayList<LayeredGraphNode> l : layers )
+        {
+            result.addAll( l );
+        }
+        return result;
+    }
 
 
     @Override
     @Override
     public ArrayList<ArrayList<LayeredGraphNode>> getContainedLayers() {
     public ArrayList<ArrayList<LayeredGraphNode>> getContainedLayers() {
@@ -398,7 +674,7 @@ public class LayeredNode implements LayeredGraphNode {
         {
         {
         	for( LayeredGraphEdge e : unsorted )
         	for( LayeredGraphEdge e : unsorted )
             {
             {
-                if( e.getSources().contains( node ) )
+                if( e.getTargets().contains( node ) )
                 	result.add( e );
                 	result.add( e );
             }
             }
         }
         }

+ 20 - 21
src/View/EdgeView.java

@@ -10,6 +10,7 @@ import java.util.ArrayList;
 
 
 import javax.swing.JPanel;
 import javax.swing.JPanel;
 
 
+import Algorithms.Animated.BK.ExtremalLayoutCalc.LayoutType;
 import Model.LayeredGraphEdge;
 import Model.LayeredGraphEdge;
 
 
 /**
 /**
@@ -21,35 +22,33 @@ public class EdgeView extends JPanel {
     private static final long serialVersionUID = 1L;
     private static final long serialVersionUID = 1L;
 
 
     private LayeredGraphEdge model;
     private LayeredGraphEdge model;
+    private LayoutType layout;
     
     
-    public EdgeView( LayeredGraphEdge model ) {
+    public EdgeView( LayeredGraphEdge model, LayoutType lt ) {
         this.model = model;
         this.model = model;
+        layout = lt;
     }
     }
     
     
     @Override
     @Override
-    public int getX()
+    public Point getLocation()
     {
     {
-        ArrayList<Point> bps = model.getLinePoints();
-        double min = bps.get( 0 ).getX();
+        ArrayList<Point> bps = model.getLinePoints( layout );
+        double minX = bps.get( 0 ).getX();
+        double minY = bps.get( 0 ).getY();
         for( Point p : bps )
         for( Point p : bps )
-            min = Math.min( min, p.getX() );
-        return (int)min - 5;
-    }
-    
-    @Override
-    public int getY()
-    {
-        ArrayList<Point> bps = model.getLinePoints();
-        double min = bps.get( 0 ).getY();
-        for( Point p : bps )
-            min =  Math.min( min, p.getY() );
-        return (int)min - 5;
+        {
+            minX = Math.min( minX, p.getX() );
+            minY =  Math.min( minY, p.getY() );
+        }
+        minX -= 5;
+        minY -= 5;
+        return new Point( (int)minX, (int)minY );
     }
     }
     
     
     @Override
     @Override
     public int getWidth()
     public int getWidth()
     {
     {
-        ArrayList<Point> bps = model.getLinePoints();
+        ArrayList<Point> bps = model.getLinePoints( layout );
         double max = bps.get( 0 ).getX();
         double max = bps.get( 0 ).getX();
         for( Point p : bps )
         for( Point p : bps )
             max =  Math.max( max, p.getX() );
             max =  Math.max( max, p.getX() );
@@ -59,7 +58,7 @@ public class EdgeView extends JPanel {
     @Override
     @Override
     public int getHeight()
     public int getHeight()
     {
     {
-        ArrayList<Point> bps = model.getLinePoints();
+        ArrayList<Point> bps = model.getLinePoints( layout );
         double max = bps.get( 0 ).getY();
         double max = bps.get( 0 ).getY();
         for( Point p : bps )
         for( Point p : bps )
             max =  Math.max( max, p.getY() );
             max =  Math.max( max, p.getY() );
@@ -90,12 +89,12 @@ public class EdgeView extends JPanel {
         ((Graphics2D)g).setStroke(new BasicStroke(1));
         ((Graphics2D)g).setStroke(new BasicStroke(1));
         //System.out.println( "Clipping: x:" + g.getClip().getBounds().getX() + " y:" + g.getClip().getBounds().getY() + " w:" + g.getClip().getBounds().getWidth() + " h:" + g.getClip().getBounds().getHeight() );
         //System.out.println( "Clipping: x:" + g.getClip().getBounds().getX() + " y:" + g.getClip().getBounds().getY() + " w:" + g.getClip().getBounds().getWidth() + " h:" + g.getClip().getBounds().getHeight() );
         g.setColor( Color.GREEN );
         g.setColor( Color.GREEN );
-        ArrayList<Point> bps = model.getLinePoints();
+        ArrayList<Point> bps = model.getLinePoints( layout );
         for( int i = 1; i < bps.size(); i++ )
         for( int i = 1; i < bps.size(); i++ )
         {
         {
           //  System.out.println( "Draw a Line from (" + (int)bps.get( i - 1 ).getX() + "," + (int)bps.get( i - 1 ).getY() + ") to (" + (int)bps.get( i ).getX() + "," + (int)bps.get( i ).getY() + ")" );
           //  System.out.println( "Draw a Line from (" + (int)bps.get( i - 1 ).getX() + "," + (int)bps.get( i - 1 ).getY() + ") to (" + (int)bps.get( i ).getX() + "," + (int)bps.get( i ).getY() + ")" );
-            g.drawLine( (int)bps.get( i - 1 ).getX() - getX(), (int)bps.get( i - 1 ).getY() - getY(), (int)bps.get( i ).getX() - getX(), (int)bps.get( i ).getY() - getY() );
+            g.drawLine( (int)bps.get( i - 1 ).getX() - getLocation().x, (int)bps.get( i - 1 ).getY() - getLocation().y, (int)bps.get( i ).getX() - getLocation().x, (int)bps.get( i ).getY() - getLocation().y );
         }
         }
-        ((Graphics2D)g).fill( RenderHelper.createArrowShape( new Point( bps.get( bps.size() - 2 ).x - getX(), bps.get( bps.size() - 2 ).y - getY() ), new Point( bps.get( bps.size() - 1 ).x - getX(), bps.get( bps.size() - 1 ).y - getY() ) ) );
+        ((Graphics2D)g).fill( RenderHelper.createArrowShape( new Point( bps.get( bps.size() - 2 ).x - getLocation().x, bps.get( bps.size() - 2 ).y - getLocation().y ), new Point( bps.get( bps.size() - 1 ).x - getLocation().x, bps.get( bps.size() - 1 ).y - getLocation().y ) ) );
     }
     }
 }
 }

+ 12 - 10
src/View/MainView.java

@@ -1,6 +1,6 @@
 package View;
 package View;
 
 
-import java.awt.BorderLayout;
+import java.awt.GridLayout;
 import java.awt.event.KeyEvent;
 import java.awt.event.KeyEvent;
 import java.awt.event.KeyListener;
 import java.awt.event.KeyListener;
 
 
@@ -9,6 +9,7 @@ import javax.swing.JFrame;
 import Algorithms.Animated.Action;
 import Algorithms.Animated.Action;
 import Algorithms.Animated.AnimationController;
 import Algorithms.Animated.AnimationController;
 import Algorithms.Animated.BK.BKNodePlacement;
 import Algorithms.Animated.BK.BKNodePlacement;
+import Algorithms.Animated.BK.ExtremalLayoutCalc.LayoutType;
 import IO.Writer;
 import IO.Writer;
 import Model.LayeredGraphEdge;
 import Model.LayeredGraphEdge;
 import Model.LayeredGraphNode;
 import Model.LayeredGraphNode;
@@ -34,7 +35,7 @@ public class MainView {
 		controller = new AnimationController();
 		controller = new AnimationController();
 		controller.setTimeBetween( 100 );
 		controller.setTimeBetween( 100 );
 		frame = new JFrame();
 		frame = new JFrame();
-        frame.setSize( Math.min( (int)graph.getWidth() + 200, 1700 ), Math.min( (int)graph.getHeight() + 200, 900 ) );
+        frame.setSize( Math.min( (int)graph.getWidth( LayoutType.TOP_BOTTOM_LEFT ) * 2 + 200, 1700 ), Math.min( (int)graph.getHeight( LayoutType.TOP_BOTTOM_LEFT ) * 2 + 200, 900 ) );
 		frame.setLocation( 100, 100 );
 		frame.setLocation( 100, 100 );
 		frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
 		frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
 		frame.setVisible( true );
 		frame.setVisible( true );
@@ -71,29 +72,30 @@ public class MainView {
 		    
 		    
 		});
 		});
 		
 		
-		NodeView view = createNodeView( graph );
-		frame.setLayout(new BorderLayout());
-		frame.add(view, BorderLayout.CENTER);
-		frame.add( view );
+		frame.setLayout(new GridLayout( 2, 2, 10, 10 ));
+		frame.add(createNodeView( graph, LayoutType.TOP_BOTTOM_LEFT ));
+        frame.add(createNodeView( graph, LayoutType.TOP_BOTTOM_RIGHT ));
+        frame.add(createNodeView( graph, LayoutType.BOTTOM_TOP_LEFT ));
+        frame.add(createNodeView( graph, LayoutType.BOTTOM_TOP_RIGHT ));
 		frame.validate();
 		frame.validate();
 		frame.repaint();
 		frame.repaint();
 		new BKNodePlacement( controller, graph );
 		new BKNodePlacement( controller, graph );
 	}
 	}
 	
 	
-	private NodeView createNodeView( LayeredGraphNode gNode )
+	private NodeView createNodeView( LayeredGraphNode gNode, LayoutType lt )
 	{
 	{
-		NodeView graphView = new NodeView( gNode );
+		NodeView graphView = new NodeView( gNode, lt );
 		graphView.setLayout( null );
 		graphView.setLayout( null );
 		graphView.setOpaque( true );
 		graphView.setOpaque( true );
 		for( LayeredGraphNode n : gNode.getContainedNodes() )
 		for( LayeredGraphNode n : gNode.getContainedNodes() )
 		{
 		{
-		    NodeView nv = createNodeView( n );
+		    NodeView nv = createNodeView( n, lt );
 		    nv.setBounds( nv.getX(), nv.getY(), nv.getWidth(), nv.getHeight() );
 		    nv.setBounds( nv.getX(), nv.getY(), nv.getWidth(), nv.getHeight() );
 			graphView.add( nv );
 			graphView.add( nv );
 		}
 		}
         for( LayeredGraphEdge e : gNode.getContainedEdges() )
         for( LayeredGraphEdge e : gNode.getContainedEdges() )
         {
         {
-            EdgeView ev = new EdgeView( e );
+            EdgeView ev = new EdgeView( e, lt );
             ev.setOpaque( true );
             ev.setOpaque( true );
             graphView.add( ev );
             graphView.add( ev );
         }
         }

+ 20 - 23
src/View/NodeView.java

@@ -6,10 +6,12 @@ import java.awt.Component;
 import java.awt.Dimension;
 import java.awt.Dimension;
 import java.awt.Graphics;
 import java.awt.Graphics;
 import java.awt.Graphics2D;
 import java.awt.Graphics2D;
+import java.awt.Point;
 
 
 import javax.swing.*;
 import javax.swing.*;
 import javax.swing.border.Border;
 import javax.swing.border.Border;
 
 
+import Algorithms.Animated.BK.ExtremalLayoutCalc.LayoutType;
 import Model.LayeredGraphNode;
 import Model.LayeredGraphNode;
 
 
 /**
 /**
@@ -20,44 +22,39 @@ import Model.LayeredGraphNode;
 public class NodeView extends JPanel {
 public class NodeView extends JPanel {
 	private static final long serialVersionUID = 1L;
 	private static final long serialVersionUID = 1L;
 	private LayeredGraphNode model;
 	private LayeredGraphNode model;
+	private LayoutType layout;
 	
 	
-	public NodeView( LayeredGraphNode model ) {
+	public NodeView( LayeredGraphNode model, LayoutType lt ) {
 		this.model = model;
 		this.model = model;
-		model.setView( this );
-		setSize( (int)model.getWidth(), (int)model.getHeight() );
+		layout = lt;
+		setSize( (int)model.getWidth( layout ), (int)model.getHeight( layout ) );
 	}
 	}
 	
 	
 	@Override
 	@Override
-	public int getX()
+	public Point getLocation()
 	{
 	{
-	    return (int)model.getX();
+	    return new Point( (int)model.getX( layout ), (int)model.getY( layout ) );
 	}
 	}
     
     
-    @Override
-    public int getY()
-    {
-        return (int)model.getY();
-    }
-    
     @Override
     @Override
     public Dimension getPreferredSize()
     public Dimension getPreferredSize()
     {
     {
-    	return new Dimension( (int)model.getWidth(), (int)model.getHeight() );
+    	return new Dimension( (int)model.getWidth( layout ), (int)model.getHeight( layout ) );
     }
     }
     
     
     @Override
     @Override
     public void paint( Graphics g )
     public void paint( Graphics g )
     {
     {
-        double scale = Math.min( (double)super.getWidth() / (int)model.getWidth(), (double)super.getHeight() / (int)model.getHeight());
+        double scale = Math.min( (double)super.getWidth() / (int)model.getWidth( layout ), (double)super.getHeight() / (int)model.getHeight( layout ));
         ((Graphics2D)g).scale( scale, scale );
         ((Graphics2D)g).scale( scale, scale );
         paintComponent( g );
         paintComponent( g );
         for( Component c : getComponents() )
         for( Component c : getComponents() )
         {
         {
             c.paint( g.create( 
             c.paint( g.create( 
-                    c.getX() + 25, 
-                    c.getY() + 25, 
-                    Math.min( (int)model.getWidth() - 25, c.getPreferredSize().width + c.getX() + 25 ), 
-                    Math.min( (int)model.getHeight() - 25, c.getPreferredSize().height + c.getY() + 25 ) ) );
+                    c.getLocation().x + 25, 
+                    c.getLocation().y + 25, 
+                    Math.min( (int)model.getWidth( layout ) - 25, c.getPreferredSize().width + c.getLocation().x + 25 ), 
+                    Math.min( (int)model.getHeight( layout ) - 25, c.getPreferredSize().height + c.getLocation().y + 25 ) ) );
         }
         }
     }
     }
 
 
@@ -65,16 +62,16 @@ public class NodeView extends JPanel {
 	public void paintComponent( Graphics g )
 	public void paintComponent( Graphics g )
 	{
 	{
 		Graphics2D g2 = (Graphics2D)g;
 		Graphics2D g2 = (Graphics2D)g;
-		g2.setColor( model.getColor() );
+		g2.setColor( model.getColor( layout ) );
 		g2.setStroke(new BasicStroke(5));
 		g2.setStroke(new BasicStroke(5));
 		if( model.getContainedNodes().size() == 0 )
 		if( model.getContainedNodes().size() == 0 )
-			g2.fillRect( 0, 0, (int)model.getWidth()-1, (int)model.getHeight()-1 );
-		if( model.isSelected() )
+			g2.fillRect( 0, 0, (int)model.getWidth( layout )-1, (int)model.getHeight( layout )-1 );
+		if( model.isSelected( layout ) )
 		{
 		{
 			g.setColor( Color.GRAY );
 			g.setColor( Color.GRAY );
-			g.fillRect( 0, 0, (int)model.getWidth()-1, (int)model.getHeight()-1 );
+			g.fillRect( 0, 0, (int)model.getWidth( layout )-1, (int)model.getHeight( layout )-1 );
 		}
 		}
-		Border linebor = BorderFactory.createLineBorder(model.getColor(), 5);
-		linebor.paintBorder( this, g2, 0, 0, (int)model.getWidth()-1, (int)model.getHeight()-1 );
+		Border linebor = BorderFactory.createLineBorder(model.getColor( layout ), 5);
+		linebor.paintBorder( this, g2, 0, 0, (int)model.getWidth( layout )-1, (int)model.getHeight( layout )-1 );
 	}
 	}
 }
 }