如何在 latex 中创建这样的流程图?到目前为止,我还没有实现任何接近这一点的东西。我的代码如下。
\documentclass{article}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}[node distance=2cm, auto,
level1/.style={rectangle, draw, fill=red!20, rounded corners, text width=4em, text centered, minimum height=2em},
level2/.style={rectangle, draw, fill=blue!20, rounded corners, text width=4em, text centered, minimum height=2em},
level3/.style={rectangle, draw, fill=green!20, rounded corners, text width=4em, text centered, minimum height=2em}]
% Root node
\node [level1] (root) {Root};
% Level 2 nodes
\node [level2, right of=root] (node1) {Node 1};
\node [level2, right of=node1] (node2) {Node 2};
\node [level2, right of=node2] (node3) {Node 3};
\node [level2, right of=node3] (node4) {Node 4};
\node [level2, right of=node4] (node5) {Node 5};
% Level 3 nodes
\node [level3, below of=node1, yshift=-1cm] (child1) {Child 1};
\node [level3, below of=node2, yshift=-1cm] (child2) {Child 2};
\node [level3, below of=node3, yshift=-1cm] (child3) {Child 3};
\node [level3, below of=node4, yshift=-1cm] (child4) {Child 4};
\node [level3, below of=node5, yshift=-1cm] (child5) {Child 5};
% Arrows
\foreach \from in {root}
\foreach \to in {node1, node2, node3, node4, node5}
\draw [->] (\from) -- (\to);
\foreach \from in {node1, node2, node3, node4, node5}
\foreach \to in {child1, child2, child3}
\draw [->] (\from) -- (\to);
\end{tikzpicture}
\end{document}
答案1
这是一个forest
解决方案。
\documentclass{article}
\usepackage{forest}
\useforestlibrary{edges}
\begin{document}
\begin{forest}
forked edges,
for tree={
grow'=0,
align=center,
minimum width=3cm,
anchor=center,
inner xsep=3mm,
rounded corners,
font=\small,
if level=1{fill=orange, text=white}
{if level=2{fill=brown, text=white}{draw=red}}
}
[Root node, rotate=90, fill=red, text=white
[level 1 node
[level 2 node
[Some very long reference]
]
[level 2 node
[Some very long reference\\with two lines]
]
]
[level 1 node
[level 2 node
[Another even longer reference\\with two lines]
]
[level 2 node
[Some very long reference\\with two lines]
]
[level 2 node\\has two lines
[Some reference[Another reference]]
[Some reference\\with two lines[Another reference\\with two lines]]
]
]
[level 1 node
[level 2 node
[A very very very long long long reference\\with two lines]
]
[level 2 node
[A very very very long long long reference]
]
]
[level 1 node
[level 2 node
[A very very very long long long reference]
]
[level 2 node
[A long reference]
]
]
[level 1 node
[level 2 node
[A very very very long long long reference]
]
[level 2 node
[A very very very long long long reference]
]
]
]
\end{forest}
\end{document}
答案2
有很多方法可以做到这一点,例如使用child
pgfmanual 中的方法、使用包forest
、使用matrix
放置节点、使用 tiklzlibrarypositioning
等。
如果你是初学者,我建议你更多地逐个对象地进行操作,并进行高度的控制。因此基本上如下:
- 合理放置节点
- 绘制所需的连接
我在评论中记录了相关步骤,重点放在中间有趣的部分。我建议出于训练的原因,尝试从头开始重复这些操作,并观察代码如何从简单演变为精致。我建议在 pgfmanual 中并行查找这些命令。
第一个代码显示了完成放置和连接后的结果。第二个是关于美化,即引入颜色等。
有几个参数需要调整。除了分支之外,它们都位于样式部分中。因此,那里的更改几乎总是正确的。分支的那个可以而且应该移到\newcommand
进一步重构中。
完成节点和连接
从后往前,从最右边的子节点向根节点工作。
旋转根节点比较棘手,所以我暂时保持原样。
对于连接,有两件事:
- 一个注释掉的试验,检查代码是否良好,并使用节点对(也就是它们的名称)重构为一个循环
- 对于分支也是一样,引入一个中间点作为相对坐标
% ~~~ makes development much easier ~~~~~~~~~~~~~~~~~~
\documentclass[10pt,border=3mm,tikz]{standalone}
% ~~~ PROCESS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
% care for positioning text, first
% 1) start with node at (0,0), ignoring all colors etc.
% 2) put next node above it, introduce style up
% 3) continue, introduce style and nodes for dn
% 4) introduce brown child level as nodes + style lft
% 4b) making nodes width the same, i.e. adjust style lft
% 5) introducing orange children, style lftb reuses lft
% 6) introducing ROOT and extra
% 7) adding simple and branched connections
\begin{document}
\begin{tikzpicture}[% ~~~ introducing styles as suitable
up/.style={draw,anchor=south west,yshift=2mm},
dn/.style={draw,anchor=north west,yshift=-2mm},
lft/.style={draw,anchor=east,xshift=-4mm,minimum width=2cm},
lftb/.style={lft,minimum width=32mm,yshift=-4mm},
rt/.style={draw,anchor=west,xshift=4mm},
root/.style={draw,xshift=-10mm,yshift=-9mm,
rotate=0,anchor=east},
]
% ~~~ starting backwards with "rightmost" child level ~~~
% ~~~ upwards
\node[draw] (D0) at (0,0) {Denoisung};
\node[up] (D1) at (D0.north west) {HDR};
\node[up] (D2) at (D1.north west) {Semantic NeRF};
% ~~~ downwards
\node[dn] (D-1) at (D0.south west) {GIRAFFE};
\node[dn] (D-2) at (D-1.south west){Dream Fusion};
% ~~~ brown children ~~~~~
\node[lft] (C-1) at (D-2.west) {Diffusion};
\node[lft] (C1) at (D1.west) {Semantics};
\node[lft] (C2) at (D2.west) {Editing};
% ~~~ this one is special ~~~~~~~~~
\node[lft,yshift=-4mm] (C0) at (D0.west) {Functional};
% ~~~ orange children ~~~~~~~~~~
\node[lftb] (B0) at (C0.west) {Generative Models};
\node[lftb] (B1) at (C2.west) {Image Processing};
% ~~~ ROOT ~~~~~~~~~~
\node[root] (RT) at (B1.west) {Applications};
% ~~~ extra ~~~~~~~~~
\node[rt] (X0) at (D0.east) {RawNeRF};
% ~~~ SIMPLE connections ~~~~~~~~~
% \draw (C2) -- (D2);
% \draw (C1) -- (D1);
% now refactored, i.e. as loop
\foreach \a/\b in {C2/D2, C1/D1, D0/X0, C-1/D-2}
\draw (\a) -- (\b);
% ~~~ branched connections ~~~~~~~~
% \draw (C0.east) -- +(.2,0) |- (D0.west);
% \draw (C0.east) -- +(.2,0) |- (D-1.west);
% now refactored, i.e. as loop
\foreach \a/\b in {C0/D0, C0/D-1,
B1/C2, B1/C1, B0/C0, B0/C-1,
RT/B1, RT/B0}
\draw (\a.east) -- +(.2,0) |- (\b.west);
\end{tikzpicture}
\end{document}
美化
现在这几乎很无聊:
- 定义不同级别的样式
- 将上述样式添加到相关节点
当您向图表中添加更多试验时,删除试验可能是一个好主意。为此,只需遵循以下模式:
- 新节点,现在具有正确的样式组合和新节点名称
\draw
为两个循环添加所需的连接- 采取小步骤,尽早发现并解决问题
我建议重新考虑一下,引入多行文本是否是个好主意。虽然这是可能的,但你很可能必须重新调整几种样式,甚至可能改变一些方法。通常:少即是多 - 多或少...
% ~~~ makes development much easier ~~~~~~~~~~~~~~~~~~
\documentclass[10pt,border=3mm,tikz]{standalone}
% ~~~ PROCESS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
% now let's take care of colors and shapes
% 8) define styles nd etc. AND add to the relevant nodes
\begin{document}
\begin{tikzpicture}[% ~~~ introducing styles as suitable
up/.style={draw,anchor=south west,yshift=2mm},
dn/.style={draw,anchor=north west,yshift=-2mm},
lft/.style={draw,anchor=east,xshift=-4mm,
minimum width=2cm},
lftb/.style={lft,minimum width=32mm,yshift=-4mm},
rt/.style={draw,anchor=west,xshift=4mm},
root/.style={draw,xshift=-10mm,yshift=-9mm,
rotate=0,anchor=east},
% ~~~ now the colors etc. ~~~~~~~~~~
nd/.style={draw=red,rounded corners},
nc/.style={draw=none,rounded corners,fill=brown!30},
nb/.style={draw=none,rounded corners,fill=orange!30},
nr/.style={draw=none,rounded corners,fill=red,
text=white,},% not recommended !
]
% ~~~ starting backwards with "rightmost" child level ~~~
% ~~~ upwards
\node[draw,nd] (D0) at (0,0) {Denoisung};
\node[up,nd] (D1) at (D0.north west) {HDR};
\node[up,nd] (D2) at (D1.north west) {Semantic NeRF};
% ~~~ downwards
\node[dn,nd] (D-1) at (D0.south west) {GIRAFFE};
\node[dn,nd] (D-2) at (D-1.south west){Dream Fusion};
% ~~~ brown children ~~~~~
\node[lft,nc] (C-1) at (D-2.west) {Diffusion};
\node[lft,nc] (C1) at (D1.west) {Semantics};
\node[lft,nc] (C2) at (D2.west) {Editing};
% ~~~ this one is special ~~~~~~~~~
\node[lft,yshift=-4mm,nc] (C0) at (D0.west) {Functional};
% ~~~ orange children ~~~~~~~~~~
\node[lftb,nb] (B0) at (C0.west) {Generative Models};
\node[lftb,nb] (B1) at (C2.west) {Image Processing};
% ~~~ ROOT ~~~~~~~~~~
\node[root,nr] (RT) at (B1.west) {Applications};
% ~~~ extra ~~~~~~~~~
\node[rt,nd] (X0) at (D0.east) {RawNeRF};
% ~~~ SIMPLE connections ~~~~~~~~~
% \draw (C2) -- (D2);
% \draw (C1) -- (D1);
% now refactored, i.e. as loop
\foreach \a/\b in {C2/D2, C1/D1, D0/X0, C-1/D-2}
\draw (\a) -- (\b);
% ~~~ branched connections ~~~~~~~~
% \draw (C0.east) -- +(.2,0) |- (D0.west);
% \draw (C0.east) -- +(.2,0) |- (D-1.west);
% now refactored, i.e. as loop
\foreach \a/\b in {C0/D0, C0/D-1,
B1/C2, B1/C1, B0/C0, B0/C-1,
RT/B1, RT/B0}
\draw (\a.east) -- +(.2,0) |- (\b.west);
\end{tikzpicture}
\end{document}