【发布时间】:2015-06-23 08:26:44
【问题描述】:
我正在玩 D3 强制布局。在力布局中,您必须提供“链接”和“节点”才能制作力图。 D3 将链接的“源”和“目标”解释为“节点”数组中节点的索引。我的问题是:如何通过“节点”属性中的 ID 而不是“节点”数组中的索引来索引数据? 这是我的 Json 文件:
{
"nodes":
[
{"name": "A", "ID": 10},
{"name": "B", "ID": 20},
{"name": "C", "ID": 30},
{"name": "D", "ID": 40}
],
"links":
[
{"source": 10, "target": 20},
{"source": 20, "target": 30},
{"source": 30, "target": 40}
]
}
我知道这里有人问过它: D3: Using node attribute for links instead of index in array
但解决方案不是我想要的。因为最近我看到有些人只是通过一个简单的键函数来做特殊的索引:
http://flowingdata.com/2012/08/02/how-to-make-an-interactive-network-visualization/
node = nodesG.selectAll("circle.node")
.data(curNodesData, (d) -> d.id)
link = linksG.selectAll("line.link")
.data(curLinksData, (d) -> "#{d.source.id}_#{d.target.id}")
问题是我不明白“#{d.source.id}_#{d.target.id}”的含义。
有人愿意解释一下吗?
好的。以上是用咖啡稿写的。当我尝试将其转换为常规 D3 javascript 时,以下操作无法正常工作:
node = nodesG.selectAll("circle.node")
.data(curNodesData,function(d) {return d.ID;})
link = linksG.selectAll("line.link")
.data(curLinksData, function(d) {return "#{d.source.id}_#{d.target.id}";})
也无法按预期工作:
link = linksG.selectAll("line.link")
.data(curLinksData, function(d) {return d.source.id+"_"+d.target.id;})
谢谢 德里克
【问题讨论】:
-
这里有两件不同的事情——首先,解析链接,然后将数据匹配到 DOM 元素。如果我正确理解你的问题,你关心的是前者。您可以在代码中将链接中节点的 ID 替换为对相应节点对象的引用——这是 D3 在您指定 ID 时在内部执行的操作。这允许您以任何您喜欢的方式解析 ID。
-
@Lars Kotthoff,您能否再谈一谈“将链接中的节点 ID 替换为对相应节点对象的引用”?你能用我的例子来展示它吗?谢谢。
-
这就是您在链接到的答案中所做的——您不是输入节点的编号,而是输入实际的节点本身。
-
@Lars Kotthoff,现在我可以理解这部分了。但是如何在常规 D3 javascript 中做到这一点。请看我的更新。我试过{return d.source.id + "_" + d.target.id;},可以显示图形但链接的两端仍然是由数组索引而不是ID属性索引。
-
你在那里做的是数据匹配,它与解析链接完全分开。您需要在遍历链接并替换节点 ID 之前的代码,例如
links.forEach(function(d) { d.source = findNodeWithId(d.source); d.target = findNodeWithId(d.target); })。
标签: d3.js force-layout