2012-06-18 23 views
33

Pur seguendo numerosi esempi D3, i dati di solito ottiene formattato nel formato indicato in flare.json:Come convertire in formato JSON di D3?

{ 
"name": "flare", 
"children": [ 
    { 
    "name": "analytics", 
    "children": [ 
    { 
    "name": "cluster", 
    "children": [ 
     {"name": "AgglomerativeCluster", "size": 3938}, 
     : 

Ho una lista di adiacenza come segue:

A1 A2 
A2 A3 
A2 A4 

che voglio convertire al formato di cui sopra . Attualmente sto facendo questo sul lato server, ma c'è un modo per ottenere questo usando le funzioni di d3? Ho trovato uno here, ma l'approccio sembra richiedere la modifica della libreria core d3 che non sono favorevole a causa della manutenibilità. Eventuali suggerimenti?

+1

Che cosa vuoi dire "lista di adiacenza"? – jbabey

+1

Penso che significhi '[(A1, A2), (A2, A3), (A2, A4)]'? – sczizzo

+0

@sczizzo: Sì, questo è quello che intendevo! Mi dispiace jbabey. Avrei dovuto essere più chiaro – Legend

risposta

51

Non c'è formato prescritto , in genere puoi ridefinire i tuoi dati attraverso varie funzioni di accesso (come hierarchy.children) e array.map. Ma il formato che hai citato è probabilmente la rappresentazione più comoda per gli alberi perché funziona con i metodi di accesso predefiniti.

La prima domanda è se si intende visualizzare un graph o un tree. Per i grafici, la struttura dei dati è definita in termini di nodes e links. Per gli alberi, l'input per il layout è il nodo radice, che può avere una matrice di child nodes e ai cui nodi foglia è associato uno value.

Se si desidera visualizzare un grafico e tutto ciò che si ha è un elenco di spigoli, quindi si desidera eseguire un'iterazione oltre i bordi per produrre una serie di nodi e una serie di collegamenti. Diciamo che ha avuto un file chiamato "graph.csv":

source,target 
A1,A2 
A2,A3 
A2,A4 

Si potrebbe caricare questo file utilizzando d3.csv e quindi produrre una serie di nodi e collegamenti:

d3.csv("graph.csv", function(links) { 
    var nodesByName = {}; 

    // Create nodes for each unique source and target. 
    links.forEach(function(link) { 
    link.source = nodeByName(link.source); 
    link.target = nodeByName(link.target); 
    }); 

    // Extract the array of nodes from the map by name. 
    var nodes = d3.values(nodeByName); 

    function nodeByName(name) { 
    return nodesByName[name] || (nodesByName[name] = {name: name}); 
    } 
}); 

Si può quindi passare questi nodi e collegamenti al layout forza di visualizzare il grafico:

Se si desidera produrre un albero , è necessario eseguire una forma leggermente diversa di trasformazione dei dati per accumulare i nodi figlio per ciascun genitore.

d3.csv("graph.csv", function(links) { 
    var nodesByName = {}; 

    // Create nodes for each unique source and target. 
    links.forEach(function(link) { 
    var parent = link.source = nodeByName(link.source), 
     child = link.target = nodeByName(link.target); 
    if (parent.children) parent.children.push(child); 
    else parent.children = [child]; 
    }); 

    // Extract the root node. 
    var root = links[0].source; 

    function nodeByName(name) { 
    return nodesByName[name] || (nodesByName[name] = {name: name}); 
    } 
}); 

Come così:

+0

+1 Grazie mille per il tuo tempo e la spiegazione dettagliata. Cancella alcuni dei malintesi che ho avuto. – Legend

+0

Considera di utilizzare la funzionalità nest di d3 come parte di questo approccio per convertire csv in diverse strutture ad albero https://github.com/mbostock/d3/wiki/Arrays#-nest – PhoebeB

4

D3 non richiede un formato specifico. Tutto dipende dalla tua applicazione. È sicuramente possibile convertire un elenco di adiacenza nel formato utilizzato in flare.json, ma questo sarebbe di nuovo il codice specifico dell'applicazione. In generale, non è possibile farlo come elenchi di adiacenza in quanto tali non hanno elementi "testa" o "radice" necessari per costruire un albero. Inoltre, dovrai gestire separatamente cicli, orfani, ecc.

Dato che si sta facendo la conversione sul lato server, sarei tentato di dire che "se non è rotto, non aggiustarlo";)

Problemi correlati