2012-06-18 23 views
33

Mientras que después de numerosos ejemplos D3, los datos por lo general recibe formateado en el formato que figura en flare.json:Cómo convertir a formato JSON de D3?

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

Tengo una lista de adyacencia de la siguiente manera:

A1 A2 
A2 A3 
A2 A4 

la que desea convertir al formato anterior . Actualmente, estoy haciendo esto en el lado del servidor, pero ¿hay alguna forma de lograrlo usando las funciones de d3? Encontré uno here, pero el enfoque parece requerir la modificación de la biblioteca del núcleo d3, que no estoy a favor debido a la facilidad de mantenimiento. ¿Alguna sugerencia?

+1

¿Qué quiere decir "lista de adyacencia"? – jbabey

+1

Creo que quiere decir '[(A1, A2), (A2, A3), (A2, A4)]'? – sczizzo

+0

@sczizzo: ¡Sí, eso es lo que quise decir! Lo siento jbabey. Debería haber sido más claro. – Legend

Respuesta

51

No hay formato prescrito , ya que generalmente puede redefinir sus datos a través de varias funciones de acceso (como hierarchy.children) y array.map. Pero el formato que citó es probablemente la representación más conveniente para los árboles porque funciona con los accesadores predeterminados.

La primera pregunta es si tiene la intención de mostrar graph o tree. Para los gráficos, la estructura de datos se define en términos de nodes y links. Para árboles, la entrada al diseño es el nodo raíz, que puede tener una matriz de child nodes, y cuyos nodos hoja tienen asociado value.

Si quiere mostrar un gráfico , y todo lo que tiene es una lista de bordes, entonces querrá iterar sobre los bordes para producir una matriz de nodos y una matriz de enlaces. Supongamos que tenía un archivo llamado "graph.csv":

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

Se puede cargar este archivo usando d3.csv y luego producir un conjunto de nodos y enlaces:

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}); 
    } 
}); 

entonces puede pasar de estos nodos y enlaces a la disposición de la fuerza para visualizar el gráfico:

En su lugar, si desea producir un árbol , deberá realizar una transformación de datos ligeramente diferente para acumular los nodos secundarios de cada uno de los padres.

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}); 
    } 
}); 

así:

+0

+1 Muchas gracias por su tiempo y la explicación detallada. Borra algunos de los conceptos erróneos que tenía. – Legend

+0

Considere usar la funcionalidad nido de d3 como parte de este enfoque para convertir su csv en diferentes estructuras de árbol https://github.com/mbostock/d3/wiki/Arrays#-nest – PhoebeB

4

D3 no necesita un formato específico. Todo depende de tu aplicación. Sin duda, puede convertir una lista de adyacencia al formato utilizado en flare.json, pero de nuevo sería un código específico de la aplicación. En general, no puede hacer eso ya que las listas de adyacencia no tienen elementos de "encabezado" o "raíz" que necesitaría para construir un árbol. Además, necesitaría manejar ciclos, huérfanos, etc. por separado.

Teniendo en cuenta que actualmente está haciendo la conversión en el lado del servidor, estaría tentado a decir que "si no está roto, no lo arregles";)