forest icon indicating copy to clipboard operation
forest copied to clipboard

Circle nodes need "minimum size"

Open nignasi opened this issue 4 years ago • 1 comments

Following code shows a forest-tree where nodes has to be circles instead of rectangles. The code fails with error "Dimension too large". As soon as a minimum size is fixed for nodes, the code works.

\documentclass{article}
\usepackage{forest}
	
\begin{document}
\begin{forest}
  [7, for tree={circle, draw}%, minimum size=2em}
  	[6 [5] [4]]
  	[5]
	]
\end{forest}
\end{document}

I don't know if it's a know topic, but I've not seen any minimum size reference for circle nodes examples in forest-doc.

Thank you,

Ignasi

nignasi avatar Sep 01 '21 07:09 nignasi

I don't know if this is a bug or just what TikZ does since this kind of error happens pretty regularly regardless of application. However, for whatever it is worth the first error occurs on line 6449 of forest.sty

\forest@node@getedge{negative}{\forest@plu@grow}{\forest@plnu@negativechildedge}%

If you force packing per node, it happens after all the nodes in the sub-tree are packed i.e. between before packing node and after packing node for the root.

What I don't quite understand is that it seems to perform exactly the same action with precisely the same values one and only complains the second time. So it almost seems as if the problem is that there's a zero difference between the two? Does PGF not like moving 0pt? But probably I'm just misunderstanding what's going on.

\forest@node@marshal ->\bix \show \ri 
\show \forest@plu@grow \show \forest@p...
l.1233 \end{forest}

? 
> \forest@plu@grow=macro:
->270.
\forest@node@marshal ...ri \show \forest@plu@grow 
\show \forest@plnu@negativ...
l.1233 \end{forest}

? 
> \forest@plnu@negativechildedge=macro:
->\pgfsyssoftpath@movetotoken {0.0pt}{-5.76367pt}\pgfsyssoftpath@linetotoken {-
6.35397pt}{-3.13176pt}\pgfsyssoftpath@linetotoken {-8.98589pt}{3.22221pt}\pgfsy
ssoftpath@linetotoken {-6.35397pt}{9.57619pt}\pgfsyssoftpath@linetotoken {0.0pt
}{12.2081pt}.
\forest@node@marshal ...st@plnu@negativechildedge 
\forest@node@getedge {nega...
l.1233 \end{forest}

? 
! Undefined control sequence.
\forest@node@marshal ...u@negativechildedge }\bix 
\forest@node@getedge {posi...
l.1233 \end{forest}

? 
node@3
node@6
5
node@6
node@2
7
> \oi=undefined.
<argument> \show \oi 

l.1233 \end{forest}

? 
> \ghi=undefined.
<argument> \show \ghi 
\def \bix {\show \hi }
l.1233 \end{forest}

? 
> \hi=undefined.
\bix ->\show \hi 

l.1233 \end{forest}

? 
> \ri=undefined.
\forest@node@marshal ->\bix \show \ri 
\show \forest@plu@grow \show \forest@p...
l.1233 \end{forest}

? 
> \forest@plu@grow=macro:
->270.
\forest@node@marshal ...ri \show \forest@plu@grow 
\show \forest@plnu@negativ...
l.1233 \end{forest}

? 
> \forest@plnu@negativechildedge=macro:
->\pgfsyssoftpath@movetotoken {0.0pt}{-5.76367pt}\pgfsyssoftpath@linetotoken {-
6.35397pt}{-3.13176pt}\pgfsyssoftpath@linetotoken {-8.98589pt}{3.22221pt}\pgfsy
ssoftpath@linetotoken {-6.35397pt}{9.57619pt}\pgfsyssoftpath@linetotoken {0.0pt
}{12.2081pt}.
\forest@node@marshal ...st@plnu@negativechildedge
\forest@node@getedge {nega...
l.1233 \end{forest}

?
! Dimension too large.
<recently read> \pgf@x

Code probably isn't much more informative, but it features Bagpuss, so why not?

\documentclass{article}
\usepackage{forest}
\makeatletter
\def\forest@pack{%
  \forestmath@if{bagpuss}{}{}%
  \pgfsyssoftpath@getcurrentpath\forest@pack@original@path
  \forest@pack@computetiers
  \forest@pack@computegrowthuniformity
  \forestmath@if{bagpuss}{}{}%
  \forest@@pack
  \forestmath@if{bagpuss}{}{}%
  \pgfsyssoftpath@setcurrentpath\forest@pack@original@path
}
\def\forest@@pack{%
  \ifnum\forestove{uniform growth}>0
    \ifnum\forestove{n children}>0
      \forest@pack@level@uniform
      \forest@pack@aligntiers@ofsubtree
      \forest@pack@sibling@uniform@recursive
    \fi
    \else
      \forest@node@foreachchild{\forest@@pack}%
      \forest@process@hook@keylist@nodynamics{before packing node}{current}%
      \ifnum\forestove{n children}>0
        \forestmath@if{bagpuss}{\show\oi}{}%
        \forest@pack@level@nonuniform
        \forestmath@if{bagpuss}{\show\vi}{}%
        \forest@pack@aligntiers
        \forest@pack@sibling@uniform@applyreversed
      \fi
    \forestoget{after packing node}\forest@temp@keys
    \forest@process@hook@keylist@nodynamics{after packing node}{current}%
  \fi
}
\def\forest@pack@onlythisnode{%
  \ifnum\forestove{n children}>0
    \forest@pack@computetiers
    \forest@pack@level@nonuniform
    \forest@pack@aligntiers
    \forest@node@foreachchild{\forestoset{s}{0\pgfmath@pt}}%
    \forest@pack@sibling@uniform@applyreversed
  \fi
}
\def\forest@pack@computegrowthuniformity{%
  \forest@node@foreachchild{\forest@pack@computegrowthuniformity}%
  \edef\forest@pack@cgu@uniformity{%
    \ifnum\forestove{n children}=0
      2\else 1\fi
  }%
  \forestoget{grow}\forest@pack@cgu@parentgrow
  \forest@node@foreachchild{%
    \ifnum\forestove{uniform growth}=0
      \def\forest@pack@cgu@uniformity{0}%
    \else
      \ifnum\forestove{uniform growth}=1
        \ifnum\forestove{grow}=\forest@pack@cgu@parentgrow\relax\else
          \def\forest@pack@cgu@uniformity{0}%
        \fi
      \fi
    \fi
  }%
  \forestoget{before packing node}\forest@temp@a
  \forestoget{after packing node}\forest@temp@b
  \expandafter\expandafter\expandafter\ifstrempty\expandafter\expandafter\expandafter{\expandafter\forest@temp@a\forest@temp@b}{%
    \forestolet{uniform growth}\forest@pack@cgu@uniformity
  }{%
    \forestoset{uniform growth}{0}%
  }%
}
\def\forest@pack@level@nonuniform{%
  \let\forest@plu@minchildl\relax
  \forestoget{grow}\forest@plu@grow
  \forestmath@if{bagpuss}{\show\ghi\def\bix{\show\hi}}{}%
  \forest@node@foreachchild{%
    \bix
    \show\ri
    \show\forest@plu@grow
    \show\forest@plnu@negativechildedge
    \forest@node@getedge{negative}{\forest@plu@grow}{\forest@plnu@negativechildedge}%
    \bix
    \forest@node@getedge{positive}{\forest@plu@grow}{\forest@plnu@positivechildedge}%
    \def\forest@plnu@childedge{\forest@plnu@negativechildedge\forest@plnu@positivechildedge}%
    \forest@path@getboundingrectangle@ls\forest@plnu@childedge{\forest@plu@grow}%
    \advance\pgf@xa\forestove{l}\relax
    \ifx\forest@plu@minchildl\relax
      \edef\forest@plu@minchildl{\the\pgf@xa}%
    \else
      \ifdim\pgf@xa<\forest@plu@minchildl\relax
        \edef\forest@plu@minchildl{\the\pgf@xa}%
      \fi
    \fi
  }%
  \let\bix\relax
  \forest@node@getboundingrectangle@ls{\forest@plu@grow}%
  \pgfutil@tempdima=\pgf@xb\relax
  \advance\pgfutil@tempdima -\forest@plu@minchildl\relax
  \advance\pgfutil@tempdima \forestove{l sep}\relax
  \ifdim\pgfutil@tempdima>0pt
    \forest@node@foreachchild{%
      \forestoeset{l}{\the\dimexpr\the\pgfutil@tempdima+\forestove{l}}%
    }%
  \fi
}
\makeatother
\forestset{%
  declare boolean={bagpuss}{false},
}
\begin{document}
\begin{forest} 
  for tree={%
    circle,
    draw,
    before packing node={%
      typeout/.option=name,
      typeout/.option=content,
    },
    after packing node={%
      typeout/.option=name,
    },
  }%, minimum size=2em}
  [7,bagpuss
  	[6 [5] [4]]
  	[5]
  ]
\end{forest}
\end{document}

[I do realise Bagpuss is a culturally parochial reference - not to mention a temporally specific one, but he's easy to find in code. ]

cfr42 avatar May 20 '24 04:05 cfr42