本文介绍了在 D3 力有向图中的链接上添加文本/标签的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在研究修改后的力有向图,但在将文本/标签添加到链接与节点未正确对齐的链接上时遇到了一些问题.如何解决?

以及如何向 SVG 文本元素添加事件侦听器?添加 .on("dblclick",function(d) {....} 只是不起作用.

这是代码片段:

.link { 笔画:#ccc;}.routertext { 指针事件:无;字体:10px 无衬线;填充:#000000;}.routertext2 { 指针事件:无;字体:9px 无衬线;填充:#000000;}.linktext { 指针事件:无;字体:9px 无衬线;填充:#000000;}</风格><div id="画布">

<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">无功 w = 960,h = 600,大小 = [w, h];//宽高var vis = d3.select("#canvas").append("svg:svg").attr("宽度", w).attr("高度", h).attr("transform", "translate(0,0) scale(1)").call(d3.behavior.zoom().on("zoom", redraw)).attr("idx", -1).attr("idsel", -1);无功路由器 = {节点: [{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" }],链接: [{源:0,目标:1,值:3,名称:'link-1',速度:1000mbps",outif:"ge-0/1/0.0",nextif:"ge-5/0/3.0"},{源:1,目标:2,值:3,名称:'link-2',速度:10Gbps",outif:"xe-4/2/0.0",nextif:"xe-1/0/1.0"},{源:2,目标:3,值:3,名称:'link-3',速度:20Gbps",outif:"ae1.0",nextif:"xe-1/2/1.0"},{源:3,目标:4,值:3,名称:'link-4',速度:1Gbps",outif:"as0.0",nextif:"as1.0"},{源:4,目标:5,值:3,名称:'link-5',速度:OC3",outif:"so-4/0/2.0",nextif:"PO0/2/2/1"}]};var force = d3.layout.force().nodes(routers.nodes).links(routers.links).重力(0).距离(100).charge(0).size([w, h]).开始();var link = vis.selectAll("g.link").data(routers.links).enter().append("svg:g");link.append("svg:line").attr(类",链接").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("要添加的一些文本...");var node = vis.selectAll("g.node").数据(路由器.节点).进入().append("svg:g").attr("id", function(d) { return d.id;}).attr("title", function(d) {return d.ip}).attr(类",节点").attr("x", function(d) { return d.x; }).attr("y", function(d) { return d.y; }).on("dblclick",function(d) {alert('路由器双击');d3.event.stopPropagation();}).on(鼠标按下",功能(d){如果(d3.event.which==3){d3.event.stopPropagation();alert('路由器右击');}}).call(force.drag);node.append("svg:image").attr(类",节点").attr("xlink:href", "router.png").attr("x", -24).attr("y", -18).attr("宽度", 48).attr("高度", 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", "一些要显示的标题....").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(转换",函数(d){返回 "translate(" + d.x + "," + d.y + ")";});});函数重绘(){vis.attr("转换",翻译("+ d3.event.translate +)"+ "scale(" + d3.event.scale + ")");};

解决方案

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

I've been working on modified force directed graph and having some problems with adding text/label onto links where the links are not properly aligned to nodes. How to fix it?

And how I can add an event listener to an SVG text element? Adding .on("dblclick",function(d) {....} just doesn't work.

Here's the code snippet:

<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>
解决方案

Use a smaller example outside of D3 to see how the SVG stuff works. Then just rebuild this structure using D3 and your custom data.

<html>
    <body>

<svg width="600px" height="400px">

    <defs>
        <!-- DEFINE AN ARROW THAT WE CAN PLACE AT THE END OF EDGES. -->
        <!-- USE REFX TO MOVE THE ARROW'S TIP TO THE END OF THE PATH. -->
        <marker
            orient="auto"
            markerHeight="12"
            markerWidth="12"
            refY="0"
            refX="9"
            viewBox="0 -5 10 10"
            id="ARROW_ID"
            style="fill: red; fill-opacity: 0.5;">

            <path d="M0, -5L10, 0L0, 5"></path>

        </marker>
    </defs>

    <!-- DEFINE A PATH. SET ITS END MARKER TO THE ARROW'S ID. -->
    <!-- SET FILL NONE TO DRAW A LINE INSTEAD OF A SHAPE. -->
    <path
        d="M100,100 A300,250 0 0,1 500,300"
        style="fill:none; stroke:grey; stroke-width:2px;"
        id="PATH_ID"
        marker-end="url(#ARROW_ID)" />

    <!-- DEFINE A TEXT ELEMENT AND SET FONT PROPERTIES. -->
    <!-- USE DY TO MOVE TEXT ABOVE THE PATH. -->
    <text
        style="text-anchor:middle; font: 16px sans-serif;"
        dy="-12">

        <!-- DEFINE A TEXT PATH FOLLOWING THE PATH DEFINED ABOVE. -->
        <!-- USE STARTOFFSET TO CENTER TEXT. -->
        <textPath
            xlink:href="#PATH_ID"
            startOffset="50%">Centered edge label</textPath>
    </text>

</svg>

    </body>
</html>

这篇关于在 D3 力有向图中的链接上添加文本/标签的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-04 01:24
查看更多