如何将特定对象添加到 `ocg` 列表

如何将特定对象添加到 `ocg` 列表

这是上一个问题的附录:如何放置框并使用列来分隔箭头

请考虑这个 MWE(改编自很好的答案这个问题):

\documentclass{article}
\usepackage[margin=0in,footskip=0in]{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},
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);
 }},
 manoooh/.style={column sep=-1.75cm,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{1} % Define the total of subjects that need arrows-1
%%%%%%%%%%%%%%%%%%%%%%%%%

\begin{document}

\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

\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={Subject0}};  & &
        \pic (1) {nonfillable subject={Subject1}};  \\
        & \pic (2) {nonfillable subject={Subject2}}; & \\
    };
    \matrix[manoooh] (mat1) at ({\LstMatXShifts[1]},{\LstMatYShifts[1]}) {
        \pic (3) {nonfillable subject={Subject3}};  \\
        \pic (4) {nonfillable subject={Subject4}};  \\
        \pic (5) {nonfillable subject={Subject5}};  \\
        \pic (6) {nonfillable subject={Subject6}};  \\
        \pic (7) {nonfillable subject={Subject7}};  \\
        \pic (8) {nonfillable subject={Subject8}};  \\
    };
    \end{scope}
    \pgfmathsetmacro{\groupwidth}{0}
    \pgfmathsetmacro{\lastwidth}{0}
    \foreach \X in {0,...,1}{ %<- if you have more or less matrices, adjust 3
        \ifnodedefined{matE\X}
        {
            % has inlay
        }
        {
        % 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
        }
    }
    \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{%
        {
            "{6/1}",
            "{4}",
        }
    }
    \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}
    }
    %\pgfmathsetmacro{\huenumm}{2*0.75*(1/\totalnodes)}
    %\definecolor{mycolor2}{hsb}{\huenumm,1,1}
    %\draw[-latex,mycolor2,very thick] (2-Title.east) -- ++ (3,0) to[manoooh curve=1.6] (3-Title.west);
\end{tikzpicture}

\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}}
    \fbox{%
        \parbox{12cm}{%
            % 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}\begin{tikzpicture}[baseline=-1ex]%
                \pgfmathsetmacro{\huenum}{\X*0.75*(1/\totalnodes)}%
                \definecolor{mycolor}{hsb}{\huenum,1,1}\draw[-latex,mycolor,very thick] (0,0) -- (1,0);%
                \end{tikzpicture}\qquad%
            }%
        }
    }
}

\end{document}

MWE 输出

效果非常棒。

现在我想添加另一个箭头,从 到(2)(3)因此可能会添加

"{3}",

\LstCon对象(请将的值增加\totalnodes1!),但这会产生丑陋的输出,因为它与“Subject1”冲突。

为了解决这个问题,有人告诉我我需要创造这个新箭头外部循环\foreach位于tikzpicture环境中。因此,我在代码中删除"{3}",并添加了以下三行:

\pgfmathsetmacro{\huenumm}{2*0.75*(1/\totalnodes)}
\definecolor{mycolor2}{hsb}{\huenumm,1,1}
\draw[-latex,mycolor2,very thick] -- ++ (3,0) (2-Title.east) to[manoooh curve=1.6] (3-Title.west);

您只需取消注释给定 MWE 的那些行即可获得以下输出:

新输出

看上去好像没有什么问题。

但是,在循环外部添加箭头\foreach会使复选框不可点击

问题

我想让这个新复选框可以点击。我们该怎么做?

谢谢!!

overfull \hboxPS 此外,由于 ,我收到了坏箱消息\parbox。您能否尝试找出我收到此消息的原因?

答案1

初步估计:有两个不同的数字:

  1. \totalnodes是您将要获得的复选框的数量。
  2. \listednodes小于或等于 \totalnodes,就是您循环的列表的条目数。

对于每个更复杂的连接,您需要执行额外的范围

 \begin{scope}[ocg={name={Arrow<X>},ref=myArrow<X>,status=visible}] 
    ....
 \end{scope}

其中是大于和小于或等于 的<X>数字,用于标记额外条目。下面是等于 1(因为列表有两个条目,我们从 0 开始)、等于 2 以及也等于 2 的示例。\listednodes\totalnodes\listednodes\totalnodesX

\documentclass{article}
\usepackage[margin=0in,footskip=0in]{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},
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);
 }},
 manoooh/.style={column sep=-1.75cm,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{2} % Define the total of subjects that need arrows-1
%%%%%%%%%%%%%%%%%%%%%%%%%

\begin{document}

\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

\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={Subject0}};  & &
        \pic (1) {nonfillable subject={Subject1}};  \\
        & \pic (2) {nonfillable subject={Subject2}}; & \\
    };
    \matrix[manoooh] (mat1) at ({\LstMatXShifts[1]},{\LstMatYShifts[1]}) {
        \pic (3) {nonfillable subject={Subject3}};  \\
        \pic (4) {nonfillable subject={Subject4}};  \\
        \pic (5) {nonfillable subject={Subject5}};  \\
        \pic (6) {nonfillable subject={Subject6}};  \\
        \pic (7) {nonfillable subject={Subject7}};  \\
        \pic (8) {nonfillable subject={Subject8}};  \\
    };
    \end{scope}
    \pgfmathsetmacro{\groupwidth}{0}
    \pgfmathsetmacro{\lastwidth}{0}
    \foreach \X in {0,...,1}{ %<- if you have more or less matrices, adjust 3
        \ifnodedefined{matE\X}
        {
            % has inlay
        }
        {
        % 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
        }
    }
    \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{%
        {
            "{6/1}",
            "{4}",
        }
    }
    \def\listednodes{1}
    \pgfmathsetmacro{\mylst}{\LstCon[0]}
    \foreach \X in {0,...,\listednodes} {
        \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}
    }
    \begin{scope}[ocg={name={Arrow2},ref=myArrow2,status=visible}]
    \pgfmathsetmacro{\huenumm}{2*0.75*(1/\totalnodes)}
    \definecolor{mycolor2}{hsb}{\huenumm,1,1}
    \draw[-latex,mycolor2,very thick] (2-Title.east) -- ++ (3,0) to[manoooh curve=1.6] (3-Title.west);
    \end{scope}
\end{tikzpicture}

\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}}
    \fbox{%
        \parbox{12cm}{%
            % 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}\begin{tikzpicture}[baseline=-1ex]%
                \pgfmathsetmacro{\huenum}{\X*0.75*(1/\totalnodes)}%
                \definecolor{mycolor}{hsb}{\huenum,1,1}\draw[-latex,mycolor,very thick] (0,0) -- (1,0);%
                \end{tikzpicture}\qquad%
            }%
        }
    }
}

\end{document}

相关内容