2017-06-10 2 views
0

En essayant de changer cet exemple https://bl.ocks.org/mbostock/1667139 pour utiliser le chemin au lieu de la ligne, mais son ne fonctionne pas. Im essayez d'utiliser la fonction propre à cocher comme ceci:Disposition de force statique D3.js ne fonctionne pas avec le chemin?

function tick() { 
      link.attr("d", function(d) { 
      var x1 = d.source.x, 
       y1 = d.source.y, 
       x2 = d.target.x, 
       y2 = d.target.y, 
       dx = x2 - x1, 
       dy = y2 - y1, 
       dr = Math.sqrt(dx * dx + dy * dy), 

       // z uzla do ineho uzla 
       drx = dr, 
       dry = dr, 
       xRotation = 0, 
       largeArc = 0, 
       sweep = 1; 

      //do sameho seba 
      if (x1 === x2 && y1 === y2) { 
       xRotation = -45; 
       largeArc = 1; 
       drx = 30; 
       dry = 30; 
       x2 = x2 + 1; 
       y2 = y2 + 1; 
      } 

      return "M" + x1 + "," + y1 + "A" + drx + "," + dry + " " + xRotation + "," + largeArc + "," + sweep + " " + x2 + "," + y2; 
     });  
} 

Je ne sais pas, si je manque quelque chose ou la mise en page de force statique de chemin d'utilisation juste ne peux pas. mise en page active avec le chemin de travail normaly

Répondre

1

De l'docs (mine de caractères gras):

simulation.tick()

incrémente l'alpha actuelle en (alphaTarget - alpha) × alphaDecay; invoque alors chaque force enregistrée, en passant le nouvel alpha; puis décrémente la vitesse de chaque nœud par la vitesse × vitesseDécompte; Enfin, incrémente la position de chaque nœud par vélocité.

Cette méthode ne distribue pas les événements; les événements sont uniquement envoyés par le temporisateur interne lorsque la simulation est démarrée automatiquement lors de la création ou en appelant simulation.restart. Le nombre naturel de graduations au démarrage de la simulation est ⌈log (alphaMin)/log (1 - alphaDecay) ⌉; par défaut, il s'agit de 300.

Cette méthode peut être utilisée conjointement avec simulation.stop pour calculer une disposition de force statique. Pour les grands graphiques, les mises en page statiques doivent être calculées dans un agent Web pour éviter de geler l'interface utilisateur.

Comme il ne distribue pas d'événements, votre fonction de tic n'est jamais appelée ou utilisée. Au lieu de cela, il suffit de remplacer la ligne et de définir votre chemin une fois:

<!DOCTYPE html> 
 
<svg width="960" height="500"></svg> 
 
<script src="https://d3js.org/d3.v4.min.js"></script> 
 
<script> 
 
    var svg = d3.select("svg"), 
 
    width = +svg.attr("width"), 
 
    height = +svg.attr("height"), 
 
    g = svg.append("g").attr("transform", "translate(" + width/2 + "," + height/2 + ")"); 
 

 
    var n = 100, 
 
    nodes = d3.range(n).map(function(i) { 
 
     return { 
 
     index: i 
 
     }; 
 
    }), 
 
    links = d3.range(n).map(function(i) { 
 
     return { 
 
     source: i, 
 
     target: (i + 3) % n 
 
     }; 
 
    }); 
 

 
    var simulation = d3.forceSimulation(nodes) 
 
    .force("charge", d3.forceManyBody().strength(-80)) 
 
    .force("link", d3.forceLink(links).distance(20).strength(1).iterations(10)) 
 
    .force("x", d3.forceX()) 
 
    .force("y", d3.forceY()) 
 
    .stop(); 
 

 
    var loading = svg.append("text") 
 
    .attr("dy", "0.35em") 
 
    .attr("text-anchor", "middle") 
 
    .attr("font-family", "sans-serif") 
 
    .attr("font-size", 10) 
 
    .text("Simulating. One moment please…"); 
 

 
    // Use a timeout to allow the rest of the page to load first. 
 
    d3.timeout(function() { 
 
    loading.remove(); 
 

 
    // See https://github.com/d3/d3-force/blob/master/README.md#simulation_tick 
 
    for (var i = 0, n = Math.ceil(Math.log(simulation.alphaMin())/Math.log(1 - simulation.alphaDecay())); i < n; ++i) { 
 
     simulation.tick(); 
 
    } 
 

 
    g.append("g") 
 
     .attr("stroke", "#000") 
 
     .attr("stroke-width", 1.5) 
 
     .selectAll("line") 
 
     .data(links) 
 
     .enter().append("path") 
 
     .attr("d", function(d) { 
 
     var x1 = d.source.x, 
 
      y1 = d.source.y, 
 
      x2 = d.target.x, 
 
      y2 = d.target.y, 
 
      dx = x2 - x1, 
 
      dy = y2 - y1, 
 
      dr = Math.sqrt(dx * dx + dy * dy), 
 

 
      // z uzla do ineho uzla 
 
      drx = dr, 
 
      dry = dr, 
 
      xRotation = 0, 
 
      largeArc = 0, 
 
      sweep = 1; 
 

 
     //do sameho seba 
 
     if (x1 === x2 && y1 === y2) { 
 
      xRotation = -45; 
 
      largeArc = 1; 
 
      drx = 30; 
 
      dry = 30; 
 
      x2 = x2 + 1; 
 
      y2 = y2 + 1; 
 
     } 
 

 
     return "M" + x1 + "," + y1 + "A" + drx + "," + dry + " " + xRotation + "," + largeArc + "," + sweep + " " + x2 + "," + y2; 
 
     }); 
 

 
    g.append("g") 
 
     .attr("stroke", "#fff") 
 
     .attr("stroke-width", 1.5) 
 
     .selectAll("circle") 
 
     .data(nodes) 
 
     .enter().append("circle") 
 
     .attr("cx", function(d) { 
 
     return d.x; 
 
     }) 
 
     .attr("cy", function(d) { 
 
     return d.y; 
 
     }) 
 
     .attr("r", 4.5); 
 

 

 
    }); 
 
</script>

Réponse aux commentaires:

Pour ajouter un cercle et le texte comme un « nœud », je créer un g, position cela et puis mettre le cercle et le texte dedans:

var g = node 
    .selectAll(".node") 
    .data(nodes) 
    .enter() 
    .append("g") 
    .attr("transform", function(d){ 
     return "translate(" + d.x + "," + d.y + ")"; 
    }); 

    g.append("circle") 
    .attr("class", "node") 
    .attr("stroke", "#fff") 
    .attr("r", 28); 

    g.append("text") 
    .text("test"); 
+0

Realy thx, peut Je vous demande une chose de plus? Comment ajouter du texte à tous les cercles? La disposition de force non statique crée juste var circle.append ("g") puis ajoute ("circle") et ajoute ensuite ("text") pour ajouter du texte mais cela ne fonctionne pas ici. Mon essai est ici https://jsfiddle.net/f7e20crm/. Ce texte est un élément séparé qui ne fait pas partie de l'élément g quand est un élément de cercle et de texte – Martin

+0

@Martin, voir la mise à jour de la réponse à votre question. Et mis à jour le violon [ici] (https://jsfiddle.net/f7e20crm/6/). – Mark