这是上一个问题的附录:如何放置框并使用列来分隔箭头。
请考虑这个 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}
效果非常棒。
现在我想添加另一个箭头,从 到(2)
,(3)
因此可能会添加
"{3}",
到\LstCon
对象(请将的值增加\totalnodes
1!),但这会产生丑陋的输出,因为它与“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 \hbox
PS 此外,由于 ,我收到了坏箱消息\parbox
。您能否尝试找出我收到此消息的原因?
答案1
初步估计:有两个不同的数字:
\totalnodes
是您将要获得的复选框的数量。\listednodes
小于或等于\totalnodes
,就是您循环的列表的条目数。
对于每个更复杂的连接,您需要执行额外的范围
\begin{scope}[ocg={name={Arrow<X>},ref=myArrow<X>,status=visible}]
....
\end{scope}
其中是大于和小于或等于 的<X>
数字,用于标记额外条目。下面是等于 1(因为列表有两个条目,我们从 0 开始)、等于 2 以及也等于 2 的示例。\listednodes
\totalnodes
\listednodes
\totalnodes
X
\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}