Search code examples
javascriptjsond3.jsgraphhierarchy

Trying to connect D3 Nodes from "flat" JSON to make company heirarchy graph


I am trying to create a company hierarchy graph using D3..using the code from this example:

http://bl.ocks.org/mbostock/2949981

Is there a way to create that graph from this json:

      links = [
        {
            "Source": "1",
            "Target": "2",
        },
        {
            "Source": "1",
            "Target" : "3"
        },
        {
            "Source": "2",
            "Target": "4",
        },
        {
            "Source": "2",
            "Target": "5",
        },
        {
           "Source" : "3",
           "Target" " "6"
        }
    ]

      nodes = [
        {
            "Id": "1",
            "Name": "TEST NODE ONE",
            "Url": "http://www.google.com"
        },
        {
            "Id": "2",
            "Name": "TEST NODE TWO",
            "Url": "http://www.yahoo.com"
        },
        {
            "Id": "3",
            "Name": "TEST NODE THREE",
            "Url": "http://www.stackoverflow.com"
        },
        {
            "Id": "4",
            "Name": "TEST NODE FOUR",
            "Url": "http://www.reddit.com"
        }
         {
            "Id": "5",
            "Name": "TEST NODE FIVE",
            "Url": "http://www.stack.com"
        }
        {
            "Id": "6",
            "Name": "TEST NODE SIX",
            "Url": "http://www.six.com"
        }

    ]

I want to make each node a rectangle where I can put the employee name, which comes from the "nodes" json. But connect each node with the data in the "link" json. Feel free to alter the link json to have it make more sense to you.

I would also like to make the lines connecting the nodes straight and make it vertical as well but my main concern is displaying the graph on the page via the json above.

Thanks for the help.


Solution

  • You need to convert your links, which associates between ids of nodes, to an array that associates — via reference — between the actual objects in nodes. A simple loop does this:

    var links = [ { "Source": "1", "Target": "2" }, ... ]
    var nodes = [ { "Id": "1", "Name": "TEST NODE ONE", "Url": "http://www.google.com" }, ... ]
    
    var cachedNodesById = {};
    var linksBetweenNodeObjs = links.map(funciont(link) {
      return {
        source: nodeById(link.Source),
        target: nodeById(link.Target)
      };
    });
    
    function nodeById(id) {
      // return the node if it's been found before, otherwise loop over the
      // array to find it
      if(cachedNodesById[id] != null) { return cachedNodesById[id]; }
      else {
        for(var i=0; i < nodes.length; i++) {
          if(nodes[i].Id == id) { return cachedNodesById[id] = nodes[i]; }
        }
      }
    }