I'm trying to pre-calculate the positions of the stable force directed graph using igraph and pass them into my d3.js graph. This is due to the size of the dataset I will be using which means I cannot rely on the client not to freeze if the full force calculation is done on client-side. I have the positions in JSON format and have used linear scales in order to make them useful in d3.js.
var positions =
{"positions": [{"x":"-68.824367374", "y": "-6.10824525755"},
{"x":"-80.8080803911", "y": "-3.38997541264"},
{"x":"6.75334817585", "y": "-49.6040729697"},
{"x":"14.6608797291", "y": "-81.8897019921"},
....
var force = d3.layout.force()
.charge(-100)
.linkDistance(3)
.size([width, height])
.nodes(data.nodes)
.links(data.links)
.start();
var posX = d3.scale.linear()
.range([0,960])
.domain([-125,120]);
var posY = d3.scale.linear()
.range([0,500])
.domain([-125,125]);
And this is the way I've tried to do it. I've experimented with px and py but the results are the same. It's as if this code is never ran. If I throw in a console.log
where seen below, the value does not get printed. This is regardless of where I put this code, be it before or after starting the force.
force.on("start", function() {
node
.data(positions.positions)
.attr("cx", function(d) {
console.log(posX(d.x));
return posX(d.x);
})
.attr("cy", function(d) {
return posY(d.y);
})
});
Why does the on start event not set the initial positions of my nodes? They seem to be initialised randomly still. Alternatively, what's a good way of pre-calculating the stable state of a d3.js force directed graph? I've had a look at doing it on Phantomjs but gave up.
Thank you for taking the time to read my question!
EDIT
Here is a dumbed down example: https://jsfiddle.net/xp0zgqes/ If you run it a few times and pay attention to the starting positions of the nodes you can see they are randomly initialised.