使用d3.js在svg path元素上绘制文本

时间:2015-10-08 19:58:05

标签: javascript d3.js svg

我正在尝试修改此force directed graph,特别是我想要做的是在每个图形边缘上绘制文字。我尝试了以下方法:

  // add new links
  path.enter().append('svg:path')
    .attr('class', 'link')
    .classed('selected', function(d) { return d === selected_link; })
    .style('marker-start', function(d) { return d.left ? 'url(#start-arrow)' : ''; })
    .style('marker-end', function(d) { return d.right ? 'url(#end-arrow)' : ''; })
    .on('mousedown', function(d) {
      if(d3.event.ctrlKey) return;

      // select link
      mousedown_link = d;
      if(mousedown_link === selected_link) selected_link = null;
      else selected_link = mousedown_link;
      selected_node = null;
      restart();
    })
    .append('svg:text').attr('x', 0).attr('y', 4)
    .attr('class', 'id').text(function(d) { console.log(d.id); return d.id; })

只有最后一行是我的修改。我还在id个对象中添加了link属性,因此与我合作的代码并不完全与我所链接的相关联。日志语句按预期打印,但不显示任何文本或错误消息。如何在每个link的中间附加文字?

1 个答案:

答案 0 :(得分:1)

您将需要使用svg组<g>,这样您就可以在其中添加元素。

var new_paths = path.enter().append('g'),
    links = new_paths.append('svg:path').attr('class', 'link');

可以根据需要随意添加任何样式或行为links。 然后,对于标签,您将再次追加到该组:

var labels = new_paths.append('svg:text').attr('class', 'label');

您可以再次添加任何内容labels

定义力时,您需要选择链接和标签,如下所示:

force.on("tick", function() {
    links.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){
        return
        "translate("+
            (0.5*(d.source.x+d.target.x))+
        ","+
            (0.5*(d.source.y+d.target.y))+
        ")";
    });
});

这是一个演示小提琴http://jsfiddle.net/k2oyef30/

更新

抱歉,我之前没有按照你的例子。这是您的特殊解决方案。

将路径更改为:

// handles to link and node element groups
var path = svg.append('svg:g').selectAll('.path'),
    circle = svg.append('svg:g').selectAll('g');

function tick() {内,您必须选择.links.id

path.select('.link').attr('d', function(d) {

并管理新元素:

path.select('.id').attr("transform",function(d){
    return "translate("+
        (0.5*(d.source.x+d.target.x))+
    ","+
        (0.5*(d.source.y+d.target.y))+
    ")";
});

function restart() {内,您必须创建<g>元素,例如使用类path,并将元素附加到其中。

// add new links
var newPaths = path.enter().append('svg:g').attr('class','path');

newPaths.append('svg:path')
    .attr('class', 'link')
    .classed('selected', function(d) { return d === selected_link; })
    .style('marker-start', function(d) { return d.left ? 'url(#start-arrow)' : ''; })
    .style('marker-end', function(d) { return d.right ? 'url(#end-arrow)' : ''; })
    .on('mousedown', function(d) {
        if(d3.event.ctrlKey) return;

        // select link
        mousedown_link = d;
        if(mousedown_link === selected_link) selected_link = null;
        else selected_link = mousedown_link;
        selected_node = null;
        restart();
    });

newPaths.append('svg:text').attr('x', 0).attr('y', 4)
    .attr('class', 'id').text(function(d) { return d.id; });

示例定义的问题在于它已选择了<path>元素,因此您无法选择新的<g class="path">