2016-07-18 142 views
8

Sto cercando di aggiornare alcuni codici d3 dalla versione 3 alla versione 4. Ho un diagramma ad albero che utilizza i dati JSON. Gli esempi d3.v4 mostrano come convertire i dati tabulari (ad es. Flare.csv) in dati gerarchici usando stratify() https://bl.ocks.org/mbostock/9d0899acb5d3b8d839d9d613a9e1fe04. Ma i miei dati sono JSON, quindi non voglio o ho bisogno di stratify(). Ottengo questo errore:Come creare un layout ad albero utilizzando i dati JSON in d3.v4 - senza stratify()

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

esecuzione di questo codice:

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" 
    } 
    ] 
} 
] 

E 'realmente possibile creare un layout albero in d3.v4 senza l'utilizzo di stratificare , cioè utilizzando dati che sono già gerarchici? Qualcuno sa di un esempio o può individuare il problema nel mio codice? grazie

risposta

5

È necessario eseguire d3.hierarchy sui dati per essere pronti per tree(). Stratify presumibilmente esegue la gerarchia o è simile in qualche modo. Quindi cambia la linea appropriata a: var root = d3.hierarchy (treeData [0]);

+0

L'oggetto restituito dal d3.hierarchy() non contiene il "name" e "id" proprietà più. – jackOfAll

6

Ho avuto lo stesso problema. Emma's response essenzialmente ha risposto, ma ho ancora avuto problemi a farlo funzionare correttamente. Elaborerò un po 'nel caso qualcuno possa trovarlo utile. Ho creato un blocco che mostra il risultato funzionale here, che si basa sui dati di esempio sopra, Emma's response e this.

La risposta è tre parti:

  • avete il vostro oggetto JSON avvolti tra parentesi Array. Rimuovere le parentesi (come ho fatto nel senso), o mettere un [0] alla fine del tuo treeData (come ha fatto Emma nel link sopra) per ottenere l'oggetto fuori da quella matrice di 1 elemento.
  • Passa il tuo oggetto JSON a d3.hierarchy (come ha spiegato Emma).
  • Infine, sembra che l'API sia cambiata per la denominazione dei nodi, anch'essa curata nel mio blocco collegato sopra.

Per comodità, qui è il codice da 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; 
     }); 
}); 

ed ecco treeData.json rimossi dalla matrice:

{ 
    "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

L'oggetto restituito da d3.hierarchy() non contiene più le proprietà "name" e "id". – jackOfAll

+0

I callback in funzione sono indefiniti quando provo questo. Cosa dovrei essere? –