This is a fully backwards-compatible reimplementation of the D3 tree layout, that allows for node sizes that vary in either x or y directions.
See the demo.
To use this plugin, use d3-flextree.js. See the API documentation, which is an edited copy of the original tree layout documentation, with additions for the new features.
The existing D3 tree layout is based on an algorithm developed originally by Reingold and Tilford in a paper from 1981, with improvements by various others, the latest being from a paper by Bucheim and Leipert, in 2002. The algorithm has been proven to run in linear time (O(n)).
A limitation of the existing algorithm is that it requires (or assumes) that all of the nodes of the tree are the same size. This is fine for many applications, but some types of tree visualizations would greatly benefit from the ability to auto-generate tree layouts with variable node sizes.
In a paper from 2013, A.J. van der Ploeg enhanced this algorithm to allow for variable-sized nodes, while keeping its linear runtime nature. The author of that paper provide his algorithm as a working Java application on GitHub at cwi-swat/non-layered-tidy-trees.
I adapted that code into this flextree plugin as follows:
- Forked the Java code to Klortho/flextree-java, and modified it so that its API closely resembles the D3 tree layout API.
- Wrote a set of fixed-node-size test cases, and tweaked the output of the Java application such that, for these cases, its output was identical to that produced by D3.
- Added a lot of variable-node-size test cases, and verified the results
- Ported the code to JavaScript, into the src/layout/tree.js module of my fork of D3.
- Got the result to pass the same set of test cases.
- Wrote the demo page to render these same test cases.
- Wrote a script to take the new src/layout/tree.js, and produce the plugin d3-flextree.js.
Because I thought this might be considered as a replacement for the existing
tree layout (it is backwards-compatible, and still runs in linear time), the
code is in my fork of the D3 repository, Klortho/d3,
in the flextree
branch, in two files:
- src/layout/tree.js
- test/layout/tree-test.js
That fork is included here as a git submodule.
To regenerate the plugin, you'll need Node.js and gulp. Follow these steps:
# Install gulp globally, if you haven't already:
npm install --global gulp
git clone --recursive https://github.com/Klortho/d3-flextree.git
cd d3-flextree
npm install
gulp
Then bring up index.html and/or test/index.html in a browser, and verify the results.
This is registered with bower. It will automatically pick up git tags from GitHub.
Many thanks to A.J. van der Ploeg, for making his code available on GitHub!
- Tidier Drawings of Trees. Reingold and Tilford, 1981
- A Node-Positioning Algorithm for General Trees. Walker, 1989
- Improving Walker's Algorithm to Run in Linear Time. Buchheim, Junger, and Leipert, 2002.
- Drawing Non-layered Tidy Trees in Linear Time. A.J. van der Ploeg, 2013
- D3 GitHub issue 1992 - Allow nodeSize for trees to be dynamic.
- D3 pull request #2571
- Plugin wiki page
- My post to the d3-js mailing list.
- Somebody else asking for this feature on the d3.js list.