我想根据我的数据自动调整流程图的功能。这里的例子是线宽,但我想对节点大小也使用相同的原理。
我已将这些数据保存为文本文件,其中一列包含数据点的名称,第二列对应我想要显示的实际文本,第三列包含我想要在文件中使用的参数,该文件名为flows.txt
:
Z2A, 2$\pm$0, 0.5
A2B, 110$\pm$6, 2.5
我已成功使用该包导入数据datatool
,并且能够使用\flowvar
获取所需数据的自定义命令将其作为文本写在我的图表上,但我无法使用它来修改图形参数。
\DTLloaddb[noheader, keys={thekey,thevalue,thewidth}]{myflows}{flow.txt}
\newcommand{\flowvar}[1]{\DTLfetch{myflows}{thekey}{#1}{thevalue}}
\newcommand{\flowwidth}[1]{\DTLfetch{myflows}{thekey}{#1}{thewidth}}
因此以下命令有效:
\path [ARROW] ([shift={(-1.5,0)}]a.west) -- (a.west) node[pos=0.5,above] {\scriptsize \flowvar{Z2A}};
但是,如果我尝试按如下方式调整线宽,则会出现错误:
\path [ARROW, line width = \flowwidth{Z2A} mm] ([shift={(-1.5,0)}]a.west) -- (a.west) node[pos=0.5,above] {\scriptsize \flowvar{Z2A}};
我尝试更改字符串,使其包含单位或不包含单位(0.5
vs. 0.5 mm
),但无济于事。我还尝试使用 tikzset 定义一个新变量并使用它(如另一个问题中所建议的那样):\tikzset{\flowwidth{A2B}/.store in=\tempwidth}
以下是我的代码示例:
\documentclass[tikz]{standalone}
\usepackage{datatool}
\usetikzlibrary{arrows,positioning}
\DTLsetseparator{, }
\usepackage{filecontents}
\begin{filecontents*}{flow.txt}
Z2A, 2$\pm$0, 0.5
A2B, 110$\pm$6, 2.5
\end{filecontents*}
\begin{document}
% For importing data
\DTLloaddb[noheader, keys={thekey,thevalue,thewidth}]{myflows}{flow.txt}
\newcommand{\flowvar}[1]{\DTLfetch{myflows}{thekey}{#1}{thevalue}}
\newcommand{\flowwidth}[1]{\DTLfetch{myflows}{thekey}{#1}{thewidth}}
\begin{tikzpicture}[BOX/.style={rectangle, draw, text centered},
ARROW/.style ={draw,-latex', line width = 0.5mm}]
% BOXES
\node [BOX] (a) {A};
\node [BOX, below= of a] (b) {B};
% ARROWS
\path [ARROW] ([shift={(-1.5,0)}]a.west) -- (a.west) node[pos=0.5,above] {\scriptsize \flowvar{Z2A}};
\path [ARROW, line width = 2 mm] (a.south) -- (b.north) node[pos=0.5,left] {\scriptsize \flowvar{A2B}};
\end{tikzpicture}
\end{document}
结果如下:
我怀疑问题在于我不知道如何处理 LaTeX/TikZ 中的变量。有人对如何使用导入的数据作为图形参数有什么建议吗?
非常感谢您的阅读!
答案1
而不是datatool
,我使用readarray
将文件数据放入\def
然后使用listofitems
(由加载readarray
)来消化\def
并进行适当的分配。
\documentclass[tikz]{standalone}
\usetikzlibrary{arrows,positioning}
\usepackage{filecontents}
\begin{filecontents*}{flow.txt}
Z2A, 2$\pm$0, 0.5 mm
A2B, 110$\pm$6, 2.0 mm
\end{filecontents*}
% USE readarray TO GET THE DATA INTO A \def
\usepackage{readarray}
\readarraysepchar{;}
\readdef{flow.txt}\myflowdef
% USE listofitems TO DIGEST THE \def APPROPRIATELY
\setsepchar{;/,}
\ignoreemptyitems
\readlist*\myflowdata{\myflowdef}
\foreachitem\i\in\myflowdata[]{%
\expandafter\edef\csname\myflowdata[\icnt,1]var\endcsname{\myflowdata[\icnt,2]}%
\expandafter\edef\csname\myflowdata[\icnt,1]width\endcsname{\myflowdata[\icnt,3]}%
}
% For importing data
\newcommand{\flowvar}[1]{\csname#1var\endcsname}
\newcommand{\flowwidth}[1]{\csname#1width\endcsname}
\begin{document}
\begin{tikzpicture}[BOX/.style={rectangle, draw, text centered},
ARROW/.style ={draw,-latex', line width = 0.5mm}]
% BOXES
\node [BOX] (a) {A};
\node [BOX, below= of a] (b) {B};
% ARROWS
\path [ARROW, line width=\flowwidth{Z2A}] ([shift={(-1.5,0)}]a.west) -- (a.west) node[pos=0.5,above] {\scriptsize \flowvar{Z2A}};
\path [ARROW, line width=\flowwidth{A2B}] (a.south) -- (b.north) node[pos=0.5,left] {\scriptsize \flowvar{A2B}};
\end{tikzpicture}
\end{document}