我正在与d3.js一起将动物(有机体)家族(一次最多4000个)可视化为树状图,尽管数据源也可以是目录列表或命名空间对象列表。我的数据如下:

json = {
    organisms:[
        {name: 'Hemiptera.Miridae.Kanakamiris'},
        {name: 'Hemiptera.Miridae.Neophloeobia.incisa'},
        {name: 'Lepidoptera.Nymphalidae.Ephinephile.rawnsleyi'},
        ... etc ...
    ]
}

我的问题是:我正在尝试找到将上述数据转换为分层的父级/子级数据结构的最佳方法,这是许多d3可视化方法(例如treemap)使用的(有关数据示例,请参见d3 / examples /中的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/

10-12 12:36
查看更多