CSV File Data:
parent_name, child_name A1, A2 A1, A3 A1, A4 A1, A5 A2, A12 A2, A16 A2, A18 A2, A19
Output: Javascript Object to be made
{ name: A1, children: [ { name: A2, children: [ { name: A4, children: [] } ] }, { name: A3, children: [] } }
Basically, I have to convert a CSV file to make a Tree in d3. I am wondering how to make the dictionary required from the CSV file
d3.csv("test1.csv").then(function (data) { var dataset = {}; data.forEach(function (d,i){ console.log(d.parent_name, d.child_name); if(i === 0){ dataset["name"] = d.parent_name; dataset["children"] = []; } if (dataset["name"] === d.parent_name){ dataset.children.push(NodeMaker(d.child_name)) } }); function NodeMaker(name){ return {"name": name, "children": []}; } console.log(dataset); });
So this is the code, I have which only make a dictionary-like, It doesn’t go deeper than the 1st level of the root node
{ name: A1, children: [ { name: A2, children: [] }, { name: A3, children: [] } ] }
Advertisement
Answer
Currently you’re only checking to see if the node matches the root (first) node. One idea might be to traverse the existing tree and check if the parent node you want to add already exists and then add a child to it. But this has some issues: it requires going back through the data, so it’s inefficient; and what happens if you encounter a parent_node
that isn’t part of the tree yet? As vicatcu pointed out, a more efficient (and robust) way would be to create nodes as you encounter them and keep them in a dictionary/lookup object.
It could look something like this:
var sampleData = [ { parent_name: 'A1', child_name: 'A2' }, { parent_name: 'A1', child_name: 'A3' }, { parent_name: 'A1', child_name: 'A4' }, { parent_name: 'A1', child_name: 'A5' }, { parent_name: 'A2', child_name: 'A12' }, { parent_name: 'A2', child_name: 'A16' }, { parent_name: 'A2', child_name: 'A18' }, { parent_name: 'A2', child_name: 'A19' } ] // if loading from a file, use this line instead to load data // d3.csv("test1.csv").then(function (data) { Promise.resolve(sampleData).then(function (data) { var lookup = {}; data.forEach(function (d,i) { var parentNode = getNode(d.parent_name); parentNode.children.push(getNode(d.child_name)); }); function getNode(name) { if (!lookup[name]) { // if the node doesn't exist, make it lookup[name] = NodeMaker(name); } return lookup[name]; } function NodeMaker(name){ return {"name": name, "children": []}; } // if the first parent node is the root, it represents the whole tree var tree = lookup[data[0].parent_name]; console.log(tree); // do something with `tree` });