# Automatically fill forest nodes depending on their level

I'm working with trees of different depth, created with forest package, and I'd like to automatically colour their background with different shades of gray, starting from the same shade down to white, for example:

Tree-level tree
level 0: black!60 % darkest gray
level 1: black!30
level 2: black!0 % white

Four-level tree
level 0: black!60 % darkest gray
level 1: black!40
level 2: black!20
level 3: black!0 % white

Is there any way to get the maximum level of the tree and automatize the filling using the formula below?
darkest = 60 % parameter
level n: black!((maxlevel-level)*darkest/maxlevel)

My working code so far (with maxlevel manually set to 2, and darkest gray set to 40):

\documentclass{book}
\usepackage[edges]{forest}
\forestset{
AlignOddChildren/.style = {
for tree={
if={isodd(n_children())}{
calign primary child/.pgfmath={(n_children()+1)/2},
calign=child edge
}{}
}
},
}
\begin{document}
\begin{forest}
for tree = {draw, rectangle, thick, align=center},
forked edges,
for tree = {fill/.wrap pgfmath arg={black!#1}{40*(2-level())/2}},
AlignOddChildren
[ Maintenance
[ Corrective\\Maintenance\\(CM)
[ Run to failure\\(RTF) ]
]
[ Preventive\\Maintenance\\(PvM)
[ Experience-based\\Maintenance\\(EBM) ]
[ Time-based\\Maintenance\\(TBM) ]
]
[ Predictive\\Maintenance\\(PdM)
[ Condition-based\\Maintenance\\(CBM) ]
]
]
\end{forest}
\end{document}


I found somewhere this code for getting the maximum level, but I don't know how to use it (replacing maxlevel() in the expression does not work):

maxlevel/.max={level}{tree}


Thank you!

• Welcome to TeX.se. Instead of just listing your requirements, and expecting someone to do it for you, perhaps you could post (in the form of a compilable minimal document) some code to show what you've tried. – Alan Munn Mar 8 '18 at 18:36
• Hi, thank you for your reply. Actually I don't need someone to do the whole work for me, I just need to know how to get the "maxlevel" parameter before trying to write any code (the way that parameter is obtained may affect the way I'm going to write the code) – Taekwondavide Mar 8 '18 at 18:43
• Perhaps this question will help: TikZ/Forest: How to uniquely color parent/children/grandchildren branch nodes? – Alan Munn Mar 8 '18 at 19:22
• Maximum of an expression over a(ny) set of nodes can be computed by using aggregate function max, section of 3.14 of the docs. The level of a node is stored in level. – Sašo Živanović Mar 8 '18 at 21:19
• My answer at tex.stackexchange.com/questions/327014/… may be helpful for the shading, though it uses a hard-coded maximum, rather than max. – cfr Mar 10 '18 at 0:09

## 1 Answer

You can use .max to get the maximum level of the tree and store this in a temporary register. This can then be used in an expression to specify the fill.

For example,

\documentclass[border=10pt]{standalone}
\usepackage[edges]{forest}
\forestset{
AlignOddChildren/.style = {
for tree={
if={isodd(n_children())}{
calign primary child/.process={Ow+n {n children}{(##1+1)/2}},
calign=child edge
}{}
}
},
gradual fill/.style={
before typesetting nodes={
tempcounta/.max={level}{r,tree},
for tree={
fill/.process={
ROw2+nw {tempcounta} {level} { (100*##2)/##1 } {white!##1!black!60}
},
},
},
},
}
\begin{document}
\begin{forest}
for tree = {draw, rectangle, thick, align=center},
forked edges,
gradual fill,
AlignOddChildren,
[ Maintenance
[ Corrective\\Maintenance\\(CM)
[ Run to failure\\(RTF) ]
]
[ Preventive\\Maintenance\\(PvM)
[ Experience-based\\Maintenance\\(EBM) ]
[ Time-based\\Maintenance\\(TBM) ]
]
[ Predictive\\Maintenance\\(PdM)
[ Condition-based\\Maintenance\\(CBM) ]
]
]
\end{forest}
\begin{forest}
for tree = {draw, rectangle, thick, align=center},
forked edges,
gradual fill,
AlignOddChildren,
[ Maintenance
[ Corrective\\Maintenance\\(CM)
[ Run to failure\\(RTF) ]
[ Preventive\\Maintenance\\(PvM)
[ Experience-based\\Maintenance\\(EBM) ]
[ Time-based\\Maintenance\\(TBM) ]
[ Predictive\\Maintenance\\(PdM)
[ Condition-based\\Maintenance\\(CBM) ]
]
]
]
]
\end{forest}
\end{document}