1
   var treeData = {"name" : "A",  "children" : [
                         {"name" : "B", "children": [
                                 {"name" : "C", "children" :[]}
                          ]}
                   ]};

THE ARRAY BEFORE SHOULD BE EMPTY. THE ARRAY AFTER SHOULD BE POPULATED DEPENDING ON THE NUMBER OF NODES NEEDED THAT WILL BE DEFINED FROM A DYNAMIC VALUE THAT IS PASSED.

I would like to build the hierarchy dynamically with each node created as a layer/level in the hierarchy having its own array of nodes. THIS SHOULD FORM A TREE STRUCTURE. This is hierarchy structure is described in the above code.There should be a root node, and an undefined number of nodes and levels to make up the hierarchy size. Nothing should be fixed besides the root node. I do not need to read or search the hierarchy, I need to construct it. The array should start {"name" : "A", "children" : []} and every new node as levels would be created {"name" : "A", "children" : [HERE-{"name" : "A", "children" : []}]}. In the child array, going deeper and deeper. Basically the array should have no values before the call, except maybe the root node. After the function call, the array should comprise of the required nodes of a number that may vary with every call depending on the results of a database query. Every child array will contain one or more node values. There should be a minimum of 2 node levels, including the root. It should initially be a Blank canvas, that is no predefined array values.

user1684586
  • 175
  • 2
  • 4
  • 13

1 Answers1

1

Here is the example of function to create your nodes dynamically:

function createNode(name) {
   return({name: name, children: []});
}

function addChild(node, child) {
    node.children.push(child);
    return node;
}

var treeData = createNode("");
var subChild = createNode("");
addChild(subChild, createNode("A31"));
addChild(treeData, subChild);

But I suggest to use prototypes instead.

To find any node by 'path' with any level:

function findNodeByPath(root, path) {
   var curr; 
   while(root && ((curr = path.splice(0,1)[0]) !== undefined)) {
        if (root.children) root = root.children[curr];
        else root = undefined;
   }
   return root;
}


function findNodeByName(root, namePath, create) {
   var curr; 
   while(root && ((curr = namePath.splice(0,1)[0]) !== undefined)) {
        if (root.children) {
            var found = undefined;
            for (var i = 0; !found && i < root.children.length; i++)
                if (root.children[i].name == curr) found = root.children[i];
            if (create && !found) {
                found = createNode(curr);
                addChild(root, found);
            }
            root = found;
        }
        else root = undefined;
   }
   return root;
}


var A31 = findNodeByPath(treeData, [0, 0]); // Will return the node with name A31
addChild(A31, createNode("A31 child 1"));
addChild(A31, createNode("A31 child 2"));

// second child will be accessible by:
var secondChildOfA31 = findNodeByPath(treeData, [0, 0, 1]);

// also to find node by the name:
var secondChildOfA31 = findNodeByName(treeData, ["", "A31", "A31 child 2"]);

// will create all intermenient nodes with respective names:
var veryDeepChild =  findNodeByName(treeData, ["foo", "bar", "baz", "quux", "moo"], true);

function createOuterNode(name, childNode) {
    return {name: name, children: childNode? [childNode] : []}
}

// Example to create nodes in the question:
var CNode = createOuterNode("C");
var BNode = createOuterNode("B", CNode);
var ANode = createOuterNode("A", BNode);

// Example using LOOP:
var list = ["A", "B", "C"];
var outer = undefined;
for (var i = list.length - 1; i >= 0; i--) outer = createOuterNode(list[i], outer);

// outer will contain A node with child B with child C
console.log(outer);
irezvin
  • 101
  • 5
  • Hey thanks. I would like the var treeData to represent the entire hierarchy created and its data. Is this done in the code you have shown me.I am sorry but I am still novice. – user1684586 Sep 20 '12 at 16:26
  • In the example I provided, executed code will leave treeData in exact state that you specified in the question (but I hardly can guess why do you need to create such simple array 'dynamically' instead of using quite a readable JSON-like declaration) – irezvin Sep 20 '12 at 16:31
  • Lol. Well it should not be that simple. I was initially using JSON, but I needed the hierarchy to be able to 'grow'. The code in my original question describes the general structure and workings of how the hierarchy should look and work. But I need it to work as if the number of levels and the depth of each of the levels in the hierarchy is not known. The code I provided, and the code You provided, both allow for this 3 levels in the hierarchy. The structure should remain the same as described above, but the levels and size of the hierarchy should be dynamic. – user1684586 Sep 20 '12 at 16:47
  • How do I alter the code to allow for any number (in my case it should'nt be more than 5) of levels depending on the data source to be be generated. treeData should again represent the entire hierarchy produced. How do I do this? through a Loop? Can You help with this please? I would really appreciate it :) PS. I am sorry that I was unclear before on how it should work. – user1684586 Sep 20 '12 at 16:47
  • See my updated answer for the example of infinite tree traversal using path array. You can modify the function to use child names instead of indexes – irezvin Sep 20 '12 at 16:54
  • I am a bit confused with this updated code. Does this still produce the same 3 levels. What defines the number of levels in the hierarchy and the depth of each of the levels? – user1684586 Sep 20 '12 at 17:06
  • this example has 4 levels indeed. Just add more indexes to the path parameter. `findNodeByPath(root, [])` returns `root`; `findNodeByPath(root, [N])` returns Nth node on 1st level; `findNodeByPath(root, [a, b, c, d, e])` returns `root.children[a].children[b].children[c].children[d].children[e]` (on 5th level) and so on – irezvin Sep 20 '12 at 17:09
  • I am attempting to see it work, but I am having trouble modifying the function to use the child name instead of the indexes as you told me to. How do I do this. I am sorry to be a bother. I kinda new to this level of code. – user1684586 Sep 20 '12 at 17:18
  • Do I have to make any changes to indexes or anything to allow this to work with my code. Just as it is above, it doesn't work. Do I hae to change an index format of anything? How do I change indexes to child names so that I can see how it works? – user1684586 Sep 20 '12 at 17:32
  • I haven't seen your code; if you will take the code from my example (one in the grey fields) and execute it, it will work. Probably you still have to read something on tree traversal [here](http://stackoverflow.com/questions/722668/traverse-all-the-nodes-of-a-json-object-tree-with-javascript) or [here](https://www.google.com/search?q=dynamic%20tree%20traversal%20in%20javascript) to properly use it. – irezvin Sep 20 '12 at 17:36
  • The first code you gave me, that is the createnode(), worked great, except for the fact that there were a fixed 3 levels. This new code is giving problems to integrate with the code I am using. The code That I am using can be seen here: http://bl.ocks.org/1312406. You will see the oirginal var treeData here. – user1684586 Sep 20 '12 at 17:43
  • To create node in any position of hierarchy, you have to find its parent with findNodeByPath() or findNodeByName() and then call createNode(). Also I'm going to update my example with 'create' param for findNodeByName() - take a look – irezvin Sep 20 '12 at 17:46
  • I am finding it very difficult to integrate this code with that of bl.ocks.org/1312406. The first example that you gave me worked great for the 3 levels. I have been trying to alter that code to achieve the dynamic hierarchy building that I want. – user1684586 Sep 20 '12 at 17:59
  • Can something of this nature work: That is using Loops here. function createNode(name) { return({name: name, children: []}); } function addChild(node, child) { node.children.push(child); //loop here return node; } var treeData = createNode(""); var subChild = createNode(""); addChild(subChild, createNode("A31")); //Loop here addChild(treeData, subChild); – user1684586 Sep 20 '12 at 18:00
  • To create nodes from blocks example you can use my code: `var root=createNode("A"); findNodeByName(root, ["A1"], true); findNodeByName(root, ["A2"], true); findNodeByName(root, ["A2", "A31", "A311"], true); findNodeByName(root, ["A2", "A31", "A312"], true);`. Intermediate nodes A2 and A31 will be added too. – irezvin Sep 20 '12 at 18:02
  • smh.This does not seem to work with me. I am sorry for that. Like my previous comment: Can I include loops in the first code you gave me (function createNode(name)) to dynamically generate nodes in the hierarchy. – user1684586 Sep 20 '12 at 18:19
  • Please update your question with examples of array 'before' and 'after' function call and I will try to figure out what do you want to do – irezvin Sep 20 '12 at 19:48
  • I have made the changes to the original question. Check it out. Please let me know if you understand this. I will try to explain it better. I really need help, I have been at this for days now. – user1684586 Sep 20 '12 at 20:30
  • Look, you tell that "THE ARRAY AFTER SHOULD BE POPULATED DEPENDING ON THE NUMBER OF NODES NEEDED THAT WILL BE DEFINED FROM A DYNAMIC VALUE THAT IS PASSED". But to pouplate the array, the number of nodes is just not enough, where should we take information about node names and parent-child relationships? Please explain. If we have only number, should we interpret it as depth? If yes, how should we guess names of sub-nodes? – irezvin Sep 20 '12 at 21:53
  • The node names will be derived from a database, which I know how to do. But my problem is building the hierarchy. My actual use for this code will be applied to show the levels in differnet school programme. So I am trying to figure out the depth yes, as you said, and how to build it dynamically because the levels for programmes may vary. One programme may have 3 levels (certificate, diploma, bachelor's degree-in the case of a BSC degree), while another may have only 2 levels(certificate and diploma-in the case of a diploma). Pleas help. – user1684586 Sep 20 '12 at 22:02
  • Please take a look at createOuterNode() function in the example and onwards. Also give some example from data from a database. – irezvin Sep 20 '12 at 22:05
  • Thanks, I will try this now, but I need for the entire hierarchy created to be represented by the var treeData, so I can call it. How do I do this? – user1684586 Sep 20 '12 at 22:09
  • In my example with the loop, root node always changes, just change outer to treeData. But it will be much more helpful if you will provide an example of input data (or I will die while trying to guess what exactly you need to accomplish) – irezvin Sep 20 '12 at 22:11
  • Like I said in my previous comment, the data to be displayed on the hierarchy are to be levels of school courses. For example the structure of one particular programme may be 'UCL year1' as root node, 'UCL year2' as 2nd node and 'UCL Final Year' as last node. The depth and number of nodes will vary. – user1684586 Sep 20 '12 at 22:22
  • It is not enough. Do you have an array with such structure: [[node2label, parentNodeLabel], [node2label, parentNode2Label]]? – irezvin Sep 20 '12 at 22:26
  • I have update my question to include the code that I am using. This uses Mysql, php and javascript. I hope this shows you how the data will be populated to the hierarchy. Of course this is my first rough version that misses much detail. – user1684586 Sep 20 '12 at 22:29
  • As you can see from the above code, the var treeData must hold the hierarchy, and its data is populated from the database through php. – user1684586 Sep 20 '12 at 22:30
  • Oh, your code is completely broken on server-side. I would happily help you but I can't spend more time. I suggest to create new question and provide these details: - some rows from Products table - how javascript tree should look like for these Products And, of course, whole page you have posted above. – irezvin Sep 20 '12 at 22:34
  • [[rootnode, node1[node2[node3[node4]]]] I think this represents what I am trying to do. Tell me what you think :) – user1684586 Sep 20 '12 at 22:36
  • Ok well I really appreciated your help (Y) – user1684586 Sep 20 '12 at 22:38