D3 disposition de la force - relier les noeuds par leur nom au lieu de leur index

j'essaie de relier les noeuds d3 par un ID au lieu d'un index (L'ID du noeud est généré par mon application).

Voici mes noeuds:

"Nodes": [
    {
      "Id": "338",
      "Name": "TEST NODE ONE",
      "Url": "http://www.google.com"
    },
    {
      "Id": "340",
      "Name": "TEST NODE TWO",
      "Url": "http://www.yahoo.com"
    },
    {
      "Id": "341",
      "Name": "TEST NODE THREE",
      "Url": "http://www.stackoverflow.com"
    },
    {
      "Id": "342",
      "Name": "TEST NODE FOUR",
      "Url": "http://www.reddit.com"
    }
  ]

Ils sont actuellement liés par index:

  "links": [
    {
      "source": 0,
      "target": 0,
      "value": "0"
    },
    {
      "source": 0,
      "target": 1,
      "value": "0"
    },
    {
      "source": 1,
      "target": 2,
      "value": "0"
    },
    {
      "source": 3,
      "target": 2,
      "value": "0"
    }
  ]

Toutefois, je tiens à les relier par "Id":

  "Links": [
    {
      "Source": "338",
      "Target": "338",
      "Value": "0"
    },
    {
      "Source": "338",
      "Target": "340",
      "Value": "0"
    },
    {
      "Source": "340",
      "Target": "341",
      "Value": "0"
    },
    {
      "Source": "342",
      "Target": "341",
      "Value": "0"
    }
  ]

j'ai essayé la solution proposée ici:https://groups.google.com/forum/#!msg / d3-js/LWuhBeEipz4/0kZIojCYvhIJ

en ajoutant les lignes suivantes avant d'appeler force.nœuds:

  // make links reference nodes directly for this particular data format:
  var hash_lookup = [];
  // make it so we can lookup nodes in O(1):
  json.Nodes.forEach(function(d, i) {
    hash_lookup[d.Id] = d;
  });
  json.Links.forEach(function(d, i) {
    d.source = hash_lookup[d.Source];
    d.target = hash_lookup[d.Target];
  });

j'ai essayé de déboguer ce qui précède, mais je n'arrive pas à le comprendre. Je reçois le message d'erreur suivant (ce qui signifie en général je n'ai pas défini correctement les liens):

Uncaught TypeError: Cannot read property 'weight' of undefined

Lien vers mon JS: http://jsfiddle.net/9sMrw/

19
demandé sur Blair 2014-06-02 06:09:07

1 réponses

Voici une façon simple de faire ceci:

var edges = [];
json.Links.forEach(function(e) {
    var sourceNode = json.Nodes.filter(function(n) {
        return n.Id === e.Source;
    })[0],
        targetNode = json.Nodes.filter(function(n) {
            return n.Id === e.Target;
        })[0];

    edges.push({
        source: sourceNode,
        target: targetNode,
        value: e.Value
    });
});

force
    .nodes(json.Nodes)
    .links(edges)
    .start();

var link = svg.selectAll(".link")
    .data(edges)
    ...

en Voici un qui fonctionne PLUNK. (Vous devez fourche pour être sûr, dans le cas où je supprimées par inadvertance.)

25
répondu FernOfTheAndes 2014-06-02 04:04:23