Вопрос
Я только что закончил свою первую диаграмму в Тикзе. Похоже, как я хотел, но я недоволен тем, как у меня есть «закодирован»:
\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}
Чтобы гарантировать, что метка «аппаратное обеспечение» имеет ту же базовый уровень, что и две другие этикетки.
Решение
Чтобы построить структуру дерева, проконсультируйтесь pgfmanual.pdf
, Изготовление деревьев расти.
Для линий я бы создал узлы, представляющие в середине двух узлов, а затем используйте перпендикулярную систему координат, как вы сделали. Также вы можете использовать current bounding box
определить «границу».
Правильно выровнять базовые линии, укажите text height
а также text depth
. Отказ В вашем случае, например, в стиле every label
. Отказ Но, как вы видите, я сделал этикетки как узлы ниже ...
begin {Tikzpicture} [Расстояние на уровне = 35 мм, расстояние узла = 15 мм, высота текста = 1.5ex, глубина текста = 0,25EX] Начало {Scope} [каждый узел / .style = {округлые углы, прямоугольник, толстый, минимальная ширина = 20 мм, минимальная высота = 10 мм}] begin {Scope} [Уровень 1 / .style = {Расстояниею сестра = 19 мм, узлы = {Fill = Green! 20, Draw = Green! 50}}] Node ! 50, заполните = синий! 20] (стек) {1394 Stack} [расти = левый] ребенок {узел (APP2) {приложение}} Child {Node (App1) {приложение}}; end {case} begin {scope} [Уровень 1 / .style = {Расстояниею сестра = 15 мм, узлы = {fill = yellow! 70, draw = yellow! 35}}] Node [справа = стека, рисовать = Orange! 50, Fill = Orange! 20] (Ohci) {Ohci} [Расти = справа] Ребенок {Узел {Устройство}} Ребенок {Узел {Устройство}} Ребенок {узел {устройство}}; end {scope} end {scope} node [ниже = 0 мм app1] (userspace) {пространство пользователя}; Node at (userspace - | стек) (ядро) {ядро}; Node at (userspace - | Ohci) (оборудование) {оборудование}; PATH (APP1) - (стек) узла [координата, на полпути] (между1) {}; Draw (Ohci) - (стек) узла [координата, на полпути] (между2) {}; Draw [Disped] (текущая ограничивающая коробка. North - | между1) - (текущая ограничивающий box.south - | между1); Draw [disped] (текущая ограничивающая коробка. North - | между2) - (текущая ограничивающий box.south - | между2); end {tikzpicture}