2
\documentclass[png,tikz,border=10pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{trees,decorations,shadows}

% style definitions
\tikzset{level 1/.style={sibling angle=90,level distance=25mm}}

\begin{document}

\begin{tikzpicture}
[grow cyclic,cap=round]
\node[shape=circle, draw, minimum size=12pt] {\large PL} 
 child {node[shape=circle, draw, minimum size=8pt] {}
    [level distance=1cm]
    child {node {Textual}}
    child {node {Visual}}
}
 child {node[shape=circle, draw, minimum size=8pt] {}
    [level distance=1cm]
    child {node {General-purpose}}
    child {node {Special-purpose}}
}
 child {node[shape=circle, draw, minimum size=8pt] {}}
 child {node[shape=circle, draw, minimum size=8pt] {}}
;
\end{tikzpicture}

\end{document}

enter image description here

As you can see, although I specify level distance=1cm. It measures from the center, so "Special-purpose" is too close to its parent. The edge lengths of "Textual" and "Visual" are also different.

Can I measure level distance from edges so that the edge length is 1cm regardless of the length of the text?

This problem is in a way similar to Set node distance between borders in tikz but that post is not building trees.

Gqqnbig
  • 564

2 Answers2

3

An alternative is to use chains, which by default measures distance between node borders. The scopes library makes the code cleaner when you have a lot of branches.

enter image description here

\documentclass{article}

\usepackage{tikz} \usetikzlibrary{chains, scopes}

\begin{document}

\begin{tikzpicture}[start chain, every on chain/.style=join, node distance=10mm and 10mm] \node [on chain, draw, circle] {PL}; {[start branch=1 going above right] \node [on chain, draw, circle] {}; } {[start branch=2 going above left] \node [on chain, draw, circle] {}; } {[start branch=3 going below left] \node [on chain, draw, circle] {}; {[start branch=31 going left] \node [on chain] {Textual}; } {[start branch=32 going below] \node [on chain] {Visual}; } } {[start branch=4 going below right] \node [on chain, draw, circle] {}; {[start branch=41 going right] \node [on chain] {Special purpose}; } {[start branch=42 going below] \node [on chain] {General purpose}; } } \end{tikzpicture}

\end{document}

Sandy G
  • 42,558
2

This is because the coorinatate used for positioning the nodes sits at the center of each node. You can change that using anchor:

\documentclass[border=10pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{trees}

% style definitions \tikzset{level 1/.style={sibling angle=90,level distance=25mm}}

\begin{document}

\begin{tikzpicture}[grow cyclic,cap=round] \node[shape=circle, draw, minimum size=12pt] {\large PL} child {node[shape=circle, draw, minimum size=8pt] {} [level distance=1cm] child {node[anchor=east] {Textual}} child {node[anchor=north] {Visual}} } child {node[shape=circle, draw, minimum size=8pt] {} [level distance=1cm] child {node[anchor=north] {General-purpose}} child {node[anchor=west] {Special-purpose}} } child {node[shape=circle, draw, minimum size=8pt] {}} child {node[shape=circle, draw, minimum size=8pt] {}} ; \end{tikzpicture}

\end{document}

enter image description here

  • 1
    I just re-read your question and think that you probably want an automated approach, right? – Jasper Habicht Feb 09 '24 at 08:41
  • Yes. I would add more nodes, do not want to specify anchor for each nodes. Plus, some nodes may not be at 90 or 180 degree. But your approach works if I micro-manage each nodes. – Gqqnbig Feb 09 '24 at 09:07