D3箭头链接标签

时间:2016-05-10 17:02:10

标签: javascript jquery d3.js

我正在尝试使用此代码使用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);});

信息记录在控制台中。

我想知道为什么我的文字没有被呈现,以及是否有更简单的方法来做我想做的事。

感谢。

1 个答案:

答案 0 :(得分:3)

不是两次.data(force.links());,而是为每个组创建一个g元素,并将textpath放在其中:

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;
&#13;
&#13;