Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Svg “中间” “结束”_Svg_D3.js_Label_Force Layout - Fatal编程技术网

Svg “中间” “结束”

Svg “中间” “结束”,svg,d3.js,label,force-layout,Svg,D3.js,Label,Force Layout,还有“dx”属性,它很容易用于填充。但是,我不推荐它,因为Firefox和Opera中存在一个bug,导致它无法与文本锚中间或结尾一起正常工作。只需添加这一行: .attr("text-anchor", "middle") 到行后的代码: node.append("svg:text") 应该是这样的: node.append("svg:text") .attr("text-anchor", "middle") ...... 我使用一个拱作为节点之间的链接,标签文本放置在中间。以下是一段代码

还有“dx”属性,它很容易用于填充。但是,我不推荐它,因为Firefox和Opera中存在一个bug,导致它无法与文本锚中间或结尾一起正常工作。

只需添加这一行:

.attr("text-anchor", "middle")
到行后的代码:

node.append("svg:text")
应该是这样的:

node.append("svg:text")
.attr("text-anchor", "middle")
......

我使用一个拱作为节点之间的链接,标签文本放置在中间。以下是一段代码片段:

<style type="text/css">
    .link { stroke: #ccc; }
    .routertext { pointer-events: none; font: 10px sans-serif; fill: #000000; }
    .routertext2 { pointer-events: none; font: 9px sans-serif; fill: #000000; }
    .linktext { pointer-events: none; font: 9px sans-serif; fill: #000000; }
</style>

<div id="canvas">
</div>

<script type="text/javascript" src="d3/d3.js"></script>
<script type="text/javascript" src="d3/d3.layout.js"></script>
<script type="text/javascript" src="d3/d3.geo"></script>
<script type="text/javascript" src="d3/d3.geom.js"></script>


<script type="text/javascript">

var w = 960,
    h = 600,
    size = [w, h]; // width height    
var vis = d3.select("#canvas").append("svg:svg")
  .attr("width", w)
  .attr("height", h)
  .attr("transform", "translate(0,0) scale(1)")
  .call(d3.behavior.zoom().on("zoom", redraw))
  .attr("idx", -1)
  .attr("idsel", -1)
  ;

var routers = {
    nodes: [
        {id:0, name:"ROUTER-1", group:1, ip: "123.123.123.111",
            x:394.027, y:450.978,outif:"ge-0/1/0.0",inif:""},
        {id:1, name:"ROUTER-2", group:1, ip: "123.123.123.222",
            x:385.584, y:351.513,outif:"xe-4/2/0.0",inif:"ge-5/0/3.0"},
        {id:2, name:"ROUTER-3", group:1, ip: "123.123.123.333",
            x:473.457, y:252.27,outif:"ae1.0",inif:"xe-1/0/1.0"},
        {id:3, name:"ROUTER-4", group:2, ip: "123.123.123.444",
            x:723.106, y:266.569,outif:"as0.0",inif:"ae1.0"},
        {id:4, name:"ROUTER-5", group:3, ip: "123.123.123.555",
            x:728.14, y:125.287,outif:"so-4/0/2.0",inif:"as1.0"},
        {id:5, name:"ROUTER-6", group:3, ip: "123.123.123.666",
            x:738.975, y:-151.772,outif:"",inif:"PO0/2/2/1" }
    ],
    links: [
        {source:0, target:1, value:3, name:'link-1',speed:"1000mbps",
            outif:"ge-0/1/0.0",nextif:"ge-5/0/3.0"},
        {source:1, target:2, value:3, name:'link-2',speed:"10Gbps",
            outif:"xe-4/2/0.0",nextif:"xe-1/0/1.0"},
        {source:2, target:3, value:3, name:'link-3',speed:"20Gbps",
            outif:"ae1.0",nextif:"xe-1/2/1.0"},
        {source:3, target:4, value:3, name:'link-4',speed:"1Gbps",
            outif:"as0.0",nextif:"as1.0"},
        {source:4, target:5, value:3, name:'link-5',speed:"OC3",
            outif:"so-4/0/2.0",nextif:"PO0/2/2/1"}
    ]
};  

var force = d3.layout.force()
      .nodes(routers.nodes)
      .links(routers.links)
      .gravity(0)
      .distance(100)
      .charge(0)
      .size([w, h])
      .start();

var link = vis.selectAll("g.link")
      .data(routers.links)
      .enter().append("svg:g");

  link.append("svg:line")   
      .attr("class", "link")
      .attr("title", function(d) { return "From: "+d.outif+", To: "+d.nextif })
      .attr("style", "stroke:#00d1d6;stroke-width:4px")
      .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; });

  link.append("svg:text")
      .attr("class", "linktext")
      .attr("dx", function(d) { return d.source.x; })
      .attr("dy", function(d) { return d.source.y; })
      .text("some text to add...");

  var node = vis.selectAll("g.node")
      .data(routers.nodes)
     .enter()
      .append("svg:g")
      .attr("id", function(d) { return d.id;})
      .attr("title", function(d) {return d.ip})
      .attr("class", "node")
      .attr("x", function(d) { return d.x; })
      .attr("y", function(d) { return d.y; })
      .on("dblclick",function(d) {
           alert('router double-clicked'); d3.event.stopPropagation();
      })
      .on("mousedown", function(d) {
          if (d3.event.which==3) {
              d3.event.stopPropagation();
              alert('Router right-clicked');
          }
      })
      .call(force.drag);

  node.append("svg:image")
      .attr("class", "node")
      .attr("xlink:href", "router.png")
      .attr("x", -24)
      .attr("y", -18)
      .attr("width", 48)
      .attr("height", 36);

  node.append("svg:text")
      .attr("class", "routertext")
      .attr("dx", -30)
      .attr("dy", 20)
      .text(function(d) { return d.name });

  node.append("svg:text")
      .attr("class", "routertext2")
      .attr("dx", 0)
      .attr("dy", -20)
      .attr("title", "some title to show....")
      .text(function(d) { return d.outif })
      .on("click", function(d,i) {alert("outif text clicked");})
      .call(force.drag);

    node.append("svg:text")
      .attr("class", "routertext2")
      .attr("dx", -40)
      .attr("dy", 30)
      .text(function(d) { return d.inif });

  force.on("tick", function() {
    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; });

    node.attr("transform", function(d) {
        return "translate(" + d.x + "," + d.y + ")"; });
    });

  function redraw() {
    vis.attr("transform",
      "translate(" + d3.event.translate + ")"
      + "scale(" + d3.event.scale + ")");
  };

</script>
    var vis = d3.select("body")
     .append("svg")
     .attr("width", 600)
     .attr("height", 400)
     .append("g");

    var force = d3.layout.force()
     .gravity(.05)
     .distance(120)
     .charge(-100)
     .size([600, 400]);
    var nodes = force.nodes(), links = force.links();

    // make an arch between nodes and a text label in the middle
    var link = vis.selectAll("path.link").data(links, function(d) {
       return d.source.node_id + "-" + d.target.node_id; });
    link.enter().append("path").attr("class", "link");

    var linktext = vis.selectAll("g.linklabelholder").data(links);
    linktext.enter().append("g").attr("class", "linklabelholder")
     .append("text")
     .attr("class", "linklabel")
     .attr("dx", 1)
     .attr("dy", ".35em")
     .attr("text-anchor", "middle")
     .text(function(d) { return "my label" });

    // add your code for nodes  ....

    force.on("tick", tick); force.start();

    function tick () {   
     // curve
     link.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;
     });    
     // link label
     linktext.attr("transform", function(d) {
      return "translate(" + (d.source.x + d.target.x) / 2 + "," 
      + (d.source.y + d.target.y) / 2 + ")"; });
     // nodes 
    node.attr("transform", function(d) {
        return "translate(" + d.x + "," + d.y + ")"; });
    }

使用D3之外的一个较小的示例来了解SVG是如何工作的。然后使用D3和您的自定义数据重建这个结构


中心边缘标签

创建了JS FIDLE示例,用于在D3强制布局图中的链接上显示标签

请参阅JS Fiddle中的工作演示:

如下图所示为您的路径提供Id

var path = svg.append("svg:g").selectAll("path")
    .data(force.links())
  .enter().append("svg:path")
    .attr("class", function(d) { return "link " + d.type; })
    .attr("id",function(d,i) { return "linkId_" + i; })
    .attr("marker-end", function(d) { return "url(#" + d.type + ")"; });
通过指定标签的“xlink:href”属性指向其各自的链接/路径,使用SVG textPath元素将标签与上述链接相关联

 var linktext = svg.append("svg:g").selectAll("g.linklabelholder").data(force.links());
     linktext.enter().append("g").attr("class", "linklabelholder")
     .append("text")
     .attr("class", "linklabel")
     .style("font-size", "13px")
     .attr("x", "50")
     .attr("y", "-20")
     .attr("text-anchor", "start")
     .style("fill","#000")
     .append("textPath")
    .attr("xlink:href",function(d,i) { return "#linkId_" + i;})
     .text(function(d) { 
         return "my text"; //Can be dynamic via d object 
     });

您可以添加指向文本svg元素的链接,也许您可以使用jquery绑定此链接。这将使文本在节点内居中,但我相信问题是要求在链接上居中。与
textPath
一样,svg区分大小写(至少在Chrome中),因此属性应为
startOffset