Отрегулируйте уровень узла с помощью фантомного узла

Отрегулируйте уровень узла с помощью фантомного узла

Рассмотрим 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}

Я использую фантомный узел, чтобы получить P7 на том же уровне, что и P4, P5 и P10.

Но вместо фантомного узла я получаю пустое пространство, соединитель от P6 там заканчивается, а новый соединитель начинается от этого пустого пространства до P7.

Как сделать прямой коннектор от P6 до P7? Как вообще мы настраиваем «уровень» различных узлов?

решение1

Это тот случай, когда силаforestможет быть полезным; tierключ позволяет вам получить желаемое выравнивание без усилий (обратите внимание также на более короткий код):

\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}

введите описание изображения здесь

Код может быть еще короче, поскольку текущую схему маркировки узлов также можно оставить пакету.

решение2

Это возможное решение. Чтобы убрать пробел, используйте coordinateвместо node, Здесь edge from parent/.style={draw=none}используется , чтобы не рисовать линию от P6 до P7, а затем нарисовать линию (P6)--(P7) вручную.

введите описание изображения здесь

Код

\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}

Связанный контент