# Binary Tree: Force lonely node to be left or right

**URL:** <https://forum.graphviz.org/t/binary-tree-force-lonely-node-to-be-left-or-right/1159>\
**Category:** Help\
**Created:** [May 8, 2022, 5:32pm UTC](https://forum.graphviz.org/t/binary-tree-force-lonely-node-to-be-left-or-right/1159 "2022-05-08T17:32:27Z")\
**Posts on this page:** 1\
**Showing post:** 4

<div class="post-metadata">

**Author:** ![steveroush](https://avatars.discourse-cdn.com/v4/letter/s/a9adbd/32.png) [@steveroush](https://forum.graphviz.org/u/steveroush)\
**Post date:** [May 9, 2022, 5:36pm UTC](https://forum.graphviz.org/t/binary-tree-force-lonely-node-to-be-left-or-right/1159/4 "2022-05-09T17:36:21Z")

</div>

Unfortunately, Graphviz does not include a tree model (see [How to lay out binary tree / hierarchicy? - #3 by steveroush](https://forum.graphviz.org/t/how-to-lay-out-binary-tree-hierarchicy/610/3) and [Provide a collection of simple tree layouts (#2032) · Issues · graphviz / graphviz · GitLab](https://gitlab.com/graphviz/graphviz/-/issues/2032)).  
However, here is a post-processor program for binary trees (not well tested). It is pretty simple-minded, defaulting to _single-edges-always-go-left_ rule. (_single-edges-always-go-right_ is equally easy). The problem with these simple rules is that they tend to be very lop-sided (see bottom).  
To allow for more symmetric layouts, the post-processor allows the user to explicitly direct an edge right or left using a new edge attribute: **side**. Values: _L|l|R|r|U|u|D|d_  
The post-processor is written in the **GVPR** ([https://www.graphviz.org/pdf/gvpr.1.pdf](https://www.graphviz.org/pdf/gvpr.1.pdf)) language - part of the Graphviz package. The **GVPR** output is passed to `neato -n` (see [FAQ | Graphviz](https://graphviz.org/faq/#FaqDotWithNodeCoords)). Somewhat convoluted, but you should not have to mess with anything other than your input.  
Command-line (Linux) (Windows should be similar):  
`dot -Tdot myfile.gv | gvpr -c -f binaryTree.gvpr | neato -n -Tpng >myfile.png`

binaryTree.gvpr:

```auto
BEGIN{
 int left_right, Right[], Left[];
 float shiftFactor;
 node_t Head, Tail;
}
BEG_G{
  left_right=0;
  if ((hasAttr($G, "rankdir")) && ($G.rankdir!="") && $G.rankdir=="@(LR|RL)") left_right = 1;
  shiftFactor=1.1*72; // effectively sets the angle (eyeballed, no trig)
}
E{
    Head=$.head;
    Tail=$.tail;
    // legal values for side: left(L|l) or right(R|r) or up(U|u) or down(D|d)
    // current value testing is incomplete
    // awkwardly written, but seemingly correct
    if (Left[Tail]!=1 && (((!((hasAttr($, "side")) && ($.side!=""))) || Right[Tail]==1 || ((hasAttr($, "side")) && ($.side!="") && $.side=="@(L|l|D|d)")))){
      print("// LEFT/UP");
      Left[Tail]=1;
      if (left_right==0)
        Head.pos=(string)(Tail.X-(shiftFactor*(float)Head.width)) + "," + (string)Head.Y;
      else
        Head.pos=(string)Head.X + "," + (string)(Tail.Y-(shiftFactor*(float)Head.height)) ;
    }else{
      print("// RIGHT/DOWN");
      Right[Tail]=1;
      if (left_right==0)
        Head.pos=(string)(Tail.X+(shiftFactor*(float)Head.width)) + "," + (string)Head.Y;
      else
        Head.pos=(string)Head.X + "," + (string)(Tail.Y+(shiftFactor*(float)Head.height)) ;
    }
  $.pos="";
}

```

Your file, modified:

```auto
graph{
  node [shape=circle]
  1 -- 2;
  2 -- 5;
  2 -- 4;
  5 -- 7;
  7 -- 6;
  6 -- 13 [side=R] // added a new attribute (side), send this edge to the right
  13 -- 11;
  11 -- 12 [side=R] // this edge to the right
  12 -- 14;
  4 -- 8;
  4 -- 3;
  3 -- 9;
  9 -- 10 [side=R] // this edge to the right
}

```

Giving:

 ![binaryTree10.LR](https://global.discourse-cdn.com/graphviz/original/1X/ced96e263c6f2a9cabd7066760e611e37198a54c.png)

Default (lop-sided) version from the program:

 ![binaryTree0.L](https://global.discourse-cdn.com/graphviz/original/1X/69267669921120aa87a5ca1f1bad80a14adcc3b0.png)

---

_[View the full topic](https://forum.graphviz.org/t/binary-tree-force-lonely-node-to-be-left-or-right/1159)._
