如何在d3.js行添加链接名称?

时间:2016-03-03 09:32:53

标签: javascript d3.js

我能够显示节点并能够通过链接动态连接节点。这里我显示图像而不是节点(圆圈)。但我试图在行顶部显示链接名称。我已经浏览了一些链接,但无法显示名称。

我可以在浏览器检查元素中看到text元素。但文字不可见。这是我的代码。

var nodes = [{"x":100,"y":240,"image":"/fpui/img/lan.png"},{"x":230,"y":240,"image":"/fpui/img/mpvpn_boxsmall.png"},{"x":360,"y":120,"image":"/fpui/img/router.png"},{"x":360,"y":240,"image":"/fpui/img/router.png"},{"x":360,"y":360,"image":"/fpui/img/router.png"},{"x":490,"y":120,"image":"/fpui/img/isp.png"},{"x":490,"y":240,"image":"/fpui/img/isp.png"},{"x":490,"y":360,"image":"/fpui/img/isp.png"},{"x":620,"y":240,"image":"/fpui/img/internet.png"},{"x":750,"y":120,"image":"/fpui/img/server.png"},{"x":750,"y":240,"image":"/fpui/img/server.png"},{"x":750,"y":360,"image":"/fpui/img/server.png"}] jquery-2.0.2.min.js line 4 > eval:405:1
var links = [{"source":0,"target":1,"class":"link-green","name":"LAN"},{"source":1,"target":2,"class":"link-green","name":"WAN1"},{"source":1,"target":3,"class":"link-green","name":"WAN2"},{"source":1,"target":4,"class":"link-green","name":"WAN3"},{"source":2,"target":5,"name":"","class":"link-green"},{"source":3,"target":6,"name":"","class":"link-green"},{"source":4,"target":7,"name":"","class":"link-green"},{"source":5,"target":8,"class":"link-green","name":""},{"source":6,"target":8,"class":"link-green","name":""},{"source":7,"target":8,"class":"link-green","name":""},{"source":8,"target":9,"class":"link-green","name":""},{"source":8,"target":10,"class":"link-green","name":""},{"source":8,"target":11,"class":"link-green","name":""}]

var svg = d3.select('#routeTestDisplay').append('svg')
        .attr('width', width)
        .attr('height', height);

    var force = d3.layout.force()
        .size([width, height])
        .nodes(nodes)
        .links(linkArr)
        .start();
    force.linkDistance(200);
    var link = svg.selectAll('.link')
        .data(linkArr)
        .enter().append('line')
        /*.attr('class', 'link')
         .style("stroke", function(d,i){
         return color(i)
         })*/
        .style("stroke-width", 3);

        link.append("text")
        .attr("class", "link-label")
        .attr("font-family", "Arial, Helvetica, sans-serif")
        .attr("fill", "Black")
        .style("font", "normal 12px Arial")
        .style("color", "black")
        .attr("dy", ".35em")
        .attr("text-anchor", "middle")
        .text(function(d) {
            return d.name;
        })
            .attr("x", function(d) {
                return ((d.source.x + d.target.x)/2);
            })
            .attr("y", function(d) {
                return ((d.source.y + d.target.y)/2);
            });



    var node = svg.selectAll('.node')
        .data(nodes)
        .enter().append('svg:image')
        .attr("width", 50)
        .attr("height", 50)

    node.attr('r', 30)
        .attr("xlink:href", function(d) {
            return d.image;
        })
        .attr('x', function(d) {
            return d.x - 15;
        })
        .attr('y', function(d) {
            return d.y - 30;
        });
    link.attr('class', function(d) {
        return d.class;
    });
    link.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;
        });

你能不能请任何人帮忙如何实现这个目标?

2 个答案:

答案 0 :(得分:1)

您无法将文字追加到某一行,您必须将该行和文字追加到同一父级,如下所示:

var link = svg.selectAll('.link')
    .data(links)
    .enter().append('g') 
    .attr('class', 'link');

var singlelink= link.append('line') //set this as a variable to translate later
   .style('stroke', 'black')
  .style("stroke-width", 3);

link.append("text")
  .attr("class", "link-label") ...

正如代码注释中所提到的,我必须在你翻译链接的那一刻设置你将行追加到链接变量的行到它自己的变量。但链接现在是一个容器而不是线本身。因此,稍后您的翻译功能现在将如下所示:

singlelink.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;
  });

完整的工作代码:

var nodes = [{
  "x": 100,
  "y": 240,
  "image": "/fpui/img/lan.png"
}, {
  "x": 230,
  "y": 240,
  "image": "/fpui/img/mpvpn_boxsmall.png"
}, {
  "x": 360,
  "y": 120,
  "image": "/fpui/img/router.png"
}, {
  "x": 360,
  "y": 240,
  "image": "/fpui/img/router.png"
}, {
  "x": 360,
  "y": 360,
  "image": "/fpui/img/router.png"
}, {
  "x": 490,
  "y": 120,
  "image": "/fpui/img/isp.png"
}, {
  "x": 490,
  "y": 240,
  "image": "/fpui/img/isp.png"
}, {
  "x": 490,
  "y": 360,
  "image": "/fpui/img/isp.png"
}, {
  "x": 620,
  "y": 240,
  "image": "/fpui/img/internet.png"
}, {
  "x": 750,
  "y": 120,
  "image": "/fpui/img/server.png"
}, {
  "x": 750,
  "y": 240,
  "image": "/fpui/img/server.png"
}, {
  "x": 750,
  "y": 360,
  "image": "/fpui/img/server.png"
}] 
//jquery - 2.0.2. min.js line 4 > eval: 405: 1
var links = [{
  "source": 0,
  "target": 1,
  "class": "link-green",
  "name": "LAN"
}, {
  "source": 1,
  "target": 2,
  "class": "link-green",
  "name": "WAN1"
}, {
  "source": 1,
  "target": 3,
  "class": "link-green",
  "name": "WAN2"
}, {
  "source": 1,
  "target": 4,
  "class": "link-green",
  "name": "WAN3"
}, {
  "source": 2,
  "target": 5,
  "name": "",
  "class": "link-green"
}, {
  "source": 3,
  "target": 6,
  "name": "",
  "class": "link-green"
}, {
  "source": 4,
  "target": 7,
  "name": "",
  "class": "link-green"
}, {
  "source": 5,
  "target": 8,
  "class": "link-green",
  "name": ""
}, {
  "source": 6,
  "target": 8,
  "class": "link-green",
  "name": ""
}, {
  "source": 7,
  "target": 8,
  "class": "link-green",
  "name": ""
}, {
  "source": 8,
  "target": 9,
  "class": "link-green",
  "name": ""
}, {
  "source": 8,
  "target": 10,
  "class": "link-green",
  "name": ""
}, {
  "source": 8,
  "target": 11,
  "class": "link-green",
  "name": ""
}]
console.log(links)
var width = 1500,height=1500;
var svg = d3.select('#routeTestDisplay').append('svg')
  .attr('width', width)
  .attr('height', height);

var force = d3.layout.force()
  .size([width, height])
  .nodes(nodes)
  .links(links)
  .start();
force.linkDistance(200);

var link = svg.selectAll('.link')
    .data(links)
    .enter().append('g') 
    .attr('class', 'link');
var singlelink= link.append('line')
   .style('stroke', 'black')
  .style("stroke-width", 3);

link.append("text")
  .attr("class", "link-label")
  .attr("font-family", "Arial, Helvetica, sans-serif")
  .attr("fill", "Black")
  .style("font", "normal 12px Arial")
  .style("color", "black")
  .attr("dy", ".35em")
  .attr("text-anchor", "middle")
  .text(function(d) {
    return d.name;
  })
  .attr("x", function(d) {
    return ((d.source.x + d.target.x) / 2);
  })
  .attr("y", function(d) {
    return ((d.source.y + d.target.y) / 2);
  });



var node = svg.selectAll('.node')
  .data(nodes)
  .enter().append('svg:image')
  .attr("width", 50)
  .attr("height", 50)

node.attr('r', 30)
  .attr("xlink:href", function(d) {
    return "https://www.petfinder.com/wp-content/uploads/2012/11/140272627-grooming-needs-senior-cat-632x475.jpg"
  })
  .attr('x', function(d) {
    return d.x - 15;
  })
  .attr('y', function(d) {
    return d.y - 30;
  });
  
link.attr('class', function(d) {
  return d.class;
});

singlelink.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;
  });
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div id='routeTestDisplay'></div>

P.S

只是旁注,我必须编辑您正在使用的链接数组的名称以及图像,因为显然它们的链接不起作用

答案 1 :(得分:0)

您无法在text中嵌套line元素,它们需要是独立的DOM元素。要使它们具有相同的数据,您可以将它们放在g块中:

 var link = svg.selectAll('.link')
    .data(linkArr)
    .enter().append('g') //link now represents the selection of  g elements  
    .attr('class', 'link') //class can be tricky: here I put the class on the g object, you might want to have a separate one for the line object.

link.append('line') 
    /*.attr('class', 'link')
     .style("stroke", function(d,i){
     return color(i)
     })*/
    .style("stroke-width", 3);

link.append("text")
    (...)