Melhorando um diagrama de tikz
Pergunta
Acabei de terminar meu primeiro diagrama em Tikz. Parece que eu queria, mas estou descontente com como eu "codificei":
\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}
As coisas com as quais me sinto desconfortável são:
Como movi manualmente os nós "aplicativos" e "dispositivo" usando yshift
para espaçá -los além um do outro; Estou certo de que deve haver uma maneira mais elegante de produzir uma estrutura simples em forma de árvore
As linhas (topKern -- botKern
e topUser -- botUser
) indo do topo da imagem para o fundo; estes estão alinhados manualmente no eixo x estar entre dois nós usando xshift=7mm
.
Meu uso de \phantom{p}
Para garantir que o rótulo "hardware" tenha a mesma linha de base que os outros dois rótulos.
Solução
Para construir uma estrutura de árvore, consulte pgfmanual.pdf
, Fazendo as árvores crescerem.
Para as linhas, eu criaria nós representando no meio de dois nós e, em seguida, usaria o sistema de coordenadas perpendiculares como você fez. Também você pode usar current bounding box
para identificar a "borda".
Para alinhar as linhas de base corretamente, especifique text height
e text depth
. No seu caso, por exemplo no estilo every label
. Mas, como você vê, eu fiz os rótulos como nós abaixo ...
\begin{tikzpicture}[level distance=35mm,node distance=15mm,text height=1.5ex,text depth=0.25ex] \begin{scope}[every node/.style={rounded corners,rectangle,thick,minimum width=20mm, minimum height=10mm}] \begin{scope}[level 1/.style={sibling distance=19mm,nodes={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}}; \end{scope} \begin{scope}[level 1/.style={sibling distance=15mm,nodes={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}}; \end{scope} \end{scope} \node[below=0mm of app1] (userspace) {User space}; \node at (userspace -| stack) (kernel) {Kernel}; \node at (userspace -| ohci) (hardware) {Hardware}; \path (app1) -- (stack) node[coordinate,midway] (between1) {}; \draw (ohci) -- (stack) node[coordinate,midway] (between2) {}; \draw[dashed] (current bounding box.north -| between1) -- (current bounding box.south -| between1); \draw[dashed] (current bounding box.north -| between2) -- (current bounding box.south -| between2); \end{tikzpicture}