8

I'm working on some sort of org-chart/hierarchy-tree and ran into issues with the edge-alignment. As a guideline I used the family-tree-TeXample. See the TeX.sx-dicussion here.

However, the text in my nodes is a lot longer than the short names in the example. Therefore, starting the edges from the south-anchor of the criteria-nodes produces quite a bit of whitespace.

As a solution to this, I'd like to start the edges at the west-anchor of the criteria-nodes. However, edge from parent path is set to |- and thus does not produce a horizontal section before going vertical.

Current edge-alignment in the MWE

I tried the below of=<node>, but that didn't help either. The option I'm trying to avoid is setting a coordinate for each edge, in case I'd have to adjust something later. Spreading the tree out horizontally is unfortunately not an option either, because the attribute-count is too high.

I googled a bit to find some pictures of trees that have this edge-style:

Preferred Also nice Last resort

The first tree uses an edge style like -|-.

The second one is also nice, but this anchor does not exist in TikZ-nodes.

The third is better than my current solution, but doesn't look very clean.

Here's the MWE that produces a tree as shown in the picture at the top:

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\usetikzlibrary{trees}
\tikzstyle{every node}=[draw=black,thick,anchor=west, minimum height=2.5em]

\begin{document}

\begin{figure}[!htb]
\resizebox{\linewidth}{!}{

\begin{tikzpicture}[
criteria/.style={text centered, text width=2cm, fill=gray!50},
attribute/.style={%
    grow=down, xshift=-1cm,
    text centered, text width=2cm,
    edge from parent path={(\tikzparentnode.south west) |- (\tikzchildnode.west)}},
first/.style    ={level distance=8ex},
second/.style   ={level distance=16ex},
third/.style    ={level distance=24ex},
fourth/.style   ={level distance=32ex},
fifth/.style    ={level distance=40ex},
level 1/.style={sibling distance=10em}]
    % Main Goal
    \node[anchor=south]{SuperLongTitleWithNoMeaning}
    [edge from parent fork down]

    % Criteria and Attributes
    child{node (crit1) [criteria] {Criteria1}
        child[attribute,first]  {node {Attribute\\Number1}}
        child[attribute,second] {node {Attribute2}}
        child[attribute,third]  {node {Attribute3}}
        child[attribute,fourth] {node {Attribute4}}
        child[attribute,fifth]  {node {Another\\Attribute}}}
    %
    child{node [criteria] {Criteria2}
        child[attribute,first]  {node {Attribute1}}
        child[attribute,second] {node {Attribute2}}
        child[attribute,third]  {node {Third\\Criteria}}
        child[attribute,fourth] {node {Longtext-\\criteria}}}
    %
    child{node [criteria] {Criteria3}
        child[attribute,first]  {node {Attribute\\two lines}}
        child[attribute,second] {node {Attribute2}}     
        child[attribute,third]  {node {Attribute3}}}
    %
    child{node [criteria] {Criteria4}
        child[attribute,first]  {node {Attribute1}}
        child[attribute,second] {node {Attribute2}}}
    %
    child{node [criteria] {Criteria5}
        child[attribute,first]  {node {First\\Attribute}}
        child[attribute,second] {node {Attribute2}}
        child[attribute,third]  {node {Third\\Criteria}}
        child[attribute,fourth] {node {Longtext-\\criteria}}};
\end{tikzpicture}}
\caption{This is a nice tree.}
\end{figure}

\end{document}

Bonus question:

The top-node centers itself according to the total number of nodes in all levels. Therefore, it's a bit shifted toward the left. Can I tell TikZ to ignore the attribute-level for the centering? It would look nicer, if the heading would be right above the middle criteria.

2 Answers 2

10

Here's something like the second option (the node does exist).

There are only two changes to your MWE, in attribute/,style:

  1. The xshift needs adjusting

  2. The anchor point you need can be expressed as an angle

Sorry: I pass on the bonus.

Here it is -- I leave final adjustments to your taste:

\documentclass[12pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\usetikzlibrary{trees}
\tikzstyle{every node}=[draw=black,thick,anchor=west, minimum height=2.5em]

\begin{document}

\begin{figure}[!htb]
\resizebox{\linewidth}{!}{

\begin{tikzpicture}[
criteria/.style={text centered, text width=2cm, fill=gray!50},
attribute/.style={%
    grow=down, xshift=0cm,
    text centered, text width=2cm,
    edge from parent path={(\tikzparentnode.225) |- (\tikzchildnode.west)}},
first/.style    ={level distance=8ex},
second/.style   ={level distance=16ex},
third/.style    ={level distance=24ex},
fourth/.style   ={level distance=32ex},
fifth/.style    ={level distance=40ex},
level 1/.style={sibling distance=10em}]
    % Main Goal
    \node[anchor=south]{SuperLongTitleWithNoMeaning}
    [edge from parent fork down]

    % Criteria and Attributes
    child{node (crit1) [criteria] {Criteria1}
        child[attribute,first]  {node {Attribute\\Number1}}
        child[attribute,second] {node {Attribute2}}
        child[attribute,third]  {node {Attribute3}}
        child[attribute,fourth] {node {Attribute4}}
        child[attribute,fifth]  {node {Another\\Attribute}}}
    %
    child{node [criteria] {Criteria2}
        child[attribute,first]  {node {Attribute1}}
        child[attribute,second] {node {Attribute2}}
        child[attribute,third]  {node {Third\\Criteria}}
        child[attribute,fourth] {node {Longtext-\\criteria}}}
    %
    child{node [criteria] {Criteria3}
        child[attribute,first]  {node {Attribute\\two lines}}
        child[attribute,second] {node {Attribute2}}     
        child[attribute,third]  {node {Attribute3}}}
    %
    child{node [criteria] {Criteria4}
        child[attribute,first]  {node {Attribute1}}
        child[attribute,second] {node {Attribute2}}}
    %
    child{node [criteria] {Criteria5}
        child[attribute,first]  {node {First\\Attribute}}
        child[attribute,second] {node {Attribute2}}
        child[attribute,third]  {node {Third\\Criteria}}
        child[attribute,fourth] {node {Longtext-\\criteria}}};
\end{tikzpicture}}
\caption{This is a nice tree.}
\end{figure}

\end{document}

enter image description here

8
  • Thanks, Brent! I read about the angle-setting yesterday, but never actually tried to just write a number. I like the tree a lot more now. Do you happen to have an idea about the centering of the top-node without rearranging the branches?
    – dhst
    Mar 2, 2012 at 10:04
  • 1
    @Daniel: No, sorry, I had a couple of private monkey-fingerpoken tries at it, but to no avail. Mar 2, 2012 at 10:17
  • Too bad. Seems like xshift has no effect on the top-node.
    – dhst
    Mar 2, 2012 at 11:05
  • @Daniel: First thing I tried... Welcome to fingerpokenwelt. Mar 2, 2012 at 11:07
  • 2
    Fingerpoken-magic: xshift-ing all the criteria-nodes by a bit less than half the sibling-distance (10em in the MWE) centers the top-node. From there on it comes down to playing around with the third decimal place. With my current settings (different than the MWE) xshift=-4.775em looks flawless.
    – dhst
    Mar 2, 2012 at 11:34
5

Or a forest solution (fancy colouring optional):

fancier colouring

\documentclass[tikz,border=20pt]{standalone}
\usepackage{forest}
\usetikzlibrary{shadows}
\forestset{
  dir switch tree 2/.style={
    for tree={
      if level=1{
        edge path={
          \noexpand\path [\forestoption{edge}] (!u.parent anchor) -- ++(0,-1.5em) -| (.child anchor)\forestoption{edge label};
        },
        for descendants={
          child anchor=west,
          align=left,
          edge path={
            \noexpand\path [\forestoption{edge}] (!u.parent anchor) -- ++(-.5em,0) |- (.child anchor)\forestoption{edge label};
          },
          before computing xy={
            l=.5em
          }
        },
        before computing xy={
          l=3em
        },
        for tree={
          parent anchor=west,
          anchor=mid west,
          grow'=0,
          font=\sffamily,
          if n children=0{}{
            delay={
              prepend={[,phantom, calign with current]}
            }
          },
        },
      }{},
    },
  },
}
\tikzset{
  colour me/.style={
      draw=colour#1,
      fill=colour#1!20!white,
      text=colour#1!25!black,
  }
}
\begin{document}
\colorlet{colour0}{blue}
\colorlet{colour1}{green}
\colorlet{colour2}{red}
\colorlet{colour3}{orange}
\colorlet{colour4}{yellow}
\colorlet{colour5}{magenta}
\begin{forest}
  dir switch tree 2,
  for tree={
    if level=0{
      colour me=0
    }{
      if level=1{
        node options/.wrap pgfmath arg={colour me=#1}{n()}
      }{
        node options/.wrap 2 pgfmath args={colour me=#1!#2!black}{n("!u")}{100*(n_children("!u")-n()/2)/(n_children("!u"))}
      }
    },
    rounded corners,
    thick,
    drop shadow,
    edge={thick}
  }
  [Super Long Title With No Meaning
    [Criteria 1
      [Attribute\\Number 1]
      [Attribute 2]
      [Attribute 3]
      [Attribute 4]
      [Another\\Attribute]
    ]
    [Criteria 2
      [Attribute 1]
      [Attribute 2]
      [Third\\Criteria]
      [Longtext-\\criteria]
    ]
    [Criteria 3
      [Attribute\\two lines]
      [Attribute 2]
      [Attribute 3]
    ]
    [Criteria 4
      [Attribute 1]
      [Attribute 2]
    ]
    [Criteria 5
      [First\\Attribute]
      [Attribute 2]
      [Third\\Criteria]
      [Longtext-\\criteria]
    ]
  ]
\end{forest}
\end{document}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .