我正在使用D3创建一个用户可以操作的树形布局。我有一个对象,其中包含应用程序中其他对象的子数组,让用户可以选择不同的路径。
我开始使用没有ID的对象,并使用D3来添加ID:
var source = {
"name": "Top Condition",
"state": "condition",
"children": [{
"name": "Open",
"dest": "true",
"state": "open"
}, {
"name": "Sub Condition 1",
"dest": "false",
"state": "condition",
"children": [{
"name": "Open",
"dest": "true",
"state": "open"
}, {
"name": "Open",
"dest": "false",
"state": "open"
}, {
"name": "Open",
"dest": "unknown",
"state": "open",
"children": [{
"name": "Open",
"dest": "true",
"state": "open"
}, {
"name": "Open",
"dest": "false",
"state": "open"
}, {
"name": "Open",
"dest": "unknown",
"state": "open"
}]
}]
},{
"name": "Sub Condition 2",
"dest": "unknown",
"state": "condition"
,"children": [{
"name": "Open",
"dest": "true",
"state": "open"
}, {
"name": "Open",
"dest": "false",
"state": "open"
}, {
"name": "Sub Condition 3",
"dest": "false",
"state": "condition",
"children": [{
"name": "Open",
"dest": "true",
"state": "open"
}, {
"name": "Open",
"dest": "false",
"state": "open"
}, {
"name": "Open",
"dest": "unknown",
"state": "open"
}]
}]
}]
}
// Compute the new tree layout.
var nodes = tree.nodes(source).reverse(),
links = tree.links(nodes);
// Update the nodes with IDs
var node = svg.selectAll("g.node")
.data(nodes, function (d) {
return d.id || (d.id = ++i);
});
这是我正在使用的对象之后D3上面的魔术(手动添加ID,不完全是D3生成的内容):
source = {
"name": "Top Condition",
"id": 1,
"state": "condition",
"children": [{
"name": "Open",
"id": 2,
"dest": "true",
"state": "open"
}, {
"name": "Sub Condition 1",
"id": 3,
"dest": "false",
"state": "condition",
"children": [{
"name": "Open",
"id": 4,
"dest": "true",
"state": "open"
}, {
"name": "Open",
"id": 5,
"dest": "false",
"state": "open"
}, {
"name": "Open",
"id": 6,
"dest": "unknown",
"state": "open",
"children": [{
"name": "Open",
"id": 14,
"dest": "true",
"state": "open"
}, {
"name": "Open",
"id": 15,
"dest": "false",
"state": "open"
}, {
"name": "Open",
"id": 16,
"dest": "unknown",
"state": "open"
}]
}]
},{
"name": "Sub Condition 2",
"id": 7,
"dest": "unknown",
"state": "condition"
,"children": [{
"name": "Open",
"id": 8,
"dest": "true",
"state": "open"
}, {
"name": "Open",
"id": 9,
"dest": "false",
"state": "open"
}, {
"name": "Sub Condition 3",
"id": 10,
"dest": "false",
"state": "condition",
"children": [{
"name": "Open",
"id": 11,
"dest": "true",
"state": "open"
}, {
"name": "Open",
"id": 12,
"dest": "false",
"state": "open"
}, {
"name": "Open",
"id": 13,
"dest": "unknown",
"state": "open"
}]
}]
}]
}
所以我想要做的是拥有一个带有对象ID的函数,并将一个'children'数组添加到一个对象中(或删除一个子数组)嵌套在源代码中的某个地方。
因此,例如,对于包含id:13的对象,我想将其添加到对象:
var children = [{
"name": "Open",
"dest": "true",
"state": "open"
}, {
"name": "Open",
"dest": "false",
"state": "open"
}, {
"name": "Open",
"dest": "unknown",
"state": "open"
}];
此外,我需要能够执行相反的操作并从ID 10中删除子数组。
然后我会通过D3运行它来获取输入的任何节点的ID并重新渲染树。
这可能吗?我怎么能完成它?我愿意使用下划线或其他库,但根据我对文档的理解无法弄清楚。
答案 0 :(得分:3)
这里最简单的方法可能是走树,创建一个单独的地图,通过id:
来引用对象// set up the map
var idMap = {};
// recursive collection function
function collect(item) {
idMap[item.id] = item;
// recurse through the children, if any
(item.children || []).map(collect);
}
// kick off
collect(source);
现在你有一个像{ 1: <Object>, 2: <Object>, ...}
这样的地图,它很简单,可以添加或删除具有单独功能的子项,例如:
function updateChildren(id, children) {
var o = idMap[id];
o.children = children;
}
你可能也想在这里做其他事情,例如根据新孩子(或删除孩子),合并新老孩子等更新id地图。