为什么我不能得到D3强制有向图链接标签的工作

Why Can I not Get D3 Force Directed Graph Link Labels to work

本文关键字:链接 有向图 标签 工作 不能 D3 为什么      更新时间:2023-09-26

我正试图将链接标签添加到支持拖放节点的力有向图中,就像这里的例子一样。使用这个例子,我能够创建我的图形修改,以满足我的需求。

我现在想给链接添加标签。我发现这是一个非常常见的问题,我已经在StackOverflow上查看了许多示例,并尝试实现了其中的几个。然而,我所看到的那些不支持拖放节点。我目前正试图使用这里发现的例子作为模板,并添加了似乎创建链接标签到我的项目的代码,但它仍然不起作用。

下面是我的链接标签代码片段:
var vis = d3.select("body").append("svg:svg").attr("width", w).attr("height", h);
var link = vis.selectAll("line.link")
.data(json.links)
.enter().append("svg:line")
.attr("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; })
//****I have added this code to create the link labels****
    vis.append("svg:defs")
    .data(json.links)
    .enter().append("svg:line")
    .attr("id", String)
    .append("svg:path");
var path = vis.append("svg:g").selectAll("path")
.data(force.links())
.enter().append("svg:path")
 .attr("id", function (d) { return d.source.index + "_" +d.target.index; })
.attr("class", function (d) { return "link " + d.linkName; })
.attr("line-end", function (d) { return "url(#" + d.linkName + ")"; });
var path_label = vis.append("svg:g").selectAll(".path_label")
.data(force.links())
.enter().append("svg:text")
.attr("class", "path_label")
.append("svg:textPath")
  .attr("startOffset", "50%")
  .attr("text-anchor", "middle")
  .attr("xlink:href", function (d) { return "#" + d.source.index + "_" + d.target.index; })
  .style("fill", "#000")
  .style("font-family", "Arial")
  .text(function (d) { return d.linkName; });
//****End of added code******

谢谢你的帮助和建议。只是更多的信息,我已经添加的代码,并在上面显示,不会导致图形失败,它呈现图形与节点信息和链接线,它只是不添加标签。

很抱歉没有真正回答您的特定问题,但提供了一个链接到另一个例子。

这是我1.5年前做的课程作业,所以我现在不太记得细节了。在github主页上,你可以找到网络编辑器的热键列表(或者只是在控制台中输入Visualizer.test()作为现成的例子)。

这个编辑器提供了选择/添加/删除图形节点,拖放等-我认为这是你需要的。您可能会发现有用的编辑器源代码的整个部分都在这个文件中。

我希望它能对你有所帮助。

好的,我已经对我正在使用的代码进行了更改,如下所示。

var json = {
"nodes": [
    { "name": "Fabby MONDESIR", "dob": "5.24.97", "ImageUrl": "http://172.18.215.101/MugImageAsp/MUGImageASP.ASP?WCI=RetrieveImage&WCE=FD635099", "group": 1 },
    { "name": "ADNES D BRONSON", "dob": "5.24.97", "ImageUrl": "http://172.18.215.101/MugImageAsp/MUGImageASP.ASP?WCI=RetrieveImage&WCE=FD635098", "group": 1 }
],
"links": [
   { "source": 0, "target": 1, "linkName": "test", "value": 8 }
]
}
var w = 1024, h = 768;

var vis = d3.select("body").append("svg:svg").attr("width",   w).attr("height", h);
//Create a force layout and bind Nodes and Links
var force = self.force = d3.layout.force()
.nodes(json.nodes)
.links(json.links)
.gravity(.05)
.distance(250)
.charge(-100)
.size([w, h])
.start();
//draw lines for links between nodes
var link = vis.selectAll("line.link")
.data(json.links)
.enter().append("svg:line")
.attr("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; });

var node_drag = d3.behavior.drag()
.on("dragstart", dragstart)
.on("drag", dragmove)
.on("dragend", dragend);
function dragstart(d, i) {
force.stop() // stops the force auto positioning before you start dragging
}
function dragmove(d, i) {
d.px += d3.event.dx;
d.py += d3.event.dy;
d.x += d3.event.dx;
d.y += d3.event.dy;
tick(); // this is the key to make it work together with updating both px,py,x,y on d !
}
function dragend(d, i) {
d.fixed = true; // of course set the node to fixed so the force doesn't include the node in its auto positioning stuff
tick();
force.resume();
}
//draw the nodes
var node = vis.selectAll("g.node")
.data(json.nodes)
.enter().append("svg:g")
.call(node_drag);
//place photos on the nodes
node.append("svg:image")
.attr("class", "circle")
.attr("class", "circle")
.attr("xlink:href", function (d, i) {
// d is the node data, i is the index of the node
return d.ImageUrl;
})
.attr("x", "-8px")
.attr("y", "-8px")
.attr("width", "96px")
.attr("height", "96px");
//Append text data for the nodes
node.append("svg:text")
.attr("class", "nodetext")
.attr("dx", 0)//offset to move node data off the picture
.attr("dy", -10)
.style("fill", "blue")
.text(function (d) { return d.name });
node.append("svg:text")
    .attr("class", "nodetext")
    .attr("dx", 0)//offset to move node data off the picture
    .attr("dy", 100)
    .style("fill", "blue")
    .text(function (d) { return d.dob });
// Append text to Link lines
var linkText = vis.selectAll(".link")
.data(json.links)
.append("text")
.attr("font-family", "Arial, Helvetica, sans-serif")
.attr("x", function (d) {
if (d.target.x > d.source.x) { return (d.source.x + (d.target.x - d.source.x) / 2); }
else { return (d.target.x + (d.source.x - d.target.x) / 2); }
})
.attr("y", function (d) {
    if (d.target.y > d.source.y) { return (d.source.y + (d.target.y - d.source.y) / 2); }
    else { return (d.target.y + (d.source.y - d.target.y) / 2); }
})
.attr("fill", "Black")
.style("font", "normal 12px Arial")
.attr("dy", ".35em")
.text(function (d) { return d.linkName });

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

正在绘制图形,但仍然没有文本被附加到链接行。当我调试时,我可以看到从绘图中拉出的x y坐标和从数据中拉出的linkName,我只是无法弄清楚为什么文本不被显示。

我终于想出了如何让它工作。工作代码如下所示,供任何正在寻找支持带线标签

的拖放节点的力向图的人使用。
var json = {
"nodes": [
{ "name": "Fabby MONDESIR", "dob": "5.24.97","group": 1 },
{ "name": "ADNES D BRONSON", "dob": "5.24.97","group": 1 }
],
"links": [
   { "source": 0, "target": 1, "linkName": "FCC", "value": 8 },
   { "source": 0, "target": 2, "linkName": "Arr", "value": 10 }
]
}
var w = 1024,
h = 768
var vis = d3.select("body").append("svg:svg")
.attr("width", w)
.attr("height", h);
//Create a force layout and bind Nodes and Links
var force = self.force = d3.layout.force()
    .nodes(json.nodes)
    .links(json.links)
    .gravity(.05)
    .distance(250)
    .charge(-100)
    .size([w, h])
    .start();
//draw lines for links between nodes
var link = vis.selectAll(".gLink")
.data(json.links)
          .enter().append("g")
            .attr("class", "gLink")
          .append("line")
            .attr("class", "link")
            .style("stroke", "#ccc")
            .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; });
/*  .data(json.links)
    .enter().append("svg:line")
    .attr("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; });*/

var node_drag = d3.behavior.drag()
    .on("dragstart", dragstart)
    .on("drag", dragmove)
    .on("dragend", dragend);
function dragstart(d, i) {
    force.stop() // stops the force auto positioning before you start dragging
}
function dragmove(d, i) {
    d.px += d3.event.dx;
    d.py += d3.event.dy;
    d.x += d3.event.dx;
    d.y += d3.event.dy;
    tick(); // this is the key to make it work together with updating both px,py,x,y on d !
}
function dragend(d, i) {
    d.fixed = true; // of course set the node to fixed so the force doesn't include the node in its auto positioning stuff
    tick();
    force.resume();
}
//draw the nodes
var node = vis.selectAll("g.node")
    .data(json.nodes)
  .enter().append("svg:g")
    .call(node_drag);
//place mug shots on the nodes
node.append("svg:image")
    .attr("class", "circle")
    .attr("class", "circle")
.attr("xlink:href", function (d, i) {
    // d is the node data, i is the index of the node
    return d.ImageUrl;
})
    .attr("x", "-8px")
    .attr("y", "-8px")
    .attr("width", "96px")
    .attr("height", "96px");
//Append text data for the nodes
node.append("svg:text")
    .attr("class", "nodetext")
    .attr("dx", 0)//offset to move node text off the picture
    .attr("dy", -10)
    .style("fill", "blue")
    .text(function (d) { return d.name });
node.append("svg:text")//this gives us a second text line under the picture
        .attr("class", "nodetext")
        .attr("dx", 0)//offset to move node text off the picture
        .attr("dy", 100)
        .style("fill", "blue")
        .text(function (d) { return d.dob });
// Append text to Link lines
var linkText = vis.selectAll(".gLink")
    .data(json.links)
    .append("text")
    .attr("font-family", "Arial, Helvetica, sans-serif")
    .attr("class", "link")
    .attr("x", function (d) {
        if (d.target.x > d.source.x) { return (d.source.x + (d.target.x - d.source.x) / 2); }
        else { return (d.target.x + (d.source.x - d.target.x) / 2); }
    })
    .attr("y", function (d) {
        if (d.target.y > d.source.y) { return (d.source.y + (d.target.y - d.source.y) / 2); }
        else { return (d.target.y + (d.source.y - d.target.y) / 2); }
    })
    //.attr("fill", "red")
    .style("fill", "Red")
    .style("font", "normal 12px Arial")
   .attr("dy", ".35em")
    .text(function (d) { return d.linkName });

force.on("tick", tick);
function tick() {
    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 + ")"; });
    linkText
      .attr("x", function (d) {
          if (d.target.x > d.source.x) { return (d.source.x + (d.target.x - d.source.x) / 2); }
          else { return (d.target.x + (d.source.x - d.target.x) / 2); }
      })
      .attr("y", function (d) {
          if (d.target.y > d.source.y) { return (d.source.y + (d.target.y - d.source.y) / 2); }
          else { return (d.target.y + (d.source.y - d.target.y) / 2); }
      });
}

谢谢