更新されたソリューション (Forest バージョン 2+)

更新されたソリューション (Forest バージョン 2+)

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}

異なるノード間のコネクタは斜めの線です。これらの代わりに水平 - 垂直の線を取得するにはどうすればよいでしょうか?

答え1

もう 1 つのオプションは を使用することですforest。この場合、phantomノードを省略し、 などを使用してとtier揃えることができます。また、ライブラリによって提供される現在の矢印構文を使用するようにコードを更新しました。これが推奨されるようになったためです。ツリーを指定すると入力する回数が大幅に減るので気に入っています。P7P4P5arrows.metaforest

更新されたソリューション (Forest バージョン 2+)

\documentclass[tikz, border=5pt]{standalone}
\usepackage[edges]{forest}
\usetikzlibrary{arrows.meta}
\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},
}

% Forest version 2.1
\begin{forest}
  for tree={
    block,
    edge+={thick, -{Stealth[]}}
  },
  forked edges
  [P1
    [P2
      [P3
        [P4, tier=terminal]
        [P5]
      ]
    ]
    [P6, calign with current
      [P7, tier=terminal]
    ]
    [P8
      [P9
        [P10]
      ]
    ]
  ]
  ;
\end{forest}
\end{document}

オリジナルソリューション(フォレストバージョン1)

\documentclass[tikz, border=5pt]{standalone}
\usepackage{forest}
\usetikzlibrary{arrows.meta}
\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},
}

\begin{forest}
  for tree={
    parent anchor=south,
    child anchor=north,
    block,
    edge path={
      \noexpand\path [-{Stealth[]}, \forestoption{edge}, thick]
        (!u.parent anchor) -- +(0,-5pt) -| (.child anchor)\forestoption{edge label};
    },
  }
  [P1
    [P2
      [P3
        [P4, tier=terminal]
        [P5]
      ]
    ]
    [P6, calign with current
      [P7, tier=terminal]
    ]
    [P8
      [P9
        [P10]
      ]
    ]
  ]
  ;
\end{forest}
\end{document}

結果

基本的に、どのソリューションを使用しても、出力は同じです。

森の木

答え2

水平/垂直というのは、これのことですか?

出力

コードは次のとおりです:

\documentclass[tikz,border=10]{standalone}
\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 = {},
  edge from parent/.style={draw,red,thick},
  edge from parent path={(\tikzparentnode.south)-- ++(0,-3mm) -| (\tikzchildnode.north)}
}

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

編集:[edge from parent fork down]ライブラリのスタイルを使用しtreesて同じ効果を生み出せることを発見しました。

答え3

PSTricks のソリューション:

\documentclass{article}

\usepackage{pstricks}
\usepackage{xfp}

\psset{
  linecolor = red,
  arrows = ->
}

\def\Label(#1,#2)#3{%
  \psframe[
    framearc = 0.3,
    linecolor = black,
    fillstyle = solid,
    fillcolor = black
  ](\fpeval{#1-0.5*\widthBox},\fpeval{#2-0.5*\heightBox})%
   (\fpeval{#1+0.5*\widthBox},\fpeval{#2+0.5*\heightBox})
  \rput(#1,#2){\textcolor{white}{#3}}}

\begin{document}

% parameters
\def\widthBox{1.4}
\def\heightBox{0.4}
\def\horiDist{4.5}
\def\vertDist{1.6}

% drawing
\begin{pspicture}(\fpeval{2*\horiDist+1.75*\widthBox},\fpeval{4*\heightBox+3*\vertDist})
  % left
  \Label(\fpeval{1.25*\widthBox},\fpeval{2.5*\heightBox+2*\vertDist}){P2}
  \psline(\fpeval{1.25*\widthBox},\fpeval{2*\heightBox+2*\vertDist})%
         (\fpeval{1.25*\widthBox},\fpeval{2*\heightBox+\vertDist})
  \Label(\fpeval{1.25*\widthBox},\fpeval{1.5*\heightBox+\vertDist}){P3}
  \psline(\fpeval{1.25*\widthBox},\fpeval{\heightBox+\vertDist})%
         (\fpeval{1.25*\widthBox},\fpeval{\heightBox+0.5*\vertDist})%
         (\fpeval{0.5*\widthBox},\fpeval{\heightBox+0.5*\vertDist})%
         (\fpeval{0.5*\widthBox},\heightBox)
  \psline(\fpeval{1.25*\widthBox},\fpeval{\heightBox+0.5*\vertDist})%
         (\fpeval{2*\widthBox},\fpeval{\heightBox+0.5*\vertDist})%
         (\fpeval{2*\widthBox},\heightBox)
  \Label(\fpeval{0.5*\widthBox},\fpeval{0.5*\heightBox}){P4}
  \Label(\fpeval{2*\widthBox},\fpeval{0.5*\heightBox}){P5}
  % middle
  \Label(\fpeval{\horiDist+1.25*\widthBox},\fpeval{3.5*\heightBox+3*\vertDist}){P1}
  \psline(\fpeval{\horiDist+1.25*\widthBox},\fpeval{3*\heightBox+3*\vertDist})%
         (\fpeval{\horiDist+1.25*\widthBox},\fpeval{3*\heightBox+2*\vertDist})
  \Label(\fpeval{\horiDist+1.25*\widthBox},\fpeval{2.5*\heightBox+2*\vertDist}){P6}
  \psline(\fpeval{\horiDist+1.25*\widthBox},\fpeval{2*\heightBox+2*\vertDist})%
         (\fpeval{\horiDist+1.25*\widthBox},\heightBox)
  \Label(\fpeval{\horiDist+1.25*\widthBox},\fpeval{0.5*\heightBox}){P7}
  \psline(\fpeval{\horiDist+1.25*\widthBox},\fpeval{1.5*\heightBox+\vertDist-0.1})%
         (\fpeval{\horiDist+1.25*\widthBox},\heightBox)
  % right
  \Label(\fpeval{2*\horiDist+1.25*\widthBox},\fpeval{2.5*\heightBox+2*\vertDist}){P8}
  \psline(\fpeval{2*\horiDist+1.25*\widthBox},\fpeval{2*\heightBox+2*\vertDist})%
         (\fpeval{2*\horiDist+1.25*\widthBox},\fpeval{2*\heightBox+\vertDist})
  \Label(\fpeval{2*\horiDist+1.25*\widthBox},\fpeval{1.5*\heightBox+\vertDist}){P9}
  \psline(\fpeval{2*\horiDist+1.25*\widthBox},\fpeval{\heightBox+\vertDist})%
         (\fpeval{2*\horiDist+1.25*\widthBox},\heightBox)
  \Label(\fpeval{2*\horiDist+1.25*\widthBox},\fpeval{0.5*\heightBox}){P10}
  % connection
  \psline(\fpeval{\horiDist+1.25*\widthBox},\fpeval{3*\heightBox+2.5*\vertDist})%
         (\fpeval{1.25*\widthBox},\fpeval{3*\heightBox+2.5*\vertDist})%
         (\fpeval{1.25*\widthBox},\fpeval{3*\heightBox+2*\vertDist})
  \psline(\fpeval{\horiDist+1.25*\widthBox},\fpeval{3*\heightBox+2.5*\vertDist})%
         (\fpeval{2*\horiDist+1.25*\widthBox},\fpeval{3*\heightBox+2.5*\vertDist})%
         (\fpeval{2*\horiDist+1.25*\widthBox},\fpeval{3*\heightBox+2*\vertDist})
\end{pspicture}

\end{document}

出力

このコードでは、ボックスの幅 ( \widthBox) と高さ ( )、およびボックス間の水平距離 ( ) と垂直距離 ( )を選択するだけです。描画はそれに応じて自動的に調整されます。\heightBox\horiDist\vertDist

関連情報