我尝试了一些方法,比如mbostock提出的d3 Node Labeling。但它不起作用,我的文本仍然不随节点移动,它们是静态的。
(使用CoffeeScript编码)
vis = d3.select(selection).append("svg")
.attr("width", width)
.attr("height", height)
linksG = vis.append("g").attr("class", "links")
nodesG = vis.append("g").attr("class", "nodes")
labelG = vis.append("g").attr("class", "labels")
nodeP = nodesG.selectAll("circle.node")
.data(curNodesDataP)
nodeP.enter().append("circle")
.attr("class", "node")
.attr("r", 15)
.style("fill", (d) -> nodeColors(d.id))
.style("stroke", (d) -> strokeFor(d))
.style("stroke-width", 1.0)
.call(force.drag)
text = labelG.selectAll("text")
.data(curNodesDataP)
text.enter().append("text")
.attr("dx", 12)
.attr("dy", ".35em")
.text((d) -> d.id)
我困扰了好几天,我该怎么修呢?谢谢!
- zzcheng
答案 0 :(得分:1)
您将链接,节点和标签附加到单独的g组中。因此,您应该在tick函数(链接组,节点组和标签组)中更新每个组的位置。
这是一个相同的小提琴。请注意,我也在tick函数中更新标签组的位置。
var w = 900,
h = 400;
var circleWidth = 5;
var nodes = [{
"name": "Matteo"
}, {
"name": "Daniele"
}, {
"name": "Marco"
}, {
"name": "Lucio"
}, {
"name": "Davide"
}];
var links = [{
source: nodes[0],
target: nodes[1]
}, {
source: nodes[1],
target: nodes[2]
}, {
source: nodes[0],
target: nodes[3]
}, {
source: nodes[4],
target: nodes[2]
}, {
source: nodes[2],
target: nodes[3]
}];
var vis = d3.select("body")
.append("svg:svg")
.attr("class", "stage")
.attr("width", w)
.attr("height", h);
var force = d3.layout.force()
.nodes(nodes)
.links([])
.gravity(0.1)
.charge(-1000)
.size([w, h]);
var link = vis.selectAll(".link")
.data(links)
.enter().append("line")
.attr("class", "link")
.attr("stroke", "#CCC")
.attr("fill", "none");
var node = vis.selectAll("circle.node")
.data(nodes)
.enter().append("g")
.attr("class", "node")
.call(force.drag);
var labels = vis.selectAll("text.label")
.data(nodes)
.enter().append("g")
.attr("class", "label");
//CIRCLE
node.append("svg:circle")
.attr("cx", function(d) {
return d.x;
})
.attr("cy", function(d) {
return d.y;
})
.attr("r", circleWidth)
.attr("fill", "pink");
//TEXT
labels.append("text")
.text(function(d, i) {
return d.name;
})
.attr("x", function(d, i) {
return circleWidth + 5;
})
.attr("y", function(d, i) {
if (i > 0) {
return circleWidth + 0
} else {
return 8
}
})
.attr("font-family", "Bree Serif")
.attr("fill", "green")
.attr("font-size", "1em")
.attr("text-anchor", function(d, i) {
if (i > 0) {
return "beginning";
} else {
return "end"
}
})
force.on("tick", function(e) {
node.attr("transform", function(d, i) {
return "translate(" + d.x + "," + d.y + ")";
});
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;
});
labels.attr("transform", function(d, i) {
return "translate(" + d.x + "," + d.y + ")";
});
});
force.start();

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
&#13;
其他可能且更有效的方法是将节点和标签组合在一起。这是一个示例小提琴,其中节点和标签被分组,并且仅在tick函数中更新节点组和链接组的位置。
var w = 900,
h = 400;
var circleWidth = 5;
var nodes = [{
"name": "Matteo"
}, {
"name": "Daniele"
}, {
"name": "Marco"
}, {
"name": "Lucio"
}, {
"name": "Davide"
}];
var links = [{
source: nodes[0],
target: nodes[1]
}, {
source: nodes[1],
target: nodes[2]
}, {
source: nodes[0],
target: nodes[3]
}, {
source: nodes[4],
target: nodes[2]
}, {
source: nodes[2],
target: nodes[3]
}];
var vis = d3.select("body")
.append("svg:svg")
.attr("class", "stage")
.attr("width", w)
.attr("height", h);
var force = d3.layout.force()
.nodes(nodes)
.links([])
.gravity(0.1)
.charge(-1000)
.size([w, h]);
var link = vis.selectAll(".link")
.data(links)
.enter().append("line")
.attr("class", "link")
.attr("stroke", "#CCC")
.attr("fill", "none");
var node = vis.selectAll("circle.node")
.data(nodes)
.enter().append("g")
.attr("class", "node")
.call(force.drag);
//CIRCLE
node.append("svg:circle")
.attr("cx", function(d) {
return d.x;
})
.attr("cy", function(d) {
return d.y;
})
.attr("r", circleWidth)
.attr("fill", "pink");
//TEXT
node.append("text")
.text(function(d, i) {
return d.name;
})
.attr("x", function(d, i) {
return circleWidth + 5;
})
.attr("y", function(d, i) {
if (i > 0) {
return circleWidth + 0
} else {
return 8
}
})
.attr("font-family", "Bree Serif")
.attr("fill", "green")
.attr("font-size", "1em")
.attr("text-anchor", function(d, i) {
if (i > 0) {
return "beginning";
} else {
return "end"
}
})
force.on("tick", function(e) {
node.attr("transform", function(d, i) {
return "translate(" + d.x + "," + d.y + ")";
});
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;
})
});
force.start();
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
&#13;