Browse Source

dummy attribut für knoten im json

Kolja Strohm 6 years ago
parent
commit
0627439ab5

+ 0 - 0
big.graph → big.json


+ 3 - 2
doc/chapter/1introduction.tex

@@ -6,5 +6,6 @@ Thus we develop an application that not only executes this phase, but also prese
 Then each stage of the node placing algorithm by Brandes and Köpf~\cite{brandes_fast_2001} can be executed step by step, either on user input or automatically with a certain delay.
 After each step the current progress of the algorithm is displayed visually.
 
-In chapter~\ref{ch:architecture} we provide an overview over the \appname 's architecture and chapter~\ref{ch:progress} lists the main features and their progress.
-\TODO{mention chapter 4?}
+In chapter~\ref{ch:architecture} we provide an overview over the \appname 's internal architecture while chapter~\ref{ch:ui} presents and explains the graphical user interface.
+\appname is currently a work in progress so keep in mind that any of the here presented information may be slightly outdated\footnote{even this one}.
+To provide an overview of what is going on, chapter~\ref{ch:progress} lists features and their degree of completion.

+ 82 - 38
doc/chapter/2architecture.tex

@@ -18,10 +18,11 @@ The structure is as follows:
     \item An edge has the attributes that are displayed in table~\ref{table:edge-attributes}.
 \end{itemize}
 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}.
 
 \centering
-\begin{longtable}{|p{1.8cm}|p{2cm}|p{1.8cm}|p{8.5cm}|}
+\begin{longtable}{|p{1.8cm}|p{2.3cm}|p{1.7cm}|p{8.5cm}|}
     \hline
     Attribute & Type & Optional & Explanation \\\hline\hline
     name & string & yes & If not omitted, this must be unique for a given parent node. \\\hline
@@ -31,10 +32,20 @@ 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
     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
-\caption{Node Attributes}
-\label{table:node-attributes}
+    \caption{Node Attributes}
+    \label{table:node-attributes}
 \end{longtable}
 
+\begin{figure}[tp]
+    \centering
+    \includegraphics[width=\linewidth, trim={0 20cm 0 0}]{img/IO.pdf}
+    \caption[Class diagram of the \enquote{IO} package]{Class diagram of the \enquote{IO} package, containing utilities for reading and writing graphs.}
+    \label{fig:io}
+\end{figure}
+
+\newpage
+
+\TODO{attribute for dummy nodes}
 \begin{longtable}{|p{1.8cm}|p{2cm}|p{1.8cm}|p{8.5cm}|}
     \hline
     Attribute & Type & Optional & Explanation \\\hline\hline
@@ -42,8 +53,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
     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
-\caption{Edge Attributes}
-\label{table:edge-attributes}
+    \caption{Edge Attributes}
+    \label{table:edge-attributes}
 \end{longtable}
 \raggedright
 
@@ -54,41 +65,74 @@ For parsing the JSON file the JSON-java library~\cite{leary_json-java:_2018} is
 %    \label{fig:iff}
 %\end{figure}
 
+\TODO{Kante in beispielJSON}
 \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.}
     \label{fig:json-example}
 \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, including the beginning and end point of 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}

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

@@ -0,0 +1,32 @@
+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}
+\TODO{reference~\ref{fig:animated}}
+\begin{figure}[tp]
+    \centering
+    \includegraphics[width=0.6\linewidth]{img/example.jpg}
+    \caption[A simple graph with 5 nodes]{A simple graph with 5 nodes after the four extremal layout have been computed, but not balanced yet.
+    The vertical directions are down (upper row), up (lower row) and the horizontal directions are left (left column) and right (right column).
+    The background colors of the nodes display which block they belong to: For example the two blue nodes on the top right are in the same block.
+    Round nodes are the roots of the blocks.
+    A colored circle on a node indicates the class that this node belongs to and is also the color of the topmost sink in the block graph.
+    The node that is currently in the focus of the algorithm (whatever this means for the current stage) is highlighted with a grey square (here the node in the rightmost column on the bottom right).
+    Although edges are not drawn during the node placement phase we added them here as straight lines to improve readability.}
+    \label{fig:animated}
+\end{figure}
+
+\section{User interface}\label{sec:userInterface}
+Currently the only way to interact with the application is by keyboard events.
+It is planned to add both additional commands as well as some kind of graphical interface, see chapter~\ref{ch:progress}.
+
+\begin{longtable}{|l|l|}
+    \hline
+    Key & Action \\\hline\hline
+    Left arrow key & Perform one forward step of the algorithm. \\\hline
+    Right arrow key & Perform one backward step (\enquote{undo one step}) of the algorithm. \\\hline
+    P & Pause/unpause the automatic execution. Initially paused. \\\hline
+    D & Print a debug table to standard out. \\\hline
+    \caption{Overview of the currently available keyboard commands.}
+    \label{table:keys}
+\end{longtable}

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

@@ -8,7 +8,11 @@ The following features are either planned (\planned), under construction (\progr
     \item[\done] Drawing a graph with specified node sizes and positions.
     \item[\progress] Running the node placement algorithm by Brandes and Köpf~\cite{brandes_fast_2001}.
     \begin{itemize}
-        \item[\done] Calculating the blocks.
+        \item[\progress] Calculating the conflicts between edges.
+        \begin{itemize}
+            \item[\planned] Differentiating between dummy nodes and non-dummy nodes.
+        \end{itemize}
+        \item[\progress] Calculating the blocks.
         \item[\progress] Compacting the layout.
         \item[\planned] Combining the layouts.
     \end{itemize}
@@ -21,11 +25,13 @@ The following features are either planned (\planned), under construction (\progr
         \item[\progress] Drawing the four extremal layouts and the combined layout separately.
         \item[\planned] Drawing the edges of the block graph (in a different color than other edges).
     \end{itemize}
-    \item[\done] Running the algorithm step by step manually (by pushing a button labeled \enquote{Step}).
+    \item[\done] Running the algorithm step by step manually.
     \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] 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] 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}

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


+ 28 - 0
doc/chapter/6contributors.tex

@@ -0,0 +1,28 @@
+\begin{table}[ht]
+	\centering
+    \small
+    \begin{longtable}{p{7cm} p{7cm}}
+        \rowcolor{gray!50}
+		\textbf{Competency} & \textbf{Contributor} \\
+		Producer & Eren Bora Yilmaz \\
+        \rowcolor{gray!25}
+        Producer & Kolja Samuel Strohm \\
+		Lead Designer & Kolja Samuel Strohm \\
+        \rowcolor{gray!25}
+		Documentation & Eren Bora Yilmaz \\
+        Lead Systems Programmer & Kolja Samuel Strohm \\
+        \rowcolor{gray!25}
+		Lead Graphics Programmer & Kolja Samuel Strohm \\
+		Non-German Comments & Eren Bora Yilmaz \\
+        \rowcolor{gray!25}
+		Operations Director & Kolja Samuel Strohm \\
+        Director Of Quality Assurance & Eren Bora Yilmaz \\
+        \rowcolor{gray!25}
+		Senior Community Manager & Eren Bora Yilmaz \\
+        Creative Director & Kolja Samuel Strohm \\
+        \\\\\rowcolor{gray!25}
+		Special Thanks & Jens Burmeister \\\\
+	\end{longtable}
+	\caption{Contributors}
+	\label{table:contributors}
+\end{table}

+ 12 - 7
doc/doc.tex

@@ -84,7 +84,7 @@
 % Quellcode
 % für Formatierung in Quelltexten, hier im Anhang
 \usepackage{listings}
-\usepackage{color} % Farben
+\usepackage{color, colortbl} % Farben
 
 \colorlet{punct}{red!60!black}
 \definecolor{background}{HTML}{EEEEEE}
@@ -208,11 +208,12 @@ frame=tb}
         \end{Large}\\
         \vspace{8mm}
         Project documentation\\
-        \vspace{0.4cm}
-        \vspace{2 cm}
+        \vspace{2.4 cm}
         Eren Bora Yilmaz (1036085)\\
         Kolja Samuel Strohm (1036051)\\
         Summer term 2018\\
+        \vspace{8mm}
+	    \includegraphics[width=10cm]{img/logo}
     \end{center}
     \clearpage\null\clearpage
 
@@ -245,13 +246,17 @@ frame=tb}
     \chapter{Architecture}\label{ch:architecture}
     \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}
-    \input{chapter/4retrospection}
+    \input{chapter/5retrospection}
+
+    \chapter{Contributors}
+    \input{chapter/6contributors}
 
     \appendix
     \chapter{Appendix}\label{ch:appendix}

+ 0 - 0
doc/img/Algorithms.Animated.pdf → doc/img/Algorithms_Animated.pdf


BIN
doc/img/example.jpg


+ 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
material/lec07-Nodes-Size.pptx


+ 151 - 0
papergraph.json

@@ -0,0 +1,151 @@
+{
+    "layers": [
+        [
+            {"name":"1"},
+            {"name":"2"}
+        ],
+        [
+            {"name":"d1", "dummy":"true"},
+            {"name":"d2", "dummy":"true"},
+            {"name":"d3", "dummy":"true"},
+            {"name":"3"},
+            {"name":"d4", "dummy":"true"}
+        ],
+        [
+            {"name":"d5", "dummy":"true"},
+            {"name":"d6", "dummy":"true"},
+            {"name":"4"},
+            {"name":"5"},
+            {"name":"d7", "dummy":"true"},
+            {"name":"d8", "dummy":"true"}
+        ],
+        [
+            {"name":"d9", "dummy":"true"},
+            {"name":"d10", "dummy":"true"},
+            {"name":"6"},
+            {"name":"7"},
+            {"name":"d11", "dummy":"true"},
+            {"name":"d12", "dummy":"true"}
+        ],
+        [
+            {"name":"d13", "dummy":"true"},
+            {"name":"d14", "dummy":"true"},
+            {"name":"8"},
+            {"name":"d15", "dummy":"true"},
+            {"name":"d16", "dummy":"true"},
+            {"name":"9"},
+            {"name":"d17", "dummy":"true"},
+            {"name":"d18", "dummy":"true"}
+        ],
+        [
+            {"name":"d19", "dummy":"true"},
+            {"name":"d20", "dummy":"true"},
+            {"name":"10"},
+            {"name":"11"},
+            {"name":"d21", "dummy":"true"},
+            {"name":"d22", "dummy":"true"},
+            {"name":"12"},
+            {"name":"d23", "dummy":"true"},
+            {"name":"d24", "dummy":"true"}
+        ],
+        [
+            {"name":"13"},
+            {"name":"d25", "dummy":"true"},
+            {"name":"14"},
+            {"name":"15"},
+            {"name":"16"},
+            {"name":"d26", "dummy":"true"},
+            {"name":"d27", "dummy":"true"},
+            {"name":"d28", "dummy":"true"},
+            {"name":"d29", "dummy":"true"}
+        ],
+        [
+            {"name":"17"},
+            {"name":"d30", "dummy":"true"},
+            {"name":"18"},
+            {"name":"19"},
+            {"name":"d31", "dummy":"true"},
+            {"name":"20"},
+            {"name":"d32", "dummy":"true"}
+        ],
+        [
+            {"name":"21"},
+            {"name":"22"},
+            {"name":"d33", "dummy":"true"},
+            {"name":"d34", "dummy":"true"}
+        ],
+        [
+            {"name":"23"}
+        ]
+    ],
+    "edges": [
+        {"source":"1","target":"3"},
+        {"source":"1","target":"d1", "dummy":"true"},
+        {"source":"1","target":"d2", "dummy":"true"},
+        {"source":"1","target":"d3", "dummy":"true"},
+        {"source":"2","target":"3"},
+        {"source":"2","target":"d4", "dummy":"true"},
+        {"source":"d1","target":"d5", "dummy":"true"},
+        {"source":"d2","target":"d6", "dummy":"true"},
+        {"source":"d3","target":"4"},
+        {"source":"3","target":"4"},
+        {"source":"3","target":"5"},
+        {"source":"3","target":"d7", "dummy":"true"},
+        {"source":"d4","target":"d8", "dummy":"true"},
+        {"source":"d5","target":"d9", "dummy":"true"},
+        {"source":"d6","target":"d10", "dummy":"true"},
+        {"source":"4","target":"6"},
+        {"source":"5","target":"7"},
+        {"source":"d7","target":"d11", "dummy":"true"},
+        {"source":"d8","target":"d12", "dummy":"true"},
+        {"source":"d9","target":"d13", "dummy":"true"},
+        {"source":"d10","target":"d14", "dummy":"true"},
+        {"source":"6","target":"8"},
+        {"source":"6","target":"d15", "dummy":"true"},
+        {"source":"6","target":"d16", "dummy":"true"},
+        {"source":"7","target":"9"},
+        {"source":"d11","target":"d17", "dummy":"true"},
+        {"source":"d12","target":"d18", "dummy":"true"},
+        {"source":"d13","target":"d19", "dummy":"true"},
+        {"source":"d14","target":"d20", "dummy":"true"},
+        {"source":"8","target":"10"},
+        {"source":"8","target":"11"},
+        {"source":"d15","target":"d21", "dummy":"true"},
+        {"source":"d16","target":"d22", "dummy":"true"},
+        {"source":"9","target":"12"},
+        {"source":"d17","target":"d23", "dummy":"true"},
+        {"source":"d18","target":"d24", "dummy":"true"},
+        {"source":"d19","target":"13"},
+        {"source":"d20","target":"d25", "dummy":"true"},
+        {"source":"10","target":"13"},
+        {"source":"10","target":"14"},
+        {"source":"10","target":"15"},
+        {"source":"11","target":"15"},
+        {"source":"11","target":"16"},
+        {"source":"d21","target":"16"},
+        {"source":"d22","target":"d26", "dummy":"true"},
+        {"source":"12","target":"d27", "dummy":"true"},
+        {"source":"d23","target":"d28", "dummy":"true"},
+        {"source":"d24","target":"d29", "dummy":"true"},
+        {"source":"13","target":"17"},
+        {"source":"14","target":"17"},
+        {"source":"14","target":"18"},
+        {"source":"16","target":"18"},
+        {"source":"16","target":"19"},
+        {"source":"16","target":"20"},
+        {"source":"d25","target":"d30", "dummy":"true"},
+        {"source":"d26","target":"d31", "dummy":"true"},
+        {"source":"d27","target":"20"},
+        {"source":"d28","target":"d32", "dummy":"true"},
+        {"source":"d29","target":"20"},
+        {"source":"18","target":"21"},
+        {"source":"19","target":"22"},
+        {"source":"d30","target":"21"},
+        {"source":"d31","target":"d33", "dummy":"true"},
+        {"source":"21","target":"23"},
+        {"source":"22","target":"23"},
+        {"source":"d32","target":"d34", "dummy":"true"},
+        {"source":"d33","target":"23"},
+        {"source":"d34","target":"23"}
+    ]
+}

+ 0 - 0
save.graph → save.json


+ 5 - 2
save_err1.graph → save_err1.json

@@ -12,11 +12,14 @@
 		],
 		[
 			{"name":"6"},
-			{"name":"7"}
+			{"name":"7"},
+			{"name":"8"}
 		]
 	],
 	"edges":[
-		{"source":"0","target":"5"},
+        {"source":"4","target":"6"},
+        {"source":"4","target":"8"},
+        {"source":"0","target":"5"},
 		{"source":"1","target":"5"},
 		{"source":"2","target":"5"},
 		{"source":"3","target":"7"},

+ 12 - 2
src/Algorithms/Animated/BK/BKNodePlacement.java

@@ -18,6 +18,7 @@ public class BKNodePlacement extends AnimatedAlgorithm {
 	
 	private enum State
 	{
+		CONFLICTS,
 		LAYOUT1,
 		LAYOUT2,
 		LAYOUT3,
@@ -25,13 +26,15 @@ public class BKNodePlacement extends AnimatedAlgorithm {
 		COMBINE
 	}
 	
+	private ConflictDetection conftion;
 	private State state;
 	private ExtremalLayoutCalc layouts[];
 	private Combine combine;
 	
 	public BKNodePlacement(AnimationController controller, LayeredGraphNode graph) {
 		super(controller, graph);
-		state = State.LAYOUT1;
+		state = State.CONFLICTS;
+		conftion = new ConflictDetection( graph );
 		layouts = new ExtremalLayoutCalc[ 4 ];
 		layouts[ 0 ] = new ExtremalLayoutCalc( ExtremalLayoutCalc.LayoutType.TOP_BOTTOM_LEFT, graph );
 		layouts[ 1 ] = new ExtremalLayoutCalc( ExtremalLayoutCalc.LayoutType.TOP_BOTTOM_RIGHT, graph );
@@ -44,6 +47,10 @@ public class BKNodePlacement extends AnimatedAlgorithm {
 	public StageStatus forwardStep() {
 		switch( state )
 		{
+		case CONFLICTS:
+			if( conftion.forwardStep() == StageStatus.FINISHED )
+				state = State.LAYOUT1;
+			break;
 		case LAYOUT1:
 			if( layouts[ 0 ].forwardStep() == AlgorithmStage.StageStatus.FINISHED )
 				state = State.LAYOUT2;
@@ -70,8 +77,11 @@ public class BKNodePlacement extends AnimatedAlgorithm {
 	public StageStatus backwardStep() {
 		switch( state )
 		{
+		case CONFLICTS:
+			return conftion.backwardStep();
 		case LAYOUT1:
-			return layouts[ 0 ].backwardStep();
+			if( layouts[ 0 ].backwardStep() == StageStatus.FINISHED )
+				state = State.CONFLICTS;
 		case LAYOUT2:
 			if( layouts[ 1 ].backwardStep() == AlgorithmStage.StageStatus.FINISHED )
 				state = State.LAYOUT1;

+ 20 - 11
src/Algorithms/Animated/BK/BlockCalc.java

@@ -2,6 +2,7 @@ package Algorithms.Animated.BK;
 
 import java.awt.Color;
 import java.util.ArrayList;
+import java.util.Collections;
 
 import Algorithms.Animated.AlgorithmStage;
 import Algorithms.Animated.BackwardAction;
@@ -21,7 +22,7 @@ public class BlockCalc implements AlgorithmStage {
 	private int r;
 	private LayeredGraphNode graph;
 	private ArrayList< ArrayList< ExtremalLayoutCalc > > subgraphAlgs;
-	private ArrayList< BackwardAction > backwards;
+	private ArrayList< BackwardAction > backwards; // TODO: evtl richtigen "Stack" benutzen
 	private LayoutType layout;
 	int step;
 	
@@ -64,12 +65,21 @@ public class BlockCalc implements AlgorithmStage {
 	
 	private int calcNodeIndex( int index )
 	{
-        if( layout == LayoutType.TOP_BOTTOM_LEFT || layout == LayoutType.TOP_BOTTOM_RIGHT )
+        if( layout == LayoutType.TOP_BOTTOM_LEFT || layout == LayoutType.BOTTOM_TOP_LEFT )
             return index;
-        //if( layout == LayoutType.BOTTOM_TOP_LEFT || layout == LayoutType.BOTTOM_TOP_RIGHT )
-        //    return graph.getContainedLayers().get( calcLayerIndex() ).size() - index - 1;
+        if( layout == LayoutType.TOP_BOTTOM_RIGHT || layout == LayoutType.BOTTOM_TOP_RIGHT )
+            return graph.getContainedLayers().get( calcLayerIndex() ).size() - index - 1;
         return index;
 	}
+    
+    private int calcBeforeLayerNodeIndex( int index )
+    {
+        if( layout == LayoutType.TOP_BOTTOM_LEFT || layout == LayoutType.BOTTOM_TOP_LEFT )
+            return index;
+        if( layout == LayoutType.TOP_BOTTOM_RIGHT || layout == LayoutType.BOTTOM_TOP_RIGHT )
+            return graph.getContainedLayers().get( calcBeforeLayerIndex() ).size() - index - 1;
+        return index;
+    }
 	
 	@Override
 	public StageStatus forwardStep() {
@@ -87,6 +97,8 @@ public class BlockCalc implements AlgorithmStage {
             incommingEdges = current.getSortedIncomingEdges();
         if( layout == LayoutType.BOTTOM_TOP_LEFT || layout == LayoutType.BOTTOM_TOP_RIGHT )
             incommingEdges = current.getSortedOutgoingEdges();
+        if( layout == LayoutType.TOP_BOTTOM_RIGHT || layout == LayoutType.BOTTOM_TOP_RIGHT )
+        Collections.reverse( incommingEdges );
 		if( incommingEdges.size() == 0 )
 		{
 			backwards.add( 0, () -> {
@@ -94,11 +106,7 @@ public class BlockCalc implements AlgorithmStage {
 			});
 			return calcNextState();
 		}
-		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};
+		int[] ms = {(incommingEdges.size() + 1) / 2, (int)( (incommingEdges.size() + 1) / 2.0 + 0.5 )};
 		boolean backwardsAdded = false;
 		for( int m : ms )
 		{
@@ -110,7 +118,8 @@ public class BlockCalc implements AlgorithmStage {
                 if( layout == LayoutType.BOTTOM_TOP_LEFT || layout == LayoutType.BOTTOM_TOP_RIGHT )
                     u = incommingEdges.get( m - 1 ).getTargets().get( 0 );
                 ArrayList<LayeredGraphEdge> conflicts = incommingEdges.get( m - 1 ).calcConflictedEdges();
-		        if( !incommingEdges.get( m - 1 ).isConflicted( layout ) && calcNodeIndex( r ) < calcNodeIndex( graph.getContainedLayers().get( calcBeforeLayerIndex() ).indexOf( u ) + 1 ) )
+                
+		        if( !incommingEdges.get( m - 1 ).isConflicted( layout ) && r < calcBeforeLayerNodeIndex( graph.getContainedLayers().get( calcBeforeLayerIndex() ).indexOf( u ) ) + 1 )
 		        {
 		        	System.out.println( "" );
 		        	ArrayList< Boolean > oldConflicts = new ArrayList<>();
@@ -128,7 +137,7 @@ public class BlockCalc implements AlgorithmStage {
 		            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;
+		            r = calcBeforeLayerNodeIndex( graph.getContainedLayers().get( calcBeforeLayerIndex() ).indexOf( u ) ) + 1;
 		            int oldStep = step++;
 		            final LayeredGraphNode uf = u;
 		            backwards.add( 0, () -> {

+ 11 - 19
src/Algorithms/Animated/BK/Compaction.java

@@ -1,7 +1,6 @@
 package Algorithms.Animated.BK;
 
 import java.util.ArrayList;
-import java.util.Collections;
 
 import Algorithms.Animated.AlgorithmStage;
 import Algorithms.Animated.BackwardAction;
@@ -55,13 +54,9 @@ public class Compaction implements AlgorithmStage{
 		return max;
 	}
 	
-	@SuppressWarnings("unchecked")
 	private LayeredGraphNode getNodeFromIndex( int index )
 	{
-		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 )
+	    for( ArrayList< LayeredGraphNode > l : graph.getContainedLayers() )
 	    {
 	        if( index >= l.size() )
 	            index -= l.size();
@@ -87,7 +82,7 @@ public class Compaction implements AlgorithmStage{
 				{
 					if( getNodeFromIndex( vIndex ).isXUndefined( layout ) && getNodeFromIndex( vIndex ) == getNodeFromIndex( vIndex ).getRoot( layout ) )
 					{
-						found = true;
+	                    found = true;
 						break;
 					}
 				}
@@ -111,7 +106,7 @@ public class Compaction implements AlgorithmStage{
 					f.v.setX( 0, true, layout );
 					f.v.setSelected( layout ); // zeige knoten als aktiven knoten an
 					f.w = f.v;
-                    System.out.println( "call place_block( " + f.v.getName() + " )" );
+                    System.out.println( "call place_block( " + f.v + " )" );
 					stack.add( 0, f );
 					
 					// die "undo"-action
@@ -143,7 +138,7 @@ public class Compaction implements AlgorithmStage{
 							nsf.v.setX( 0, true, layout );
 							nsf.v.setSelected( layout ); // zeige knoten als aktiven knoten an
 							nsf.w = nsf.v;
-		                    System.out.println( "call place_block( " + nsf.v.getName() + " )" );
+		                    System.out.println( "call place_block( " + nsf.v + " )" );
 							stack.add( 0, nsf );
 		                    
 		                    // die "undo"-action
@@ -170,7 +165,7 @@ public class Compaction implements AlgorithmStage{
 						sf.w.setSelected( layout );
 						if( sf.w == sf.v ) // schleifenabbruchbedingung
 						{ //abbrechen, placeblock beendet
-                            System.out.println( "return place_block( " + sf.v.getName() + " )" );
+                            System.out.println( "return place_block( " + sf.v + " )" );
 							stack.remove( 0 );
 							actions.add( 0, ()-> {
 								stack.add( 0, sf );
@@ -187,7 +182,7 @@ public class Compaction implements AlgorithmStage{
 						}
 					}	
 				}
-				else // der Teil nach "placeBlock(u)", genannt "absolute coordinates"
+				else // ein "placeBlock(u)" aufruf hat gerade returned
 				{
 				    // alte Werte merken für undo
 					LayeredGraphNode oldSink = sf.v.getSink( layout );	
@@ -203,13 +198,9 @@ public class Compaction implements AlgorithmStage{
                         sf.v.setSink( sf.u.getSink( layout ), layout ); // sink[v] := sink[u]
 
 					if( sf.v.getSink( layout ) != sf.u.getSink( layout ) ) // sink[v] != sink [u]?
-					{
 						sf.u.getSink( layout ).setShift( // shift[sink[u]] =
 						  Math.min( sf.u.getSink( layout ).getShift( layout ),  // min(shift[sink[u]]
 						          sf.v.getX( layout ) - sf.u.getX( layout ) - calcSpacing() ), layout ); // y_v - y_u - s
-						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
 					    // y_v = max {y_v, y_u + s}
 						sf.v.setX( Math.max( sf.v.getX( layout ), sf.u.getX( layout ) + calcSpacing() ), true, layout );
@@ -224,7 +215,7 @@ public class Compaction implements AlgorithmStage{
 					
 					if( sf.w == sf.v ) // schleifenabbruchbedingung
 					{ //abbrechen, placeblock beendet  
-					    System.out.println( "return place_block( " + sf.v.getName() + " )" );
+					    System.out.println( "return place_block( " + sf.v + " )" );
 						stack.remove( 0 );
 						actions.add( 0, ()-> {
 							stack.add( 0, sf );
@@ -250,13 +241,14 @@ public class Compaction implements AlgorithmStage{
 				}
 			}
 		}
-		else if( state == CompactionState.APPLY_SHIFT )
+		else if( state == CompactionState.APPLY_SHIFT )// "Compute absolute coordinates"
 		{
-			LayeredGraphNode v = getNodeFromIndex( vIndex );
+			LayeredGraphNode v = graph.getContainedNodes().get( vIndex );
 			double oldX = v.getX( layout );
 			boolean oldDef = !v.isXUndefined( layout );
+			
 			v.setSelected( layout );
-			v.setX( v.getRoot( layout ).getX( layout ), true, layout );
+			v.setX( v.getRoot( layout ).getX( layout ), true, layout ); // y_v = y_root[v]
 			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, ()-> {

+ 95 - 0
src/Algorithms/Animated/BK/ConflictDetection.java

@@ -0,0 +1,95 @@
+package Algorithms.Animated.BK;
+
+import java.util.ArrayList;
+
+import Algorithms.Animated.AlgorithmStage;
+import Algorithms.Animated.BackwardAction;
+import Model.LayeredGraphEdge;
+import Model.LayeredGraphNode;
+
+public class ConflictDetection implements AlgorithmStage {
+
+    private LayeredGraphNode graph;
+    private ArrayList< BackwardAction > actions;
+    
+    private int i;
+    private int l1;
+    
+    ConflictDetection( LayeredGraphNode graph )
+    {
+        this.graph = graph;
+        actions = new ArrayList<>();
+        i = 1;
+        l1 = 0;
+    }
+    
+    @Override
+    public StageStatus forwardStep() {
+    	int oldI = i;
+    	int oldL1 = l1;
+    	LayeredGraphNode curr = graph.getContainedLayers().get( i + 1 ).get( l1 );
+    	curr.setSelected( null );
+    	ArrayList< LayeredGraphEdge > edges = curr.getIncomingEdges();
+    	LayeredGraphEdge dummyEdge = null;
+    	for( LayeredGraphEdge e : edges )
+    	{
+    		if( e.isDummyEdge() )
+    		{
+    			dummyEdge = e;
+    			break;
+    		}
+    	}
+    	ArrayList< LayeredGraphEdge > conflicts = new ArrayList<>();
+        if( dummyEdge != null )
+        {
+    		for( LayeredGraphEdge e : edges )
+    		{
+    			if( e.isDummyEdge() )
+    			{
+    				ArrayList< LayeredGraphEdge > conf = e.calcConflictedEdges();
+    				for( LayeredGraphEdge ce : conf )
+    				{
+    					if( !ce.isDummyEdge() )
+    						conflicts.add( ce );
+    				}
+    			}
+    		}
+        }
+        for( LayeredGraphEdge c : conflicts )
+        	c.setConflicted( true, null );
+    	StageStatus status =  calcNextStatus();
+    	actions.add( ()->{
+    		i = oldI;
+    		l1 = oldL1;
+            for( LayeredGraphEdge c : conflicts )
+            	c.setConflicted( false, null );
+    	});
+    	return status;
+    }
+    
+    private StageStatus calcNextStatus()
+    {
+        l1++;
+        if( l1 >= graph.getContainedLayers().get( i + 1 ).size() )
+        {
+            i++;
+            if( i >= graph.getContainedLayers().size() - 2 )
+            {
+                i--;
+                l1--;
+                return StageStatus.FINISHED;
+            }
+            l1 = 0;
+        }
+        return StageStatus.UNFINISHED;
+    }
+
+    @Override
+    public StageStatus backwardStep() {
+        if( actions.size() == 0 )
+        	return StageStatus.FINISHED;
+        actions.get( 0 ).reverse();
+        actions.remove( 0 );
+        return StageStatus.UNFINISHED;
+    }
+}

+ 8 - 1
src/IO/Reader.java

@@ -57,6 +57,10 @@ public class Reader {
 		LayeredGraphNode newNode = new LayeredNode( null, null );
 		if( parent != null )
 			newNode = parent.createNode( null );
+		if( node.has( "dummy" ) && node.getBoolean( "dummy" ) )
+		{
+			newNode.setDummyNode( true );
+		}
         if( node.has( "name" ) )
         {
             if( parent != null && parent.findNodeByName( node.getString( "name" ) ) != null )
@@ -96,7 +100,10 @@ public class Reader {
             throw new JSONException( edge + " is no valid Layered Graph Edge." );
         if( parent.findNodeByName( edge.getString( "target" ) ) == null )
             throw new JSONException( edge + " is no valid Layered Graph Edge." );
-		return parent.createSimpleEdge( null, parent.findNodeByName( edge.getString( "source" ) ), parent.findNodeByName( edge.getString( "target" ) ) );
+        LayeredGraphEdge newEdge = parent.createSimpleEdge( null, parent.findNodeByName( edge.getString( "source" ) ), parent.findNodeByName( edge.getString( "target" ) ) );
+        if( parent.findNodeByName( edge.getString( "source" ) ).isDummyNode() && parent.findNodeByName( edge.getString( "target" ) ).isDummyNode() )
+        	newEdge.setDummyEdge();
+		return newEdge;
 	}
 	
 	private ArrayList<LayeredGraphNode> parseLayer( JSONArray layer, LayeredGraphNode parent ) throws JSONException

+ 2 - 0
src/IO/Writer.java

@@ -64,6 +64,8 @@ public class Writer {
         }
         node.put( "edges", edges );
         node.put( "name", graph.getName() );
+        if( graph.isDummyNode() )
+        	node.put( "dummy", "true" );
         return node;
     }
     

+ 1 - 1
src/Main.java

@@ -13,7 +13,7 @@ import View.MainView;
 public class Main {
 
 	public static void main(String[] args) {
-		Reader r = new Reader( "save_err1.graph" );
+		Reader r = new Reader( "papergraph.json" );
 		LayeredGraphNode graph = r.readInputGraph();
 	    //RandomGraphGenerator r = new RandomGraphGenerator( 0.1, 0.2, 5,5, 5, 5, 1 );
 	    //LayeredGraphNode graph = r.createRandomNode( null, 0 );

+ 2 - 0
src/Model/LayeredGraphNode.java

@@ -39,6 +39,8 @@ public interface LayeredGraphNode {
     public void update();
     public void setSelected( LayoutType layoutType );
     public boolean isSelected( LayoutType layout );
+    public void setDummyNode( boolean dummy );
+    public boolean isDummyNode();
     
     /**
      * Setzt den Index des Layers, zu dem der Knoten geh�ren soll

+ 14 - 0
src/Model/LayeredNode.java

@@ -23,6 +23,7 @@ public class LayeredNode implements LayeredGraphNode {
     // for this node
     private ElkNode original;
     private LayeredGraphNode parent;
+    private boolean dummy;
     
     private class LayoutInfo
     {
@@ -76,6 +77,19 @@ public class LayeredNode implements LayeredGraphNode {
             l.shift = Double.POSITIVE_INFINITY;
             l.xUndef = true;
         }
+        dummy = false;
+    }
+    
+    @Override
+    public void setDummyNode( boolean dummy )
+    {
+    	this.dummy = dummy;
+    }
+    
+    @Override
+    public boolean isDummyNode()
+    {
+    	return dummy;
     }
 
     @Override

+ 2 - 0
src/View/EdgeView.java

@@ -89,6 +89,8 @@ 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 );
+        if( model.isConflicted( layout ) )
+        	g.setColor( Color.RED );
         ArrayList<Point> bps = model.getLinePoints( layout );
         for( int i = 1; i < bps.size(); i++ )
         {

+ 1 - 1
src/View/MainView.java

@@ -63,7 +63,7 @@ public class MainView {
             public void keyPressed(KeyEvent e) {
                 if( e.getKeyCode() == KeyEvent.VK_S )
                 {
-                    Writer w = new Writer( "save.graph" );
+                    Writer w = new Writer( "save.json" );
                     w.writeOutputGraph( graph );
                 }
                 if( e.getKeyCode() == KeyEvent.VK_LEFT )

+ 4 - 3
src/View/NodeView.java

@@ -84,12 +84,13 @@ public class NodeView extends JPanel {
 			g.fillRect( 0, 0, (int)model.getWidth( layout )-1, (int)model.getHeight( layout )-1 );
 		}
 		Border linebor = BorderFactory.createLineBorder(model.getColor( layout ), 5);
-		if( model.getRoot( layout ) != model )
+		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 ) )
+		if( model.getRoot( layout ).getSink( layout ).getColor( layout ) != model.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


+ 0 - 0
test4.graph → test4.json