D3 基于名称而不是索引链接节点 [英] D3 Linking nodes based on names rather than index
问题描述
我正在尝试根据 Id 而不是此 codepen<中的索引链接节点/a>,我不知道该怎么做.
I am trying to link the nodes based on Id rather than the index in this codepen, I am not able to figure out how to do it.
以下工作:
var links = [{ source: 0, target: 1 }];
但是如果我根据名称创建链接,它不会创建任何链接.
But if I create a link based on names, it does not create any link.
var links = [{ source: "FH" , target: "TP" }];
推荐答案
D3v3 强制布局不支持链接中的命名节点.如果您想在不需要任何额外工作的情况下使用它们,我建议使用 d3v4 或 v5.
A D3v3 force layout doesn't support named nodes in the links. I'd suggest d3v4 or v5 if you want to use them without requiring any extra work.
但是,与 REEE 的回答一样,您可以通过更改代码并保留 v3 来达到相同的效果.我没有更改刻度,而是在启动数组之前更改 link
数组:
But, as with REEE's answer, you can achieve the same effect by altering your code and keeping v3. Rather than alter the tick, I'm altering the link
array prior to initiating the array:
var obj = {}
nodes.forEach(function(d,i){
obj[d.id] = i; // create an object to look up a node's index by id
})
links.forEach(function(d) {
d.source = obj[d.source]; // look up the index of source
d.target = obj[d.target]; // look up the index of target
})
这是一个分叉的 plunkr,或者下面的一个片段(我已经将您的节点数组移动到它自己的变量中 - 是的,它被称为节点,稍后会被覆盖):
Here's a forked plunkr, or a snippet below (I've moved your node array into its own variable - yes, it's called nodes and gets overwritten later):
var width = 500,
height = 200;
var fill = d3.scale.category20();
var links = [{ source: "FH", target: "TP" }];
var nodes = [
{ id: "FH", x: 100, y: 110 },
{ id: "TP", x: 200, y: 110 },
{ id: "GW", x: 200, y: 110 },
{ id: "DB", x: 100, y: 110 }
]
var obj = {}
nodes.forEach(function(d,i){
obj[d.id] = i;
})
links.forEach(function(d) {
d.source = obj[d.source];
d.target = obj[d.target];
})
var force = d3.layout
.force()
.size([width, height])
.nodes(nodes)
.links(links)
.linkDistance(150)
.charge(-500)
.on("tick", tick);
var svg = d3
.select("body")
.append("svg")
.attr("width", width)
.attr("height", height);
var arrows = svg
.append("svg:defs")
.selectAll("marker")
.data(["arrow"])
.enter()
.append("marker")
.attr("id", String)
.attr("viewBox", "0 -5 10 10")
.attr("refX", 15)
.attr("refY", -1.5)
.attr("markerWidth", 6)
.attr("markerHeight", 6)
.attr("orient", "auto")
.append("path")
.attr("d", "M0,-5L10,0L0,5");
svg
.append("rect")
.attr("width", width)
.attr("height", height);
var nodes = force.nodes(),
links = force.links(),
node = svg.selectAll(".node"),
link = svg.selectAll(".link");
restart();
function tick() {
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
);
});
node.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")";
});
}
function restart() {
node = node.data(nodes);
node
.enter()
.insert("g")
.attr("class", "node")
.call(force.drag);
node
.append("image")
.attr("xlink:href", "https://github.com/favicon.ico")
.attr("x", -8)
.attr("y", -8)
.attr("width", 16)
.attr("height", 16);
node
.append("text")
.attr("dx", 12)
.attr("dy", ".35em")
.text(function(d) {
return d.id;
});
node.exit().remove();
link = link.data(links);
link
.enter()
.append("path")
.attr("class", "link")
.attr("marker-end", "url(#arrow)");
link.exit().remove();
force.start();
}
#nodeConsole {
width: 80%;
height: 1px;
font-family: courier new;
padding: 1px;
border: 3px solid gray;
margin-top: 1px;
overflow: autao;
}
#linkedNodes {
width: 80%;
font-family: courier new;
padding: 10px;
}
#srcNodes {
width: 40%;
font-family: courier new;
padding: 8px;
}
#targetNodes {
width: 40%;
font-family: courier new;
padding: 8px;
}
rect {
fill: none;
pointer-events: all;
}
.node {
fill: #000;
}
.cursor {
fill: none;
stroke: brown;
pointer-events: none;
}
.link {
stroke: #999;
}
.node text {
pointer-events: none;
font: 10px sans-serif;
}
path.link {
fill: none;
stroke: #666;
stroke-width: 1.5px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
这篇关于D3 基于名称而不是索引链接节点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!