似乎\graph
命令不接受名称包含 的节点-
。
编译
\documentclass[tikz,border=2mm]{standalone}
\usetikzlibrary{graphs}
\begin{document}
\begin{tikzpicture}
\node[draw] (A-1) {A};
\node[draw] (B-1) at (1,0) {B};
\graph [use existing nodes] { A-1 -> B-1;};
\end{tikzpicture}
\end{document}
结束并显示错误消息:
! Package tikz Error: One of the arrow types <-, --, ->, -!- or <-> expected.
因此看起来-
(抱歉我不记得英文名字了)被视为箭头而不是节点名称的一部分。
这不是什么大问题,因为我们可以使用没有 的名称-
。但是当节点用 声明时matrix of nodes
,它们包含两个-
。这意味着 的主要优点之一是 ,matrix of nodes
它自动不能使用名称和选项|(...)|
,或者|[name=...]|
必须在每个带有节点的单元中使用 。
命令是否可以\graph
接受-
节点名称?
答案1
除了可以修改与矩阵或图形相关的代码外,这里还有另一种选择。
我们通常的想法是保护通过添加额外的括号来区分敏感字符,例如(\x,sin(\x))
不起作用,但(\x,{sin(\x)})
起作用。
对于图形来说,括号有另一种含义,我们应该保护用引号括住节点名称。理想的代码应该是这样的
\begin{tikzpicture}
\node[draw] (A-1) {A};
\node[draw] (B-1) at (1,0) {B};
\graph [use existing nodes] {"A-1"->"B-1";};
\end{tikzpicture}
但是,出于安全原因,引号内的任何内容都会被处理:特殊字符将被其他内容替换,例如-
变为@HYPHEN MINUS@
和>
变为@GREATER THAN SIGN@
。因此,以下代码实际上是有效的。
\begin{tikzpicture}
\node[draw] (A@HYPHEN MINUS@1) {A};
\node[draw] (B@GREATER THAN SIGN@2) at (1,0) {B};
\graph [use existing nodes] {"A-1"->"B>2";};
\end{tikzpicture}
下一步是,每当我们(或 Ti钾Z) 创建并命名一个节点,我们想用-
上面的相同字符串替换名称。因此我们破解了这个name=
方案
\makeatletter
\tikzset{
name/.code={
{
\catcode`\-=13\relax
\scantokens{
\def-{@HYPHEN MINUS@}
\xdef\hypenminusname{#1}
}
}
\edef\tikz@fig@name{\tikz@pp@name{\hypenminusname}}
}
}
\makeatother
如果涉及其他特殊字符,您可以自行扩展列表。
现在开头的代码可以正常工作了。以下代码也可以正常工作
\tikz{
\matrix(magic)[matrix of nodes]{
8 & 1 & 6 \\
3 & 5 & 7 \\
4 & 9 & 2 \\
};
\graph[use existing nodes]{
"magic-2-1"->{"magic-1-3","magic-2-3","magic-3-3"};
};
}
完整代码
\documentclass[tikz,border=2mm]{standalone}
\usetikzlibrary{graphs,matrix}
\begin{document}
\begin{tikzpicture}
\node[draw] (A@HYPHEN MINUS@1) {A};
\node[draw] (B@GREATER THAN SIGN@2) at (1,0) {B};
\graph [use existing nodes] {"A-1"->"B>2";};
\end{tikzpicture}
\makeatletter
\tikzset{
name/.code={
{
\catcode`\-=13\relax
\scantokens{
\def-{@HYPHEN MINUS@}
\xdef\hypenminusname{#1}
}
}
\edef\tikz@fig@name{\tikz@pp@name{\hypenminusname}}
}
}
\makeatother
\begin{tikzpicture}
\node[draw] (A-1) {A};
\node[draw] (B-1) at (1,0) {B};
\graph [use existing nodes] {"A-1"->"B-1";};
\end{tikzpicture}
\tikz{
\matrix(magic)[matrix of nodes]{
8 & 1 & 6 \\
3 & 5 & 7 \\
4 & 9 & 2 \\
};
\graph[use existing nodes]{
"magic-2-1"->{"magic-1-3","magic-2-3","magic-3-3"};
};
}
\end{document}
答案2
graph
您可以更改代码的相关部分,而不是破解库或解析matrix of nodes
。您还可以将其设为本地行为等。
\documentclass[tikz]{standalone}
\usetikzlibrary{graphs,matrix}
\makeatletter
\def\tikz@lib@matrix@empty@cell{\iftikz@lib@matrix@empty\node[name=\tikzmatrixname!\the\pgfmatrixcurrentrow!\the\pgfmatrixcurrentcolumn]{};\fi}
\def\tikz@lib@matrix@with@options|#1|{\tikz@lib@matrix@plainfalse\node%
[name=\tikzmatrixname!\the\pgfmatrixcurrentrow!\the\pgfmatrixcurrentcolumn]#1\bgroup\tikz@lib@matrix@startup}
\def\tikz@lib@matrix@normal@start@cell{\pgfutil@ifnextchar\let{\tikz@lib@matrix@check}{\tikz@lib@matrix@plainfalse\node
[name=\tikzmatrixname!\the\pgfmatrixcurrentrow!\the\pgfmatrixcurrentcolumn]\bgroup\tikz@lib@matrix@startup}}%
\def\tikz@lib@matrix@check#1{% evil hackery to find out about start of path
\pgfutil@ifnextchar\tikz@signal@path{\tikz@lib@matrix@plaintrue\let}{\tikz@lib@matrix@plainfalse\node
[name=\tikzmatrixname!\the\pgfmatrixcurrentrow!\the\pgfmatrixcurrentcolumn]\bgroup\tikz@lib@matrix@startup\let}%
}
\makeatother
\begin{document}
\begin{tikzpicture}
\matrix[matrix of nodes] (a) {
A\\[4mm]
B\\
};
\graph [use existing nodes] {a!1!1 -> a!2!1;};
\end{tikzpicture}
\end{document}