简体   繁体   English

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

[英]Draw text on svg path element with d3.js

I am trying to modify this force directed graph , and in particular what I'd like to do is to draw text on each graph edge. 我正在尝试修改此力导向图 ,特别是我想做的是在每个图的边缘绘制文本。 I tried the following: 我尝试了以下方法:

  // 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; })

Only the last line is my modification. 只有最后一行是我的修改。 I also added an id property to the link objects so the code I'm working with is not exactly what I've linked to. 我还向link对象添加了id属性,因此正在使用的代码与link对象不完全相同。 The log statement is printing as expected but no text or error messages appear. 日志语句按预期打印,但是没有文本或错误消息出现。 How can I append text right in the middle of each link ? 如何在每个link的中间附加文字?

You will need to use the svg group <g> , that will let you append elements inside. 您将需要使用svg组<g> ,这将允许您在其中附加元素。

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

Be free to add whatever style or behaviour to links as you wish. 可以随意向links添加任何样式或行为。 Then, for the labels, you will append again to the group: 然后,对于标签,您将再次追加到该组:

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

And again you can add whatever you want to labels . 同样,您可以在labels添加任何内容。

When you define the force, you will need to select the links and labels, wich will be something like this: 定义力时,需要选择链接和标签,这将是这样的:

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))+
        ")";
    });
});

Here is a demo fiddle http://jsfiddle.net/k2oyef30/ 这是一个演示小提琴http://jsfiddle.net/k2oyef30/

Update 更新资料

Sorry, I didn't follow your example before. 抱歉,我之前没有听过您的榜样。 Here is your particular solution. 这是您的特定解决方案。

Change path to be defined as: 将更改路径定义为:

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

Inside function tick() { you have to select the .links or the .id 内部function tick() {您必须选择.links.id

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

and manage the new element: 并管理新元素:

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))+
    ")";
});

Inside function restart() { you have to create a <g> element, for example with class path , and append the elements into it. function restart() {您必须创建一个<g>元素,例如,使用class 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; });

The problem with the example definition was that it already selected the <path> element making you unable to select the new <g class="path"> 示例定义的问题在于它已经选择了<path>元素,从而使您无法选择新的<g class="path">

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM