9

親子接続のデータベースがあります。データは次のようになりますが、任意の方法 (辞書、リストのリスト、JSON など) で表示できます。

links=(("Tom","Dick"),("Dick","Harry"),("Tom","Larry"),("Bob","Leroy"),("Bob","Earl"))

必要な出力は、d3 でレンダリングされる階層的な JSON ツリーです。データには個別のサブツリーがあり、ルート ノードにアタッチします。そのため、リンクを再帰的に調べて、ツリー構造を構築する必要があります。私が得ることができる最も遠いのは、すべての人を反復して子供を追加することですが、高次のリンクを実行する方法がわかりません(たとえば、子供を持つ人を他の人の子供に追加する方法)。これは別の質問hereに似ていますが、ルートノードを事前に知る方法がないため、受け入れられたソリューションを実装できません。

サンプル データから次のツリー構造を作成します。

{
"name":"Root",
"children":[
    {
     "name":"Tom",
     "children":[
         {
         "name":"Dick",
         "children":[
             {"name":"Harry"}
         ]
         },
         {
          "name":"Larry"}
     ]
    },
    {
    "name":"Bob",
    "children":[
        {
        "name":"Leroy"
        },
        {
        "name":"Earl"
        }
    ]
    }
]
}

この構造は、私の d3 レイアウトでは次のようにレンダリングされます。 レンダリング画像

4

3 に答える 3

8

ルート ノードを特定するには、解凍linksして、子ではない親を探します。

parents, children = zip(*links)
root_nodes = {x for x in parents if x not in children}

次に、再帰的な方法を適用できます。

import json

links = [("Tom","Dick"),("Dick","Harry"),("Tom","Larry"),("Bob","Leroy"),("Bob","Earl")]
parents, children = zip(*links)
root_nodes = {x for x in parents if x not in children}
for node in root_nodes:
    links.append(('Root', node))

def get_nodes(node):
    d = {}
    d['name'] = node
    children = get_children(node)
    if children:
        d['children'] = [get_nodes(child) for child in children]
    return d

def get_children(node):
    return [x[1] for x in links if x[0] == node]

tree = get_nodes('Root')
print json.dumps(tree, indent=4)

セットを使用してルート ノードを取得しましたが、順序が重要な場合は、リストを使用して重複を削除できます。

于 2013-08-02T21:09:31.093 に答える
3

次のコードを試してください:

import json

links = (("Tom","Dick"),("Dick","Harry"),("Tom","Larry"),("Tom","Hurbert"),("Tom","Neil"),("Bob","Leroy"),("Bob","Earl"),("Tom","Reginald"))

name_to_node = {}
root = {'name': 'Root', 'children': []}
for parent, child in links:
    parent_node = name_to_node.get(parent)
    if not parent_node:
        name_to_node[parent] = parent_node = {'name': parent}
        root['children'].append(parent_node)
    name_to_node[child] = child_node = {'name': child}
    parent_node.setdefault('children', []).append(child_node)

print json.dumps(root, indent=4)
于 2013-08-02T20:08:37.887 に答える
0

HTML/JS 自体の階層としてデータをフォーマットする場合は、以下をご覧ください。

フラット json から(マルチレベルの)flare.json データ形式を生成する

大量のデータがある場合、Python には関数型プログラミングがありませんが、reduce 機能を使用するため、Web 変換は高速になります。

ところで:私は同じトピック、つまりd3.jsで折りたたみ可能なツリー構造を生成することにも取り組んでいます。一緒に仕事をしたい場合は、私のメールは erprateek.vit@gmail.com です。

于 2013-08-02T20:19:18.363 に答える