使用“tikzpicture”环境创建大量复选框以使箭头可见/不可见

使用“tikzpicture”环境创建大量复选框以使箭头可见/不可见

我有这个 MWE,取自marmot 的精彩回答

\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}

平均能量损失

我想添加一组复选框ocgx2包裹,我们可以将连接两个或多个主题的箭头设置为“可见”或“不可见”:

我想要的是

例如,如果我们取消选择“主题 C 的相关项”,那么从“主题 C”开始的所有箭头都必须更改为“不可见”,这样我们就看不到它们了。此外,“全选”复选框也必须更改,这意味着“我们没有选中所有复选框”,即:

例子

如果我们取消选择所有:

示例 2

请注意,由于用户取消选择所有其他复选框,“全选”复选框会自动更改为“关闭”。

正如预期的那样,用户可以选择“全选”以使所有箭头可见。如果他取消选择,则所有箭头都必须不可见。

您可以信赖这是 AlexG 评论的一个很好的例子

\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}

如果可能的话,复选框的添加应该是自动的,也就是说,如果有一组箭头,那么它们将被插入到大黑框的新行中。

编译后,所有复选框都必须开始“开启”。

编辑。感谢 AlexG,我能够改进代码。

我添加了scope 里面循环\foreach,因为我们需要totalnodes需要箭头的主题:

\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}
}

tikzpicture在 MWE之外,我还添加了以下内容:

\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}\\%
}

但:

  1. on/off无法正常工作:它显示/不显示从(0)和开始的箭头(4)(以及(1)(2)(3)?)。
  2. 我认为单击一个或多个复选框会重新绘制所有图形,包括浅蓝色形状: 问题

我们如何才能只写一次所有的数字但又正确使用on/ off

答案1

可以添加单独的显示和隐藏开关(\showocg...\hideocg...)来设置多个 OCG 的可见性。但是,似乎不可能将复选框与它们关联起来,其状态取决于所操作的 OCG 集的可见性。到目前为止,我能想到的最好的办法是:

\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} 

更新:

至于问题末尾的 (1.),您忘记将 和 也添加到myArrow1 myArrow2 myArrow3要使用和进行操作的 OCG 列表中。因此,单击开/关链接时,只会显示/隐藏箭头 0 和 4。Arrow0Arrow4\showocg...\hideocg...

为了在实际文档底部生成带有复选框和开/关全部链接的图例,我会添加类似

% 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}\\
}

完整示例:

\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}

相关内容