4

I have this MWE, 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,
 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 4 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}

MWE

I would like to add a set of checkbox'es from ocgx2 package, where we can set the arrows to "Visible" or "Invisible" that connect two or more subjects:

What I want

If we deselect e.g. "Correlatives of subject C" then all the arrows that start from "Subject C" must be changed to "Invisible", so we cannot see them. Also the "Select All" checkbox has to change, meaning that "We have not selected all the checkbox'es" i.e.:

Example

If we deselect all of them:

Example 2

Note that the "Select All" checkbox is automatically changed to "off" due to the user's deselection of all the other checkbox'es.

As expected, the user can select "Select All" to make all the arrows visible. If he deselects it, all the arrows must be invisible.

You can rely on this great example of AlexG's comment:

\documentclass[12pt,margin=3pt]{standalone}

\usepackage[tikz]{ocgx2}  % PDF Layers
\usepackage{amssymb} % \checkmark
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% check box command for layer switching    
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\newcommand\layerCheckBox[3]{%
  % #1: layer name (as shown in Layers tab), #2: layer id,
  % #3: initial visibility
  \resizebox{2ex}{!}{\ooalign{%
    \switchocg{#2}{$\square$}\cr%
    \begin{ocg}{#1}{#2}{#3}$\checkmark$\end{ocg}%
  }}%
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\begin{document}

\begin{tikzpicture}
  \node (a) at (0,0) {A};
  \node (b) at (1,1) {B};
  \begin{scope}[ocg={name=Arrow,ref=myArrow,status=visible}]
    \draw[->] (a.east) -| (b.south);
  \end{scope}
\end{tikzpicture}

\layerCheckBox{Arrow}{myArrow}{on}A$\rightarrow$B

\end{document}

If possible, the addition of the checkbox'es should be automatic, in the sense that if there is a set of arrows then they will be inserted in a new line of the big black frame.

After the compilation all the checkbox'es have to start "on".

EDIT. Thanks to AlexG I could improve the code.

I have added a scope inside the \foreach loop because we need totalnodes subjects that need arrows:

\foreach \X in {0,...,\totalnodes} {
\begin{scope}[ocg={name={Arrow\X},ref=myArrow\X,status=visible}]
        \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{scope}
}

Outside the tikzpicture I added to the MWE the following:

\parbox[b]{0.8in}{\noindent% 
\showocg{myArrow0 myArrow4}{\fboxsep=1pt\fbox{\rule{0pt}{1.7ex}on}} 
\hideocg{myArrow4 myArrow0}{\fboxsep=1pt\fbox{\rule{0pt}{1.7ex}off}}\mbox{ All}\\% 
\layerCheckBox{}{myArrow0}{on}\mbox{A$\rightarrow$B}\\% 
\layerCheckBox{}{myArrow1}{on}\mbox{B$\rightarrow$A}\\%
\layerCheckBox{}{myArrow2}{on}\mbox{B$\rightarrow$A}\\%
\layerCheckBox{}{myArrow3}{on}\mbox{B$\rightarrow$A}\\%
\layerCheckBox{}{myArrow4}{on}\mbox{B$\rightarrow$A}\\%
}

But:

  1. on/off does not work properly: it shows/does not show the arrows that start from (0) and (4) (and what about (1), (2) and (3)?).
  2. I think clicking one or more checkbox'es redrawn all the figures, including the lightblue shapes: Problem

How can we write just one time all the figures but making a correct use of on/off?

  • The code for the switches/checkboxes outside the tikzpicture, do you insert it manually? If so, you just forgot to also put myArrow1 myArrow2 myArrow3 along with myArrow0 myArrow4 into the \showocg and \hideocg argument. Also, the order of ids in these arguments doesn't matter. – AlexG Mar 29 at 9:47
4
+50

Separate show and hide switches (\showocg..., \hideocg...) can be added that set the visibility of multiple OCGs. It seems impossible, however, to associate a checkbox with them whose state depends on the visibility of the set of OCGs that are manipulated. The best I could come up with so far is:

\documentclass[12pt,margin=3pt]{standalone} 

\usepackage[tikz]{ocgx2}  % PDF Layers 
\usepackage{amssymb} % \checkmark 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
% check box command for layer switching     
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
\newcommand\layerCheckBox[3]{% 
  % #1: switch id, if empty use #2 instead 
  % #2: layer ids to be toggled (space separated if multiple ids), 
  % #3: initial visibility 
  \resizebox{2ex}{!}{\ooalign{% 
    \switchocg{#1 #2}{$\square$}\cr% 
    \begin{ocg}{% 
      \ifx\nil#1\nil#2\else#1\fi% 
    }{% 
      \ifx\nil#1\nil#2\else#1\fi% 
    }{#3}$\checkmark$\end{ocg}% 
  }}% 
} 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 

\begin{document} 

\begin{tikzpicture} 
  \node (a) at (0,0) {A}; 
  \node (b) at (1,1) {B}; 
  \begin{scope}[ocg={name={Arrow A->B},ref=myArrowAB,status=visible}] 
    \draw[->] (a.east) -| (b.south); 
  \end{scope} 
  \begin{scope}[ocg={name={Arrow B->A},ref=myArrowBA,status=visible}] 
    \draw[->] (b.west) -| (a.north); 
  \end{scope} 
\end{tikzpicture} 

\parbox[b]{0.8in}{\noindent% 
\showocg{myArrowAB myArrowBA}{\fboxsep=1pt\fbox{\rule{0pt}{1.7ex}on}} 
\hideocg{myArrowAB myArrowBA}{\fboxsep=1pt\fbox{\rule{0pt}{1.7ex}off}} All\\% 
\layerCheckBox{}{myArrowAB}{on}A$\rightarrow$B\\% 
\layerCheckBox{}{myArrowBA}{on}B$\rightarrow$A} 

\end{document} 

Update:

As for (1.) at the end of your question, you forgot to also put myArrow1 myArrow2 myArrow3 along with Arrow0 and Arrow4 to the list of OCGs to be manipulated with \showocg... and \hideocg.... Therefore, only arrows 0 and 4 are shown/hidden when clicking the on/off links.

In order to produce the legend with checkboxes and on/off-All links at the bottom of your actual document, I would add something like

% list of OCGs, space separated
\def\ocglist{}%
\foreach \X in {0,...,\totalnodes} {\xdef\ocglist{\ocglist\space myArrow\X}}
% on/off All
\showocg{\ocglist}{\fboxsep=1pt\fbox{\rule{0pt}{1.7ex}on}}/%
\hideocg{\ocglist}{\fboxsep=1pt\fbox{\rule{0pt}{1.7ex}off}} All\\%
% checkboxes
\foreach \X in {0,...,\totalnodes} {%
  \layerCheckBox{}{myArrow\X}{on}%
  \pgfmathsetmacro{\mylst}{\LstCon[\X]}%
  \foreach \Y/\dummy in \mylst {\space\X$\rightarrow$\Y}\\
}

Complete example:

\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]{ocgx2}
\usepackage{amssymb} % \checkmark 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
% check box command for layer switching     
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
\newcommand\layerCheckBox[3]{% 
  % #1: switch id, if empty use #2 instead 
  % #2: layer ids to be toggled (space separated if multiple ids), 
  % #3: initial visibility 
  \resizebox{2ex}{!}{\ooalign{% 
    \switchocg{#1 #2}{$\square$}\cr% 
    \begin{ocg}{% 
      \ifx\nil#1\nil#2\else#1\fi% 
    }{% 
      \ifx\nil#1\nil#2\else#1\fi% 
    }{#3}$\checkmark$\end{ocg}% 
  }}% 
} 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 

\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

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

\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

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

    % now add the arrows.

    \gdef\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 4 links
        }
    }
    \pgfmathsetmacro{\mylst}{\LstCon[0]}
    \foreach \X in {0,...,\totalnodes} {
    \begin{scope}[ocg={name={Arrow\X},ref=myArrow\X,status=visible}]
            \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{scope}
    }
\end{tikzpicture}
\end{Form}
\flushleft
\qquad\parbox{0.4\linewidth}{\hypersetup{pdfborder={0 0 0}}%
    % list of OCGs, space separated
    \def\ocglist{}%
    \foreach \X in {0,...,\totalnodes} {\xdef\ocglist{\ocglist\space myArrow\X}}
    % on/off All
    \showocg{\ocglist}{\fboxsep=1pt\fbox{\rule{0pt}{1.7ex}on}}/%
    \hideocg{\ocglist}{\fboxsep=1pt\fbox{\rule{0pt}{1.7ex}off}} All\\%
    % checkboxes
    \foreach \X in {0,...,\totalnodes} {%
      \layerCheckBox{}{myArrow\X}{on}%
      \pgfmathsetmacro{\mylst}{\LstCon[\X]}%
      \foreach \Y/\dummy in \mylst {\space\X$\rightarrow$\Y}\\
    }
}

\end{document}
  • Thanks, your MWE looks fantastic!! However, your answer is an approximation because we need to figure out how to asign a layerCheckBox to a set of paths of one subject, because we do not have a draw command for every path but \draw[-latex,mycolor,very thick] (\X-Title.east) to[manoooh curve] (\Y-Title.west); and \draw[-latex,mycolor,very thick] (\X-Title.east) [along node/.list/.expanded=\myalong] to[manoooh curve] (\Y-Title.west);. – manooooh Mar 28 at 19:52
  • 1
    If you want multiple paths to be associated with a particular layer you can place them all into the same scope environment that defines that layer. There is no problem with placing any number of TikZ objects on the same layer. – AlexG Mar 28 at 20:13
  • How can we group multiple paths with a particular layer considering our MWE? The arrows are drawn in the last lines of the source code. – manooooh Mar 28 at 20:16
  • 1
    I hope I got your point. You could put a \foreach loop into a scope. – AlexG Mar 28 at 20:41
  • 2
    WOW! I didn't even think this is possible. – marmot Mar 30 at 4:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.