问题
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");
回答1:
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.
来源:https://stackoverflow.com/questions/21304427/d3-force-layout-links-and-nodes-z-index