Search code examples
javascriptnode.jstreeviewes6-modules

create a tree structure the hierarchy -JavaScript


I need assistance with creating a tree structure showing the hierarchy, I have a working code but my issue is with formatting the data to be displayed since the data is coming from 2 different arrays variables.

This how the output be should formatted.

  • Terry Cats - Chief Creative Officer: Executive
    • Nick Thompson - Head of Design: Operations
      • Nick Jenson - Intern designer: Interns
  • Bruce Davids - Chief Strategy Officer: Executive
    • David Smith - Head of Development: Operations
    • John Jones - Head of Marketing: Operations
  • Bill Bass - Chief Executive Officer: Executive

Here's my code.

const staffMembers = [
    { 
        "_id" :0, 
        "name" : "David", 
        "surname" : "Smith", 
        "slug": "david-smith",
        "category" : "operations",
        "title": "Head of Development",
        "reportsTo": "bruce-davids"
    },
    { 
        "_id" :1, 
        "name" : "John", 
        "surname" : "Jones", 
        "slug": "john-jones",
        "category" : "operations",
        "title": "Head of Marketing",
        "reportsTo": "bruce-davids"
    },
    { 
        "_id" :3, 
        "name" : "Nick", 
        "surname" : "Thompson", 
        "slug": "nick-thompson",
        "category" : "operations",
        "title": "Head of Design",
        "reportsTo": "terry-cats"
    },
    { 
        "_id" :4, 
        "name" : "Nick", 
        "surname" : "Jenson", 
        "slug": "nick-jenson",
        "category" : "interns",
        "title": "Intern designer",
        "reportsTo": "nick-thompson" 
    },
    { 
        "_id" :6, 
        "name" : "Terry", 
        "surname" : "Cats", 
        "slug": "terry-cats",
        "category" : "c-suite",
        "title": "Chief Creative Officer",
        "reportsTo": "" 
    },
    { 
        "_id" :7, 
        "name" : "Bruce", 
        "surname" : "Davids", 
        "slug": "bruce-davids",
        "category" : "c-suite",
        "title": "Chief Strategy Officer",
        "reportsTo": "" 
    },
    { 
        "_id" :8, 
        "name" : "Bill", 
        "surname" : "Bass", 
        "slug": "bill-bass",
        "category" : "c-suite",
        "title": "Chief Executive Officer",
        "reportsTo": "" 
    }
]

const categories = [
    { 
        "_id" :0, 
        "name" : "Executive", 
        "parent" : "", 
        "slug" : "c-suite" 
    },
    { 
        "_id" :1, 
        "name" : "Operations", 
        "parent" : "c-suite", 
        "slug" : "operations" 
    },
    { 
        "_id" :2, 
        "name" : "Interns", 
        "parent" : "operations", 
        "slug" : "interns" 
    },
];

const hierarchy = (data) => {
    const tree = [];
    const childOf = {};
    let results = [];
        let cat = "";
        let childrens = [];
    data.forEach((item,index) => {
        const { slug, reportsTo, category } = item;
        // console.log(category);
        childOf[slug] = childOf[slug] || [];
        item.children = childOf[slug];
        reportsTo ? (childOf[reportsTo] = childOf[reportsTo] || []).push(item) : tree.push(item);
        // if(category == categories.slug ){
            cat = category;
            const indexs = categories.findIndex(object => {
                return object._id;
            });
        // }
        });
  
  for(let i = 0;i < tree.length;i++){
    for(let j = 0;j < tree[i].children.length;j++){

        childrens = (tree[i].children[j]);
    }
    results.push(tree[i].name + " " + tree[i].surname + " - " + tree[i].title +": " 
    + cat + '*' + childrens.name + " " + childrens.surname + " - " + childrens.title + ": " + "cat"+cat);
  }
    return results;

};

Solution

  • Adapted from Build tree array from flat array in javascript, here's a function to build a tree from a list of nodes with their parents.

    Printing tree as <UL> function taken from Tree structure in Javascript

    const staffMembers = [{_id:0,name:"David",surname:"Smith",slug:"david-smith",category:"operations",title:"Head of Development",reportsTo:"bruce-davids"},{_id:1,name:"John",surname:"Jones",slug:"john-jones",category:"operations",title:"Head of Marketing",reportsTo:"bruce-davids"},{_id:3,name:"Nick",surname:"Thompson",slug:"nick-thompson",category:"operations",title:"Head of Design",reportsTo:"terry-cats"},{_id:4,name:"Nick",surname:"Jenson",slug:"nick-jenson",category:"interns",title:"Intern designer",reportsTo:"nick-thompson"},{_id:6,name:"Terry",surname:"Cats",slug:"terry-cats",category:"c-suite",title:"Chief Creative Officer",reportsTo:""},{_id:7,name:"Bruce",surname:"Davids",slug:"bruce-davids",category:"c-suite",title:"Chief Strategy Officer",reportsTo:""},{_id:8,name:"Bill",surname:"Bass",slug:"bill-bass",category:"c-suite",title:"Chief Executive Officer",reportsTo:""}];
    const categories = [{_id:0,name:"Executive",parent:"",slug:"c-suite"},{_id:1,name:"Operations",parent:"c-suite",slug:"operations"},{_id:2,name:"Interns",parent:"operations",slug:"interns"},];
    
    function unflatten(arr) {
      var tree = []
    
      var grouped = arr.reduce(function(agg, item) {
        agg[item.slug] = item;
        agg[item.slug].children = []
        return agg;
      }, {})
    
      Object.keys(grouped).forEach(function(key) {
        var value = grouped[key];
        if (value.reportsTo && grouped[value.reportsTo]) {
          grouped[value.reportsTo].children.push(value);
        } else {
          tree.push(value);
        }
      })
    
      return tree;
    }
    
    function print_list(list, ul) {
      for (var i = 0; i < list.length; i++) {
        var li = document.createElement('li');
        li.innerHTML = list[i].name + " " + list[i].surname + " - " + list[i].title;
        // adding category
        li.innerHTML += ": " + categories.find(item => item.slug == list[i].category).name
    
        if (list[i].children.length > 0) {
          var sub_list = document.createElement('ul');
          li.appendChild(sub_list);
          print_list(list[i].children, sub_list);
        }
        ul.appendChild(li);
      }
    }
    
    var result = unflatten(staffMembers)
    print_list(result, document.getElementById('list'));
    <ul id="list"></ul>