javascript D3 强制布局 - 按名称而不是索引链接节点
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23986466/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
D3 force layout - linking nodes by name instead of index
提问by Blair
I am attempting to link d3 nodes by an ID instead of index (The node ID is generated by my application).
我试图通过 ID 而不是索引链接 d3 节点(节点 ID 由我的应用程序生成)。
Here are my nodes:
这是我的节点:
"Nodes": [
{
"Id": "338",
"Name": "TEST NODE ONE",
"Url": "http://www.google.com"
},
{
"Id": "340",
"Name": "TEST NODE TWO",
"Url": "http://www.yahoo.com"
},
{
"Id": "341",
"Name": "TEST NODE THREE",
"Url": "http://www.stackoverflow.com"
},
{
"Id": "342",
"Name": "TEST NODE FOUR",
"Url": "http://www.reddit.com"
}
]
They are currently linked by index:
它们目前通过索引链接:
"links": [
{
"source": 0,
"target": 0,
"value": "0"
},
{
"source": 0,
"target": 1,
"value": "0"
},
{
"source": 1,
"target": 2,
"value": "0"
},
{
"source": 3,
"target": 2,
"value": "0"
}
]
However, I want to link them by "Id":
但是,我想通过“Id”链接它们:
"Links": [
{
"Source": "338",
"Target": "338",
"Value": "0"
},
{
"Source": "338",
"Target": "340",
"Value": "0"
},
{
"Source": "340",
"Target": "341",
"Value": "0"
},
{
"Source": "342",
"Target": "341",
"Value": "0"
}
]
I've attempted the solution proposed here: https://groups.google.com/forum/#!msg/d3-js/LWuhBeEipz4/0kZIojCYvhIJ
我已经尝试了这里提出的解决方案:https: //groups.google.com/forum/#!msg/d3-js/LWuhBeEipz4/0kZIojCYvhIJ
by adding the following lines before calling force.nodes:
通过在调用 force.nodes 之前添加以下行:
// make links reference nodes directly for this particular data format:
var hash_lookup = [];
// make it so we can lookup nodes in O(1):
json.Nodes.forEach(function(d, i) {
hash_lookup[d.Id] = d;
});
json.Links.forEach(function(d, i) {
d.source = hash_lookup[d.Source];
d.target = hash_lookup[d.Target];
});
I've tried debugging the above, but I can't manage to figure it out. I get the following error message (which usually means I haven't set links correctly):
我试过调试上面的,但我无法弄清楚。我收到以下错误消息(这通常意味着我没有正确设置链接):
Uncaught TypeError: Cannot read property 'weight' of undefined
Uncaught TypeError: Cannot read property 'weight' of undefined
Link to my full JS: http://jsfiddle.net/9sMrw/
链接到我的完整 JS:http: //jsfiddle.net/9sMrw/
回答by FernOfTheAndes
Here is a straightforward way to do this:
这是执行此操作的直接方法:
var edges = [];
json.Links.forEach(function(e) {
var sourceNode = json.Nodes.filter(function(n) {
return n.Id === e.Source;
})[0],
targetNode = json.Nodes.filter(function(n) {
return n.Id === e.Target;
})[0];
edges.push({
source: sourceNode,
target: targetNode,
value: e.Value
});
});
force
.nodes(json.Nodes)
.links(edges)
.start();
var link = svg.selectAll(".link")
.data(edges)
...
Here is a working PLUNK. (You should fork it to be safe, in case I inadvertently delete it.)
这是一个有效的PLUNK。(为了安全起见,你应该分叉它,以防我无意中删除它。)