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

Draw text on svg path element with d3.js

本文关键字:元素 绘制 文本 路径 svg d3 js 使用      更新时间:2023-09-26

我正试图修改这个力向图,特别是我想做的是在每个图边缘上绘制文本。我尝试了以下操作:

  // 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; })
只有最后一行是我修改的。我还为link对象添加了id属性,因此我正在使用的代码并不完全是我所链接的。日志语句按预期打印,但没有出现文本或错误消息。如何在每个link的中间添加文本?

您将需要使用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时,你需要选择链接和标签,就像这样:

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">