Ajustar el nivel del nodo usando el nodo fantasma

Ajustar el nivel del nodo usando el nodo fantasma

Considere el MWE:

\documentclass[landscape]{article}

\usepackage{tikz}
\usetikzlibrary{shapes,arrows}
\begin{document}

\tikzset{
  treenode/.style = {align=center, inner sep=2pt, rounded corners = 2pt, minimum width = 2cm, text centered, font=\sffamily},
  block/.style = {treenode, rectangle, white, font=\sffamily\bfseries, draw=black, fill=black},
  phantom/.style = {}
}

\begin{tikzpicture}[->,>=stealth',level/.style={sibling distance = 3in/#1, level distance = 1.5cm}] 
  \node [block] {P1}
    child {node [block] {P2}
      child {node [block] {P3}
        child {node [block] {P4}}
        child {node [block] {P5}}
      }
    }
    child {node [block] {P6}
      child {node [phantom] {}
        child {node [block] {P7}}
      }
    }
    child {node [block] {P8}
      child {node [block] {P9}
        child {node [block] {P10}}
      }
    }
  ;
\end{tikzpicture}

\end{document}

Estoy usando el nodo fantasma para colocar P7 al mismo nivel que P4, P5 y P10.

Pero en lugar del nodo fantasma, obtengo un espacio en blanco, el conector de P6 termina allí y un nuevo conector comienza desde ese espacio en blanco hasta P7.

¿Cómo obtengo un conector recto de P6 a P7? En general, ¿cómo ajustamos el "nivel" de varios nodos?

Respuesta1

Este es un caso en el que el poder delforestpuede ser útil; la tierclave le permite obtener la alineación deseada sin esfuerzo (observe también el código más corto):

\documentclass{article}
\usepackage{forest}

\tikzset{
treenode/.style={
  align=center, 
  inner sep=2pt, 
  rounded corners=2pt,
  minimum width = 2cm,
  font=\sffamily
  },
block/.style={
  treenode, 
  rectangle, 
  white, 
  font=\sffamily\bfseries, 
  draw=black, 
  fill=black
  },
  phantom/.style = {}
}

\begin{document}


\begin{forest}
for tree={
  block,
  edge={->,>=latex},
  where level={0}{s sep=1.5cm}{}
}
[P1
  [P2
    [P3
      [P4]
      [P5,tier=last]
    ]
  ]
  [P6,before computing xy={s=(s("!p")+s("!n"))}
    [P7,tier=last]
  ]
  [P8
    [P9]
    [P10,tier=last]
  ]
]
\end{forest}

\end{document}

ingrese la descripción de la imagen aquí

El código puede ser incluso más corto ya que el esquema de etiquetado actual para los nodos también se puede dejar en manos del paquete.

Respuesta2

Ésta es una posible solución. Para eliminar el uso de espacio coordinateen lugar de node, aquí edge from parent/.style={draw=none}se usa para no dibujar la línea de P6 a P7, luego dibuje la línea (P6)--(P7) manualmente.

ingrese la descripción de la imagen aquí

Código

\documentclass[border=1cm]{standalone}
%\documentclass[landscape]{article}

\usepackage{tikz}
\usetikzlibrary{shapes,arrows}
\begin{document}

\tikzset{
  treenode/.style = {align=center, inner sep=2pt, rounded corners = 2pt, minimum width = 2cm, text centered, font=\sffamily},
  block/.style = {treenode, rectangle, white, font=\sffamily\bfseries, draw=black, fill=black},
  phantom/.style = {},
}

\begin{tikzpicture}[->,>=stealth',
level/.style={sibling distance = 3in/#1, level distance = 1.5cm}
] 
  \node [block] {P1}
    child {node [block] {P2}
      child {node [block] {P3}
        child {node [block] {P4}}
        child {node [block] {P5}}
      }
    }
    child {node [block](a) {P6}
      child {coordinate [phantom,edge from parent/.style={draw=none}] {}
        child {node [block](b) {P7}}
      }
    }
    child {node [block] {P8}
      child {node [block] {P9}
        child {node [block] {P10}}
      }
    }
  ;
\draw[->] (a)--(b);
\end{tikzpicture}

información relacionada