このようなフローチャートを 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 の -approach を使用する、パッケージ を使用するforest
、matrix
ノードを配置するために を使用する、tiklzlibrary を使用するpositioning
などです。
初心者の場合は、オブジェクトごとに細かく制御しながら作業することをお勧めします。基本的には次のようになります。
- ノードを適切な方法で配置する
- 必要な接続を描画する
私はコメントに関連手順を記載し、真ん中の興味深い部分に焦点を当てました。提案するトレーニングのためにこれを最初から繰り返してみて、コードが単純なものから洗練されたものへとどのように進化していくかを確認したいと思います。提案するpgfmanual でこれらのコマンドを並行して検索します。
最初のコードは、配置と接続が完了した後の結果を示しています。2 番目は、色などを導入して美化するためのものです。
調整用のパラメータがいくつかあります。ブランチ以外はすべてスタイル セクションにローカライズされています。そのため、ここでの変更はほぼ常に正しく行われます。ブランチのパラメータは、\newcommand
さらにリファクタリングするために に移動できますし、移動する必要があります。
ノードと接続の取得
後ろ向きに始めて、右端の子からルートまで作業します。
ルートノードを回転するのは難しいので、今のところはそのままにしておきます。
接続については、次の 2 つがあります。
- アウトコメントされたトライアル、適切なコードをチェックし、ノードのペア(名前)を使用してループにリファクタリングする
- 枝についても同様で、1つの中間点を相対座標として導入する
% ~~~ 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}