我想\pics
动态生成 TikZ。设置图片所需的所有信息(名称、x 坐标、y 坐标)均在表格中给出。
有没有办法将这些信息注入 TikZ 环境并绘制它们?否则我总是必须同步 TikZ 中的图形信息和表格环境中的文本信息。
我也愿意以完全不同的格式定义这些信息,然后将其注入表格和 TikZ 环境。我只想保留单一事实来源。
\documentclass{article}%
\usepackage[a3paper,left=10mm,right=10mm,top=10mm,bottom=10mm]{geometry}%
\usepackage{courier}%
\usepackage[T1]{fontenc}%
\usepackage[parfill]{parskip}%
\usepackage[utf8]{inputenc}%
\usepackage{caption}%
\usepackage{graphicx}%
\usepackage{tikz}%
\tikzset{
PowerSupply/.pic={
\node{\includegraphics[scale=0.05,angle=270]{powerSupply.png}};},
}
\begin{document}
\section*{Electrical Installation Plan}
\subsection*{Component List}
\begin{center}
\begin{tabular}{|c|c|c|c|}
\hline
\textbf{ID} & \textbf{Description} & \textbf{X-Pos} & \textbf{Y-Pos} \\ \hline
A1F5F & PowerSupply1 & 3400 & 2000 \\ \hline %Input 1
7ZF3I & PowerSupply2 & 3400 & 2500 \\ \hline %Input 2
\hline
\end{tabular}
\end{center}
\pagenumbering{gobble}
\begin{figure}[h!]
\centering
\scalebox{2.0}{
\begin{tikzpicture}[x=0.01mm, y=-0.01mm]
\node[inner sep=0pt] (ground_floor) {\includegraphics[width=99.0mm,height=107.4mm]{groundFloor.png}};
\tikzset{shift=(ground_floor.north west)}
\draw[blue, ->, line width=1pt] (0,0) -- (10000,0);
\draw[blue, line width=1pt] (10000,0) --node[scale=0.5,black,above=1mm,align=center]{[mm]}(10000,0);
\foreach \x in {0,1000,...,9000} \draw[blue, line width=1pt] (\x,-100) --node[scale=0.5,black,above=1mm,align=center]{\x} (\x,100);
\draw[blue, ->, line width=1pt] (0,0) -- (0,11000);
\draw[blue, line width=1pt] (0,11000) --node[scale=0.5,black,left=1mm,align=center]{[mm]}(0,11000);
\foreach \y in {0,1000,...,10000} \draw[blue, line width=1pt] (-100,\y) --node[scale=0.5,black,left=1mm,align=center]{\y} (100,\y);
\pic at (3450,2000) {PowerSupply}; %This must be generated automatically from line 2 (ID: A1F5F)
\pic at (3450,2500) {PowerSupply}; %This must be generated automatically from line 3 (ID: 7ZF3I)
\end{tikzpicture}}
\caption{Ground Floor}
\end{figure}
\vfill
\clearpage
\end{document}
示例图像
答案1
您可以使用pgfplotstable
pgfplots
包(在后台加载tikz
)并读取 CSV 文件,然后您可以处理它并使用它来放置\pics
或执行任何您想做的事情。我可能会添加一个用于旋转的列,这样您\pic
也可以将其放置在其他地方。
对于以下 MWE,我还包括了我对你另一个问题的回答:
\documentclass{article}
\usepackage[a4paper, margin=10mm]{geometry}
\usepackage{pgfplotstable}
\pgfplotsset{compat=newest}
\begin{filecontents}{data.csv}
id, name, x-coord, y-coord, rotation
A1F5F, PowerSupply1, 3590, 2000, 270
7ZF3I, PowerSupply2, 3590, 2500, 270
O7PYQ, PowerSupply3, 4250, 6070, 180
\end{filecontents}
\pgfplotstableread[col sep=comma]{data.csv}{\csvdata}
\pgfplotstablegetrowsof{\csvdata}
\pgfmathtruncatemacro\CSVDataRows{\pgfplotsretval-1}
\tikzset{
PowerSupply/.pic={
\node[anchor=north, inner sep=0pt]
{\includegraphics[scale=0.09]{powerSupply}};
},
}
\begin{document}
\pagenumbering{gobble}
\section*{Electrical Installation Plan}
\subsection*{Component List}
\begin{center}
\pgfplotstabletypeset[
col sep=comma,
columns={id, name, x-coord, y-coord},
columns/id/.style={
column name=ID,
string type
},
columns/name/.style={
column name=Description,
string type
},
columns/x-coord/.style={
column name=X-Pos
},
columns/y-coord/.style={
column name=Y-Pos,
column type/.add={}{|}
},
column type/.add={|}{},
after row={\hline},
every head row/.style={before row=\hline},
]{data.csv}
\end{center}
\begin{figure}[h!]
\centering
\begin{tikzpicture}[x=0.01mm, y=-0.01mm]
\node[inner sep=0pt] (ground_floor)
{\includegraphics[width=99.0mm, height=107.4mm]{groundFloor}};
\begin{scope}[shift=(ground_floor.north west)]
\draw[blue, ->, line width=1pt] (0,0) -- (10000,0);
\draw[blue, ->, line width=1pt] (0,0) -- (0,11000);
\foreach \x in {0,1000,...,9000} {
\draw[blue, line width=1pt] (\x,-100) --
node[black, above=1mm] {\tiny\x mm} (\x,100);
}
\foreach \y in {0,1000,...,10000} {
\draw[blue, line width=1pt] (-100,\y) --
node[black, left=1mm]{\tiny\y mm} (100,\y);
}
\foreach \row in {0,...,\CSVDataRows} {
\pgfplotstablegetelem{\row}{x-coord}\of{\csvdata}
\pgfmathsetmacro{\x}{\pgfplotsretval}
\pgfplotstablegetelem{\row}{y-coord}\of{\csvdata}
\pgfmathsetmacro{\y}{\pgfplotsretval}
\pgfplotstablegetelem{\row}{rotation}\of{\csvdata}
\pgfmathsetmacro{\r}{\pgfplotsretval}
\pic[rotate=\r, transform shape] at (\x,\y) {PowerSupply};
}
\end{scope}
\end{tikzpicture}
\caption{Ground Floor}
\end{figure}
\vfill
\clearpage
\end{document}
扩展以将标签添加到节点。由于您想使用节点来包含图像,因此您需要将其添加transform shape
到\pic
,但这也会旋转附加到节点的标签。如果您希望标签不旋转,则需要取消旋转。
我扩展了\pic
代码,以便\pic
现在可以接受参数。这些参数可用于添加标签并将此标签定位到父节点。
\documentclass{article}
\usepackage[a4paper, margin=10mm]{geometry}
\usepackage{pgfplotstable}
\pgfplotsset{compat=newest}
\begin{filecontents}{data.csv}
id, name, x-coord, y-coord, rotation
A1F5F, PowerSupply1, 3590, 2000, 270
7ZF3I, PowerSupply2, 3590, 2500, 270
O7PYQ, PowerSupply3, 4250, 6070, 180
\end{filecontents}
\pgfplotstableread[col sep=comma]{data.csv}{\csvdata}
\pgfplotstablegetrowsof{\csvdata}
\pgfmathtruncatemacro\CSVDataRows{\pgfplotsretval-1}
\tikzset{
pics/PowerSupply/.style={
code={
\tikzset{PowerSupply/.cd, #1}
\node[anchor=north, inner sep=0pt] (-p)
{\includegraphics[scale=0.09]{powerSupply}};
\node[
inner sep=0pt,
anchor={90+\pgfkeysvalueof{/tikz/PowerSupply/label position}},
rotate={-1*\pgfkeysvalueof{/tikz/PowerSupply/label position}}
] at (-p.south) {\tiny \pgfkeysvalueof{/tikz/PowerSupply/label}};
}
},
PowerSupply/label/.initial={},
PowerSupply/label position/.initial={0}
}
\begin{document}
\pagenumbering{gobble}
\section*{Electrical Installation Plan}
\subsection*{Component List}
\begin{center}
\pgfplotstabletypeset[
col sep=comma,
columns={id, name, x-coord, y-coord},
columns/id/.style={
column name=ID,
string type
},
columns/name/.style={
column name=Description,
string type
},
columns/x-coord/.style={
column name=X-Pos
},
columns/y-coord/.style={
column name=Y-Pos,
column type/.add={}{|}
},
column type/.add={|}{},
after row={\hline},
every head row/.style={before row=\hline},
]{data.csv}
\end{center}
\begin{figure}[h!]
\centering
\begin{tikzpicture}[x=0.01mm, y=-0.01mm]
\node[inner sep=0pt] (ground_floor)
{\includegraphics[width=99.0mm, height=107.4mm]{groundFloor}};
\begin{scope}[shift=(ground_floor.north west)]
\draw[blue, ->, line width=1pt] (0,0) -- (10000,0);
\draw[blue, ->, line width=1pt] (0,0) -- (0,11000);
\foreach \x in {0,1000,...,9000} {
\draw[blue, line width=1pt] (\x,-100) --
node[black, above=1mm] {\tiny\x mm} (\x,100);
}
\foreach \y in {0,1000,...,10000} {
\draw[blue, line width=1pt] (-100,\y) --
node[black, left=1mm]{\tiny\y mm} (100,\y);
}
\foreach \row in {0,...,\CSVDataRows} {
\pgfplotstablegetelem{\row}{x-coord}\of{\csvdata}
\pgfmathsetmacro{\x}{\pgfplotsretval}
\pgfplotstablegetelem{\row}{y-coord}\of{\csvdata}
\pgfmathsetmacro{\y}{\pgfplotsretval}
\pgfplotstablegetelem{\row}{rotation}\of{\csvdata}
\pgfmathsetmacro{\r}{\pgfplotsretval}
\pgfplotstablegetelem{\row}{id}\of{\csvdata}
\pgfmathsetmacro{\i}{"\pgfplotsretval"}
\pic[rotate=\r, transform shape] at (\x,\y) {
PowerSupply={
label={\i},
label position={\r}
}
};
}
\end{scope}
\end{tikzpicture}
\caption{Ground Floor}
\end{figure}
\vfill
\clearpage
\end{document}
您还可以重命名为\pic
,例如,ElectricComponent
并在列表中为组件类型添加另一列。然后您可以使用相同的方式\pic
放置不同的图片:
\documentclass{article}
\usepackage[a4paper, margin=10mm]{geometry}
\usepackage{pgfplotstable}
\pgfplotsset{compat=newest}
\begin{filecontents}{data.csv}
id, name, type, x-coord, y-coord, rotation
A1F5F, PowerSupply1, PowerSupply, 3590, 2000, 270
7ZF3I, PowerSupply2, PowerSupply, 3590, 2500, 270
O7PYQ, PowerSupply3, PowerSupply, 4250, 6070, 180
A7HAZ, Switch1, singleSwitch, 5700, 6070, 180
\end{filecontents}
\pgfplotstableread[col sep=comma]{data.csv}{\csvdata}
\pgfplotstablegetrowsof{\csvdata}
\pgfmathtruncatemacro\CSVDataRows{\pgfplotsretval-1}
\tikzset{
pics/ElectricComponent/.style={
code={
\tikzset{ElectricComponent/.cd, #1}
\node[anchor=north, inner sep=0pt] (-p)
{\includegraphics[scale=0.09]{\pgfkeysvalueof{/tikz/ElectricComponent/type}}};
\node[
inner sep=0pt,
anchor={90+\pgfkeysvalueof{/tikz/ElectricComponent/label position}},
rotate={-1*\pgfkeysvalueof{/tikz/ElectricComponent/label position}}
] at (-p.south) {\tiny \pgfkeysvalueof{/tikz/ElectricComponent/label}};
}
},
ElectricComponent/type/.initial={PowerSupply},
ElectricComponent/label/.initial={},
ElectricComponent/label position/.initial={0}
}
\begin{document}
\pagenumbering{gobble}
\section*{Electrical Installation Plan}
\subsection*{Component List}
\begin{center}
\pgfplotstabletypeset[
col sep=comma,
columns={id, name, x-coord, y-coord},
columns/id/.style={
column name=ID,
string type
},
columns/name/.style={
column name=Description,
string type
},
columns/x-coord/.style={
column name=X-Pos
},
columns/y-coord/.style={
column name=Y-Pos,
column type/.add={}{|}
},
column type/.add={|}{},
after row={\hline},
every head row/.style={before row=\hline},
]{data.csv}
\end{center}
\begin{figure}[h!]
\centering
\begin{tikzpicture}[x=0.01mm, y=-0.01mm]
\node[inner sep=0pt] (ground_floor)
{\includegraphics[width=99.0mm, height=107.4mm]{groundFloor}};
\begin{scope}[shift=(ground_floor.north west)]
\draw[blue, ->, line width=1pt] (0,0) -- (10000,0);
\draw[blue, ->, line width=1pt] (0,0) -- (0,11000);
\foreach \x in {0,1000,...,9000} {
\draw[blue, line width=1pt] (\x,-100) --
node[black, above=1mm] {\tiny\x mm} (\x,100);
}
\foreach \y in {0,1000,...,10000} {
\draw[blue, line width=1pt] (-100,\y) --
node[black, left=1mm]{\tiny\y mm} (100,\y);
}
\foreach \row in {0,...,\CSVDataRows} {
\pgfplotstablegetelem{\row}{x-coord}\of{\csvdata}
\pgfmathsetmacro{\x}{\pgfplotsretval}
\pgfplotstablegetelem{\row}{y-coord}\of{\csvdata}
\pgfmathsetmacro{\y}{\pgfplotsretval}
\pgfplotstablegetelem{\row}{rotation}\of{\csvdata}
\pgfmathsetmacro{\r}{\pgfplotsretval}
\pgfplotstablegetelem{\row}{type}\of{\csvdata}
\pgfmathsetmacro{\t}{"\pgfplotsretval"}
\pgfplotstablegetelem{\row}{id}\of{\csvdata}
\pgfmathsetmacro{\i}{"\pgfplotsretval"}
\pic[rotate=\r, transform shape] at (\x,\y) {
ElectricComponent={
type={\t},
label={\i},
label position={\r}
}
};
}
\end{scope}
\end{tikzpicture}
\caption{Ground Floor}
\end{figure}
\vfill
\clearpage
\end{document}
无需任何 Ti钾Z魔法:
\documentclass{article}
\usepackage[a4paper, margin=10mm]{geometry}
\usepackage{pgfplotstable}
\pgfplotsset{compat=newest}
\begin{filecontents}{data.csv}
id, name, type, x-coord, y-coord, rotation
A1F5F, PowerSupply1, powerSupply, 3590, 2000, 270
7ZF3I, PowerSupply2, powerSupply, 3590, 2500, 270
O7PYQ, PowerSupply3, powerSupply, 4250, 6070, 180
A7HAZ, Switch1, singleSwitch, 5700, 6070, 180
\end{filecontents}
\pgfplotstableread[col sep=comma]{data.csv}{\csvdata}
\begin{document}
\pagenumbering{gobble}
\begin{center}
\pgfplotstabletypeset[
col sep=comma,
columns={id, name, type, x-coord, y-coord},
columns/id/.style={
column name=ID,
string type
},
columns/name/.style={
column name=Description,
string type
},
columns/type/.style={
column name=Type,
assign cell content/.code={
\pgfkeyssetvalue{/pgfplots/table/@cell content}{
\includegraphics[scale=0.09]{##1}
}
}
},
columns/x-coord/.style={
column name=X-Pos
},
columns/y-coord/.style={
column name=Y-Pos,
column type/.add={}{|}
},
column type/.add={|}{},
after row={\hline},
every head row/.style={before row=\hline},
]{data.csv}
\end{center}
\end{document}
答案2
如果我们使用 OpTeX,则不需要使用 TikZ,因为有\puttext
宏。powerSupply.png
图像被保存到,\pwbox
并且此框在循环中被复制(并旋转)\fornum
。
\newcount\pwtotal
\def\d #1, #2, #3, #4, #5 {\advance\pwtotal by1
\sxdef{\pws:id}{#1}\sxdef{\pws:d}{#2}\sxdef{\pws:x}{#3}\sxdef{\pws:y}{#4}\sxdef{\pws:r}{#5}%
}
\def\pws{pws:\the\pwtotal}
\def\putpw#1{\pdfsave\pdfrotate{#1}\copy\pwbox\pdfrestore}
\newdimen\pwunit \pwunit=.01mm
%% Save power supply image:
\newbox\pwbox
\setbox\pwbox=\hbox to0pt{\hss \picw=5mm \vbox to0pt{\inspic{powerSupply.png}\vss}\hss}
%% Save data:
\d A1F5F, PowerSupply1, 3590, 2000, 270
\d 7ZF3I, PowerSupply2, 3590, 2500, 270
\d O7PYQ, PowerSupply3, 4250, 6070, 180
%% Print table:
\noindent\hfil\table{|c|c|c|c|}{\crl
\bf Id & \bf Description & \bf X-Pos & \bf Y-pos \crl
\fornum 1..\pwtotal \do{\cs{pws:#1:id}&\cs{pws:#1:d}&\cs{pws:#1:x}&\cs{pws:#1:y}\crl}
}
\bigskip
%% Draw final image:
\noindent\hfil\vbox{
\picwidth=99mm \picheight=107.4mm
\vbox to0pt{\inspic{groundFloor.png}\vss} % load background image
\fornum 1..\pwtotal \do{
\puttext \cs{pws:#1:x}\pwunit -\cs{pws:#1:y}\pwunit {\putpw{\cs{pws:#1:r}}}
}
\kern \picheight
}
\bye