D3: problems between nodes and links
I created the following jsfiddle to get an idea of what i'm trying to achieve:
I want nodes to over(?) links...
Please help me. I'm sorry for my English :)
Script looks like this:
function myGraph(el) {
this.addNode = function (id) {
nodes.push({ "id": id });
update();
}
this.removeNode = function (id) {
var i = 0;
var n = findNode(id);
while (i < links.length) {
if ((links[i]['source'] == n) || (links[i]['target'] == n)) links.splice(i, 1);
else i++;
}
nodes.splice(findNodeIndex(id), 1);
update();
}
this.addLink = function (source, target) {
links.push({ "source": findNode(source), "target": findNode(target) });
update();
}
var findNode = function (id) {
for (var i in nodes) { if (nodes[i]["id"] === id) return nodes[i] };
}
var findNodeIndex = function (id) {
for (var i in nodes) { if (nodes[i]["id"] === id) return i };
}
// set up the D3 svg in the specified element
var w = window.jQuery(el).innerWidth(),
h = window.jQuery(el).innerHeight();
var svg = this.svg = d3.select(el).append("svg:svg")
.attr("width", w)
.attr("height", h);
var force = d3.layout.force()
.gravity(.05)
.distance(100)
.charge(-120)
.size([w, h]);
var nodes = force.nodes(),
links = force.links();
var update = function () {
var link = svg.selectAll(".link")
.data(links, function (d) { return d.source.id + "-" + d.target.id; })
link.enter().append("line")
.attr("class", "link")
link.exit().remove();
var node = svg.selectAll(".node")
.data(nodes, function (d) { return d.id; })
node.enter().append("g")
.attr("class", "node")
.call(force.drag);
node.append("circle")
.attr("r", function (d) { return 30; })
.style("fill", "#EFEFEF")
node.append("text")
.attr("text-anchor", "right")
.text(function (d) { return d.id; });
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; });
node.attr("transform", function (d) { return "translate(" + d.x + "," + d.y + ")"; });
});
// Restart the force layout.
force.start();
}
// Make it all go
update();
}
graph = new myGraph("#graph");
// You can do this from the console as much as you like...
graph.addNode("Cause");
graph.addNode("Effect");
graph.addLink("Cause", "Effect");
graph.addNode("A");
graph.addNode("B");
graph.addLink("A", "B");
First the formal, techie, definition: A Force Layout in D3 is a strategy for displaying data elements, visually, that position linked nodes using physical simulation. That basically means it is a way to draw a collection of data elements (nodes) and how they relate to each other...
The force layout, through its iterations, will try to arrange the nodes so that all links are approximately this distance, but that won't always be possible. Even when it is technically able to make all links the desired distance, the resulting visualization may have other undesirable properties. Too many links may cross each other, for example.
The force layout, through its iterations, will try to arrange the nodes so that all links are approximately this distance, but that won't always be possible. Even when it is technically able to make all links the desired distance, the resulting visualization may have other undesirable properties.
This allows users to easily see the relationships between elements and the most significant element within the dataset. This guide will demonstrate how to use the d3-force package to create force layout graphs.
There's no z-index
property in SVG; the elements are rendered in the order in which they are specified. This means for you that all the link elements need to be before the node elements in the generated DOM.
The easiest way to achieve this is to have separate g
elements for links and nodes, with the former first.
svg.append("g").attr("class", "links");
svg.append("g").attr("class", "nodes");
Then you can append links like this
var link = svg.select(".links").selectAll(".link")
.data(links, function (d) { return d.source.id + "-" + d.target.id; })
// etc
and nodes likewise. Complete demo here.
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