我发现代码它重新定义了定义链的方式(\chainin
),并允许在链中包含标签。但是,此代码禁用了样式选项(by
和with
关键字)。但是,我需要为每个链赋予单独的样式。
我如何才能为每个链添加单独的样式,同时能够通过添加节点来标记连接,例如:node [left] {tag}
。所以我的目标是这样的:\chainin (node) [join=by myStyle, {node [left] {my Tag}}];
\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes,chains,scopes,matrix}
% This code makes it able to include the tag
\makeatletter
\tikzset{join/.code=\tikzset{after node path={%
\ifx\tikzchainprevious\pgfutil@empty\else(\tikzchainprevious)%
edge[every join]#1(\tikzchaincurrent)\fi}}}
\makeatother
\begin{document}
\begin{tikzpicture}[auto,
decision/.style = {draw,
diamond,
text badly centered,
fill = blue!5,
text width = 15mm,
node distance = 2.5cm,
inner sep = 0pt},
block/.style = {draw,
rectangle,
text centered,
rounded corners,
fill = blue!5,
text width = 20mm,
minimum height = 10mm},
tip/.style = {->,
very thick,
color = black!50}
]
\matrix[row sep=1cm]{
\node [block] (blk) {A block here}; \\
\node [decision] (dec) {Is something?};\\
};
{ [start chain]
\chainin (blk);
% By removing the 'by tip' style this compiles
\chainin (dec) [join=by tip, {node [left] {yes}}];
}
\end{tikzpicture}
\end{document}
答案1
问题是连接未用作参数化样式,但代码已运行。也就是说,by tip, {node [left] {yes}}
变为,#1
因此join/.code
它被放置在之后edge[every join]
。这意味着如果没有它,tip
它也可以正常工作,节点被放置在边缘之后并按预期应用。问题是您希望将tip
作为选项放置在边缘上,除了every join
。实现此目的的最简单方法是让join
两个参数,一个用于边缘选项,另一个用于表示可能的节点。这可以通过以下代码实现:
\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes,chains,scopes,matrix}
% This code makes it able to include the tag
\makeatletter
\tikzset{join/.code 2 args=\tikzset{after node path={%
\ifx\tikzchainprevious\pgfutil@empty\else(\tikzchainprevious)%
edge[every join,#1]#2(\tikzchaincurrent)\fi}}}
\makeatother
\begin{document}
\begin{tikzpicture}[auto,
decision/.style = {draw,
diamond,
text badly centered,
fill = blue!5,
text width = 15mm,
node distance = 2.5cm,
inner sep = 0pt},
block/.style = {draw,
rectangle,
text centered,
rounded corners,
fill = blue!5,
text width = 20mm,
minimum height = 10mm},
tip/.style = {->,
very thick,
color = black!50}
]
\matrix[row sep=1cm]{
\node [block] (blk) {A block here}; \\
\node [decision] (dec) {Is something?};\\
};
{ [start chain]
\chainin (blk);
%tip and node:
\chainin (dec) [join={tip}{node [left] {yes}}];
%Only the tip:
%\chainin (dec) [join={tip}{}];
%Only the node:
%\chainin (dec) [join={}{node [left] {yes}}];
}
\end{tikzpicture}
\end{document}
如您所见,如果您不想要连接的特定部分,则可以将参数留空。
编辑:我看不出有办法实现这一点。因为你必须改变code
键的join
才能获得所需的行为。但要获得with .. by ...
行为,需要不同的代码。不幸的是,据我所知,你只能有一个“代码相关”的键(也就是说,TikZ 无法根据参数确定要调用哪个代码)。最简单的方法可能是将join
上面代码中引入的新方法更改为,myjoin
并在你想要标记的任何地方使用它。所以tikzset
会变成:
tikzset{myjoin/.code 2 args=\tikzset{after node path={%
\ifx\tikzchainprevious\pgfutil@empty\else(\tikzchainprevious)%
edge[every join,#1]#2(\tikzchaincurrent)\fi}}}
然后,您可以myjoin={options}{labeling node}
在需要标签的地方以及join=with ... by ...
需要旧行为的地方使用。选择一个比这更合适的名称可能是明智的myjoin
。
如果您喜欢这种详细(也许更易读)的使用键的方式,您可以myjoin
按如下方式定义选项:
\tikzset{myjoin/.code args={style #1 and label #2}{%
\tikzset{after node path={\ifx\tikzchainprevious\pgfutil@empty%
\else(\tikzchainprevious)edge[every join,#1]#2(\tikzchaincurrent)\fi}}}}
可以用作
\chainin (dec) [myjoin=style tip and label {node [left] {yes}}];
答案2
因此,在分析了wh1t3 的解决方案,以及链库,我试图实现一个允许我使用代码join
并添加标签的解决方案。
我不确定这是否是正确的方法,因为我以前从未这样做过,所以如果有更好的方法请告诉我。我重新定义了库的函数以允许label
添加关键字,它将添加我缺少的带有标签的节点。要添加的代码是:
\makeatletter
\def\tikz@lib@parse@join#1{%
\def\tikz@temp{#1}%
\ifx\tikz@temp\pgfutil@empty%
\tikz@lib@parse@join@by by \pgf@stop%
\else%
\pgfutil@in@{with }{#1}%
\ifpgfutil@in@% 'with [by] [label]'
\pgfutil@in@{by }{#1}%
\ifpgfutil@in@% 'with by [label]'
\pgfutil@in@{label }{#1}%
\ifpgfutil@in@% 'with by label'
\tikz@lib@parse@join@with@by@label#1\pgf@stop%
\else% 'with by'
\tikz@lib@parse@join@with@by#1\pgf@stop%
\fi%
\else% 'with [label]'
\pgfutil@in@{label }{#1}%
\ifpgfutil@in@% 'with label'
\tikz@lib@parse@join@with@label#1\pgf@stop%
\else% with
\tikz@lib@parse@join@with@by#1 by \pgf@stop%
\fi%
\fi%
\else% '[by] [label]'
\pgfutil@in@{by }{#1}%
\ifpgfutil@in@% 'by [label]'
\pgfutil@in@{label }{#1}%
\ifpgfutil@in@% 'by label'
\tikz@lib@parse@join@by@label#1\pgf@stop%
\else% 'by'
\tikz@lib@parse@join@by#1\pgf@stop%
\fi%
\else% '[label]'
\pgfutil@in@{label }{#1}%
\ifpgfutil@in@% 'label'
\tikz@lib@parse@join@label#1\pgf@stop%
\else%
\tikz@lib@parse@join@by#1 by \pgf@stop%
\fi%
\fi%
\fi%
\fi%
}
\def\tikz@lib@parse@join@with@by@label with #1 by #2 label #3\pgf@stop{%
\tikzset{after node path={(#1)edge[every join,#2]#3(\tikzchaincurrent)}}%
}
\def\tikz@lib@parse@join@with@label with #1 label #2\pgf@stop{%
\tikzset{after node path={(#1)edge[every join]#2(\tikzchaincurrent)}}%
}
\def\tikz@lib@parse@join@by@label by #1 label #2\pgf@stop{%
\tikzset{after node path={\ifx\tikzchainprevious\pgfutil@empty\else(\tikzchainprevious)edge[every join,#1]#2(\tikzchaincurrent)\fi}}%
}
\def\tikz@lib@parse@join@label label #1\pgf@stop{%
\tikzset{after node path={\ifx\tikzchainprevious\pgfutil@empty\else(\tikzchainprevious)edge[every join]#1(\tikzchaincurrent)\fi}}%
}
\makeatother
添加该部分后,现在我可以调用我的chainin
类似功能:
\chainin (node) [join=with anotherNode by myStyle label {node[above] {some Tag}}];
\chainin (node) [join=by myStyle label {node[above] {some Tag}}];
一个完整的例子是
\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes,chains,scopes,matrix}
\makeatletter
\def\tikz@lib@parse@join#1{%
\def\tikz@temp{#1}%
\ifx\tikz@temp\pgfutil@empty%
\tikz@lib@parse@join@by by \pgf@stop%
\else%
\pgfutil@in@{with }{#1}%
\ifpgfutil@in@% 'with [by] [label]'
\pgfutil@in@{by }{#1}%
\ifpgfutil@in@% 'with by [label]'
\pgfutil@in@{label }{#1}%
\ifpgfutil@in@% 'with by label'
\tikz@lib@parse@join@with@by@label#1\pgf@stop%
\else% 'with by'
\tikz@lib@parse@join@with@by#1\pgf@stop%
\fi%
\else% 'with [label]'
\pgfutil@in@{label }{#1}%
\ifpgfutil@in@% 'with label'
\tikz@lib@parse@join@with@label#1\pgf@stop%
\else% with
\tikz@lib@parse@join@with@by#1 by \pgf@stop%
\fi%
\fi%
\else% '[by] [label]'
\pgfutil@in@{by }{#1}%
\ifpgfutil@in@% 'by [label]'
\pgfutil@in@{label }{#1}%
\ifpgfutil@in@% 'by label'
\tikz@lib@parse@join@by@label#1\pgf@stop%
\else% 'by'
\tikz@lib@parse@join@by#1\pgf@stop%
\fi%
\else% '[label]'
\pgfutil@in@{label }{#1}%
\ifpgfutil@in@% 'label'
\tikz@lib@parse@join@label#1\pgf@stop%
\else%
\tikz@lib@parse@join@by#1 by \pgf@stop%
\fi%
\fi%
\fi%
\fi%
}
\def\tikz@lib@parse@join@with@by@label with #1 by #2 label #3\pgf@stop{%
\tikzset{after node path={(#1)edge[every join,#2]#3(\tikzchaincurrent)}}%
}
\def\tikz@lib@parse@join@with@label with #1 label #2\pgf@stop{%
\tikzset{after node path={(#1)edge[every join]#2(\tikzchaincurrent)}}%
}
\def\tikz@lib@parse@join@by@label by #1 label #2\pgf@stop{%
\tikzset{after node path={\ifx\tikzchainprevious\pgfutil@empty\else(\tikzchainprevious)edge[every join,#1]#2(\tikzchaincurrent)\fi}}%
}
\def\tikz@lib@parse@join@label label #1\pgf@stop{%
\tikzset{after node path={\ifx\tikzchainprevious\pgfutil@empty\else(\tikzchainprevious)edge[every join]#1(\tikzchaincurrent)\fi}}%
}
\makeatother
\begin{document}
\begin{tikzpicture}[auto,
decision/.style = {draw,
diamond,
text badly centered,
fill = blue!5,
text width = 15mm,
node distance = 2.5cm,
inner sep = 0pt},
block/.style = {draw,
rectangle,
text centered,
rounded corners,
fill = blue!5,
text width = 20mm,
minimum height = 10mm},
tip/.style = {->,
very thick,
color = black!50},
tip2/.style = {->,
very thick,
bend right,
color = black!50}
]
\matrix[row sep=1cm]{
\node [block] (blk) {A block here}; \\
\node [decision] (dec) {Is something?};\\
\node [block] (blk2) {Another block};\\
};
{ [start chain]
\chainin (blk);
% Removing the 'by tip' style this compiles
\chainin (dec) [join=by tip label {node [left] {yes}}];
\chainin (blk2) [join=by tip];
\chainin (blk2) [join=with blk by {tip2} label {node[left]{my tag}}];
}
\end{tikzpicture}
\end{document}