2

I am looking to improve this diagram, especially the linking arrows at the top that overlap the boxes.

\documentclass{article}
\usepackage[margin=1cm]{geometry}
\usepackage{pdflscape}
\usepackage{forest}
\usepackage{capt-of}
\usetikzlibrary{shadows,arrows}
\newgeometry{left=1cm,right=1cm,bottom=1cm}

\tikzset{parent/.style={align=center,text width=2cm, fill=blue!40,rounded corners=2pt,inner sep=2pt}, child/.style={align=center,text width=2.0cm,fill=orange!60,rounded corners=2pt,inner sep=1pt,outer sep=0pt}, grandchild/.style={fill=white,text width=1.7cm} } \usepackage{hyperref} \begin{document}

\begin{landscape} \begin{forest} for tree={% thick, drop shadow, l sep=1.0cm, s sep=0.6cm, node options={draw,font={\small}}, edge={semithick,-latex}, where level=0{parent}{}, where level=1{ minimum height=1cm, child, parent anchor=south west, tier=p, l sep=0.25cm, for descendants={% grandchild, minimum height=0.6cm, %l sep=0.5cm, % s sep=0.5cm, anchor=115, edge path={ \noexpand\path[\forestoption{edge}] (!to tier=p.parent anchor) |-(.child anchor)\forestoption{edge label}; }, } }{}, } [(Phoenician)\ GREEK [Palaeo-Hispanic %heading [North-east\ Celtiberian [South-West\ South-east ] ] ], [Etruscan [Latin [\textit{Rhaetian} [\href{http://en.wikipedia.org/wiki/Gallic}{Gallic} [\href{http://en.wikipedia.org/wiki/Venetic}{Venetic} [Faliscan [Northern Picene Southern Picene\ [Oscan [Umbrian] ] ] ] ] ] ] ] ] [\href{http://en.wikipedia.org/wiki/Gothic_language}{Gothic}] [Glagolitic [Croatian] ]
[Cyrillic [Russian [Ukrainian [Bulgarian [Serb] ] ]
]
]
[Anatolian [Carian [Lydian [Lycian [\nameref{s:pamphylian} [Phrygian [\nameref{s:pisidian} [\nameref{s:sidetic}] ] ] ] ] ] ] ] [Armenian] [Georgian] [Coptic [Nubian] ] ] \end{forest} \captionof{figure}{Abridged family tree of some Greek-derived scripts.} \label{fig:greekderived} \end{landscape}

\restoregeometry \newpage

\section{Pamphylian}\label{s:pamphylian} \section{Pisidian}\label{s:pisidian} \section{Sidetic}\label{s:sidetic} \end{document}

enter image description here

yannisl
  • 117,160
  • maybe this helps -- https://tex.stackexchange.com/questions/470511/hierarchical-diagram-in-tikz-forest-level-options?rq=1 – js bibra Dec 18 '23 at 09:42
  • @jsbibra Unfortunately not. I get lost with all the brackets [[ ]] :) Can you post an answer? I am sure I am missing something small., but cant seem to find it. – yannisl Dec 18 '23 at 09:54
  • Is the first child on the left lower than the others by design? – cfr Dec 18 '23 at 23:53
  • @cfr Is an error when copying, it is a part of a larger block of text and then I added the prelims, so it can run as a minimal. – yannisl Dec 19 '23 at 00:27

2 Answers2

4

You could use forked edges:

enter image description here

Just add \useforestlibrary{edges} to your preamble and add for children={forked edge} to the root node:

[(Phoenician)\\ GREEK, for children={forked edge}

Sandy G
  • 42,558
1

forked edges was also my first thought, but I wasn't completely happy with the effect on the edges leaving the root. Whereas the original features clearly distinct paths to the children, the use of forked edges unifies the paths for the first leg. So I wondered if it would be possible to spread out the starting points of the edges (as in the original) while using a style similar to forked edges (as in Sandy G's answer).

The ext.paths.ortho library extends the syntax available for drawing paths to include, among others, |-| which goes down, then across, then down. Moreover, [distance=<dimension>] is available to adjust the distance from the starting point to the first turn, allowing each path to be separated from its neighbours. If this facility is combined with staggered starting points on the border of the root, the results combine the features I was aiming for.

ortho tree is a forest style combining these features and automating the staggering of paths from the root. I also tweaked the existing code slightly to avoid some leaves being indented more than others, to properly align the root's children in both directions and to use sans fonts (which are generally preferred in diagrams, especially at smaller sizes).

modified tree

Note that the leftmost orange node is no longer lower than the others on that tier and that the stray leaves are no longer indented more than their siblings. ortho tree is defined to work with a root with any number of children. If the number of children is even, the root is aligned with calign=midpoint. If the number is odd (as in this case), calign with current edge is applied to the middle child.

Note that the redefinition of \section is just for the example and shouldn't be used in a real document!

Code:

\documentclass[border=5pt]{standalone}
% ateb: https://tex.stackexchange.com/a/705321/ addaswyd o gwestion Yiannis Lazarides: https://tex.stackexchange.com/q/705204/
\usepackage{forest}
\usetikzlibrary{shadows,arrows,ext.paths.ortho}

\tikzset{% yl parent/.style={align=center,text width=2cm, fill=blue!40,rounded corners=2pt,inner sep=2pt}, yl child/.style={align=center,text width=2.0cm,fill=orange!60,rounded corners=2pt,inner sep=1pt,outer sep=0pt}, yl grandchild/.style={fill=white,text width=1.7cm} } \forestset{% declare count register={adjusted root child count}, declare boolean register={root children odd}, ortho tree/.style={% before typesetting nodes={% calculate root children, if root children odd={% for nodewalk={% fake=root, n/.register=adjusted root child count }{calign with current edge}, }{!r.calign=midpoint}, }, before drawing tree={% tempcountb/.process={ Rw+n {adjusted root child count}{2##1-2} }, tempdima/.process={ OOOw3+d {!r.max x}{!r.min x}{!r.n children}{(##1-##2)/(##3+1)}}, tempdimb/.process={ ORw2+d {!r.l sep}{tempcountb}{##1/##2} }, for nodewalk={fake=r,1,while nodewalk valid={next}{next}}{% if={> OR= R & {n}{adjusted root child count} {root children odd} }{% edge path'=(!u.children) -- (.child anchor) }{% if={ > OR< {n}{adjusted root child count} } {% edge path'/.process={ OSRw2+P lRw2+P w2 {n}{tempdima}{##1##2} {tempdimb}{##1##2} {(!u.south west) ++(##1pt,0pt) |-|[distance=##2pt] (.child anchor) } }, }{% edge path'/.process={ OSRw2+P lRw2+P w2 {n'}{tempdima}{##1##2} {tempdimb}{##1*##2} {(!u.south east) ++(-##1pt,0pt) |-|[distance=##2pt] (.child anchor) } }, }% }% }, }, where level=1{ parent anchor=south west, anchor=parent, child anchor=parent, tier=pxx, for descendants={% child anchor=west, edge path'={ (!to tier=pxx.parent anchor) |-(.child anchor) }, }, }{}, }, calculate root children/.style={% if={>Ow+P{!r.n children}{isodd(##1)}}{% adjusted root child count/.process={ Ow+n {!r.n children} {(##1+1)/2}}, root children odd, }{% adjusted root child count/.process={ Ow+n {!r.n children} {(##1+2)/2}}, not root children odd, }, }, } \usepackage{hyperref} \makeatletter % only for the example because standalone doesn't define \section! \RenewDocumentCommand \section { m }{\def@currentlabelname{#1}\refstepcounter{section}} \makeatother \begin{document} \begin{forest} for tree={% thick, drop shadow, l sep'=1.0cm, s sep'=0.6cm, draw, font={\small\sffamily}, edge={semithick,-latex}, }, where level=0{yl parent}{}, where level=1{ minimum height=1cm, yl child, l sep'=0.25cm, for descendants={% yl grandchild, minimum height=0.6cm, xshift=5pt, }, }{}, ortho tree, [(Phoenician)\ GREEK% [c] [Palaeo-Hispanic %heading [North-east\ Celtiberian [South-West\ South-east ] ] ] [Etruscan [Latin [\textit{Rhaetian} [\href{http://en.wikipedia.org/wiki/Gallic}{Gallic} [\href{http://en.wikipedia.org/wiki/Venetic}{Venetic} [Faliscan [Northern Picene Southern Picene\ [Oscan [Umbrian] ] ] ] ] ] ] ] ] [\href{http://en.wikipedia.org/wiki/Gothic_language}{Gothic}] [Glagolitic [Croatian] ]
[Cyrillic [Russian [Ukrainian [Bulgarian [Serb] ] ]
]
]
[Anatolian [Carian [Lydian [Lycian [\nameref{s:pamphylian} [Phrygian [\nameref{s:pisidian} [\nameref{s:sidetic}] ] ] ] ] ] ] ] [Armenian] [Georgian] [Coptic [Nubian] ] ] \end{forest} \section{Pamphylian}\label{s:pamphylian} \section{Pisidian}\label{s:pisidian} \section{Sidetic}\label{s:sidetic}

\end{document}

cfr
  • 198,882
  • Thanks. Nice to know about the paths.ortho. – yannisl Dec 19 '23 at 18:17
  • 1
    @YiannisLazarides That's on Alan Munn, who's a big fan. I thought this was a good excuse to use it ;). Were the differences in alignment in the original deliberate or inadvertent? I couldn't find code suggesting the former, so I assumed the latter. Also, I tidied up the comments a bit. – cfr Dec 19 '23 at 19:23
  • 1
    No the difference in alignment was not deliberate. Thanks for fixing it. I am not very good with Tikz as I do not have a use for it regularly, by the time I need to draw another chart, I forgotten it:) – yannisl Dec 19 '23 at 21:54