Как создать такую блок-схему в латексе? Пока что мне не удалось добиться ничего близкого к этому. Мой код следующий.
\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
, с помощью a matrix
для размещения узлов, с помощью tiklzlibrary positioning
и т. д.
Если вы новичок, я предлагаю делать это более предметно, с высокой степенью контроля. Итак, в основном следующее:
- расположить узлы разумным образом
- рисует необходимые соединения
Я задокументировал соответствующие шаги в комментариях, сосредоточившись на интересной части в середине. Япредлагатьпопробовать повторить их с нуля в учебных целях и посмотреть, как код развивается от простого к изысканному. Япредлагатьчтобы параллельно искать эти команды в 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}