Улучшение Диаграммы Тикза
Я только что закончил свою первую диаграмму в Tikz. Выглядит так, как я хотел, но недоволен тем, как я "закодировал" это:
\begin{tikzpicture}
[node distance=14mm,
item/.style={rounded corners,rectangle,
thick,
minimum width=20mm, minimum height=10mm}]
\node[item,draw=blue!50,fill=blue!20] (stack) {1394 Stack};
\node[item,left=of stack,draw=green!50,fill=green!20,yshift=-9mm] (app1) {Application};
\node[item,left=of stack,draw=green!50,fill=green!20,yshift=9mm] (app2) {Application};
\node[item,right=of stack,draw=orange!50,fill=orange!20] (ohci) {OHCI};
\node[item,right=of ohci,yshift=-15mm,draw=yellow!70,fill=yellow!35] (dev1) {Device};
\node[item,right=of ohci,yshift=0mm,draw=yellow!70,fill=yellow!35] (dev2) {Device};
\node[item,right=of ohci,yshift=15mm,draw=yellow!70,fill=yellow!35] (dev3) {Device};
\draw[thick] (app1) -- (stack)
(app2) -- (stack)
(stack) -- (ohci)
(ohci) -- (dev1)
(ohci) -- (dev2)
(ohci) -- (dev3);
\node[xshift=7mm,yshift=1mm] (topUser) at (app1.east |- dev3.north) {};
\node[xshift=7mm,yshift=-1mm,label=above left:User space] (botUser) at (app1.east |- dev1.south) {};
\draw[dashed] (topUser) -- (botUser);
\node[xshift=7mm,yshift=1mm] (topKern) at (stack.east |- dev3.north) {};
\node[xshift=7mm,yshift=-1mm,label=above left:Kernel space,
label=above right:Hardware\phantom{p}] (botKern) at (stack.east |- dev1.south) {};
\draw[dashed] (topKern) -- (botKern);
\end{tikzpicture}
Вещи, которые мне неудобны:
Как я вручную переместил узлы "Приложение" и "Устройство", используя yshift
разнести их друг от друга; Я уверен, что должен быть более элегантный способ создания простой древовидной структуры.
Линии (topKern -- botKern
а также topUser -- botUser
) переход от верхней части рисунка к нижней; они вручную выровнены по оси X, чтобы быть между двумя узлами, используя xshift=7mm
,
Мое использование \phantom{p}
чтобы метка "Аппаратное обеспечение" имела ту же базовую линию, что и две другие метки.
1 ответ
Чтобы построить древовидную структуру, проконсультируйтесь pgfmanual.pdf
, Заставляя деревья расти.
Для линий я бы создал узлы, представляющие середину двух узлов, а затем использовал бы перпендикулярную систему координат, как вы это сделали. Также вы можете использовать current bounding box
определить "границу".
Чтобы правильно выровнять базовые линии, укажите text height
а также text depth
, В вашем случае, например, в стиле every label
, Но, как вы видите, я сделал метки как узлы ниже...
\ begin {tikzpicture} [расстояние до уровня =35 мм, расстояние до узла =15 мм, высота текста = 1,5ex, глубина текста =0,25ex] \ begin {scope} [каждый узел /.style={закругленные углы, прямоугольник, толстый, минимальная ширина =20 мм, минимальная высота =10 мм}] \begin{scope}[level 1/.style={Расстояние между братьями и сестрами =19 мм, узлы ={fill=green!20,draw=green!50}}] \node[draw=blue!50,fill=blue!20] (stack) {1394 Stack} [grow=left] child {node (app2) {Application}} child {node (app1) {Application}}; \ Конец {} сфера \ begin {scope} [level 1 /.style={Расстояние между братьями и сестрами =15 мм, узлы ={fill=yellow!70,draw=yellow!35}}] \node[right= of stack,draw=orange!50,fill=orange!20] (ohci) {OHCI} [grow=right] child {node {Device}} child {node {Device}} child {node {Device}}; \ Конец {} сфера \ Конец {} сфера \ node [ниже =0 мм от app1] (пространство пользователя) {пространство пользователя}; \ node at (userspace - | stack) (kernel) {Kernel}; \ node at (userspace - | ohci) (hardware) {Hardware}; \ path (app1) - (стек) узел [координата, на полпути] (между 1) {}; \draw (ohci) - (стек) узел [координата, на полпути] (между 2) {}; \ draw [dashed] (текущий ограничивающий box.north -| Между1) - (текущий ограничивающий box.south -| Между1); \draw[dashed] (текущий ограничивающий box.north -| между2) - (текущий ограничивающий box.south -| между2); \ Конец {tikzpicture}