解释Mike Bostock节点解析循环

时间:2017-08-31 06:18:38

标签: javascript d3.js network-analysis d3-force-directed

我对JavaScript和d3比较陌生,但我对强制导向的布局非常感兴趣。在Mike Bostock的强制导向可视化中,他倾向于使用以下代码(或类似代码)从链接列表中解析节点:

var links = [
    {source: "A", target: "B"},
    {source: "B", target: "C"},
    {source: "C", target: "A"}];

var nodes = {};

links.forEach(function(link) {
    link.source = nodes[link.source] || (nodes[link.source] = {name: link.source});
    link.target = nodes[link.target] || (nodes[link.target] = {name: link.target});
});

我完全理解他最终在这里完成的任务,我只想更好地理解forEach循环中的JavaScript语法(实际上,根本就是这样)。如果有人可以解释,我真的很感激。

这显然是非常优雅的代码,但我无法在互联网上的任何地方找到解释 - 我可能在搜索中错过了一个关键术语,所以我不情愿地在这里提出这个问题。什么真的让我失望:

  • ||两侧的两项作业是什么,
  • 每行的第一次分配顺序(每个||的左侧):例如,为什么link.source = nodes[link.source]不是nodes[link.source] = link.source

1 个答案:

答案 0 :(得分:2)

在下面的代码中

link.source = nodes[link.source] || (nodes[link.source] = {name: link.source});

这意味着

link.source = nodes[link.source]

如果nodes[link.source] 未定义

如果nodes[link.source] 未定义,则下面的阻止将被执行。

(nodes[link.source] = {name: link.source})//assigning new value to nodes[link.source]

并且上述值将设置为link.source

所以,如果你说的很简单,那就像:

link.source = nodes[link.source] || (nodes[link.source] = {name: link.source}); 相当于:

if (!nodes[link.source]) {//not undefined
 link.source = nodes[link.source];
} else {
 nodes[link.source] = {name: link.source}
 link.source = nodes[link.source];
}

希望这有帮助!

您的评论说明

问题 (a = b || c equates to a = b but if b is undefined make a = c, right?)

问题还有什么不合理的是为什么这些作业的左侧是link.source和link.target?这些​​已定义,它们是我们想要的使用?

填充节点

是的!你在这里是正确的Those are already defined。 link.source当前=" A" 块执行后,每个link.source都将指向一个对象,就像这样。 link.source = {name:A}

如果您仍然感到困惑,请告诉我。