L'amélioration d'un diagramme Tikz
Question
Je viens de terminer mon premier schéma Tikz. Il semble que je le voulais, mais ne suis pas satisfait de la façon dont je « code » il:
\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}
Les choses que je suis mal à l'aise avec sont:
Comme je l'ai déplacé manuellement le « Application » et « Device » noeuds en utilisant yshift
pour les écarter les uns des autres; Je suis sûr qu'il doit y avoir une façon plus élégante de la production d'une simple structure arborescente
Les lignes (topKern -- botKern
et topUser -- botUser
) allant du haut de l'image vers le bas; ceux-ci sont alignées manuellement sur l'axe des x se situe entre deux noeuds en utilisant xshift=7mm
.
Mon utilisation de \phantom{p}
pour assurer l'étiquette « matériel » a la même base que les deux autres étiquettes.
La solution
Pour construire une structure arborescente, consultez pgfmanual.pdf
, Faire Les arbres poussent .
Pour les lignes, je créerais des noeuds représentant au milieu de deux nœuds, puis utilisez coordonner la perpendiculaire système que vous avez fait. Vous pouvez également utiliser current bounding box
pour identifier la « frontière ».
Pour aligner correctement les lignes de base, spécifiez text height
et text depth
. Dans votre cas, par exemple dans le style every label
. Mais comme vous le voyez, je l'ai fait les étiquettes sous forme de nœuds ci-dessous ...
\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}