2016-07-18 88 views
8

Próbuję zaktualizować niektóre kod d3 z wersji 3 do wersji 4. Mam diagram drzewa przy użyciu danych JSON. Przykłady d3.v4 pokazują, jak konwertować dane tabelaryczne (np. Flare.csv) na dane hierarchiczne za pomocą funkcji stratyify() https://bl.ocks.org/mbostock/9d0899acb5d3b8d839d9d613a9e1fe04. Ale moje dane to JSON, więc nie chcę ani nie potrzebuję stratyfikacji(). Otrzymuję ten błąd:Jak utworzyć układ drzewa przy użyciu danych JSON w d3.v4 - bez stratyfikacji()

undefined is not a function (evaluating 'root.eachBefore')

działa ten kod:

var height = 200; 
var width = 500; 

var xNudge = 50; 
var yNudge = 20; 

var tree = d3.tree() 
    .size([height, width]); 

var svg = d3.select("body").append("svg").attr("width","100%").attr("height","100%"); 
var chartGroup = svg.append("g").attr("transform","translate(50,200) rotate(-90)"); 

d3.json("treeData.json", function(treeData) { 


    var root = treeData[0]; 
    tree(root); 
    console.log('hello');//doesn't log to console, i.e. error occurs beforehand 
} 

treeData.json:

[ 
    { 
    "name": "Top Level", 
    "parent": "null", 
    "children": [ 
    { 
     "name": "Level 2: A", 
     "parent": "Top Level", 
     "children": [ 
     { 
      "name": "Son of A", 
      "parent": "Level 2: A" 
     }, 
     { 
      "name": "Daughter of A", 
      "parent": "Level 2: A" 
     } 
     ] 
    }, 
    { 
     "name": "Level 2: B", 
     "parent": "Top Level" 
    } 
    ] 
} 
] 

Czy to rzeczywiście możliwe, aby utworzyć układ drzewa w d3.v4 bez użycia stratify , czyli używając danych, które już są hierarchiczne? Czy ktoś zna przykład lub może wykryć problem w moim kodzie? dzięki

Odpowiedz

5

Musisz uruchomić d3.hierarchy na swoich danych, aby przygotować go do drzewa(). Stratify prawdopodobnie działa w hierarchii lub jest w pewien sposób podobny. Zmień więc odpowiednią linię na: var root = d3.hierarchy (treeData [0]);

+0

Obiekt zwrócony przez d3.hierarchy() nie zawiera właściwości "name" i "id". – jackOfAll

6

Miałem ten sam problem. Emma's response zasadniczo odpowiedział na to pytanie, ale nadal miałem problemy z jego poprawnym działaniem. Wytłumaczę trochę na wypadek, gdyby ktoś uznał to za pomocne. Stworzyłem blok pokazujący wynik funkcjonalny here, który jest oparty na przykładowych danych powyżej, Emma's response i this bloku.

Odpowiedź jest z trzech części:

  • masz swój obiekt JSON owinięte w nawiasach Array. Albo usuń te nawiasy (tak jak ja w istocie), albo umieść [0] na końcu twojej treeData (jak zrobiła to Emma w powyższym linku), aby uzyskać Obiekt z tego 1 elementu Array.
  • Przekaż obiekt JSON do d3.hierarchy (jak wyjaśniła Emma).
  • Wreszcie, wydaje się, że interfejs API został zmieniony w celu nazwania węzłów, co również zostało uwzględnione w moim bloku, który został połączony powyżej.

Dla wygody, oto kod z the block I made:

var svg = d3.select("svg"), 
    width = +svg.attr("width"), 
    height = +svg.attr("height"), 
    g = svg.append("g").attr("transform", "translate(60,0)"); 

var tree = d3.cluster() 
    .size([height, width - 160]); 

var stratify = d3.stratify() 
    .parentId(function(d) { return d.id.substring(0, d.id.lastIndexOf(".")); }); 

d3.json("treeData.json", function(error, treeData) { 
    if (error) throw error; 

    var root = d3.hierarchy(treeData); 
    tree(root); 

    var link = g.selectAll(".link") 
     .data(root.descendants().slice(1)) 
    .enter().append("path") 
     .attr("class", "link") 
     .attr("d", function(d) { 
     return "M" + d.y + "," + d.x 
      + "C" + (d.parent.y + 100) + "," + d.x 
      + " " + (d.parent.y + 100) + "," + d.parent.x 
      + " " + d.parent.y + "," + d.parent.x; 
     }); 

    var node = g.selectAll(".node") 
     .data(root.descendants()) 
    .enter().append("g") 
     .attr("class", function(d) { return "node" + (d.children ? " node--internal" : " node--leaf"); }) 
     .attr("transform", function(d) { 
     return "translate(" + d.y + "," + d.x + ")"; 
     }) 

    node.append("circle") 
     .attr("r", 2.5); 

    node.append("text") 
     .attr("dy", 3) 
     .attr("x", function(d) { return d.children ? -8 : 8; }) 
     .style("text-anchor", function(d) { return d.children ? "end" : "start"; }) 
     .text(function(d) { 
     return d.data.name; 
     }); 
}); 

i oto treeData.json usunięty z tablicy:

{ 
    "name": "Top Level", 
    "parent": "null", 
    "children": [ 
    { 
     "name": "Level 2: A", 
     "parent": "Top Level", 
     "children": [ 
     { 
      "name": "Son of A", 
      "parent": "Level 2: A" 
     }, 
     { 
      "name": "Daughter of A", 
      "parent": "Level 2: A" 
     } 
     ] 
    }, 
    { 
     "name": "Level 2: B", 
     "parent": "Top Level" 
    } 
    ] 
} 
+0

Obiekt zwracany przez d3.hierarchy() nie zawiera już właściwości "nazwa" i "identyfikator". – jackOfAll

+0

Funkcje d w wywołaniach funkcji są niezdefiniowane, gdy próbuję tego. Co powinno być? –