web-dev-qa-db-fra.com

Comment convertir au format JSON de D3?

Tout en suivant de nombreux exemples D3, les données sont généralement formatées au format indiqué dans flare.json :

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

J'ai une liste de contiguïté comme suit:

A1 A2
A2 A3
A2 A4

que je veux convertir au format ci-dessus. Actuellement, je fais cela du côté serveur, mais existe-t-il un moyen d'y parvenir en utilisant les fonctions de d3? J'en ai trouvé un ici , mais l'approche semble nécessiter une modification de la bibliothèque de base d3 à laquelle je ne suis pas favorable en raison de la maintenabilité. Aucune suggestion?

35
Legend

Il n'y a pas de format prescrit, car vous pouvez généralement redéfinir vos données via diverses fonctions d'accesseur (telles que hierarchy.children ) et array.map . Mais le format que vous avez cité est probablement la représentation la plus pratique pour les arbres car il fonctionne avec les accesseurs par défaut.

La première question est de savoir si vous avez l'intention d'afficher un graphique ou un arbre . Pour les graphiques, la structure des données est définie en termes de nœuds et liens . Pour les arbres, l'entrée de la mise en page est le nœud racine, qui peut avoir un tableau nœuds enfants , et dont les nœuds feuilles ont un valeur associé.

Si vous voulez afficher un graphique , et tout ce que vous avez est une liste d'arêtes, alors vous voudrez parcourir les bords afin de produire un tableau de nœuds et un tableau de liens. Supposons que vous disposiez d'un fichier appelé "graph.csv":

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

Vous pouvez charger ce fichier en utilisant d3.csv puis produire un tableau de nœuds et de liens:

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

Vous pouvez ensuite passer ces nœuds et ces liens à la disposition de force pour visualiser le graphique:

Si vous souhaitez produire un arbre à la place, vous devrez effectuer une forme de transformation des données légèrement différente pour accumuler les nœuds enfants pour chaque parent.

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

Ainsi:

54
mbostock

D3 ne nécessite pas de format spécifique. Tout dépend de votre application. Vous pouvez certainement convertir une liste d'adjacence au format utilisé dans flare.json, mais ce serait encore du code spécifique à l'application. En général, vous ne pouvez pas faire cela car les listes d'adjacence en tant que telles n'ont pas d'éléments "head" ou "root" dont vous auriez besoin pour construire un arbre. De plus, vous devrez gérer les cycles, les orphelins, etc. séparément.

Étant donné que vous effectuez actuellement la conversion côté serveur, je serais tenté de dire que "si ce n'est pas cassé, ne le réparez pas";)

5
Lars Kotthoff