Reputation: 231
I forked and modified following JSfiddle. Here's the js-code
var graph = {
"nodes": [{
"name": "a",
"group": 1
}, {
"name": "a",
"group": 1
}, {
"name": "a",
"group": 1
}, {
"name": "a",
"group": 1
}, {
"name": "b",
"group": 8
}],
"links": [{
"source": 1,
"target": 0,
"value": 1
}, {
"source": 2,
"target": 0,
"value": 1
}, {
"source": 3,
"target": 0,
"value": 1
}, {
"source": 4,
"target": 0,
"value": 1
}]
};
var width = 600,
height = 600;
var color = d3.scale.category20();
var force = d3.layout.force()
.charge(-120)
.linkDistance(30)
.size([width, height]);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
var drawGraph = function(graph) {
force
.nodes(graph.nodes)
.links(graph.links)
.start();
var link = svg.selectAll(".link")
.data(graph.links)
.enter().append("line")
.attr("class", "link")
.style("stroke-width", function(d) {
return Math.sqrt(d.value);
});
var gnodes = svg.selectAll('g.gnode')
.data(graph.nodes)
.enter()
.append('g')
.classed('gnode', true)
.call(force.drag);
var node = gnodes.append("circle")
.attr("class", "node")
.attr("r", 10)
.style("fill", function(d) {
return color(d.group);
});
node.append("title")
.text(function(d) {
return d.name;
});
var labels = gnodes.append("text")
.text(function(d) {
return d.name;
})
.attr('text-anchor', 'middle')
.attr('font-size', 12.0)
.attr('font-weight', 'bold')
.attr('y', 2.5)
.attr('fill', d3.rgb(50, 50, 50))
.attr('class', 'node-label')
.append("svg:title")
.text(function(d) {
return d.name;
});
force.on("tick", function() {
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;
})
.each(function(d) {
console.log(Math.sqrt((d.source.x - d.target.x) * (d.source.x - d.target.x) + (d.source.y - d.target.y) * (d.source.y - d.target.y)));
});
gnodes.attr("transform", function(d) {
return 'translate(' + [d.x, d.y] + ')';
});
});
};
drawGraph(graph);
Now here's my question:
(How) Is it possible to get and extract the node's positions after the Force-Directed Algorithm finished rendering? I need to save the node positions in a JSON to work with a pre-rendered svg graph in another framework. The best would be to have normalized position values, based on a canvas size 600*600
Thanks for your help!
Upvotes: 2
Views: 1731
Reputation: 3431
You can use end
event of force
which is triggered after all calculations are done. After that you can get nodes via var nodes = force.nodes()
and manipulate with them as you want.
Here the fiddle - open your console, and after all calculation are done it should show nodes with positions.
Please note that it will trigger after every manipulation, you should add some flag to not trigger this callback every time if you want.
Upvotes: 6