D3强制布局 - 按名称而不是索引链接节点 [英] D3 force layout - linking nodes by name instead of index

查看:379
本文介绍了D3强制布局 - 按名称而不是索引链接节点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我试图通过ID而不是索引来链接d3节点(节点ID由我的应用程序生成)。

 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
}
]

目前通过索引链接:

 links:[
{
source:0,
target:0,
:0
},
{
source:0,
target:1,
value:0 b},
{
source:1,
target:2,
value:0
}
source:3,
target:2,
value:0
}
]
 

Links:[
{
Source:338,
Target:338,
Value:0
},
{
Source:338,
Target:340,
Value:0
},
{
Source:340,
Target:341,
Value:0
} b $ b {
Source:342,
Target:341,
Value:0
}
] b $ b

我试过这里提出的解决方案: https://groups.google.com/forum/#!msg/d3-js/LWuhBeEipz4/0kZIojCYvhIJ



通过在调用force.nodes之前添加以下行:

 直接为这个特定的数据格式:
var hash_lookup = [];
//使它可以查找O(1)中的节点:$ b​​ $ b 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];
});

我试过调试上面的,但我不能设法弄清楚。我收到以下错误消息(通常意味着我没有正确设置链接):



未捕获的TypeError:无法读取属性'weight' undefined



链接到我的完整JS: http:// jsfiddle.net/9sMrw/

解决方案

这是一个简单的方法:

  var edges = []; 
json.Links.forEach(function(e){
var sourceNode = json.Nodes.filter(function(n){
return n.Id === eSource;
})[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)
...

这是一个正常的 PLUNK 。 (你应该分叉,以保证安全,万一我不小心删除它。)


I am attempting to link d3 nodes by an ID instead of index (The node ID is generated by my application).

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":

  "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

by adding the following lines before calling 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

Link to my full JS: http://jsfiddle.net/9sMrw/

解决方案

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.)

这篇关于D3强制布局 - 按名称而不是索引链接节点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆