I am building a graph visualization using D3 library. But it is giving some problems. There can be multiple boxes and each box can have multiple nodes inside it. There are links between various links. Nodes should be draggable and links should also drag with their respective links. When i am applying force layout, the nodes are created outside their respective boxes and their respective links. Any help would be greatly appreciated.
Here's my jsfiddle link : http://jsfiddle.net/qfhfzrL2/
var width = 700,
height = 600;
radius =10;
var svg = d3.select("body").append("svg")
.attr("width", 900)
.attr("height", 800)
.style("background-color","#ECE9E9")
.attr("overflow","scroll");
var graph = {
"nodes": [
{"name": "Probe1", "group": "A"},
{"name": "Probe2", "group": "A"},
{"name": "Probe3", "group": "A"},
{"name": "Probe4", "group": "B"},
{"name": "Probe5", "group": "B"},
{"name": "Probe6", "group": "B"},
{"name": "Probe7", "group": "C"}
],
"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"}
];
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",150)
.attr("width",150);
var oNode = svg.selectAll(".outer")
//.data(graph.nodes)
.append("title")
.text(function(d) { return d.group; });
//---------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 changeForceouter(charge, gravity) {
var tmp = "inner"+"A"+"Layout";
outerLayout .charge(charge).gravity(gravity);
}
setTimeout(function(){ changeForceouter(0,0); }, 2000);
//---------------------------
for(var i=0;i<7;i++)
{
var ident = "#" + graph.nodes[i].group;
svg.select(ident).append("circle")
.attr("r", radius - 2)
.style("fill", "#8DD623" );
}
var force = d3.layout.force()
.gravity(.4)
.charge(-300)
.friction(.7)
.linkDistance(1000)
.linkStrength(0)
.size([width, height]);
var link = svg.selectAll("line")
.data(graph.links)
.enter().append("line")
.style("fill", "green" );
var node = svg.selectAll("circle")
.data(graph.nodes)
//.call(force.drag);
.call(force.drag()
.on("dragstart", function(){
d3.event.sourceEvent.stopPropagation();
})
);
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("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; });
}
//---------------------------
/* var populateCell = function(i) {
var ident = "#" + graph.nodes[i].group;
d3.select(ident).append("circle")
.attr("r", radius - .75)
.style("fill", "#8DD623" );
}; */
setTimeout(function(){ changeForce(0, 0);}, 2000);
//changeForce(0, 0);