我正在使用 d3.js 将动物(生物)家族(一次最多 4000 个)可视化为树形图,尽管数据源也可以是目录列表或命名空间对象列表。我的数据看起来像:
json = {
organisms:[
{name: 'Hemiptera.Miridae.Kanakamiris'},
{name: 'Hemiptera.Miridae.Neophloeobia.incisa'},
{name: 'Lepidoptera.Nymphalidae.Ephinephile.rawnsleyi'},
... etc ...
]
}
我的问题是:我正在尝试找到将上述数据转换为分层父/子数据结构的最佳方法,如 treemap 等许多 d3 可视化所使用的那样。 (有关数据示例,请参阅 d3/examples/data/目录中的 flare.json)。 这是所需数据结构的示例:
{"name": "ROOT",
"children": [
{"name": "Hemiptera",
"children": [
{"name": "Miridae",
"children": [
{"name": "Kanakamiris", "children":[]},
{"name": "Neophloeobia",
"children": [
{"name": "incisa", "children":[] }
]}
]}
]},
{"name": "Lepidoptera",
"children": [
{"name": "Nymphalidae",
"children": [
{"name": "Ephinephile",
"children": [
{"name": "rawnsleyi", "children":[] }
]}
]}
]}
]}
}
编辑:将所有原始所需的数据结构包含在一个ROOT
节点中,以符合只有一个主父节点的d3 示例的结构。
我希望了解一般的设计模式,作为奖励,我希望看到一些使用 javascript、php(甚至 python)的解决方案。 javascript 是我的偏好。 关于 php:我实际使用的数据来自将结果编码为 json 的 php 脚本对数据库的调用。 php 脚本中的数据库结果是一个有序数组(见下文),如果这对基于 php 的答案有任何用处的话。
Array
(
[0] => Array
(
['Rank_Order'] => 'Hemiptera'
['Rank_Family'] => 'Miridae'
['Rank_Genus'] => 'Kanakamiris'
['Rank_Species'] => ''
) ........
哪里:
'Rank_Order'
isParentOf 'Rank_Family'
isParentOf 'Rank_Genus'
isParentOf 'Rank_Species'
我问了一个关于 php 解决方案的类似问题 here ,但唯一的答案是在我的服务器上不起作用,我不太明白这是怎么回事,所以我想从设计模式的 Angular 提出这个问题,并包括对我在 javascript 和 d3 中的实际使用的引用。 js.
最佳答案
以下内容特定于您提供的结构,可以很容易地使其更通用。我确信可以简化 addChild 函数。希望评论对您有所帮助。
function toHeirarchy(obj) {
// Get the organisms array
var orgName, orgNames = obj.organisms;
// Make root object
var root = {name:'ROOT', children:[]};
// For each organism, get the name parts
for (var i=0, iLen=orgNames.length; i<iLen; i++) {
orgName = orgNames[i].name.split('.');
// Start from root.children
children = root.children;
// For each part of name, get child if already have it
// or add new object and child if not
for (var j=0, jLen=orgName.length; j<jLen; j++) {
children = addChild(children, orgName[j]);
}
}
return root;
// Helper function, iterates over children looking for
// name. If found, returns its child array, otherwise adds a new
// child object and child array and returns it.
function addChild(children, name) {
// Look for name in children
for (var i=0, iLen=children.length; i<iLen; i++) {
// If find name, return its child array
if (children[i].name == name) {
return children[i].children;
}
}
// If didn't find name, add a new object and
// return its child array
children.push({'name': name, 'children':[]});
return children[children.length - 1].children;
}
}
关于javascript - 如何将此数据编码为 JSON 中的父/子结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12126914/