我正在尝试将链接标签添加到强制定向图,并支持拖放节点,如此示例here。使用该示例,我能够创建我的图形,并修改了我的要求。
我现在想为链接添加标签。我在这里看到这是一个非常常见的问题,我已经查看了StackOverflow上显示的许多示例,并尝试实现其中的几个。然而,我所看到的那些没有支持拖放节点。我目前正在尝试使用找到的here示例作为模板,并添加了为我的项目创建链接标签的代码,但它仍然不起作用。
以下是我的链接标签代码段:
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******
感谢您提供任何帮助或建议。更多信息我添加的代码,如上所示,不会导致图形失败,它会使用节点信息呈现图形,而链接线只是不添加标签。
答案 0 :(得分:0)
很抱歉没有真正回答您的具体问题,只提供了另一个示例的链接。
Here's我的课程工作,我做了〜1。5年前所以我现在还没有真正记住细节。在github main page上,您可以找到网络编辑器的热键列表(或者只需在控制台中输入Visualizer.test()
作为示例)。
此编辑器提供图形节点的选择/添加/删除,拖放等等 - 我认为这就是您所需要的。您可能会觉得有用的编辑器源代码的全部内容都在this file中。
我希望它能以某种方式帮助你:)
答案 1 :(得分:0)
好的,我已经对使用下面显示的代码的代码进行了更改。
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,我只能找出文本没有显示的原因。
答案 2 :(得分:0)
我终于想出了如何让它发挥作用。对于正在寻找支持使用行标签拖放节点的强制定向图
的任何人,工作代码如下所示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); }
});
}
由于