How to create link between nodes from different svg elements using d3.js

941 views Asked by At

UPDATED : I am working a visualization using D3.js (javascript library). My requirement is as follows: There are multiple number of groups ( represented as rectangular boxes), and there are multiple number of nodes in each group. We are given with the set of links between various nodes. I also want to use force directed layout. We can move boxes and nodes across the screen and links should also move accordingly.

I am able to create boxes and nodes inside the boxes but not able to create links. The links are not getting aligned with the nodes and also the links are not moving in accordance to movement of nodes. Can anyone please help me? Here is the jsfiddle link of my code.

http://jsfiddle.net/s6y183mh/32/

var width = 600,
height = 500;
radius =10;

var svg = d3.select("body").append("svg")
   .attr("width", 900)
   .attr("height", 800)
   .style("background-color","#ECE9E9")
   .attr("overflow","scroll");

// outer force layout

var graph = {
  "nodes": [
    {"name": "Probe1", "group": 1},
    {"name": "Probe2", "group": 1},
    {"name": "Probe3", "group": 1},
    {"name": "Probe4", "group": 1},
    {"name": "Probe5", "group": 2},
    {"name": "Probe6", "group": 2}
  ],
  "links": [
    {"source": 1, "target": 0, "value": 1},
    {"source": 2, "target": 0, "value": 8},
    {"source": 3, "target": 0, "value": 10},
    {"source": 3, "target": 2, "value": 6},
    {"source": 4, "target": 0, "value": 1}
  ]
};

var outerData = [
    {"group": "A"},
    {"group": "B"},
    {"group": "C"},

    {"group": "D"},
    {"group": "E"},
    {"group": "F"},

    {"group": "G"},
    {"group": "H"},
    {"group": "I"}
];

var outerLayout = d3.layout.force()
   .size([800,800])
   .charge(-8000)
   .gravity(0.1)
   .friction(.7)
   .links([])
   .nodes(outerData)
   .on("tick", outerTick)
   .start();

var outerNodes = svg.selectAll("g.outer")
  .data(outerData, function (d) {return d.group;})
  .enter()
  .append("g")
  .attr("class", "outer")
  .attr("id", function (d) {return d.group;})
  .call(outerLayout.drag());

outerNodes
  .append("rect")
  .style("fill", "#ECE9E9")
  .style("stroke", "black")
  .attr("height",120)
  .attr("width",120);

  var oNode = svg.selectAll(".outer")
    .append("title")
      .text(function(d) { return d.group; });

// inner force layouts

var innerAdata = {
  "nodes": [
    {"name": "Probe 1", "group": 1},
    {"name": "Probe 2", "group": 1},
    {"name": "Probe 3", "group": 1},
    {"name": "Probe 4", "group": 1}
  ],
  "links": [
    {"source": 1, "target": 0, "value": 1},
    {"source": 2, "target": 0, "value": 2}
  ]
};

var innerAlayout = d3.layout.force()
   .size([100,100])
   .charge(-400)
   .gravity(0.75)
   .links([])
   .nodes(graph.nodes)
   .on("tick", innerAtick)
   .start();

var aNode = svg.select(".outer#A");

var innerAnodes = aNode.selectAll("g.inner")
  .data(graph.nodes, function (d) {return d.name;})
  .enter()
  .append("g")
  .attr("id", function (d) {return d.name;})
  .call(innerAlayout.drag()
   .on("dragstart", function(){            
        d3.event.sourceEvent.stopPropagation();
    })
   );

innerAnodes
  .append("circle")
  .style("fill", "#8DD623")
  .style("stroke", "#8DD623")
  .attr("r", 6)
  .attr("class", "inner");

// functions

function outerTick (e) {outerNodes.attr("transform", function (d) {return        "translate(" + d.x + "," + d.y + ")";});
                    outerNodes.attr("x", function(d) { return d.x = Math.max(20, Math.min(width, d.x)); }) 
                                .attr("y", function(d) { return d.y = Math.max(20, Math.min(height, d.y)); });
                    }
function innerAtick (e) {//innerAnodes.attr("cx", function(d) { return d.x = Math.max(radius, Math.min(width - radius, d.x)); })
    //.attr("cy", function(d) { return d.y = Math.max(radius, Math.min(height - radius, d.y)); });
innerAnodes.attr("transform", function (d) {return "translate(" + (d.x +10) + "," + (d.y +10) + ")";});
}

 function changeForceOuter(charge, gravity) {
    outerLayout.charge(charge).gravity(gravity);
}
 function changeForceInner(charge, gravity) {
    var tmp = "inner"+"A"+"Layout";
    innerAlayout.charge(charge).gravity(gravity);
}

setTimeout(function(){ changeForceOuter(0,0);
changeForceInner(0,0); 
}, 2000);

(function()
    {
        var force = d3.layout.force()
                  .gravity(.5)
                  .charge(-300)
                  .friction(.7)
                  .linkDistance(100)
                  .linkStrength(0)
                  .size([width, height]);

        var link = svg.selectAll(".line")
                      .data(graph.links)
                      .enter().append("line")
                      .style("fill", "green" )

        var temp = svg.selectAll(".inner")
                  .style("fill","red");


        var node = svg.selectAll(".inner")
                      //.data(graph.nodes)
                      .append("title")
                      .text(function(d) { return d.name; });

        node = svg.selectAll(".inner")
                  .data(graph.nodes)
                  .enter().append("circle")
                 .attr("r", radius - .75)
                 .style("fill", "red" );
        node.append("title")
       .text(function(d) { return d.name; });

        force
          .nodes(graph.nodes)
           .links(graph.links)
           .on("tick", tick)
           .start();

       /*while (force.alpha() >0.005) {
             force.tick();
         }*/
         function changeForce(charge, gravity) {
             force.charge(charge).gravity(gravity);
          }

     //----------------------------

    function tick() {
        node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
        node.attr("cx", function(d) { return d.x = Math.max(radius, Math.min(width - radius, d.x)); })
    .attr("cy", function(d) { return d.y = Math.max(radius, Math.min(height - radius, d.y)); });


     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; });

   }

      function changeForce(charge, gravity) {
        force.charge(charge).gravity(gravity);
    }
    changeForce(0, 0);
})();
0

There are 0 answers