taproot
Tree manipulation made easy.
Installation
npm
npm install taproot
web
Simply source the file in a script tag:
<script src='lib/taproot.js'></script>
Usage
Creating nodes
createNode( value, identifier, [parent = null] )
Note that you can only have one root node per tree.
tree = new Tree();
tree.createNode('root', 'root');
tree.createNode('1st level', '1a', 'root');
tree.createNode(['value', 'can', 'be', 'anything'], '2a', '1a');
tree.createNode({objects: 'yes'}, '1b', 'root');
tree.createNode('deep nesting', '2b', '1b');
Retrieving the value of a node
getNodeValue( identifier )
tree.getNodeValue('2b');
// "deep nesting"
Retrieving the level of a node
getNodeLevel( identifier )
tree.getNodeLevel('2b');
// 2
Iterating through the tree
expand( [position = tree.root], [mode = 'DEPTH'], [filter = function(identifier) { return true; }] )
Supported modes are 'DEPTH' and 'WIDTH'. The result list will be passed through the filter function if one is provided.
tree.expand();
// ["root", "1a", "2a", "1b", "2b"]
tree.expand(tree.root, 'WIDTH');
// ["root", "1a", "1b", "2a", "2b"]
reverse( position, [filter = function() { return true; }] )
tree.reverse('2b', function(identifier) { return identifier !== 'root'});
// ["2b", "1b"]
Checking relationships
isAncestor( identifier, child )
tree.isAncestor('root', '2b');
// true
isDescendant( identifier, parent )
tree.isDescendant('root', '2b');
// false
isParent( identifier, child )
This will return true only if the supplied node is the direct parent of the supplied child.
tree.isParent('root', '1a');
// true
tree.isParent('root', '2b');
// false
isChild( identifier, child )
This will return true only if the supplied node is the direct child of the supplied child.
tree.isChild('1a', 'root');
// true
tree.isChild('2b', 'root');
// false
Rendering the tree as an object
toObj( [position = tree.root], [nodeKey = 'data'], [childrenKey = 'children'] )
tree.toObj();
// {
// "data": "root",
// "children": [
// {
// "data": "1st level",
// "children": [
// {
// "data": [
// "value",
// "can",
// "be",
// "anything"
// ]
// }
// ]
// },
// {
// "data": {
// "objects": "yes"
// },
// "children": [
// {
// "data": "deep nesting"
// }
// ]
// }
// ]
// }
Getting a subtree
subTree( position )
subtree = tree.subTree('1a');
// {
// "data": "1st level",
// "children": [
// {
// "data": [
// "value",
// "can",
// "be",
// "anything"
// ]
// }
// ]
// }
Removing nodes
removeNode( identifier, [clearChildren = true] )
If clearChildren is set to true, all children nodes of the supplied node will be removed. Otherwise, the children nodes will become the children of the removed node's parent.
tree.removeNode('1a');
// {
// "data": "root",
// "children": [
// {
// "data": {
// "objects": "yes"
// },
// "children": [
// {
// "data": "deep nesting"
// }
// ]
// }
// ]
// }
Moving nodes
moveNode( node, destinationParent )
tree.moveNode('2b', 'root');
// {
// "data": "root",
// "children": [
// {
// "data": {
// "objects": "yes"
// }
// },
// {
// "data": "deep nesting"
// }
// ]
// }
Transplanting a tree
transplant( destinationParent, newTree )
tree = new Tree();
tree.createNode('root', 'root');
tree.createNode('1st level', '1', 'root');
tree.createNode('2nd level', '2', '1');
newTree = new Tree();
newTree.createNode('root', 'rootn');
newTree.createNode('1st level new', '1n', 'rootn');
newTree.createNode('2nd level new', '2n', '1n');
tree.transplant('1', newTree);
// {
// "data": "root",
// "children": [
// {
// "data": "1st level",
// "children": [
// {
// "data": "2nd level"
// },
// {
// "data": "root",
// "children": [
// {
// "data": "1st level new",
// "children": [
// {
// "data": "2nd level new"
// }
// ]
// }
// ]
// }
// ]
// }
// ]
// }
Running Tests
npm install
npm test
Credits
Special thanks to the folks behind pyTree, from which this code is largely derived.