#CeTZ Tree: middle of three children isn't in the center

14 messages · Page 1 of 1 (latest)

light hill
#

The image shows a TikZ picture which I am trying to mimic. My problem currently is that the Lt node isn't centered below its parent, probably because the left sibling has multiple children while the right one only has one. Is there a way to force it in the center?

The connecting lines also differ, but unless there is an easy way to replicate the TikZ style, this isn't a big deal.

#

?render theme=light

#import "@preview/cetz:0.1.1"
#figure(
  cetz.canvas({
    let encircle(num) = {
      box(baseline: 2pt, circle(inset: (x: 1pt, y: -.5pt), stroke: .5pt)[#num])
    }
    cetz.tree.tree((
      [Expression #encircle(5)],
      (
        [Expression #encircle(3)],
        ([Expression #encircle(1)], [`Int(1)`]),
        [`Plus`],
        ([Expression #encircle(2)], [`Int(2)`]),
      ),
      [`Lt`],
      ([Expression #encircle(4)], [`Int(4)`]),
    ), spread: 1.7, content: (padding: .1))
  }),
  caption: [Abstract syntax tree for '`1 + 2 < 4`']
)
old nimbus
#

I suspect the algorithm used in isn't smart enough to recognize that there's room for it. The tree library seems very basic right now

#

It moves it completely to the right of the left subtree

#

You could create a feature request in the cetz repo

#

(You could of course recreate the figure without relying on the tree library)

light hill
#

yea that's what I figured. are you sure there isn't a way to use the tree library and then somehow manually move that one node?

old nimbus
odd axle
odd axle
#

Can you create a ticket? I will def. have a look at it.

light hill
#

for future reference, the issue is created here and I managed to get the edges to more closely resemble the TikZ version:

GitHub

From Discord here. The tree function positions the Lt node to the right of the left subtree, even though there would be enough space for centering it below its parent. Either the placement algorith...

#

?render theme=light

#import "@preview/cetz:0.1.1"
#figure(
  cetz.canvas({
    let encircle(num) = {
      box(baseline: 2pt, circle(inset: (x: 1pt, y: -.5pt), stroke: .5pt)[#num])
    }
    cetz.tree.tree((
      [Expression #encircle(5)],
      (
        [Expression #encircle(3)],
        ([Expression #encircle(1)], [`Int(1)`]),
        [`Plus`],
        ([Expression #encircle(2)], [`Int(2)`]),
      ),
      [`Lt`],
      ([Expression #encircle(4)], [`Int(4)`]),
    ), spread: 1.9, content: (padding: .15),
    draw-edge: (from, to, ..) => {
      let from = from + ".bottom"
      let to = to + ".top"
      let c = (from, "-|", to)
      let a = (from, 1/3, c)
      let b = ((from, 2/3, c), "|-", to)
      cetz.draw.line(a, b, stroke: .5pt)
    })
  }),
  caption: [Abstract syntax tree for '`1 + 2 < 4`']
)