当我看到类似的东西时,我正在寻找一些很棒的d3.js code examples。
var links = [
{source: "test1", target: "test2"},
{source: "test1", target: "test3"},
{source: "test2", target: "test3"},
{source: "test3", target: "test4"}
];
var nodes = {};
// Compute the distinct nodes from the links.
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});
});
我没有立即得到如何声明var节点。
我的第一个猜测是将其翻译成:
links.forEach(function(link) {
if(link.source != nodes[link.source]){
nodes[link.source] = {name: link.source};
}
if(link.target != nodes[link.target]){
nodes[link.target] = {name: link.target};
}
});
但链接不再被绘制了。
这两种方法有什么区别?
初始语法的重点是,只是一个快捷方式还是增加了性能?
在这种情况下是否有最好的做法?
修改
所以如果我试着完全理解
link.source = nodes[link.source] || (nodes[link.source] = {name: link.source});
由于节点[link.source] 是一个对象 link.source 获取其引用。这种情况总是在发生。
OR条件,我不确定会得到那个部分。
我想如果 nodes [link.source] 被定义 link.source = nodes [link.source] 返回true,我们不需要更进一步。
如果没有定义并返回false,则OR子句强制进一步......
节点[link.source] 获取一个值,因为引用 link.source 指向相同的值。
我想在这个阶段 link.source 还没有包含对 nodes [link.source] 的引用,但它的初始值。它将包含逗号后的新引用。
我错了吗?第2点对我来说很奇怪。
答案 0 :(得分:2)
示例中使用的代码只是一个语法快捷方式。它相当于
links.forEach(function(link) {
if(nodes[link.source]) { // we already know about the source of this link
link.source = nodes[link.source];
} else { // we haven't seen this source before, create a new node for it
nodes[link.source] = {name: link.source};
link.source = nodes[link.source];
}
if(nodes[link.target]) { // we already know about the target of this link
link.target = nodes[link.target];
} else { // we haven't seen this target before, create a new node for it
nodes[link.target] = {name: link.target};
link.target = nodes[link.target];
}
});
所有这一切都是必要的,因为节点只是通过链接隐式声明 - 也就是说,没有节点列表,只能通过遍历链接来组装节点,并且"收获"来源和目标。这就是nodes
中存储的内容 - 它是从节点ID(从链接)到表示节点的对象的映射。
上面的代码通过为看不见的节点(即映射中不存在的节点)创建新对象并插入相应的映射来同时填充此映射。然后更新链接的源和目标以指向那些对象(稍后将通过力布局操作以设置其位置),而不是原始数据中引用的节点的ID。
编辑:您编辑的解释是正确的。这基本上就是发生的事情。
答案 1 :(得分:0)
link.source = nodes[link.source] || (nodes[link.source] = {name: link.source});
可以翻译成:
if(!nodes[link.source]) {
nodes[link.source] = {name: link.source};
}
link.source = nodes[link.source];
(与link.target
相同)。
所以:
var links = [
{source: "test1", target: "test2"},
{source: "test1", target: "test3"},
{source: "test2", target: "test3"},
{source: "test3", target: "test4"}
];
将转换为:
links = [
{source: { name: "test1" }, target: { name: "test2" }},
{source: { name: "test1" }, target: { name: "test3" }},
{source: { name: "test2" }, target: { name: "test3" }},
{source: { name: "test3" }, target: { name: "test4" }}
];
和节点将等于:
nodes = {
"test1": { name: "test1" },
"test2": { name: "test2" },
"test3": { name: "test3" },
"test4": { name: "test4" },
}
答案 2 :(得分:0)
我对
的理解link.source = nodes[link.source] || (nodes[link.source] = {name: link.source});
是,如果nodes[link.source]
不存在
然后只做link.source = nodes[link.source] = {name: link.source};