2016-09-07 1 views
0

J'essaye d'écrire ma propre fonction pour peser des liens pour un graphe orienté Force d3 v4.Comment personnaliser la force de la liaison d3 en fonction du nombre de liens et de nœuds? (d3 v4)

La fonction de force par défaut est here et selon le readme il est possible de le changer en passant une nouvelle fonction comme argument. (Notez que la fonction dans le readme est légèrement différente de celle du code actuel).

Ceci est la partie du code, je voudrais travailler:

var simulation = d3.forceSimulation() 
      .force("link", d3.forceLink() 
        .distance(60) 
        .id(function (d) { return d.name;}) 
        .strength(function (link) {/* my code here */})) 

J'ai essayé de remplacer le commentaire par la valeur par défaut:

function (link) { return 1/Math.min(count[link.source.index], 
             count[link.target.index]); } 

Sans succès.

+0

'count' n'est pas accessible à partir du rappel prévu à' .strength() '. Cette variable est utilisée en interne par 'd3.forceLink()' mais n'est pas exposée. Cela peut aider à spécifier ce que vous voulez réaliser avec votre code, pour vous aider à trouver une solution avec les moyens disponibles. – altocumulus

+0

oui, je me suis rendu compte que c'était un peu en retard ... j'étais capable de le faire fonctionner avec '1/Math.min (d.source.size, d.target.size)' car mes nœuds ont un attribut 'size' remplace ce compte. Merci d'avoir répondu – Dabrule

Répondre

0

Il est difficile de dire à partir de l'exemple que vous avez fourni, mais vous devez transmettre les liens à la fonction simulations forceLink. Si votre exemple réussit à construire des liens, vous pouvez envisager d'externaliser le calcul, puis d'appeler cette fonction depuis l'intérieur des liens: Voici un exemple qui fonctionne pour moi.

var weightScale = d3.scaleLinear() 
.domain(d3.extent(edges, function (d) { return d.weight })) 
.range([.1, 1]) 


graph = d3.forceSimulation() 
.nodes(nodes) 
.force("charge", d3.forceManyBody() 
    .strength(-75) // -1000 
    .distanceMax([250]))  
.force("link", d3.forceLink() 
    .links(edges) 
    .id(function(d) { return d.index }) 
    .strength (function (d) {return weightScale(d.weight)}) 
    .distance(55)) 
.force("center", d3.forceCenter(250, 250)) // width/2, height/2 
.on("tick", forceTick); 

J'utilise une échelle weightScale sur les poids de lien, qui est appelé à l'intérieur .strenght. Vous pouvez passer les liens comme celui-ci:

.force("link", d3.forceLink(*YOURLINKS*) 

ou ceci:

.force("link", d3.forceLink() 
    .links(*YOURLINKS*)