Currently, I am developing a Force Directed Graph using D3 and managed to make it work with svg circles for the nodes. However, when attempting to use div elements along with CSS left and top properties, the positioning of the nodes seems to be incorrect. I am struggling to identify what mistake I might be making in this scenario. I have utilized the x and y coordinates generated by D3 force as the values for the left and top properties, but could this approach be flawed?
Below is the part of my code written in JavaScript:
var url = "https://raw.githubusercontent.com/DealPete/forceDirected/master/countries.json";
d3.json(url, function(json){
var data = json;
var margin = {top: 40, right: 40, bottom: 40, left: 40};
var w = 1000 - margin.left - margin.right;
var h = 1000 - margin.top - margin.bottom;
var svg = d3.select("#chart")
.append("svg")
.attr("width", w + margin.left + margin.right)
.attr("height", h + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var nodes = data.nodes;
var links = data.links;
//Code snippet responsible for defining a force layout object and its properties
var force = d3.layout.force()
.size([w,h])
.nodes(nodes)
.links(links);
force.linkDistance(h/20);
force.charge(-120)
var link = svg.selectAll(".link")
.data(links)
.enter()
.append("line")
.attr("class", "link");
var node = d3.select("#chart").selectAll(".node")
.data(nodes)
.enter()
.append("div")
force.on("end", function(){
//Adjust node and link position attributes once force calculations are complete
//Node positioning
node.style("left", function(d){
return d.x + "px";
})
.style("top", function(d){
return d.y + "px";
})
.attr("class", function(d){
return "flag flag-" + d.code + " node";
})
.attr("src", "https://res.cloudinary.com/dettjqo9j/image/upload/v1485942660/flags_xf9dde.png");
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;
})
})//force.on
force.start();
//Initiate the force calculations
})
My CSS styling:
svg {
background-color: white;
box-shadow: 0 0 10px #888888;
}
.link {
stroke: #2c3e50;
stroke-width: 2px;
}
.flag {
display: inline-block;
position:absolute;
width: 16px;
height: 11px;
background: url('https://res.cloudinary.com/dettjqo9j/image/upload/v1485942660/flags_xf9dde.png') no-repeat;
}
.flag.flag-ml {
background-position: -224px -88px;
}
The current status of the graph on CodePen: