我正在尝试使用此代码使用D3在力图中绘制一些带有标签的有向链接:
// Per-type markers, as they don't inherit styles.
var svg = d3.select("body").select("svg");
svg.append("svg:defs").selectAll("marker")
.data(["end"])
.enter().append("svg:marker")
.attr("id", "arrow")
.attr("viewBox", "0 -5 10 10")
.attr("refX", 15)
.attr("refY", -0.8)
.attr("markerWidth", 6)
.attr("markerHeight", 6)
.attr("orient", "auto")
.append("svg:path")
.attr("d", "M0,-5L10,0L0,5");
// add the links and the arrows
var path = svg.append("svg:g").selectAll("path")
.data(force.links())
.enter().append("svg:path")
.attr("class", "link")
.attr("marker-mid", "url(#arrow)");
var marker = vis.selectAll("marker")
.data(force.links());
marker.append("text")
.attr("text-anchor", "middle")
.attr("font-family", "Arial, Helvetica, sans-serif")
.attr("fill", "Black")
.style("font", "normal 12px Arial")
.attr("transform", function(d) {
return "translate(" +
((d.source.y + d.target.y)/2) + "," +
((d.source.x + d.target.x)/2) + ")";
})
.attr("dy", ".35em")
.attr("text-anchor", "middle")
.text(function(d){return d.type;});
考虑到任务相当简单,对我来说看起来很多代码。但这是我设法做到的唯一方式,即便如此,文字也没有显示出来。
如果我改变.text(function(d){return d.type;});
for:.text(function(d){console.log(d.type);});
信息记录在控制台中。
我想知道为什么我的文字没有被呈现,以及是否有更简单的方法来做我想做的事。
感谢。
答案 0 :(得分:3)
不是两次.data(force.links());
,而是为每个组创建一个g
元素,并将text
和path
放在其中:
var pg = svg.append("svg:g").selectAll("path")
.data(force.links())
.enter().append("g");
var path = pg.append("path")
.attr("class", "link")
.attr("marker-end", "url(#end)");
var text = pg.append("text")
.text("text")
.style("fill", "black");
然后在tick
函数中更新文本的位置:
function tick() {
path.attr("d", function(d) {
var dx = d.target.x - d.source.x,
dy = d.target.y - d.source.y,
dr = Math.sqrt(dx * dx + dy * dy);
return "M" +
d.source.x + "," +
d.source.y + "A" +
dr + "," + dr + " 0 0,1 " +
d.target.x + "," +
d.target.y;
});
text.attr("transform", function(d) {
return "translate(" + ((d.source.x + d.target.x)/2) + "," + ((d.source.y + d.target.y)/2) + ")"; });
node
.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")"; });
}
由于您似乎正在使用此example,因此对其进行了修改:
<!DOCTYPE html>
<meta charset="utf-8">
<script src="http://d3js.org/d3.v3.js"></script>
<style>
path.link {
fill: none;
stroke: #666;
stroke-width: 1.5px;
}
circle {
fill: #ccc;
stroke: #fff;
stroke-width: 1.5px;
}
text {
fill: #000;
font: 10px sans-serif;
pointer-events: none;
}
</style>
<body>
<script>
// get the data
//d3.csv("force.csv", function(error, links) {
var links = [{"source":"Harry","target":"Sally","value":"1.2"},{"source":"Harry","target":"Mario","value":"1.3"},{"source":"Sarah","target":"Alice","value":"0.2"},{"source":"Eveie","target":"Alice","value":"0.5"},{"source":"Peter","target":"Alice","value":"1.6"},{"source":"Mario","target":"Alice","value":"0.4"},{"source":"James","target":"Alice","value":"0.6"},{"source":"Harry","target":"Carol","value":"0.7"},{"source":"Harry","target":"Nicky","value":"0.8"},{"source":"Bobby","target":"Frank","value":"0.8"},{"source":"Alice","target":"Mario","value":"0.7"},{"source":"Harry","target":"Lynne","value":"0.5"},{"source":"Sarah","target":"James","value":"1.9"},{"source":"Roger","target":"James","value":"1.1"},{"source":"Maddy","target":"James","value":"0.3"},{"source":"Sonny","target":"Roger","value":"0.5"},{"source":"James","target":"Roger","value":"1.5"},{"source":"Alice","target":"Peter","value":"1.1"},{"source":"Johan","target":"Peter","value":"1.6"},{"source":"Alice","target":"Eveie","value":"0.5"},{"source":"Harry","target":"Eveie","value":"0.1"},{"source":"Eveie","target":"Harry","value":"2.0"},{"source":"Henry","target":"Mikey","value":"0.4"},{"source":"Elric","target":"Mikey","value":"0.6"},{"source":"James","target":"Sarah","value":"1.5"},{"source":"Alice","target":"Sarah","value":"0.6"},{"source":"James","target":"Maddy","value":"0.5"},{"source":"Peter","target":"Johan","value":"0.7"}];
var nodes = {};
// Compute the distinct nodes from the links.
links.forEach(function(link) {
link.source = nodes[link.source] ||
(nodes[link.source] = {name: link.source});
link.target = nodes[link.target] ||
(nodes[link.target] = {name: link.target});
link.value = +link.value;
});
var width = 960,
height = 500;
var force = d3.layout.force()
.nodes(d3.values(nodes))
.links(links)
.size([width, height])
.linkDistance(60)
.charge(-300)
.on("tick", tick)
.start();
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
// build the arrow.
svg.append("svg:defs").selectAll("marker")
.data(["end"]) // Different link/path types can be defined here
.enter().append("svg:marker") // This section adds in the arrows
.attr("id", String)
.attr("viewBox", "0 -5 10 10")
.attr("refX", 15)
.attr("refY", -1.5)
.attr("markerWidth", 6)
.attr("markerHeight", 6)
.attr("orient", "auto")
.append("svg:path")
.attr("d", "M0,-5L10,0L0,5");
// add the links and the arrows
var pg = svg.append("svg:g").selectAll("path")
.data(force.links())
.enter().append("g");
var path = pg.append("path")
.attr("class", "link")
.attr("marker-end", "url(#end)");
var text = pg.append("text")
.text("My Awesome Text!!")
.style("fill", "black");
// define the nodes
var node = svg.selectAll(".node")
.data(force.nodes())
.enter().append("g")
.attr("class", "node")
.call(force.drag);
// add the nodes
node.append("circle")
.attr("r", 5);
// add the text
node.append("text")
.attr("x", 12)
.attr("dy", ".35em")
.text(function(d) { return d.name; });
// add the curvy lines
function tick() {
path.attr("d", function(d) {
var dx = d.target.x - d.source.x,
dy = d.target.y - d.source.y,
dr = Math.sqrt(dx * dx + dy * dy);
return "M" +
d.source.x + "," +
d.source.y + "A" +
dr + "," + dr + " 0 0,1 " +
d.target.x + "," +
d.target.y;
});
text.attr("transform", function(d) {
return "translate(" + ((d.source.x + d.target.x)/2) + "," + ((d.source.y + d.target.y)/2) + ")"; });
node
.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")"; });
}
//});
</script>
</body>
</html>
&#13;