I have a force layout with nodes defined as follows...
nodes = someData.map(function (d) {
return {
image_location: d.image_location,
image_width: d.image_width,
image_height: d.image_height,
aspect_ratio: d.aspect_ratio,
radius: circleRadiusScale(d.someCount),
x: width/2,
y: height / 2,
px: width/2,
py: height/2,
cx: width/2,
cy: height / 2
};
});
And then the force layout being created later in the code with...
force = d3.layout.force()
.gravity(.05)
.alpha(0.1)
.size([width, height])
.on("tick", tick);
force.nodes(nodes)
.start();
The reason I've forced the x/y, px/py, cx/cy values is that I'm simply trying to ensure that the nodes don't always start being projected at the top left of the browser (which is only for a split second until the force simulation takes affect, but is pretty noticeable especially on firefox or mobile devices).
What's strange to me is that I'm starting the force layout with my x/y, cx/cy, px/py values BEFORE the code I've written joining circles, images etc that the browser should display - in other words, this code comes AFTER defining/starting the force layout...
node = svg.selectAll(".node")
.data(force.nodes(), function(d) { return d.id; })
.enter()
.append("g")
.attr("class", "node") etc to append circles, images...
So I'm wondering how to hold back the projection of the nodes by the browser until I know the force layout has an initial position of something other than 0,0. Thanks for any thoughts!
I would check the position inside the tick
handler function and initialise once the condition has been met:
var initialized = false;
force.on("tick", function() {
if(!initialized) {
// can also check multiple nodes here...
if(nodes[0].x != width/2 && nodes[0].y != height/2) initialize();
} else {
// update node positions
}
});
function initialize() {
node = svg.selectAll(".node")
.data(force.nodes(), function(d) { return d.id; })
.enter()
.append("g")
.attr("class", "node") // etc
initialized = true;
}
In my case, nodes inited and displayed before call tick(). So they will display at top left of screen firstly, after that call tick() to translate to real position in graph. Just hidden node when add graphic:
nodeEnter.style("visibility", "hidden")
And, visible in tick() function:
nodeEnter.style("visibility", "visible")
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With