Hi! I'm Nicolas and I'm interested in information visualization, JavaScript and web standards.
I currently work as a Data Visualization Scientist at Twitter. I wrote PhiloGL, the JavaScript InfoVis Toolkit and V8-GL.
Two nodes at the same level should be placed at least a given distance apart.
A parent should be centred over its o?spring.
Tree drawings should be symmetrical with respect to re?ection a tree and
its mirror image should produce drawings that are re?ections of each other. In
particular, this means that symmetric trees will be rendered symmetrically.
Identical subtrees should be rendered identically their position in the larger
tree should not a?ect their appearance.
Trees should be as narrow as possible without violating these rules
In order to calculate nodes' positions Kennedy takes a "bottom-up" approach:
Starting from the root node, draw for each node all its subtrees without breaking any rules. Fit these subtrees together without changing their shape, and also without breaking rules 1 and 3 (i.e do not break symmetry and avoid cluttering/overlapping of nodes). Finally, center their parent above them like specified in rule 2.
The "fitting" of the subtrees is calculated by operating on subtrees extents. A subtree extent is a data structure containing the relative coordinates of the boundary of a subtree. One frequent operation between extents is merging:
Other operations involve setting the distance between two extents, translating extents, etc.
Implementation
Kennedy implements this algorithm in Standard ML. I made a JavaScript adaptation. I like the Standard ML version a lot more; in this case rich typing makes very elegant code.
Here's my code implementation, in case you want to compare it to Kennedy's.
My version takes into account different tree layouts (left, right, bottom, top), siblings and subtrees offsets and different node sizes as opposed to Kennedy's version.