【问题标题】:creating links for d3 force layout from json file从 json 文件创建 d3 强制布局的链接
【发布时间】:2014-02-20 14:50:09
【问题描述】:

我是 d3 和 javascript 的新手,如果这是一个愚蠢的问题,我很抱歉。我对 d3 强制布局有疑问。我可以用数据填充“节点”,但我不知道如何编写正确的函数来构造我的链接,格式为"links": [ {"source": 0, "target": 1},

我试图写一个循环,但它不起作用,目标有“权重:NaN”,因为我正在引用父级和与父级同名的节点,我猜:

d3.json('file.json',function(data){
    var nodes = data;
    var links = [];
      for (var i = 0; i < data.length; i++) {
        for (var j = 0; j < data[i].parents.length; j++) {
              links.push({"source": i, "target": data[i].parents[j]})
      }
    }

我的 json 文件看起来像这样,我必须将所有对象与相应的父对象连接起来(更改 json 文件不是选项):

[
{
"name": "name 1",
"parents": [
  {"name": "name 5"},
  {"name": "name 4"}
 ]
},
{
"name": "name 2",
"parents": [
  {"name": "name 1"},
  {"name": "name 3"}
  ]
 },...
]

我希望有人可以帮助并向我解释如何正确编写此函数。 谢谢。苏珊

【问题讨论】:

  • 那是因为你的变量nodes 需要一个平面数组,而不是一个层次结构。然后,例如,links 数组中对象内的属性source 需要nodes 数组中节点的索引,或对该节点对象的直接引用。无论如何,强制布局在这里似乎不合适,您检查过树形布局,您可以使用它轻松管理分层结构吗?

标签: javascript json d3.js force-layout


【解决方案1】:

D3 文档有点做作,恕我直言,它没有强调许多特性和功能的足够关键部分。尽管如此,您确实需要仔细阅读并理解这两部分:

传递给force.nodes() 的参数必须是一个数组。然后,您将看到传递给force.links() 的参数也必须是一个数组,并且该数组的每个元素都必须是一个对象,格式为
{"source": source_index, "target": target_index}
(正如您在代码中所做的那样),其中source_indextarget_index 是节点数组中对应节点的索引(传递给force.nodes())(这是您的错误所在)。

因此,如果您查看您的代码,您会发现您没有在链接数组中传递正确的值。您需要找到使用节点数组中的正确索引填充链接数组的方法(假设将“名称 5”转换为适当的索引,我相信它会是 4,在您的情况下,假设节点数组名称是“名称 1”, “名称 2”、名称 3”等...)。

【讨论】:

  • 谢谢,我就是这么想的。我在想我必须编写一个循环来访问所有名称和父名称并比较它们。如果 name == parents.name: 给我父母的索引。我只是不知道该怎么做。实际名称和父名称如下: 18e17f85458307def0a4a19ca9a1b445cd220e65, 3969a3506da09465ef49c8c724c72680b1f1b9d5,... 为了便于阅读,我只是更改了它们。一些节点有 2 个父节点,大多数有 1 个。
  • 解决此问题的一种方法是编写一个函数,对于给定的节点名称,该函数将返回其在节点数组中的索引。该函数将简单地从头开始遍历节点数组,将当前节点名称与给定名称进行比较,计算已检查的节点,然后在给定名称和节点名称匹配时返回该计数。可能有更好的方法可以做到这一点,但我会这样做,因为它很清楚。然后,只要您有节点名称并需要节点索引,您只需调用该函数。这不会显着影响性能,因为它仅在初始化时完成。
  • 非常感谢!您的指示确实有助于编写我的函数
猜你喜欢
  • 2015-05-23
  • 2018-09-20
  • 1970-01-01
  • 2012-10-11
  • 1970-01-01
  • 1970-01-01
  • 2014-08-01
  • 2016-11-10
  • 1970-01-01
相关资源
最近更新 更多