Saturday, 28 January 2023

Plotting nodes in a network graph with the help of co-ordinate positions

"nodes": [
{
  "data": {
    "id": 1,
    "desc": "Rohit",
    "pos": [
      121.0284957885742,
      116.3165512084961,
      59.36788940429688
    ]
   }
  },
  {
  "data": {
    "id": 2,
    "desc": "Deep",
    "pos": [
      12.10284957885742,
      116.3165512084961,
      5.936788940429688
    ]
  }
 },
 "data": {
    "id": 3,
    "desc": "Deepa",
    "pos": [
      12.10284957885742,
      11.63165512084961,
      5.936788940429688
    ]
   }
  }
  ]

The above is the co-ordinates of nodes.

"edges": [
{
  "data": {
    "id": "1_2",
    "source": 1,
    "target": 2
  }
}

The above is a sample input for the link. How can I create and assign the positions of nodes in d3 according to the given co-ordinates? I've tried with co-ordinates which has pixel as unit of the co-ordinates but the above sample set does not contain any units as such.

The full code is below...

<!DOCTYPE html>
<meta charset="utf-8">
<style>
 .node {
   fill: blue;
   stroke: black;
   stroke-width: 2px;
  }

 .node.visited {
   fill: red;
 }

 .link {
   stroke-width: 2px;
 }
</style>

<body>
 <script src="https://d3js.org/d3.v3.min.js"></script>
 <script>
   var width = 640,
       height = 480;

   var links = [{
       source: 'Rohit',
       target: 'Deep'
     },
     {
       source: 'Deep',
       target: 'Deepa'
     },
     {
       source: 'Deepa',
       target: 'Rohit'
     },
   ];
   var nodes = {};

   //adding to nodes
   links.forEach(function(link) {
     link.source = nodes[link.source] ||
       (nodes[link.source] = {
         name: link.source
       });

     link.target = nodes[link.target] ||
       (nodes[link.target] = {
         name: link.target
       });
   });

   //adding svg to body

   var svg = d3.select('body').append('svg')
     .attr('width', width)
     .attr('height', height);

   var defs = svg.append('defs');

   var gradient = defs
     .append('linearGradient')
     .attr('id', 'svgGradient')
     .attr('x1', '0%')
     .attr('x2', '10%')
     .attr('y1', '0%')
     .attr('y2', '10%');

   gradient
     .append('stop')
     .attr('class', 'start')
     .attr('offset', '0%')
     .attr('start-color', 'red')
     .attr('start-opacity', 1);

   gradient
     .append('stop')
     .attr('class', 'end')
     .attr('offset', '100%')
     .attr('stop-color', 'blue')
     .attr('stop-opacity', 1);

   var force = d3.layout.force()
     .size([width, height])
     .nodes(d3.values(nodes))
     .links(links)
     .on("tick", tick)
     .linkDistance(300)
     .start();

   var link = svg.selectAll('.link')
     .data(links)
     .enter().append('line')
     .attr('class', 'link')
     .attr('stroke', 'url(#svgGradient)');

   var node = svg.selectAll('.node')
     .data(force.nodes())
     .enter().append('circle')
     .attr('class', 'node')
     .on("click", clicked)
     .attr('r', width * 0.03);

   function clicked(event, d) {
     if (event.defaultPrevented) return; // dragged

     d3.select(this).transition()
       .style("fill", "black")
       .attr("r", width * 0.2)
       .transition()
       .attr("r", width * 0.03)
       .transition()
       .style("fill", "blue")
       //.attr("fill", d3.schemeCategory10[d.index % 10]);
   }


   //define the tick func.
   function tick(e) {
     node
       .attr('cx', function(d) {
         return d.x;
       })
       .attr('cy', function(d) {
         return d.y;
       })
       .call(force.drag);

     link
       .attr('x1', function(d) {
         return d.source.x;
       })
       .attr('y1', function(d) {
         return d.source.y;
       })
       .attr('x2', function(d) {
         return d.target.x;
       })
       .attr('y2', function(d) {
         return d.target.y;
       })

   }
    </script>
  </body>
</html>

Any changes to the above code snippet is acceptable. Please help me in finding the proper solution



from Plotting nodes in a network graph with the help of co-ordinate positions

No comments:

Post a Comment