Kolja Strohm 7 жил өмнө
parent
commit
eb64ad5f1b

+ 2 - 1
.gitignore

@@ -3,4 +3,5 @@ bin
 out
 out
 auxil
 auxil
 svg-inkscape
 svg-inkscape
-*.synctex*
+*.synctex*
+*.vpp.bak*

+ 0 - 0
big.graph → big.json


+ 78 - 36
doc/chapter/2architecture.tex

@@ -18,7 +18,15 @@ The structure is as follows:
     \item An edge has the attributes that are displayed in table~\ref{table:edge-attributes}.
     \item An edge has the attributes that are displayed in table~\ref{table:edge-attributes}.
 \end{itemize}
 \end{itemize}
 For parsing the JSON file the JSON-java library~\cite{leary_json-java:_2018} is used.
 For parsing the JSON file the JSON-java library~\cite{leary_json-java:_2018} is used.
+The classes for reading and writing those JSON files are displayed in figure~\ref{fig:io}.
+The internal representation of graphs is further explained in the section~\ref{sec:model}.
 
 
+\begin{figure}[tp]
+    \centering
+    \includegraphics[width=\linewidth, trim={0 20cm 0 0}]{img/IO.pdf}
+    \caption{Class diagram of the \enquote{IO} package, containing utilities for reading and writing graphs.}
+    \label{fig:io}
+\end{figure}
 
 
 \centering
 \centering
 \begin{longtable}{|p{1.8cm}|p{2cm}|p{1.8cm}|p{8.5cm}|}
 \begin{longtable}{|p{1.8cm}|p{2cm}|p{1.8cm}|p{8.5cm}|}
@@ -31,10 +39,12 @@ For parsing the JSON file the JSON-java library~\cite{leary_json-java:_2018} is
     The node can be higher if it contains other nodes that need more space. \\\hline
     The node can be higher if it contains other nodes that need more space. \\\hline
     layers & list of lists of nodes & yes & The layers of nodes inside this node (Hierarchy). \\\hline
     layers & list of lists of nodes & yes & The layers of nodes inside this node (Hierarchy). \\\hline
     edges & list of edges & yes & The edges between nodes whose parent node is this node. \\\hline
     edges & list of edges & yes & The edges between nodes whose parent node is this node. \\\hline
-\caption{Node Attributes}
-\label{table:node-attributes}
+    \caption{Node Attributes}
+    \label{table:node-attributes}
 \end{longtable}
 \end{longtable}
 
 
+\newpage
+
 \begin{longtable}{|p{1.8cm}|p{2cm}|p{1.8cm}|p{8.5cm}|}
 \begin{longtable}{|p{1.8cm}|p{2cm}|p{1.8cm}|p{8.5cm}|}
     \hline
     \hline
     Attribute & Type & Optional & Explanation \\\hline\hline
     Attribute & Type & Optional & Explanation \\\hline\hline
@@ -42,8 +52,8 @@ For parsing the JSON file the JSON-java library~\cite{leary_json-java:_2018} is
     Must be a node with the same parent node as the node specified by the \enquote{target} attribute. \\\hline
     Must be a node with the same parent node as the node specified by the \enquote{target} attribute. \\\hline
     target & string & no & The name of the target of this edge.
     target & string & no & The name of the target of this edge.
     Must be a node with the same parent node as the node specified by the \enquote{source} attribute. \\\hline
     Must be a node with the same parent node as the node specified by the \enquote{source} attribute. \\\hline
-\caption{Edge Attributes}
-\label{table:edge-attributes}
+    \caption{Edge Attributes}
+    \label{table:edge-attributes}
 \end{longtable}
 \end{longtable}
 \raggedright
 \raggedright
 
 
@@ -55,40 +65,72 @@ For parsing the JSON file the JSON-java library~\cite{leary_json-java:_2018} is
 %\end{figure}
 %\end{figure}
 
 
 \begin{figure}
 \begin{figure}
-    \begin{lstlisting}[language=json,emph={}]
-    {
-       "layers":[
-          [
-             {
-                "name":"n2",
-                "width":10,
-                "height":10
-             },
-             {
-                "name":"n1",
-                "width":10,
-                "height":10,
-                "layers":[
-                   [
-                      {
-                         "name":"n2",
-                         "width":10,
-                         "height":10
-                      }
-                   ]
-                ]
-             }
-          ]
-       ],
-       "name":"n0"
-    }
-    \end{lstlisting}
+    \begin{lstinputlisting}[language=json,emph={}]{img/graph.json}
+    \end{lstinputlisting}
     \caption[Example Input File]{Example Input file that is understood by \appname.}
     \caption[Example Input File]{Example Input file that is understood by \appname.}
     \label{fig:json-example}
     \label{fig:json-example}
 \end{figure}
 \end{figure}
 
 
-\section{Internal graph representation}\label{sec:internalGraphRepresentation}
-\TODO{some class diagram}
+\section{Internal graph representation, \enquote{Model}}\label{sec:model}
+One feature that is important to us, is to be able to work with hierarchical graphs (cf.\ chapter~\ref{ch:progress}).
+Therefore a node not only has edges to other nodes, but also it can contain other nodes and edges.
+So far this is similar to what we described in section~\ref{sec:inputFileFormat}.
+Additionally, there are multiple attributes that are used during the computation or as output variables.
+\begin{itemize}
+    \item The attributes \enquote{shift},  \enquote{sink},  \enquote{root} and  \enquote{align} correspond to the variables used by Brandes and Köpf~\cite{brandes_fast_2001}.
+    They are summarized in table~\ref{table:bk-variables}.
+    \item The \enquote{parent} of a node is the node that contains it in the hierarchy.
+    \item The attributes $x$ and $y$ are the coordinates of the node relative to its parent node.
+\end{itemize}
+Similarly, edges have additional attributes:
+\begin{itemize}
+    \item \enquote{dummy} specifies whether they are dummy edges.
+    \item \enquote{conflicted} corresponds to the variable used by Brandes and Köpf~\cite{brandes_fast_2001} and indicates that this edge won't be drawn vertically.
+    \item \enquote{bindPoints} is a list of bend points for the edge.
+\end{itemize}
+
+A class diagram of the package \enquote{Model} is displayed in figure~\ref{fig:model}.
+
+\begin{figure}[tp]
+    \centering
+    \includegraphics[width=\linewidth, trim={0 6cm 0 0}]{img/Model.pdf}
+    \caption{Class diagram of the \enquote{Model} package.}
+    \label{fig:model}
+\end{figure}
+
+\begin{longtable}{|p{2.8cm}|p{10cm}|}
+    \hline
+    Attribute & Explanation \\\hline\hline
+    root & The root node of the block of this node.
+    Unique for all nodes in the same block. \\\hline
+    sink & The topmost sink in the block graph that can be reached from the block that this node belongs to.
+    Only used for nodes that are the root of a block.
+    Unique for all nodes in the same class. \\\hline
+    shift & The shift of the class that this node belongs to.
+    Only used for nodes that are a sink of a class. \\\hline
+    \caption{Variables also used by Brandes and Köpf~\cite{brandes_fast_2001}}
+    \label{table:bk-variables}
+\end{longtable}
+
+\section{The actual algorithm}\label{sec:theActualAlgorithm}
+This section assumes that the reader is familiar with the node placement algorithm by Brandes and Köpf~\cite{brandes_fast_2001}.
+
+A \enquote{stage} of the algorithm, interface \enquote{AlgorithmStage}, is an interval during which each step of the algorithm is performed in a similar way.
+Each time such a step is performed it returns whether the stage is already finished.
+For example, a forward step in the stage of calculating one extremal layout, class \enquote{ExtremalLayoutCalc}, consists of either a step of calculating the blocks, class \enquote{BlockCalc}, or a step of compacting the layout, class \enquote{Compaction}.
+All the stages are displayed in class diagram~\ref{fig:animated}.
+
+To be able to undo a step each stage needs to implement methods for both forward and backward steps.
+
+\begin{figure}[tp]
+    \centering
+    \includegraphics[width=\linewidth, trim={0 9cm 0 0}]{img/Algorithms_Animated.pdf}
+    \caption{Class diagram of the package \enquote{Algorithms.Animated}.}
+    \label{fig:animated}
+\end{figure}
+
+\section{View}\label{sec:view}
+This section only covers the software architecture regarding the views.
+For an explanation of what is actually displayed, see chapter~\ref{ch:ui}
 
 
-\section{TODO: More Class Diagrams}\label{sec:classDiagrams}
-\TODO{maybe even into appendix}
+\TODO{Kolja ausfragen}

+ 7 - 0
doc/chapter/3ui.tex

@@ -0,0 +1,7 @@
+Note that since the application is still under construction, so not all screenshots may be up to date.
+
+\section{Graphical presentation of the running algorithm}\label{sec:graphicalPresentationOfTheRunningAlgorithm}
+\TODO{under construction}
+
+\section{User interface}\label{sec:userInterface}
+\TODO{under construction}

+ 5 - 3
doc/chapter/3progress.tex → doc/chapter/4progress.tex

@@ -21,11 +21,13 @@ The following features are either planned (\planned), under construction (\progr
         \item[\progress] Drawing the four extremal layouts and the combined layout separately.
         \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).
         \item[\planned] Drawing the edges of the block graph (in a different color than other edges).
     \end{itemize}
     \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.
     \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}.
+    \item[\planned] Adding buttons and other graphical elements to support the user interface (low priority).
+    Currently there is only keyboard input (cf.\ section~\ref{sec:userInterface}).
     \item[\done] Working with hierarchical graphs.
     \item[\done] Working with hierarchical graphs.
     \item[\done] Scaling the display with the (adjustable) window size.
     \item[\done] Scaling the display with the (adjustable) window size.
-    \item[\planned] Creating ElkNode~\cite{noauthor_elk:_2018} objects from LayeredNode (\ref{sec:internalGraphRepresentation}) objects
-    \item[\planned] Creating LayeredNode (\ref{sec:internalGraphRepresentation}) objects from ElkNode~\cite{noauthor_elk:_2018} objects (low priority)
+    \item[\planned] Creating ElkNode~\cite{noauthor_elk:_2018} objects from LayeredNode (\ref{sec:model}) objects
+    \item[\planned] Creating LayeredNode (\ref{sec:model}) objects from ElkNode~\cite{noauthor_elk:_2018} objects (low priority)
 \end{itemize}
 \end{itemize}

+ 0 - 0
doc/chapter/4retrospection.tex → doc/chapter/5retrospection.tex


+ 5 - 4
doc/doc.tex

@@ -245,13 +245,14 @@ frame=tb}
     \chapter{Architecture}\label{ch:architecture}
     \chapter{Architecture}\label{ch:architecture}
     \input{chapter/2architecture}
     \input{chapter/2architecture}
 
 
-    \chapter{Current Progress}\label{ch:progress}
-    \input{chapter/3progress}
+    \chapter{UI and visuals}\label{ch:ui}
+    \input{chapter/3ui}
 
 
-    \TODO{UI and visuals chapter}
+    \chapter{Current Progress}\label{ch:progress}
+    \input{chapter/4progress}
 
 
     \chapter{Retrospection}
     \chapter{Retrospection}
-    \input{chapter/4retrospection}
+    \input{chapter/5retrospection}
 
 
     \appendix
     \appendix
     \chapter{Appendix}\label{ch:appendix}
     \chapter{Appendix}\label{ch:appendix}

BIN
doc/img/Algorithms_Animated.pdf


BIN
doc/img/IO.pdf


BIN
doc/img/Model.pdf


BIN
doc/img/View.pdf


+ 26 - 0
doc/img/graph.json

@@ -0,0 +1,26 @@
+{
+   "layers":[
+      [
+         {
+            "name":"n2",
+            "width":10,
+            "height":10
+         },
+         {
+            "name":"n1",
+            "width":10,
+            "height":10,
+            "layers":[
+               [
+                  {
+                     "name":"n2",
+                     "width":10,
+                     "height":10
+                  }
+               ]
+            ]
+         }
+      ]
+   ],
+   "name":"n0"
+}

BIN
doc/img/logo.jpg


BIN
doc/vpp/animation.animated.vpp


BIN
doc/vpp/io.vpp


BIN
doc/vpp/model.vpp


BIN
doc/vpp/view.vpp


+ 0 - 0
save.graph → save.json


+ 0 - 1
save_err1.graph

@@ -1 +0,0 @@
-{"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":"0","target":"7"},{"source":"1","target":"7"},{"source":"2","target":"9"},{"source":"7","target":"10"},{"source":"7","target":"13"},{"source":"13","target":"17"},{"source":"12","target":"16"},{"source":"19","target":"23"},{"source":"19","target":"24"},{"source":"15","target":"20"},{"source":"18","target":"22"},{"source":"17","target":"21"}]}

+ 24 - 0
save_err1.json

@@ -0,0 +1,24 @@
+{
+	"layers":[
+		[
+			{"name":"1"},
+			{"name":"2"}
+		],
+		[
+			{"name":"3"},
+			{"name":"4"},
+			{"name":"5"}
+		],
+		[
+			{"name":"6"},
+			{"name":"7"}
+		]
+	],
+	"edges":[
+		{"source":"1","target":"5"},
+		{"source":"2","target":"5"},
+		{"source":"3","target":"7"},
+		{"source":"5","target":"7"},
+		{"source":"4","target":"7"}
+	]
+}

+ 4 - 4
src/Algorithms/Animated/BK/BlockCalc.java

@@ -20,8 +20,8 @@ public class BlockCalc implements AlgorithmStage {
 	private int nodeIndex;
 	private int nodeIndex;
 	private int r;
 	private int r;
 	private LayeredGraphNode graph;
 	private LayeredGraphNode graph;
-	private ArrayList< ArrayList< BKNodePlacement > > subgraphAlgs;
-	private ArrayList< BackwardAction > backwards;
+	private ArrayList< ArrayList< ExtremalLayoutCalc > > subgraphAlgs;
+	private ArrayList< BackwardAction > backwards; // TODO: evtl richtigen "Stack" benutzen
 	private LayoutType layout;
 	private LayoutType layout;
 	int step;
 	int step;
 	
 	
@@ -36,7 +36,7 @@ public class BlockCalc implements AlgorithmStage {
 		subgraphAlgs = new ArrayList<>();
 		subgraphAlgs = new ArrayList<>();
 		for( ArrayList<LayeredGraphNode> l : graph.getContainedLayers() )
 		for( ArrayList<LayeredGraphNode> l : graph.getContainedLayers() )
 		{
 		{
-			ArrayList< BKNodePlacement > algs = new ArrayList<>();
+			ArrayList< ExtremalLayoutCalc > algs = new ArrayList<>();
 			for( int i = 0; i < l.size(); i++ )
 			for( int i = 0; i < l.size(); i++ )
 				algs.add( null );
 				algs.add( null );
 			subgraphAlgs.add( algs );
 			subgraphAlgs.add( algs );
@@ -78,7 +78,7 @@ public class BlockCalc implements AlgorithmStage {
 		if( current.getContainedNodes().size() > 0 )
 		if( current.getContainedNodes().size() > 0 )
 		{
 		{
 			if( subgraphAlgs.get( calcLayerIndex() ).get( calcNodeIndex( nodeIndex ) ) == null )
 			if( subgraphAlgs.get( calcLayerIndex() ).get( calcNodeIndex( nodeIndex ) ) == null )
-				subgraphAlgs.get( calcLayerIndex() ).set( calcNodeIndex( nodeIndex ), new BKNodePlacement( null, current ) );
+				subgraphAlgs.get( calcLayerIndex() ).set( calcNodeIndex( nodeIndex ), new ExtremalLayoutCalc( layout, current ) );
 			if( subgraphAlgs.get( calcLayerIndex() ).get( calcNodeIndex( nodeIndex ) ).forwardStep() == StageStatus.UNFINISHED )
 			if( subgraphAlgs.get( calcLayerIndex() ).get( calcNodeIndex( nodeIndex ) ).forwardStep() == StageStatus.UNFINISHED )
 				return StageStatus.UNFINISHED;
 				return StageStatus.UNFINISHED;
 		}
 		}

+ 17 - 8
src/Algorithms/Animated/BK/Compaction.java

@@ -1,6 +1,7 @@
 package Algorithms.Animated.BK;
 package Algorithms.Animated.BK;
 
 
 import java.util.ArrayList;
 import java.util.ArrayList;
+import java.util.Collections;
 
 
 import Algorithms.Animated.AlgorithmStage;
 import Algorithms.Animated.AlgorithmStage;
 import Algorithms.Animated.BackwardAction;
 import Algorithms.Animated.BackwardAction;
@@ -54,9 +55,13 @@ public class Compaction implements AlgorithmStage{
 		return max;
 		return max;
 	}
 	}
 	
 	
+	@SuppressWarnings("unchecked")
 	private LayeredGraphNode getNodeFromIndex( int index )
 	private LayeredGraphNode getNodeFromIndex( int index )
 	{
 	{
-	    for( ArrayList< LayeredGraphNode > l : graph.getContainedLayers() )
+		ArrayList< ArrayList< LayeredGraphNode > > layers = (ArrayList<ArrayList<LayeredGraphNode>>) graph.getContainedLayers().clone();
+        if( layout == LayoutType.BOTTOM_TOP_LEFT || layout == LayoutType.BOTTOM_TOP_RIGHT )
+        	Collections.reverse( layers );
+	    for( ArrayList< LayeredGraphNode > l : layers )
 	    {
 	    {
 	        if( index >= l.size() )
 	        if( index >= l.size() )
 	            index -= l.size();
 	            index -= l.size();
@@ -106,7 +111,7 @@ public class Compaction implements AlgorithmStage{
 					f.v.setX( 0, true, layout );
 					f.v.setX( 0, true, layout );
 					f.v.setSelected( layout ); // zeige knoten als aktiven knoten an
 					f.v.setSelected( layout ); // zeige knoten als aktiven knoten an
 					f.w = f.v;
 					f.w = f.v;
-                    System.out.println( "call place_block( " + f.v + " )" );
+                    System.out.println( "call place_block( " + f.v.getName() + " )" );
 					stack.add( 0, f );
 					stack.add( 0, f );
 					
 					
 					// die "undo"-action
 					// die "undo"-action
@@ -138,7 +143,7 @@ public class Compaction implements AlgorithmStage{
 							nsf.v.setX( 0, true, layout );
 							nsf.v.setX( 0, true, layout );
 							nsf.v.setSelected( layout ); // zeige knoten als aktiven knoten an
 							nsf.v.setSelected( layout ); // zeige knoten als aktiven knoten an
 							nsf.w = nsf.v;
 							nsf.w = nsf.v;
-		                    System.out.println( "call place_block( " + nsf.v + " )" );
+		                    System.out.println( "call place_block( " + nsf.v.getName() + " )" );
 							stack.add( 0, nsf );
 							stack.add( 0, nsf );
 		                    
 		                    
 		                    // die "undo"-action
 		                    // die "undo"-action
@@ -165,7 +170,7 @@ public class Compaction implements AlgorithmStage{
 						sf.w = sf.w.getAlignedTo( layout );
 						sf.w = sf.w.getAlignedTo( layout );
 						if( sf.w == sf.v ) // schleifenabbruchbedingung
 						if( sf.w == sf.v ) // schleifenabbruchbedingung
 						{ //abbrechen, placeblock beendet
 						{ //abbrechen, placeblock beendet
-                            System.out.println( "return place_block( " + sf.v + " )" );
+                            System.out.println( "return place_block( " + sf.v.getName() + " )" );
 							stack.remove( 0 );
 							stack.remove( 0 );
 							actions.add( 0, ()-> {
 							actions.add( 0, ()-> {
 								stack.add( 0, sf );
 								stack.add( 0, sf );
@@ -198,9 +203,13 @@ public class Compaction implements AlgorithmStage{
                         sf.v.setSink( sf.u.getSink( layout ), layout ); // sink[v] := sink[u]
                         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]?
 					if( sf.v.getSink( layout ) != sf.u.getSink( layout ) ) // sink[v] != sink [u]?
+					{
 						sf.u.getSink( layout ).setShift( // shift[sink[u]] =
 						sf.u.getSink( layout ).setShift( // shift[sink[u]] =
 						  Math.min( sf.u.getSink( layout ).getShift( layout ),  // min(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
 						          sf.v.getX( layout ) - sf.u.getX( layout ) - calcSpacing() ), layout ); // y_v - y_u - s
+						System.out.println( "Set Shift von " + sf.u.getSink( layout ).getName() + " to " + Math.min( sf.u.getSink( layout ).getShift( layout ),  // min(shift[sink[u]]
+						          sf.v.getX( layout ) - sf.u.getX( layout ) - calcSpacing() ) );
+					}
 					else
 					else
 					    // y_v = max {y_v, y_u + s}
 					    // y_v = max {y_v, y_u + s}
 						sf.v.setX( Math.max( sf.v.getX( layout ), sf.u.getX( layout ) + calcSpacing() ), true, layout );
 						sf.v.setX( Math.max( sf.v.getX( layout ), sf.u.getX( layout ) + calcSpacing() ), true, layout );
@@ -215,7 +224,7 @@ public class Compaction implements AlgorithmStage{
 					
 					
 					if( sf.w == sf.v ) // schleifenabbruchbedingung
 					if( sf.w == sf.v ) // schleifenabbruchbedingung
 					{ //abbrechen, placeblock beendet  
 					{ //abbrechen, placeblock beendet  
-					    System.out.println( "return place_block( " + sf.v + " )" );
+					    System.out.println( "return place_block( " + sf.v.getName() + " )" );
 						stack.remove( 0 );
 						stack.remove( 0 );
 						actions.add( 0, ()-> {
 						actions.add( 0, ()-> {
 							stack.add( 0, sf );
 							stack.add( 0, sf );
@@ -243,13 +252,13 @@ 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 = getNodeFromIndex( vIndex );
 			double oldX = v.getX( layout );
 			double oldX = v.getX( layout );
 			boolean oldDef = !v.isXUndefined( layout );
 			boolean oldDef = !v.isXUndefined( layout );
 			v.setSelected( layout );
 			v.setSelected( layout );
 			v.setX( v.getRoot( layout ).getX( layout ), true, layout );
 			v.setX( v.getRoot( layout ).getX( layout ), true, layout );
-			if( v == v.getRoot( layout ) && v.getRoot( layout ).getSink( layout ).getShift( layout ) < Double.POSITIVE_INFINITY )
-				v.setX( v.getX( layout ) + v.getRoot( layout ).getSink( layout ).getShift( 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, layout );
 				v.setX( oldX, oldDef, layout );
 				v.setSelected( layout );
 				v.setSelected( layout );

+ 3 - 1
src/IO/Reader.java

@@ -36,7 +36,9 @@ public class Reader {
 		String file = "";
 		String file = "";
 		try {
 		try {
 			BufferedReader r = new BufferedReader( new FileReader( fileName ) );
 			BufferedReader r = new BufferedReader( new FileReader( fileName ) );
-			file += r.readLine();
+			String tmp = null;
+			while( (tmp = r.readLine()) != null )
+				file += tmp;
 			r.close();
 			r.close();
 		} catch (IOException e) {
 		} catch (IOException e) {
 			e.printStackTrace();
 			e.printStackTrace();

+ 1 - 1
src/Main.java

@@ -15,7 +15,7 @@ public class Main {
 	public static void main(String[] args) {
 	public static void main(String[] args) {
 		//Reader r = new Reader( "save.graph" );
 		//Reader r = new Reader( "save.graph" );
 		//LayeredGraphNode graph = r.readInputGraph();
 		//LayeredGraphNode graph = r.readInputGraph();
-	    RandomGraphGenerator r = new RandomGraphGenerator( 1, 0.5, 2, 2, 2, 2, 5 );
+	    RandomGraphGenerator r = new RandomGraphGenerator( 1, 0.5, 2, 2, 2, 2, 3 );
 	    LayeredGraphNode graph = r.createRandomNode( null, 0 );
 	    LayeredGraphNode graph = r.createRandomNode( null, 0 );
 	    SweepCrossingMinimizer cminzer = new SweepCrossingMinimizer();
 	    SweepCrossingMinimizer cminzer = new SweepCrossingMinimizer();
 	    for( int i = 0; i < 10; i++ )
 	    for( int i = 0; i < 10; i++ )

+ 52 - 1
src/View/MainView.java

@@ -26,6 +26,17 @@ public class MainView {
 	public static JFrame frame;
 	public static JFrame frame;
 	AnimationController controller;
 	AnimationController controller;
 	
 	
+	private String strToLen( String s, int l )
+	{
+		while( s.length() < l )
+		{
+			s = " " + s + " ";
+		}
+		if( s.length() > l )
+			return s.substring( 0, l );
+		return s;
+	}
+	
 	/**
 	/**
 	 * Initialize the window and its contents.
 	 * Initialize the window and its contents.
 	 * @param graph the graph that is displayed in this window.
 	 * @param graph the graph that is displayed in this window.
@@ -52,7 +63,7 @@ public class MainView {
             public void keyPressed(KeyEvent e) {
             public void keyPressed(KeyEvent e) {
                 if( e.getKeyCode() == KeyEvent.VK_S )
                 if( e.getKeyCode() == KeyEvent.VK_S )
                 {
                 {
-                    Writer w = new Writer( "save.graph" );
+                    Writer w = new Writer( "save.json" );
                     w.writeOutputGraph( graph );
                     w.writeOutputGraph( graph );
                 }
                 }
                 if( e.getKeyCode() == KeyEvent.VK_LEFT )
                 if( e.getKeyCode() == KeyEvent.VK_LEFT )
@@ -62,6 +73,46 @@ public class MainView {
                 if( e.getKeyCode() == KeyEvent.VK_P )
                 if( e.getKeyCode() == KeyEvent.VK_P )
                 	controller.setContinuous( !controller.isContinuous() );
                 	controller.setContinuous( !controller.isContinuous() );
         		frame.validate();
         		frame.validate();
+        		if( e.getKeyCode() == KeyEvent.VK_D )
+        		{
+        			System.out.println( "Debug Information Table: " );
+        			System.out.println( "_______________________________________________________________________________________________________________________________________________________________________________________________________________________" );
+        			System.out.println( "|" + strToLen( "Top -> Bottom :> Left", 51 ) + "| |" + strToLen( "Top -> Bottom :> Right", 51 ) + "| |" + strToLen( "Bottom -> Top :> Left", 51 ) + "| |" + strToLen( "Bottom -> Top :> Right", 51 ) + "|" );
+        			System.out.println( "|___________________________________________________| |___________________________________________________| |___________________________________________________| |___________________________________________________|" );
+        			System.out.println( "| Node | Shift | Sink | Root | Align |  x  |  xDef  | | Node | Shift | Sink | Root | Align |  x  |  xDef  | | Node | Shift | Sink | Root | Align |  x  |  xDef  | | Node | Shift | Sink | Root | Align |  x  |  xDef  |" );
+        			for( LayeredGraphNode n : graph.getContainedNodes() )
+        			{
+        				System.out.println( "|" + strToLen( n.getName(), 6 ) + 
+		        						    "|" + strToLen( n.getShift( LayoutType.TOP_BOTTOM_LEFT ) + "", 7 ) + 
+		        						    "|" + strToLen( n.getSink( LayoutType.TOP_BOTTOM_LEFT ).getName(), 6 ) + 
+		        						    "|" + strToLen( n.getRoot( LayoutType.TOP_BOTTOM_LEFT ).getName(), 6 ) + 
+		        						    "|" + strToLen( n.getAlignedTo( LayoutType.TOP_BOTTOM_LEFT ).getName(), 7 ) + 
+		        						    "|" + strToLen( n.getX( LayoutType.TOP_BOTTOM_LEFT ) + "", 5 ) + 
+		        						    "|" + strToLen( !n.isXUndefined( LayoutType.TOP_BOTTOM_LEFT ) + "", 8 ) + "| " +
+		        						    "|" + strToLen( n.getName(), 6 ) + 
+		        						    "|" + strToLen( n.getShift( LayoutType.TOP_BOTTOM_RIGHT ) + "", 7 ) + 
+		        						    "|" + strToLen( n.getSink( LayoutType.TOP_BOTTOM_RIGHT ).getName(), 6 ) + 
+		        						    "|" + strToLen( n.getRoot( LayoutType.TOP_BOTTOM_RIGHT ).getName(), 6 ) + 
+		        						    "|" + strToLen( n.getAlignedTo( LayoutType.TOP_BOTTOM_RIGHT ).getName(), 7 ) + 
+		        						    "|" + strToLen( n.getX( LayoutType.TOP_BOTTOM_RIGHT ) + "", 5 ) + 
+		        						    "|" + strToLen( !n.isXUndefined( LayoutType.TOP_BOTTOM_RIGHT ) + "", 8 ) + "| " +
+		        						    "|" + strToLen( n.getName(), 6 ) + 
+		        						    "|" + strToLen( n.getShift( LayoutType.BOTTOM_TOP_LEFT ) + "", 7 ) + 
+		        						    "|" + strToLen( n.getSink( LayoutType.BOTTOM_TOP_LEFT ).getName(), 6 ) + 
+		        						    "|" + strToLen( n.getRoot( LayoutType.BOTTOM_TOP_LEFT ).getName(), 6 ) + 
+		        						    "|" + strToLen( n.getAlignedTo( LayoutType.BOTTOM_TOP_LEFT ).getName(), 7 ) + 
+		        						    "|" + strToLen( n.getX( LayoutType.BOTTOM_TOP_LEFT ) + "", 5 ) + 
+		        						    "|" + strToLen( !n.isXUndefined( LayoutType.BOTTOM_TOP_LEFT ) + "", 8 ) + "| " +
+		        						    "|" + strToLen( n.getName(), 6 ) + 
+		        						    "|" + strToLen( n.getShift( LayoutType.BOTTOM_TOP_RIGHT ) + "", 7 ) + 
+		        						    "|" + strToLen( n.getSink( LayoutType.BOTTOM_TOP_RIGHT ).getName(), 6 ) + 
+		        						    "|" + strToLen( n.getRoot( LayoutType.BOTTOM_TOP_RIGHT ).getName(), 6 ) + 
+		        						    "|" + strToLen( n.getAlignedTo( LayoutType.BOTTOM_TOP_RIGHT ).getName(), 7 ) + 
+		        						    "|" + strToLen( n.getX( LayoutType.BOTTOM_TOP_RIGHT ) + "", 5 ) + 
+		        						    "|" + strToLen( !n.isXUndefined( LayoutType.BOTTOM_TOP_RIGHT ) + "", 8 ) + "|");
+        			}
+        			System.out.println( "-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------" );
+        		}
             }
             }
 
 
             @Override
             @Override

+ 11 - 4
src/View/NodeView.java

@@ -72,18 +72,25 @@ public class NodeView extends JPanel {
 		g2.setColor( model.getColor( layout ) );
 		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( layout )-1, (int)model.getHeight( layout )-1 );
+		{
+			if( model.getRoot( layout ) == model )
+				g2.fillOval( 0, 0, (int)model.getWidth( layout )-1, (int)model.getHeight( layout )-1 );
+			else
+				g2.fillRect( 0, 0, (int)model.getWidth( layout )-1, (int)model.getHeight( layout )-1 );
+		}
 		if( model.isSelected( layout ) )
 		if( model.isSelected( layout ) )
 		{
 		{
 			g.setColor( Color.GRAY );
 			g.setColor( Color.GRAY );
 			g.fillRect( 0, 0, (int)model.getWidth( layout )-1, (int)model.getHeight( layout )-1 );
 			g.fillRect( 0, 0, (int)model.getWidth( layout )-1, (int)model.getHeight( layout )-1 );
 		}
 		}
 		Border linebor = BorderFactory.createLineBorder(model.getColor( layout ), 5);
 		Border linebor = BorderFactory.createLineBorder(model.getColor( layout ), 5);
-		linebor.paintBorder( this, g2, 0, 0, (int)model.getWidth( layout )-1, (int)model.getHeight( layout )-1 );
-		if( model.getRoot( layout ).getSink( layout ).getColor( layout ) != model.getColor( layout ) )
+		if( model.getRoot( layout ) != model || model.getContainedNodes().size() != 0  )
+			linebor.paintBorder( this, g2, 0, 0, (int)model.getWidth( layout )-1, (int)model.getHeight( layout )-1 );
+		if( model.getRoot( layout ).getSink( layout ).getColor( layout ) != model.getColor( layout ))
 		{
 		{
     		g.setColor( model.getRoot( layout ).getSink( layout ).getColor( layout ) );
     		g.setColor( model.getRoot( layout ).getSink( layout ).getColor( layout ) );
-    		g.fillOval( (int)model.getWidth( layout ) / 2 - (int)model.getWidth( layout ) / 3, (int)model.getHeight( layout ) / 2 - (int)model.getHeight( layout ) / 3, (int)model.getWidth( layout ) / 3 * 2, (int)model.getHeight( layout ) / 3 * 2 );
+    		if( model.getContainedNodes().size() == 0 )
+    		    g.fillOval( (int)model.getWidth( layout ) / 2 - (int)model.getWidth( layout ) / 3, (int)model.getHeight( layout ) / 2 - (int)model.getHeight( layout ) / 3, (int)model.getWidth( layout ) / 3 * 2, (int)model.getHeight( layout ) / 3 * 2 );
 		}
 		}
 	}
 	}
 }
 }

+ 0 - 0
test.graph → test.json


+ 0 - 0
test2.graph → test2.json


+ 0 - 0
test3.graph → test3.json


+ 18 - 0
test4.json

@@ -0,0 +1,18 @@
+{
+"layers": [
+	[
+		{"name": "n1","width":40,"height":40},
+		{"name":"n2","width":40,"height":40}
+	],
+	[
+		{"name":"n3","width":40,"height":40},
+		{"name":"n4","width":40,"height":40},
+		{"name":"n0","width":40,"height":40}
+	]
+],
+"edges":[
+	{"source":"n1","target":"n0"},
+	{"source":"n2","target":"n0"}
+],
+"name":"n0"
+}