Browse Source

4 extreme layouts fetig

Kolja Strohm 6 years ago
parent
commit
a07174a7b4

+ 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"}]}

+ 61 - 32
src/Algorithms/Animated/BK/BlockCalc.java

@@ -5,6 +5,7 @@ import java.util.ArrayList;
 
 import Algorithms.Animated.AlgorithmStage;
 import Algorithms.Animated.BackwardAction;
+import Algorithms.Animated.BK.ExtremalLayoutCalc.LayoutType;
 import Model.LayeredGraphEdge;
 import Model.LayeredGraphNode;
 
@@ -21,10 +22,12 @@ public class BlockCalc implements AlgorithmStage {
 	private LayeredGraphNode graph;
 	private ArrayList< ArrayList< BKNodePlacement > > subgraphAlgs;
 	private ArrayList< BackwardAction > backwards;
+	private LayoutType layout;
 	int step;
 	
-	public BlockCalc( LayeredGraphNode graph )
+	public BlockCalc( LayeredGraphNode graph, LayoutType layout )
 	{
+	    this.layout = layout;
 		step = 0;
 		this.graph = graph;
 		layerIndex = 0;
@@ -41,18 +44,40 @@ public class BlockCalc implements AlgorithmStage {
 		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
 	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( 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;
 		}
-		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 )
 		{
 			backwards.add( 0, () -> {
@@ -60,15 +85,19 @@ public class BlockCalc implements AlgorithmStage {
 			});
 			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;
 		for( int m : ms )
 		{
-		    if( current.getAlignedTo() == current )
+		    if( current.getAlignedTo( layout ) == current )
 		    {
                 LayeredGraphNode u = incommingEdges.get( m - 1 ).getSources().get( 0 );
                 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( "" );
 		        	ArrayList< Boolean > oldConflicts = new ArrayList<>();
@@ -77,25 +106,25 @@ public class BlockCalc implements AlgorithmStage {
 		        		oldConflicts.add( e.isConflicted() );
 		        		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;
-		            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++;
 		            backwards.add( 0, () -> {
 		                System.out.println( "Stepping Backwards... (Step " + oldStep + ")" );
 			        	for( int i = 0; i < conflicts.size(); i++ )
 			        		conflicts.get( i ).setConflicted( oldConflicts.get( i ) );
-		                u.setAlignTo( oldAlignU );
-		                current.setColor( oldColorCurrent );
-		                current.setRoot( oldRootCurrent );
-		                current.setAlignTo( oldAlignCurrent );
+		                u.setAlignTo( oldAlignU, layout );
+		                current.setColor( oldColorCurrent, layout );
+		                current.setRoot( oldRootCurrent, layout );
+		                current.setAlignTo( oldAlignCurrent, layout );
 		                r = oldR;
 		            });
 		            backwardsAdded = true;
@@ -116,11 +145,11 @@ public class BlockCalc implements AlgorithmStage {
 	{
 		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;
 		}
 		nodeIndex++;
-		if( nodeIndex >= graph.getContainedLayers().get( layerIndex ).size() )
+		if( nodeIndex >= graph.getContainedLayers().get( calcLayerIndex() ).size() )
 		{
 			layerIndex++;
 			nodeIndex = 0;
@@ -135,12 +164,12 @@ public class BlockCalc implements AlgorithmStage {
 
 	@Override
 	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();
 				return StageStatus.UNFINISHED;
 			}
@@ -148,8 +177,8 @@ public class BlockCalc implements AlgorithmStage {
 		StageStatus status = calcBeforeState();
 		if( status == StageStatus.FINISHED )
 			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();
 		if( !backwards.isEmpty() )
 		{
@@ -172,7 +201,7 @@ public class BlockCalc implements AlgorithmStage {
 			layerIndex--;
 	        backwards.get( 0 ).reverse();
 	        backwards.remove( 0 );
-			nodeIndex = graph.getContainedLayers().get( layerIndex ).size() - 1;
+			nodeIndex = graph.getContainedLayers().get( calcLayerIndex() ).size() - 1;
 		}
 		return StageStatus.UNFINISHED;
 	}

+ 51 - 48
src/Algorithms/Animated/BK/Compaction.java

@@ -4,6 +4,7 @@ import java.util.ArrayList;
 
 import Algorithms.Animated.AlgorithmStage;
 import Algorithms.Animated.BackwardAction;
+import Algorithms.Animated.BK.ExtremalLayoutCalc.LayoutType;
 import Model.LayeredGraphNode;
 
 /**
@@ -32,9 +33,11 @@ public class Compaction implements AlgorithmStage{
 	
 	private ArrayList< StackFrame > stack;
 	private ArrayList< BackwardAction > actions;
+	private LayoutType layout;
 	
-	public Compaction( LayeredGraphNode graph )
+	public Compaction( LayeredGraphNode graph, LayoutType layout )
 	{
+	    this.layout = layout;
 		this.graph = graph;
 		state = CompactionState.PLACE_BLOCKS;
 		stack = new ArrayList<>();
@@ -46,7 +49,7 @@ public class Compaction implements AlgorithmStage{
 	{
 		double max = 0;
 		for( LayeredGraphNode n : graph.getContainedNodes() )
-			max = Math.max( max, n.getWidth() );
+			max = Math.max( max, n.getWidth( layout ) );
 		return max + 50;
 	}
 	
@@ -62,7 +65,7 @@ public class Compaction implements AlgorithmStage{
 				int oldVIndex = 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;
 						break;
@@ -81,14 +84,14 @@ public class Compaction implements AlgorithmStage{
 				{
 					StackFrame f = new StackFrame();
 					f.v = nodes.get( vIndex );
-					double oldX = f.v.getX();
-					f.v.setX( 0, true );
-					f.v.setSelected();
+					double oldX = f.v.getX( layout );
+					f.v.setX( 0, true, layout );
+					f.v.setSelected( layout );
 					f.w = f.v;
 					stack.add( 0, f );
 					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 );
 						vIndex = oldVIndex;
 						state = CompactionState.PLACE_BLOCKS;
@@ -102,26 +105,26 @@ public class Compaction implements AlgorithmStage{
 				{
 					if( graph.getContainedLayers().get( sf.w.getLayer() ).indexOf( sf.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() )
+						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 ) )
 						{
 							StackFrame nsf = new StackFrame();
 							nsf.v = sf.u;
-							double oldX = nsf.v.getX();
-							nsf.v.setX( 0, true );
-							nsf.v.setSelected();
+							double oldX = nsf.v.getX( layout );
+							nsf.v.setX( 0, true, layout );
+							nsf.v.setSelected( layout );
 							nsf.w = nsf.v;
 							stack.add( 0, nsf );
 							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.get( 0 ).u = null;
 							});
 						}
 						else
 						{
-							sf.u.setSelected();
+							sf.u.setSelected( layout );
 							actions.add( 0, ()-> {
 								stack.get( 0 ).u = null;
 							});
@@ -130,14 +133,14 @@ public class Compaction implements AlgorithmStage{
 					else
 					{
 						LayeredGraphNode oldW = sf.w;
-						sf.v.setSelected();
-						sf.w = sf.w.getAlignedTo();
+						sf.v.setSelected( layout );
+						sf.w = sf.w.getAlignedTo( layout );
 						if( sf.w == sf.v )
 						{
 							stack.remove( 0 );
 							actions.add( 0, ()-> {
 								stack.add( 0, sf );
-								sf.v.setSelected();
+								sf.v.setSelected( layout );
 								sf.w = oldW;
 							});
 						}
@@ -145,27 +148,27 @@ public class Compaction implements AlgorithmStage{
 						{
 							actions.add( 0, ()-> {
 								sf.w = oldW;
-								sf.v.setSelected();
+								sf.v.setSelected( layout );
 							});
 						}
 					}	
 				}
 				else
 				{
-					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() ) );
+					LayeredGraphNode oldSink = sf.v.getSink( layout );
+					if( sf.v.getSink( layout ) == sf.v )
+						sf.v.setSink( sf.u.getSink( layout ), layout );
+					LayeredGraphNode sinkOfU = sf.u.getSink( layout );
+					double oldShift = sinkOfU.getShift( layout );
+					double oldX = sf.v.getX( layout );
+					boolean oldDef = !sf.v.isXUndefined( layout );
+					sf.v.setSelected( layout );
+					if( sf.v.getSink( layout ) != sf.u.getSink( layout ) )
+						sf.u.getSink( layout ).setShift( Math.min( sf.u.getSink( layout ).getShift( layout ), sf.v.getX( layout ) - sf.u.getX( layout ) - calcSpacing() ), layout );
 					else
-						sf.v.setX( Math.max( sf.v.getX(), sf.u.getX() + calcSpacing() ), true );
+						sf.v.setX( Math.max( sf.v.getX( layout ), sf.u.getX( layout ) + calcSpacing() ), true, layout );
 					LayeredGraphNode oldW = sf.w;
-					sf.w = sf.w.getAlignedTo();
+					sf.w = sf.w.getAlignedTo( layout );
 					LayeredGraphNode oldU = sf.u;
 					sf.u = null;
 					if( sf.w == sf.v )
@@ -173,22 +176,22 @@ public class Compaction implements AlgorithmStage{
 						stack.remove( 0 );
 						actions.add( 0, ()-> {
 							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.v.setX( oldX, oldDef );
-							sf.v.setSelected();
+							sf.v.setX( oldX, oldDef, layout );
+							sf.v.setSelected( layout );
 							sf.w = oldW;
 						});
 					}
 					else
 					{
 						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.v.setX( oldX, oldDef );
-							sf.v.setSelected();
+							sf.v.setX( oldX, oldDef, layout );
+							sf.v.setSelected( layout );
 							sf.w = oldW;
 						});
 					}
@@ -198,15 +201,15 @@ public class Compaction implements AlgorithmStage{
 		else if( state == CompactionState.APPLY_SHIFT )
 		{
 			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, ()-> {
-				v.setX( oldX, oldDef );
-				v.setSelected();
+				v.setX( oldX, oldDef, layout );
+				v.setSelected( layout );
 				vIndex--;
 			} );
 			vIndex++;

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

@@ -23,7 +23,6 @@ public class ExtremalLayoutCalc implements AlgorithmStage {
 		COMPACTION
 	}
 	
-	private LayoutType typ;
 	private BlockCalc bc;
 	private Compaction cp;
 	private LayoutState status;
@@ -32,9 +31,8 @@ public class ExtremalLayoutCalc implements AlgorithmStage {
 	public ExtremalLayoutCalc( LayoutType typ, LayeredGraphNode graph )
 	{
 		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

+ 9 - 8
src/Algorithms/InitializeNodePositions.java

@@ -2,6 +2,7 @@ package Algorithms;
 
 import java.util.ArrayList;
 
+import Algorithms.Animated.BK.ExtremalLayoutCalc.LayoutType;
 import Model.LayeredGraphNode;
 
 
@@ -21,29 +22,29 @@ public class InitializeNodePositions {
     	RandomColorGenerator cGen = new RandomColorGenerator();
         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 );
         }
         int curY = 0;
         double maxWidth = 0, maxHeight = 0;
         
         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();
         for (ArrayList<LayeredGraphNode> layer : layers) { // Gehe alle Layer durch
             maxHeight = 0;
             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;
             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;
             }
             curY += maxHeight + 25;

+ 2 - 2
src/IO/Reader.java

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

+ 8 - 7
src/Main.java

@@ -1,6 +1,7 @@
 import Algorithms.InitializeNodePositions;
 import Algorithms.RandomGraphGenerator;
 import Algorithms.SweepCrossingMinimizer;
+import IO.Reader;
 import Model.LayeredGraphNode;
 import View.MainView;
 
@@ -12,13 +13,13 @@ import View.MainView;
 public class Main {
 
 	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 );
 		new MainView( graph );
 	}

+ 72 - 14
src/Model/LayeredEdge.java

@@ -5,6 +5,8 @@ import java.util.ArrayList;
 
 import org.eclipse.elk.graph.ElkEdge;
 
+import Algorithms.Animated.BK.ExtremalLayoutCalc.LayoutType;
+
 /**
  * Die Implementation einer Kante aus einem Layered Graphen.
  * Implementiert {@link LayeredGraphEdge.}
@@ -20,9 +22,10 @@ public class LayeredEdge implements LayeredGraphEdge {
     LayeredGraphNode graph;
     boolean reversed;
     boolean dummy;
-    ArrayList< Point > bindPoints;
+    ArrayList< Point >[] bindPoints;
     boolean conflicted;
     
+    @SuppressWarnings("unchecked")
     public LayeredEdge( ElkEdge original, ArrayList< LayeredGraphNode > sources, ArrayList< LayeredGraphNode > targets, LayeredGraphNode graph )
     {
         this.original = original;
@@ -31,9 +34,14 @@ public class LayeredEdge implements LayeredGraphEdge {
         this.graph = graph;
         reversed = 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;
     }
 
@@ -74,35 +82,85 @@ public class LayeredEdge implements LayeredGraphEdge {
     }
     
     @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
-    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
-    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
-    public ArrayList<Point> getLinePoints()
+    public ArrayList<Point> getLinePoints( LayoutType layout )
     {
         //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 )
         //{
-            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

+ 6 - 4
src/Model/LayeredGraphEdge.java

@@ -5,6 +5,8 @@ import java.util.ArrayList;
 
 import org.eclipse.elk.graph.ElkEdge;
 
+import Algorithms.Animated.BK.ExtremalLayoutCalc.LayoutType;
+
 /**
  * Ein Interface, welches die Methoden einer Kante aus einem gelayerten Graphen beschreibt
  * @author kolja
@@ -51,10 +53,10 @@ public interface LayeredGraphEdge {
      */
     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
      * @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.util.ArrayList;
 
-import javax.swing.JPanel;
-
 import org.eclipse.elk.graph.ElkEdge;
 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)
  * @author kolja
@@ -23,23 +23,22 @@ public interface LayeredGraphNode {
      */
     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 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 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
@@ -89,35 +88,35 @@ public interface LayeredGraphNode {
      * Legt die X Koordinate des Knotens fest
      * @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
      * @param y die Y Koordinate in Pixeln
      */
-    void setY( double y );
+    void setY( double y, LayoutType layout );
     /**
      * Gibt die X Koordinate zur�ck
      * @return die X Koordinate in Pixeln zur�ck
      */
-    double getX();
+    double getX( LayoutType layout );
     /**
      * Gibt die Y Koordinate zur�ck
      * @return die Y Koordinate in Pixeln zur�ck
      */
-    double getY();
+    double getY( LayoutType layout );
     /**
      * Gibt die Breite des Knotens zur�ck
      * @return die Breite in Pixeln
      */
-    double getWidth();
+    double getWidth( LayoutType layout );
     /**
      * Gibt die H�he des Knotens zur�ck
      * @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
     
@@ -148,6 +147,10 @@ public interface LayeredGraphNode {
      * @return Eine Liste mit allen Knoten des Subgraphen
      */
     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
      */

+ 368 - 92
src/Model/LayeredNode.java

@@ -3,12 +3,12 @@ package Model;
 import java.awt.Color;
 import java.util.ArrayList;
 
-import javax.swing.JPanel;
 import javax.swing.SwingUtilities;
 
 import org.eclipse.elk.graph.ElkEdge;
 import org.eclipse.elk.graph.ElkNode;
 
+import Algorithms.Animated.BK.ExtremalLayoutCalc.LayoutType;
 import View.MainView;
 
 /**
@@ -24,23 +24,26 @@ public class LayeredNode implements LayeredGraphNode {
     private ElkNode original;
     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;
-    JPanel view;
-    boolean selected;
-    boolean xUndef;
-    
-    // Block Calculation
-    LayeredGraphNode align;
-    LayeredGraphNode root;
-    // Compaction
-    LayeredGraphNode sink;
-    double shift;
     
     // for subgraph in this node
     private ArrayList< LayeredGraphEdge > edges;
@@ -55,72 +58,174 @@ public class LayeredNode implements LayeredGraphNode {
         edges = new ArrayList<>();
         nodes = 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
-    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
-    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
-    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
-    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
-    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
-    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
-    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
-    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
-    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
@@ -128,43 +233,94 @@ public class LayeredNode implements LayeredGraphNode {
     {
     	SwingUtilities.invokeLater(new Runnable() {
 		    public void run() {
-		        System.out.println( "UPDATE" );
 		        MainView.frame.repaint();
 		    }
 		});
     }
 
     @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();
     }
 
     @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
-    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
-    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
@@ -204,70 +360,179 @@ public class LayeredNode implements LayeredGraphNode {
     }
 
     @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
-    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
-    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
-    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
-    public double getWidth() {
+    public double getWidth( LayoutType layout ) {
         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
-    public double getHeight() {
+    public double getHeight( LayoutType layout ) {
         if( nodes.size() > 0 )
         {
         	double max = 0;
         	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
-    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
-    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
@@ -350,6 +615,17 @@ public class LayeredNode implements LayeredGraphNode {
     public ArrayList<LayeredGraphNode> getContainedNodes() {
         return nodes;
     }
+    
+    @Override
+    public ArrayList< LayeredGraphNode > getSortedContainedNodes()
+    {
+        ArrayList< LayeredGraphNode > result = new ArrayList<>();
+        for( ArrayList<LayeredGraphNode> l : layers )
+        {
+            result.addAll( l );
+        }
+        return result;
+    }
 
     @Override
     public ArrayList<ArrayList<LayeredGraphNode>> getContainedLayers() {

+ 20 - 21
src/View/EdgeView.java

@@ -10,6 +10,7 @@ import java.util.ArrayList;
 
 import javax.swing.JPanel;
 
+import Algorithms.Animated.BK.ExtremalLayoutCalc.LayoutType;
 import Model.LayeredGraphEdge;
 
 /**
@@ -21,35 +22,33 @@ public class EdgeView extends JPanel {
     private static final long serialVersionUID = 1L;
 
     private LayeredGraphEdge model;
+    private LayoutType layout;
     
-    public EdgeView( LayeredGraphEdge model ) {
+    public EdgeView( LayeredGraphEdge model, LayoutType lt ) {
         this.model = model;
+        layout = lt;
     }
     
     @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 )
-            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
     public int getWidth()
     {
-        ArrayList<Point> bps = model.getLinePoints();
+        ArrayList<Point> bps = model.getLinePoints( layout );
         double max = bps.get( 0 ).getX();
         for( Point p : bps )
             max =  Math.max( max, p.getX() );
@@ -59,7 +58,7 @@ public class EdgeView extends JPanel {
     @Override
     public int getHeight()
     {
-        ArrayList<Point> bps = model.getLinePoints();
+        ArrayList<Point> bps = model.getLinePoints( layout );
         double max = bps.get( 0 ).getY();
         for( Point p : bps )
             max =  Math.max( max, p.getY() );
@@ -90,12 +89,12 @@ public class EdgeView extends JPanel {
         ((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() );
         g.setColor( Color.GREEN );
-        ArrayList<Point> bps = model.getLinePoints();
+        ArrayList<Point> bps = model.getLinePoints( layout );
         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() + ")" );
-            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;
 
-import java.awt.BorderLayout;
+import java.awt.GridLayout;
 import java.awt.event.KeyEvent;
 import java.awt.event.KeyListener;
 
@@ -9,6 +9,7 @@ import javax.swing.JFrame;
 import Algorithms.Animated.Action;
 import Algorithms.Animated.AnimationController;
 import Algorithms.Animated.BK.BKNodePlacement;
+import Algorithms.Animated.BK.ExtremalLayoutCalc.LayoutType;
 import IO.Writer;
 import Model.LayeredGraphEdge;
 import Model.LayeredGraphNode;
@@ -34,7 +35,7 @@ public class MainView {
 		controller = new AnimationController();
 		controller.setTimeBetween( 100 );
 		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.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
 		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.repaint();
 		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.setOpaque( true );
 		for( LayeredGraphNode n : gNode.getContainedNodes() )
 		{
-		    NodeView nv = createNodeView( n );
+		    NodeView nv = createNodeView( n, lt );
 		    nv.setBounds( nv.getX(), nv.getY(), nv.getWidth(), nv.getHeight() );
 			graphView.add( nv );
 		}
         for( LayeredGraphEdge e : gNode.getContainedEdges() )
         {
-            EdgeView ev = new EdgeView( e );
+            EdgeView ev = new EdgeView( e, lt );
             ev.setOpaque( true );
             graphView.add( ev );
         }

+ 20 - 26
src/View/NodeView.java

@@ -6,10 +6,12 @@ import java.awt.Component;
 import java.awt.Dimension;
 import java.awt.Graphics;
 import java.awt.Graphics2D;
+import java.awt.Point;
 
 import javax.swing.*;
 import javax.swing.border.Border;
 
+import Algorithms.Animated.BK.ExtremalLayoutCalc.LayoutType;
 import Model.LayeredGraphNode;
 
 /**
@@ -20,47 +22,39 @@ import Model.LayeredGraphNode;
 public class NodeView extends JPanel {
 	private static final long serialVersionUID = 1L;
 	private LayeredGraphNode model;
+	private LayoutType layout;
 	
-	public NodeView( LayeredGraphNode model ) {
+	public NodeView( LayeredGraphNode model, LayoutType lt ) {
 		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
-	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
     public Dimension getPreferredSize()
     {
-    	return new Dimension( (int)model.getWidth(), (int)model.getHeight() );
+    	return new Dimension( (int)model.getWidth( layout ), (int)model.getHeight( layout ) );
     }
     
     @Override
     public void paint( Graphics g )
     {
-    	System.out.println( super.getWidth() + " " + super.getHeight() );
-        double scale = Math.min( (double)super.getWidth() / (int)model.getWidth(), (double)super.getHeight() / (int)model.getHeight());
-        System.out.println( scale );
+        double scale = Math.min( (double)super.getWidth() / (int)model.getWidth( layout ), (double)super.getHeight() / (int)model.getHeight( layout ));
         ((Graphics2D)g).scale( scale, scale );
         paintComponent( g );
         for( Component c : getComponents() )
         {
             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 ) ) );
-            System.out.println( c.getX() + " " + c.getY() + "   " + c.getPreferredSize() + " " + scale );
+                    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 ) ) );
         }
     }
 
@@ -68,16 +62,16 @@ public class NodeView extends JPanel {
 	public void paintComponent( Graphics g )
 	{
 		Graphics2D g2 = (Graphics2D)g;
-		g2.setColor( model.getColor() );
+		g2.setColor( model.getColor( layout ) );
 		g2.setStroke(new BasicStroke(5));
 		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.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 );
 	}
 }