2016-06-25 10 views
0

私は簡単にd3ツリーを作成できるようにJSONデータをネストしようとしています。D3ネスト - レベルの数が一貫していません

d3.json("dbdata/getdata", function(error, data) { 


var nestedData = { 
    "key":"root", 
    "values": 
     d3.nest() 
      .key(function(d){return d.category1}) 
      .key(function(d){return d.category2}) 
      .key(function(d){return d.category3}) 
      .key(function(d){return d.category4}) 
      .entries(data) } 

私がいる問題ではない私のすべてのデータのエントリは、それらに割り当てられたすべての4つのカテゴリを持っているということです。私はこのコードを持っています。それらの中にはcategory1とcategory2しかないものもありますので、そのような場合にはその1つのリンク上に(ツリーグラフ上に)2つのノードしか持たないと思います。しかし、ここで何が起こるかは、すべてのカテゴリが割り当てられていなくても、すべてのリンクが4レベルの構造になることです。カテゴリが2つしかないセット(カテゴリ1とカテゴリ2)がある場合は、カテゴリ1が正しい場所に、カテゴリ2が最後に、2つのレベルの空のデータがそれらの間に作成されます。

ネスティングプロセスで何を無視するかを指定する方法はありますか(空のカテゴリには「0」が割り当てられます)。 私はこのようなものを試してみた:

.key(function(d){if(d.category2 !=="0")return d.category3}) 

しかし、それだけで「0」を「未定義」に変更し、構造を変更しません。

おそらく、私はそれらの空のレベルを無視するようにd3コードを変更する方法がありますか?私はD3に新たなんだと、私のコードは、この例に完全に基づいています:http://mbostock.github.io/d3/talk/20111018/tree.html

EDIT:

このように見えるのデータ構造を考える:

elements = [ 
{name: 'johny', 
    category1: 'cat1', 
    category2: 'cat2a' 
}, 
{name: 'cindy', 
    category1: 'cat1', 
    category2: 'cat2b', 
    category3: 'cat3' 

}]; 

私はD3ツリーが見えるしたいですこのように:

:現在

 cat2a - johny 
     /  
    cat1 
     \ 
     cat2b - cat3 - cindy 

そして私は、この取得しています

答えて

1

EDIT:

あなたはd3.nest()でこれを達成することができないかもしれないが、あなたは、各要素の各カテゴリを反復処理し、子供アレイを構築することにより、適切な構造を構築することができるはずです。私も見つけ https://jsfiddle.net/b1s65ydL/8/

var root, element, key, child, j, i, catHash; 
var categoryPropertyNames = [ 
    'category4', 
    'category3', 
    'category2', 
    'category1' 
]; //in descending order 
var nodeByName = Object.create(null); //dictionary to hold category nodes 

root = {name: 'root', children: []}; 
for (j = 0; j < elements.length; j++) { 
    element = elements[j]; 
    child = element; 
    for (i = 0; i < categoryPropertyNames.length; i++) { 
     key = categoryPropertyNames[i]; 
     if (!element.hasOwnProperty(key)) { 
      continue; 
     } 
     catHash = element[key] + '-' + key; 
     if (nodeByName[catHash] === undefined) { 
      nodeByName[catHash] = {name: element[key], children: []}; 
     } 
     var node = nodeByName[catHash]; 
     //add child to the array if is not already there 
     if (node.children.indexOf(child) == -1) { 
      node.children.push(child); 
     } 
     child = node; 
    } 
    //child is now either the first category, or the element itself 
    if (root.children.indexOf(child) == -1) { 
     root.children.push(child); 
    } 
}  

//d3 should be able to take it from here 
var nodes = tree.nodes(root).reverse();  

http://learnjsdata.com/group_data.htmlは有用であることが はここjsfiddleです。

+0

回答をいただきありがとうございます。残念ながら、それは私が後にしていることではありません。私は自分の投稿を編集したので、今はちょっときれいかもしれません。 – Xnn04

+0

確かに、自分の状況に合わせて自分の答えを編集しました。これが役に立ったら教えてください。そうでなければ、さらに編集するためにjsfiddleをまとめようとします。 –

+0

あなたのコードを実装しようとしましたが、いくつかの問題がありました。問題は、この関数で作成された配列に2つのグループ(ノード/リンクの場合はセット)が格納されていることです。同じ親子グループがそこに倍増します。この特定の例では、d3MakeMeAtree(root.children [0] .children [0])のようなd3関数を呼び出すことでこれを克服できますが、これはほとんど最適な解決策ではありませんが、関数を変更する方法を理解できません正しく動作させるためです。 – Xnn04

関連する問題