3

This is and addendum of a previous question: How to connect pics through a set of colorful arrows using tikzpicture environment.

I would like to be able to draw arrows that do not overlap with nodes and/or pictures without having to manually modify each and every one of the arrows that collide with them using tikz.

The MWE is taken from marmot's nice answer:

\documentclass{article}
\usepackage[margin=0in,footskip=0in,paperwidth=60cm,paperheight=29cm]{geometry}
\usepackage[english]{babel}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{hyperref}

\usepackage{tikz}
\usetikzlibrary{positioning,fit,calc}
\pgfdeclarelayer{behind}
\pgfdeclarelayer{background}
\pgfdeclarelayer{foreground}
\pgfsetlayers{behind,background,main,foreground}
\tikzset{
text field/.style={text height=1.5ex,align=center,rounded corners},
nonfillable title field/.style={text height=2ex,text depth=0.3em,anchor=south,text 
width=5cm,align=center,font=\footnotesize\sffamily},
fillable title field/.style={text height=3.14ex,text depth=0em,anchor=south,text 
width=5cm,align=center,font=\footnotesize\sffamily},
pics/fillable subject/.style={code={%
\node[text field] (-TF) 
{\hspace*{-0.5em}\TextField[align=1,name=#1-day,width=1em,charsize=7pt,maxlen=2,bordercolor={1 1 1}]~~/\hspace*{-0.15em}\TextField[align=1,name=#1-month,width=1em,charsize=7pt,maxlen=2,bordercolor={1 1 1}]~~/\hspace*{-0em}\TextField[align=1,name=#1-year,width=2em,charsize=7pt,maxlen=4,bordercolor={1 1 1}]{}~};
\node[nonfillable title field] (-Title) 
at ([yshift=0.4em]-TF.north) {#1};
\draw[rounded corners] (-TF.south west) |- (-Title.south west)
|- (-Title.north east) -- (-Title.south east) -| (-TF.south east)
 -- cycle;
\draw ([xshift=4pt]-Title.south west) -- ([xshift=-4pt]-Title.south east);
 }},
pics/nonfillable subject/.style={code={%
\node[text field] (-TF) 
{\hspace{1.2em}~/~\hspace{1.15em}~/~\hspace{2.35em}{}};
\node[nonfillable title field] (-Title) 
at ([yshift=0.4em]-TF.north) {#1};
\draw[rounded corners] (-TF.south west) |- (-Title.south west)
|- (-Title.north east) -- (-Title.south east) -| (-TF.south east)
 -- cycle;
\draw ([xshift=4pt]-Title.south west) -- ([xshift=-4pt]-Title.south east);
 }},
pics/fillable elective subject/.style={code={%
\node[text field] (-TF) 
{\hspace*{-0.5em}\TextField[align=1,name=#1-day,width=1em,charsize=7pt,maxlen=2,bordercolor={1 1 1}]~~/\hspace*{-0.15em}\TextField[align=1,name=#1-month,width=1em,charsize=7pt,maxlen=2,bordercolor={1 1 1}]~~/\hspace*{-0em}\TextField[align=1,name=#1-year,width=2em,charsize=7pt,maxlen=4,bordercolor={1 1 1}]{}~};
\node[fillable title field] (-Title) 
at ([yshift=0.4em]-TF.north) {\hspace*{-0.34em}\TextField[align=1,name=#1-electivesubject,width=4.5cm,charsize=8pt,height=.5cm,bordercolor={1 1 1}]{}};
\draw[rounded corners] (-TF.south west) |- (-Title.south west)
|- (-Title.north east) -- (-Title.south east) -| (-TF.south east)
 -- cycle;
\draw ([xshift=4pt]-Title.south west) -- ([xshift=-4pt]-Title.south east);
 }},
pics/nonfillable elective subject/.style={code={%
\node[text field] (-TF) 
{\hspace{1.2em}~/~\hspace{1.15em}~/~\hspace{2.35em}{}};
\node[nonfillable title field] (-Title) 
at ([yshift=0.4em]-TF.north) {};
\draw[rounded corners] (-TF.south west) |- (-Title.south west)
|- (-Title.north east) -- (-Title.south east) -| (-TF.south east)
 -- cycle;
\draw ([xshift=4pt]-Title.south west) -- ([xshift=-4pt]-Title.south east);
 }},
 manoooh/.style={column sep=-1.75cm,row sep=5mm},
 manooohE/.style={column sep=-2.25cm,row sep=5mm,anchor=south},
 electives/.style={column sep=-7.25cm,row sep=5mm},
 fit sep/.initial=4pt,  % change width of node (big rectangle shape)
 fit dist/.initial=40pt, % change node distance (big rectangle shape)
 inlay top sep/.initial=24pt,
 matrix top sep/.initial=24pt,
 manoooh curve/.style={to path={let \p1=($(\tikztotarget)-(\tikztostart)$) 
 in (\tikztostart) .. controls ($(\tikztostart)+(#1*\x1,0)$)
 and ($(\tikztotarget)+(-#1*\x1,0)$) .. (\tikztotarget)}},
 manoooh curve/.default=0.3
}  % From https://tex.stackexchange.com/a/478723/152550

\makeatletter% from https://tex.stackexchange.com/a/85531/121799
\long\def\ifnodedefined#1#2#3{%
    \@ifundefined{pgf@sh@ns@#1}{#3}{#2}%
}
\makeatother

\begin{document}
\thispagestyle{empty}   % To suppress page number
\noindent
\begin{tikzpicture}
\fill[white,fill=orange] (0,0) rectangle (\paperwidth,-2cm) node[midway,align=center,font=\Huge] {\bfseries Some text here\\\LARGE More text here};
\end{tikzpicture}

\ifdefined\mymatbottom
\else
\typeout{Please\space recompile\space your\space file!}
\def\mymatbottom{-150pt}
\fi
\ifdefined\myheight
\else
\def\myheight{0}
\typeout{Please\space recompile\space your\space file!}
\fi
\ifdefined\LstMatYShifts
\else
\def\LstMatYShifts{{0pt,0pt,0pt,0pt,0pt,0pt,0pt}}
\fi
\ifdefined\LstMatXShifts
\else
\def\LstMatXShifts{{0pt,0pt,0pt,0pt,0pt,0pt,0pt}}
\fi

%\typeout{height:\myheight}
%\typeout{xshifts(in):\LstMatXShifts}

\vfill
\centering
\begin{Form}
\begin{tikzpicture}
 % step 1: add the matrices, name them mat0, mat1 etc.
 \begin{scope}[local bounding box=matrices] 
  \matrix[manoooh] (mat0) at ({\LstMatXShifts[0]},{\LstMatYShifts[0]}) {
         \pic[local bounding box=A] (0) {nonfillable subject={Subject A}};  \\
         \pic (1) {nonfillable subject={Subject B}};  \\
  };
  \matrix[manoooh] (mat1) at ({\LstMatXShifts[1]},{\LstMatYShifts[1]}) {

         \pic (2) {nonfillable subject={Subject C}};  \\
         \pic (3) {nonfillable subject={Subject D}};  \\
         \pic (4) {nonfillable subject={Subject E}};  \\
         \pic (5) {nonfillable subject={Subject F}};  \\
         \pic (6) {nonfillable subject={Subject G}};  \\
         \pic (7) {nonfillable subject={Subject H}};  \\
         \pic (8) {nonfillable subject={Subject I}};  \\
         \pic[draw=red] (9) {nonfillable subject={Subject J}};  \\
    };
  \matrix[manoooh] (mat2) at ({\LstMatXShifts[2]},{\LstMatYShifts[2]}) {
         \pic[draw=red] (10) {nonfillable subject={Subject K}};  \\
         \pic (11) {nonfillable subject={Subject L}};  \\
         \pic (12) {nonfillable subject={Subject A}};  \\
         \pic (13) {nonfillable subject={Subject N}};  \\
         \pic (14) {nonfillable subject={Subject O}};  \\
         \pic (15) {nonfillable subject={Subject P}};  \\
         \pic (16) {nonfillable subject={Subject Q}};  \\
         \pic (17) {nonfillable subject={Subject R}};  \\
    };  
  \matrix[manoooh] (mat3) at ({\LstMatXShifts[3]},{\LstMatYShifts[3]}) {
         \pic[draw=red] (18) {nonfillable subject={Subject S}};  \\
         \pic (19) {nonfillable subject={Subject T}};  \\
         \pic (20) {nonfillable subject={Subject U}};  \\
         \pic (21) {nonfillable subject={Subject V}};  \\
         \pic (22) {nonfillable subject={Subject W}};  \\
         \pic (23) {nonfillable subject={Subject X}};  \\
         \pic (24) {nonfillable subject={Subject Y}};  \\
         \pic (25) {nonfillable subject={Subject Z}};  \\
    };
  \matrix[manooohE] (matE3) at ({\LstMatXShifts[3]},\mymatbottom) {
        \pic (L3E1) {nonfillable elective subject={Subject}}; & &
        \pic (L3E2) {nonfillable elective subject={Subject}}; \\
        & \pic (L3E3) {nonfillable elective subject={Subject}};  & \\
    };
    \matrix[manoooh] (mat4) at ({\LstMatXShifts[4]},{\LstMatYShifts[4]}) {
        & \pic[draw=red] (26) {nonfillable subject={Subject AA}}; & \\
        \pic (27) {nonfillable subject={Subject AB}}; & & \pic (28) {nonfillable subject={Subject AC}}; \\
        & \pic (29) {nonfillable subject={Subject AD}}; & \\
        & \pic (30) {nonfillable subject={Subject AE}}; & \\
        & \pic (31) {nonfillable subject={Subject AF}}; & \\
        & \pic (32) {nonfillable subject={Subject AG}}; & \\
    };
    \matrix[manooohE] (matE4) at ({\LstMatXShifts[4]},\mymatbottom) {
        \pic (L4E1) {nonfillable elective subject={Subject}}; \\
    };
    \matrix[manoooh] (mat5) at ({\LstMatXShifts[5]},{\LstMatYShifts[5]}) {
         \pic (33) {nonfillable subject={Subject AH}};  \\
         \pic (34) {nonfillable subject={Subject AI}};  \\
         \pic[draw=red] (35) {nonfillable subject={Subject AJ}};  \\
         \pic (36) {nonfillable subject={Subject AK}};  \\
    };
    \matrix[manooohE] (matE5) at ({\LstMatXShifts[5]},\mymatbottom) {
         \pic (L5E1) {nonfillable elective subject={Subject}};  \\
         \pic (L5E2) {nonfillable elective subject={Subject}};  \\
         \pic (L5E3) {nonfillable elective subject={Subject}};  \\
         \pic (L5E4) {nonfillable elective subject={Subject}};  \\
         \pic (L5E5) {nonfillable elective subject={Subject}};  \\
    };
 \end{scope}
 \pgfmathsetmacro{\groupwidth}{0}
 \pgfmathsetmacro{\lastwidth}{0}
 \foreach \X in {0,...,5} %<- if you have more or less matrices, adjust 3       
 {
  \node[anchor=south,yshift=1cm,align=center,font=\LARGE\bfseries\boldmath] 
  at (mat\X |-matrices.north) (L\X) {Level $\X$}; 
  \ifnodedefined{matE\X}{% has inlay
   \node[xshift=1em,anchor=south west,font=\LARGE\bfseries,opacity=0] (matEl\X) at (matE\X.north west) {Electives};
   \begin{pgfonlayer}{background}
   \path let \p1=($(mat\X.north east)-(mat\X.south west)$) in
   node[fit=(matE\X) (matEl\X),inner ysep=5mm,fill=blue!30,rounded
   corners=40pt,minimum width=\x1-2*\pgfkeysvalueof{/tikz/fit sep},
   inner xsep=\pgfkeysvalueof{/tikz/fit sep}](F\X){};
   \node[xshift=1em,anchor=south west,font=\LARGE\bfseries] 
   (matEl\X) at ([xshift=1.3em]F\X.west|-matEl\X.center) {Electives};
   \end{pgfonlayer}
   \path let \p1=($(mat\X.north east)-(mat\X.south west)$),
    \p2=($(F\X.north east)-(F\X.south west)$),
    \n1={max(abs(\y1)/2+abs(\y2)/2+0*\pgfkeysvalueof{/tikz/inlay top sep},\mymatbottom)}
      in 
    \pgfextra{\xdef\mymatbottom{\n1}
       \ifnum\X=0
        \pgfmathsetmacro{\groupwidth}{0}
       \else    
        \pgfmathsetmacro{\groupwidth}{\groupwidth+max(\x1,\x2)/2+\lastwidth/2+2*\pgfkeysvalueof{/tikz/fit sep}+\pgfkeysvalueof{/tikz/fit dist}}
       \fi
       \pgfmathsetmacro{\lastwidth}{max(\x1,\x2)+8*\pgfkeysvalueof{/tikz/fit sep}}
       \xdef\lastwidth{\lastwidth}
       \xdef\groupwidth{\groupwidth}     
       \pgfmathsetmacro{\myheight}{max(\y1+\y2+%
         \pgfkeysvalueof{/tikz/inlay top sep}+\pgfkeysvalueof{/tikz/matrix top sep},%
         \myheight)}
       \xdef\myheight{\myheight}
       \pgfmathsetmacro{\myshift}{(\pgfkeysvalueof{/tikz/inlay top sep}+\y2)/2}
       \ifnum\X=0
       \xdef\LstMatYShifts{\myshift pt}
       \xdef\LstMatXShifts{0pt}
       \else
       \xdef\LstMatYShifts{\LstMatYShifts,\myshift pt}
       \xdef\LstMatXShifts{\LstMatXShifts,\groupwidth pt}
       \fi};    
   % the fit parameters determine the shape of the background rectangles
   \begin{pgfonlayer}{behind}
   \node[fit=(L\X) (mat\X) (matrices.south-|mat\X.south)
   (matE\X) (matEl\X),inner ysep=8mm,inner xsep=4*\pgfkeysvalueof{/tikz/fit sep},
   fill=orange!30,rounded corners=50pt](F\X){};
   \end{pgfonlayer}}{% no inlay
   \path 
    let \p1=($(mat\X.north east)-(mat\X.south west)$),
     \n1={max(abs(\y1)/2,\mymatbottom)}
      in 
     \pgfextra{\xdef\mymatbottom{\n1}
       \ifnum\X=0
        \pgfmathsetmacro{\groupwidth}{0}
       \else    
        \pgfmathsetmacro{\groupwidth}{\groupwidth+\x1/2+\lastwidth/2+\pgfkeysvalueof{/tikz/fit dist}}
       \fi
       \xdef\groupwidth{\groupwidth}
       \xdef\lastwidth{\x1}
       \pgfmathsetmacro{\myheight}{max(\y1+\pgfkeysvalueof{/tikz/matrix top sep},\myheight)} 
       \xdef\myheight{\myheight}
       \ifnum\X=0
       \xdef\LstMatYShifts{0pt}
       \xdef\LstMatXShifts{0pt}
       \else
       \xdef\LstMatYShifts{\LstMatYShifts,0pt}
       \xdef\LstMatXShifts{\LstMatXShifts,\groupwidth pt}
       \fi};   
   % the fit parameters determine the shape of the background rectangles
   \begin{pgfonlayer}{behind}
   \node[fit=(L\X) (mat\X) (matrices.south-|mat\X.south),inner ysep=8mm,
   fill=orange!30,rounded corners=50pt](F\X){};
   \end{pgfonlayer}
   }
  }
 \makeatletter
 \immediate\write\@mainaux{\xdef\string\mymatbottom{-\mymatbottom}\relax}
 \immediate\write\@mainaux{\xdef\string\myheight{\myheight}\relax}
 \immediate\write\@mainaux{\xdef\string\LstMatYShifts{{\LstMatYShifts}}\relax}
 \immediate\write\@mainaux{\xdef\string\LstMatXShifts{{\LstMatXShifts}}\relax}
 \makeatother

    \newcommand\totalnodes{5} % Define the total of subjects that need arrows-1

    % From https://tex.stackexchange.com/a/480685/152550

    % now add the arrows.

    \def\LstCon{%
        {
        "{2,...,9}",%subjects that 0 links
        "{2,10,13,14}",%subjects that 1 links
        "{11,14}",%subjects that 2 links
        "{10,13,14,25}",%subjects that 3 links
        "{36}",%subjects that 8 links
        }
    }
    \foreach \X in {0,...,\totalnodes} {
        \pgfmathsetmacro{\huenum}{\X*0.75*(1/\totalnodes)}
        \definecolor{mycolor}{hsb}{\huenum,1,1}
        \pgfmathsetmacro{\mylst}{\LstCon[\X]}
        \foreach \Y in \mylst {
            \draw[-latex,mycolor,very thick] (\X-Title.east) 
            to[manoooh curve] (\Y-Title.west);
        }
    }
\end{tikzpicture}
\end{Form}

\vfill

\end{document}

MWE

We would be able to see those arrows using something like this paths:

What I want

As you can see, some yellow, lightblue and the blue arrows have undergone changes due to the collision of one (or more) pics.

It is preferable that the algorithm detects that if many colors circulate in the same path, choose another one, since it would be visually confusing to have many colors in the same passage. For example:

Example of what I want

If the detection of a lot of arrow traffic is a computational problem, leave it, it is not very important, I am satisfied with the automatic paths.

Thanks!!

manooooh
  • 3,203
  • 2
  • 21
  • 46
  • 1
    I do not think there will be an easy algorithm that detects if some path already travelled through the same gap. What is possible is to add some style that draws a curve through gaps that you specify, –  Mar 22 '19 at 04:54
  • @marmot I do not think it is feasible to specify the path, since the diagram may suffer alterations in the positions of the objects, so the paths must be modified manually. If the detection of a lot of arrow traffic is a computational problem, leave it, it is not very important, I am satisfied with the automatic paths. – manooooh Mar 22 '19 at 04:56

1 Answers1

7

Here is a first proposal. You only need to say

\draw[-latex,blue,very thick] (4-Title.east) 
[along node/.list={12,21,29}]
        to[manoooh curve] (36-Title.west);

to get

enter image description here

As you can see, the path runs north of the forms 12, 21, 29.

And as for your loop: you could specify the nodes along which the path should run in lists.

\documentclass{article}
\usepackage[margin=0in,footskip=0in,paperwidth=60cm,paperheight=29cm]{geometry}
\usepackage[english]{babel}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{hyperref}

\usepackage{tikz}
\usetikzlibrary{positioning,fit,calc}
\pgfdeclarelayer{behind}
\pgfdeclarelayer{background}
\pgfdeclarelayer{foreground}
\pgfsetlayers{behind,background,main,foreground}
\tikzset{
text field/.style={text height=1.5ex,align=center,rounded corners},
nonfillable title field/.style={text height=2ex,text depth=0.3em,anchor=south,text 
width=5cm,align=center,font=\footnotesize\sffamily},
fillable title field/.style={text height=3.14ex,text depth=0em,anchor=south,text 
width=5cm,align=center,font=\footnotesize\sffamily},
pics/fillable subject/.style={code={%
\node[text field] (-TF) 
{\hspace*{-0.5em}\TextField[align=1,name=#1-day,width=1em,charsize=7pt,maxlen=2,bordercolor={1 1 1}]~~/\hspace*{-0.15em}\TextField[align=1,name=#1-month,width=1em,charsize=7pt,maxlen=2,bordercolor={1 1 1}]~~/\hspace*{-0em}\TextField[align=1,name=#1-year,width=2em,charsize=7pt,maxlen=4,bordercolor={1 1 1}]{}~};
\node[nonfillable title field] (-Title) 
at ([yshift=0.4em]-TF.north) {#1};
\draw[rounded corners] (-TF.south west) |- (-Title.south west)
|- (-Title.north east) -- (-Title.south east) -| (-TF.south east)
 -- cycle;
\draw ([xshift=4pt]-Title.south west) -- ([xshift=-4pt]-Title.south east);
 }},
pics/nonfillable subject/.style={code={%
\node[text field] (-TF) 
{\hspace{1.2em}~/~\hspace{1.15em}~/~\hspace{2.35em}{}};
\node[nonfillable title field] (-Title) 
at ([yshift=0.4em]-TF.north) {#1};
\draw[rounded corners] (-TF.south west) |- (-Title.south west)
|- (-Title.north east) -- (-Title.south east) -| (-TF.south east)
 -- cycle;
\draw ([xshift=4pt]-Title.south west) -- ([xshift=-4pt]-Title.south east);
 }},
pics/fillable elective subject/.style={code={%
\node[text field] (-TF) 
{\hspace*{-0.5em}\TextField[align=1,name=#1-day,width=1em,charsize=7pt,maxlen=2,bordercolor={1 1 1}]~~/\hspace*{-0.15em}\TextField[align=1,name=#1-month,width=1em,charsize=7pt,maxlen=2,bordercolor={1 1 1}]~~/\hspace*{-0em}\TextField[align=1,name=#1-year,width=2em,charsize=7pt,maxlen=4,bordercolor={1 1 1}]{}~};
\node[fillable title field] (-Title) 
at ([yshift=0.4em]-TF.north) {\hspace*{-0.34em}\TextField[align=1,name=#1-electivesubject,width=4.5cm,charsize=8pt,height=.5cm,bordercolor={1 1 1}]{}};
\draw[rounded corners] (-TF.south west) |- (-Title.south west)
|- (-Title.north east) -- (-Title.south east) -| (-TF.south east)
 -- cycle;
\draw ([xshift=4pt]-Title.south west) -- ([xshift=-4pt]-Title.south east);
 }},
pics/nonfillable elective subject/.style={code={%
\node[text field] (-TF) 
{\hspace{1.2em}~/~\hspace{1.15em}~/~\hspace{2.35em}{}};
\node[nonfillable title field] (-Title) 
at ([yshift=0.4em]-TF.north) {};
\draw[rounded corners] (-TF.south west) |- (-Title.south west)
|- (-Title.north east) -- (-Title.south east) -| (-TF.south east)
 -- cycle;
\draw ([xshift=4pt]-Title.south west) -- ([xshift=-4pt]-Title.south east);
 }},
 manoooh/.style={column sep=-1.75cm,row sep=5mm},
 manooohE/.style={column sep=-2.25cm,row sep=5mm,anchor=south},
 electives/.style={column sep=-7.25cm,row sep=5mm},
 fit sep/.initial=4pt,  % change width of node (big rectangle shape)
 fit dist/.initial=40pt, % change node distance (big rectangle shape)
 inlay top sep/.initial=24pt,
 matrix top sep/.initial=24pt,
 manoooh curve/.style={to path={let \p1=($(\tikztotarget)-(\tikztostart)$) 
 in (\tikztostart) .. controls ($(\tikztostart)+(#1*\x1,0)$)
 and ($(\tikztotarget)+(-#1*\x1,0)$) .. (\tikztotarget)}},
 manoooh curve/.default=0.3,
 along node/.style={insert path={
 to[out=0,in=180]
    ([yshift=5pt]#1-Title.north west) -- ([yshift=5pt]#1-Title.north east)}}
}  % From https://tex.stackexchange.com/a/478723/152550

\makeatletter% from https://tex.stackexchange.com/a/85531/121799
\long\def\ifnodedefined#1#2#3{%
    \@ifundefined{pgf@sh@ns@#1}{#3}{#2}%
}
\makeatother

\begin{document}
\thispagestyle{empty}   % To suppress page number
\noindent
\begin{tikzpicture}
\fill[white,fill=orange] (0,0) rectangle (\paperwidth,-2cm) node[midway,align=center,font=\Huge] {\bfseries Some text here\\\LARGE More text here};
\end{tikzpicture}

\ifdefined\mymatbottom
\else
\typeout{Please\space recompile\space your\space file!}
\def\mymatbottom{-150pt}
\fi
\ifdefined\myheight
\else
\def\myheight{0}
\typeout{Please\space recompile\space your\space file!}
\fi
\ifdefined\LstMatYShifts
\else
\def\LstMatYShifts{{0pt,0pt,0pt,0pt,0pt,0pt,0pt}}
\fi
\ifdefined\LstMatXShifts
\else
\def\LstMatXShifts{{0pt,0pt,0pt,0pt,0pt,0pt,0pt}}
\fi

%\typeout{height:\myheight}
%\typeout{xshifts(in):\LstMatXShifts}

\vfill
\centering
\begin{Form}
\begin{tikzpicture}
 % step 1: add the matrices, name them mat0, mat1 etc.
 \begin{scope}[local bounding box=matrices] 
  \matrix[manoooh] (mat0) at ({\LstMatXShifts[0]},{\LstMatYShifts[0]}) {
         \pic[local bounding box=A] (0) {nonfillable subject={Subject A}};  \\
         \pic (1) {nonfillable subject={Subject B}};  \\
  };
  \matrix[manoooh] (mat1) at ({\LstMatXShifts[1]},{\LstMatYShifts[1]}) {

         \pic (2) {nonfillable subject={Subject C}};  \\
         \pic (3) {nonfillable subject={Subject D}};  \\
         \pic (4) {nonfillable subject={Subject E}};  \\
         \pic (5) {nonfillable subject={Subject F}};  \\
         \pic (6) {nonfillable subject={Subject G}};  \\
         \pic (7) {nonfillable subject={Subject H}};  \\
         \pic (8) {nonfillable subject={Subject I}};  \\
         \pic[draw=red] (9) {nonfillable subject={Subject J}};  \\
    };
  \matrix[manoooh] (mat2) at ({\LstMatXShifts[2]},{\LstMatYShifts[2]}) {
         \pic[draw=red] (10) {nonfillable subject={Subject K}};  \\
         \pic (11) {nonfillable subject={Subject L}};  \\
         \pic (12) {nonfillable subject={Subject A}};  \\
         \pic (13) {nonfillable subject={Subject N}};  \\
         \pic (14) {nonfillable subject={Subject O}};  \\
         \pic (15) {nonfillable subject={Subject P}};  \\
         \pic (16) {nonfillable subject={Subject Q}};  \\
         \pic (17) {nonfillable subject={Subject R}};  \\
    };  
  \matrix[manoooh] (mat3) at ({\LstMatXShifts[3]},{\LstMatYShifts[3]}) {
         \pic[draw=red] (18) {nonfillable subject={Subject S}};  \\
         \pic (19) {nonfillable subject={Subject T}};  \\
         \pic (20) {nonfillable subject={Subject U}};  \\
         \pic (21) {nonfillable subject={Subject V}};  \\
         \pic (22) {nonfillable subject={Subject W}};  \\
         \pic (23) {nonfillable subject={Subject X}};  \\
         \pic (24) {nonfillable subject={Subject Y}};  \\
         \pic (25) {nonfillable subject={Subject Z}};  \\
    };
  \matrix[manooohE] (matE3) at ({\LstMatXShifts[3]},\mymatbottom) {
        \pic (L3E1) {nonfillable elective subject={Subject}}; & &
        \pic (L3E2) {nonfillable elective subject={Subject}}; \\
        & \pic (L3E3) {nonfillable elective subject={Subject}};  & \\
    };
    \matrix[manoooh] (mat4) at ({\LstMatXShifts[4]},{\LstMatYShifts[4]}) {
        & \pic[draw=red] (26) {nonfillable subject={Subject AA}}; & \\
        \pic (27) {nonfillable subject={Subject AB}}; & & \pic (28) {nonfillable subject={Subject AC}}; \\
        & \pic (29) {nonfillable subject={Subject AD}}; & \\
        & \pic (30) {nonfillable subject={Subject AE}}; & \\
        & \pic (31) {nonfillable subject={Subject AF}}; & \\
        & \pic (32) {nonfillable subject={Subject AG}}; & \\
    };
    \matrix[manooohE] (matE4) at ({\LstMatXShifts[4]},\mymatbottom) {
        \pic (L4E1) {nonfillable elective subject={Subject}}; \\
    };
    \matrix[manoooh] (mat5) at ({\LstMatXShifts[5]},{\LstMatYShifts[5]}) {
         \pic (33) {nonfillable subject={Subject AH}};  \\
         \pic (34) {nonfillable subject={Subject AI}};  \\
         \pic[draw=red] (35) {nonfillable subject={Subject AJ}};  \\
         \pic (36) {nonfillable subject={Subject AK}};  \\
    };
    \matrix[manooohE] (matE5) at ({\LstMatXShifts[5]},\mymatbottom) {
         \pic (L5E1) {nonfillable elective subject={Subject}};  \\
         \pic (L5E2) {nonfillable elective subject={Subject}};  \\
         \pic (L5E3) {nonfillable elective subject={Subject}};  \\
         \pic (L5E4) {nonfillable elective subject={Subject}};  \\
         \pic (L5E5) {nonfillable elective subject={Subject}};  \\
    };
 \end{scope}
 \pgfmathsetmacro{\groupwidth}{0}
 \pgfmathsetmacro{\lastwidth}{0}
 \foreach \X in {0,...,5} %<- if you have more or less matrices, adjust 3       
 {
  \node[anchor=south,yshift=1cm,align=center,font=\LARGE\bfseries\boldmath] 
  at (mat\X |-matrices.north) (L\X) {Level $\X$}; 
  \ifnodedefined{matE\X}{% has inlay
   \node[xshift=1em,anchor=south west,font=\LARGE\bfseries,opacity=0] (matEl\X) at (matE\X.north west) {Electives};
   \begin{pgfonlayer}{background}
   \path let \p1=($(mat\X.north east)-(mat\X.south west)$) in
   node[fit=(matE\X) (matEl\X),inner ysep=5mm,fill=blue!30,rounded
   corners=40pt,minimum width=\x1-2*\pgfkeysvalueof{/tikz/fit sep},
   inner xsep=\pgfkeysvalueof{/tikz/fit sep}](F\X){};
   \node[xshift=1em,anchor=south west,font=\LARGE\bfseries] 
   (matEl\X) at ([xshift=1.3em]F\X.west|-matEl\X.center) {Electives};
   \end{pgfonlayer}
   \path let \p1=($(mat\X.north east)-(mat\X.south west)$),
    \p2=($(F\X.north east)-(F\X.south west)$),
    \n1={max(abs(\y1)/2+abs(\y2)/2+0*\pgfkeysvalueof{/tikz/inlay top sep},\mymatbottom)}
      in 
    \pgfextra{\xdef\mymatbottom{\n1}
       \ifnum\X=0
        \pgfmathsetmacro{\groupwidth}{0}
       \else    
        \pgfmathsetmacro{\groupwidth}{\groupwidth+max(\x1,\x2)/2+\lastwidth/2+2*\pgfkeysvalueof{/tikz/fit sep}+\pgfkeysvalueof{/tikz/fit dist}}
       \fi
       \pgfmathsetmacro{\lastwidth}{max(\x1,\x2)+8*\pgfkeysvalueof{/tikz/fit sep}}
       \xdef\lastwidth{\lastwidth}
       \xdef\groupwidth{\groupwidth}     
       \pgfmathsetmacro{\myheight}{max(\y1+\y2+%
         \pgfkeysvalueof{/tikz/inlay top sep}+\pgfkeysvalueof{/tikz/matrix top sep},%
         \myheight)}
       \xdef\myheight{\myheight}
       \pgfmathsetmacro{\myshift}{(\pgfkeysvalueof{/tikz/inlay top sep}+\y2)/2}
       \ifnum\X=0
       \xdef\LstMatYShifts{\myshift pt}
       \xdef\LstMatXShifts{0pt}
       \else
       \xdef\LstMatYShifts{\LstMatYShifts,\myshift pt}
       \xdef\LstMatXShifts{\LstMatXShifts,\groupwidth pt}
       \fi};    
   % the fit parameters determine the shape of the background rectangles
   \begin{pgfonlayer}{behind}
   \node[fit=(L\X) (mat\X) (matrices.south-|mat\X.south)
   (matE\X) (matEl\X),inner ysep=8mm,inner xsep=4*\pgfkeysvalueof{/tikz/fit sep},
   fill=orange!30,rounded corners=50pt](F\X){};
   \end{pgfonlayer}}{% no inlay
   \path 
    let \p1=($(mat\X.north east)-(mat\X.south west)$),
     \n1={max(abs(\y1)/2,\mymatbottom)}
      in 
     \pgfextra{\xdef\mymatbottom{\n1}
       \ifnum\X=0
        \pgfmathsetmacro{\groupwidth}{0}
       \else    
        \pgfmathsetmacro{\groupwidth}{\groupwidth+\x1/2+\lastwidth/2+\pgfkeysvalueof{/tikz/fit dist}}
       \fi
       \xdef\groupwidth{\groupwidth}
       \xdef\lastwidth{\x1}
       \pgfmathsetmacro{\myheight}{max(\y1+\pgfkeysvalueof{/tikz/matrix top sep},\myheight)} 
       \xdef\myheight{\myheight}
       \ifnum\X=0
       \xdef\LstMatYShifts{0pt}
       \xdef\LstMatXShifts{0pt}
       \else
       \xdef\LstMatYShifts{\LstMatYShifts,0pt}
       \xdef\LstMatXShifts{\LstMatXShifts,\groupwidth pt}
       \fi};   
   % the fit parameters determine the shape of the background rectangles
   \begin{pgfonlayer}{behind}
   \node[fit=(L\X) (mat\X) (matrices.south-|mat\X.south),inner ysep=8mm,
   fill=orange!30,rounded corners=50pt](F\X){};
   \end{pgfonlayer}
   }
  }
 \makeatletter
 \immediate\write\@mainaux{\xdef\string\mymatbottom{-\mymatbottom}\relax}
 \immediate\write\@mainaux{\xdef\string\myheight{\myheight}\relax}
 \immediate\write\@mainaux{\xdef\string\LstMatYShifts{{\LstMatYShifts}}\relax}
 \immediate\write\@mainaux{\xdef\string\LstMatXShifts{{\LstMatXShifts}}\relax}
 \makeatother

    \newcommand\totalnodes{5} % Define the total of subjects that need arrows-1

    % From https://tex.stackexchange.com/a/480685/152550

    % now add the arrows.

    \def\LstCon{%
        {
        "{2,...,9}",%subjects that 0 links
        "{2,10/5,13/5,14/5}",%subjects that 1 links
        "{11,14}",%subjects that 2 links
        "{10,13,14,25/13}",%subjects that 3 links
        "{36/{12,21,29}}",%subjects that 8 links
        }
    }
    \foreach \X in {0,...,\totalnodes} {
        \pgfmathsetmacro{\huenum}{\X*0.75*(1/\totalnodes)}
        \definecolor{mycolor}{hsb}{\huenum,1,1}
        \pgfmathsetmacro{\mylst}{\LstCon[\X]}
        \typeout{\X:\mylst}
        \foreach \Y/\myalong in \mylst {
           \ifx\myalong\Y
              %\typeout{\X:\Y,empty}
              \draw[-latex,mycolor,very thick] (\X-Title.east) 
                to[manoooh curve] (\Y-Title.west);
           \else
             %\typeout{\X:\Y\space and\space \myalong}
             \draw[-latex,mycolor,very thick] (\X-Title.east) 
              [along node/.list/.expanded=\myalong]
              to[manoooh curve] (\Y-Title.west);
           \fi
        }
    }
\end{tikzpicture}
\end{Form}

\vfill

\end{document}

enter image description here

The relevant information is all in

\def\LstCon{%
    {
    "{2,...,9}",%subjects that 0 links
    "{2,10/5,13/5,14/5}",%subjects that 1 links
    "{11,14}",%subjects that 2 links
    "{10,13,14,25/13}",%subjects that 3 links
    "{36/{12,21,29}}",%subjects that 8 links
    }
}

which contains after the backslash a list of nodes along which the path should run. The list can consist 0, 1 or 0 elements, where in the case of 0 elements the path won't run along any node.

  • 1
    I would only change [yshift=5pt]#1-Title.north west by [yshift=8pt]#1-Title.north west :P but this is the kind of answer I was looking for!! – manooooh Mar 22 '19 at 06:38
  • Is it possible to also predict the left and right sides of the pictures? For example, I need to draw an arrow from (18) to (29) i.e. "Subject S" to "Subject "AD". The arrow overlaps with "Subject AB". – manooooh Mar 24 '19 at 23:33
  • 1
    @manooooh I do not think it is possible (or easily possible) to do that automatically. However, manoooh curve has a parameter for precisely this purpose. Try \draw[-latex,blue,very thick] (18-Title.east) to[manoooh curve=0.8] (29-Title.west);. –  Mar 25 '19 at 04:05
  • Thanks. At least we know how to do it. The problem with the solution is that if I add that line inside the loop (changing blue by mycolor) 1) The line is drawn totalnodes times, which produces an ugly output, 2) The color does not follow from the original hue of colors. The alternative is to try to do almost impossible as you say, or move the subjects to try to get an horizontal arrow, which seems more reasonable. – manooooh Mar 26 '19 at 00:59
  • 1
    @manooooh But you can find out the color, it is set by \pgfmathsetmacro{\huenum}{\X*0.75*(1/\totalnodes)} \definecolor{mycolor}{hsb}{\huenum,1,1} You only need to know which \X it is. And this should be obvious from \typeout{\X:\mylst}, which I forgot to remove. –  Mar 26 '19 at 01:12
  • Yes,I was already going to say it. I can draw the arrows manually but preserving the color by changing \X by the intial pic. Thanks again dear marmot, you are amazing! – manooooh Mar 26 '19 at 01:13
  • I need to connect (26) to (36) (Subject AA to Subject AK). I created a new arrow outside of the loop, like \draw[-latex,red,very thick] (26-Title.east) to[manoooh curve=1.5] (36-Title.west); but 1.5 is not enough, either 2.5. I also tried with negative values but it gets worse, I have not found a solution so that the arrow does not overlap with (28) (Subject AC). – manooooh Mar 26 '19 at 01:36
  • 1
    @manooooh Without testing: \draw[-latex,red,very thick] (26-Title.east) -- ++ (4,0) to[manoooh curve] (36-Title.west);, you may have to change (4,0) to (something else,0). –  Mar 26 '19 at 01:38
  • Yes, it works! However, from 36-Title.west.x to 4 we have a straight line, which is a bit ugly by looking at the other lines which are bent. Could we add a bent curve in that interval (something like to[out=X,in=Y])? – manooooh Mar 26 '19 at 18:42
  • @manooooh Sure. The manoooh curve was just a workaround for the dimension too large errors. –  Mar 26 '19 at 18:43
  • Ok. I am working with \draw[-latex,red,very thick] (26-Title.east) -- ++ (2,0) to[manoooh curve] (36-Title.west);. I tried to add to[out=0,in=180] between -- and ++ and things like that but no solutions. – manooooh Mar 26 '19 at 18:46
  • Regarding to \draw[-latex,red,very thick] (26-Title.east) -- ++ (2,0) to[manoooh curve] (36-Title.west);, it extends the line from the beginning of the path. How can we do the inverse i.e. how can we extend the line, let's say 2 units to the left, but in the end (where is the arrow head)? Image explaining this: https://imgur.com/a/o6jNR56 – manooooh Apr 10 '19 at 00:24
  • 1
    @manooooh Without trying: \draw[-latex,red,very thick] (26-Title.east) to[manoooh curve] ([xshift=-2cm]36-Title.west) -- (36-Title.west);. –  Apr 10 '19 at 00:57
  • Yes, that worked, thank you! I tried things like \draw[-latex,red,very thick] (26-Title.east) to[manoooh curve] -- ++ (-2,0) (36-Title.west); but it did not work. – manooooh Apr 10 '19 at 01:00
  • 1
    @manooooh Yes, this does not work. Since you load calc, you could have done \draw[-latex,red,very thick] (26-Title.east) to[manoooh curve] -- ($(-2,0)+ (36-Title.west)$); instead, this works. –  Apr 10 '19 at 01:02