简体   繁体   English

D3.js 网络只移动一次(使用教程代码)

[英]D3.js network only move once (using tutorial codes)

I am trying to use d3.js for interactive networks.我正在尝试将 d3.js 用于交互式网络。 However, I struggle to even have tutorial code working with my own data.然而,我什至很难让教程代码处理我自己的数据。 Everything seems to work as I can see my network moving using the force algorithms, but the algo stop after the nodes moved once or twice, and I don't understand why.一切似乎都在工作,因为我可以看到我的网络使用强制算法移动,但是在节点移动一两次后算法停止,我不明白为什么。

Here is for the result I get: https://alex7722.github.io/javascript/这是我得到的结果: https : //alex7722.github.io/javascript/

The html with the script:带有脚本的 html:

<!DOCTYPE html>
<meta charset="utf-8">

<!-- Load d3.js -->
<script src="https://d3js.org/d3.v4.js"></script>

<!-- Create a div where the graph will take place -->
<div id="my_dataviz"></div>

<script>

  // set the dimensions and margins of the graph
  var margin = {top: 10, right: 30, bottom: 30, left: 40},
    width = 400 - margin.left - margin.right,
    height = 400 - margin.top - margin.bottom;
  
  // append the svg object to the body of the page
  var svg = d3.select("#my_dataviz")
  .append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
  .append("g")
    .attr("transform",
          "translate(" + margin.left + "," + margin.top + ")");
  
  d3.json("data.json", function( data) {
  
    // Initialize the links
    var link = svg
      .selectAll("line")
      .data(data.links)
      .enter()
      .append("line")
        .style("stroke", "#aaa")
  
    // Initialize the nodes
    var node = svg
      .selectAll("circle")
      .data(data.nodes)
      .enter()
      .append("circle")
        .attr("r", 20)
        .style("fill", "#69b3a2")
  
    // Let's list the force we wanna apply on the network
    var simulation = d3.forceSimulation(data.nodes)                 // Force algorithm is applied to data.nodes
        .force("link", d3.forceLink()                               // This force provides links between nodes
              .id(function(d) { return d.id; })                     // This provide  the id of a node
              .links(data.links)                                    // and this the list of links
        )
        .force("charge", d3.forceManyBody().strength(-400))         // This adds repulsion between nodes. Play with the -400 for the repulsion strength
        .force("center", d3.forceCenter(width / 2, height / 2))     // This force attracts nodes to the center of the svg area
        .on("end", ticked);
  
    // This function is run at each iteration of the force algorithm, updating the nodes position.
    function ticked() {
      link
          .attr("x1", function(d) { return d.source.x; })
          .attr("y1", function(d) { return d.source.y; })
          .attr("x2", function(d) { return d.target.x; })
          .attr("y2", function(d) { return d.target.y; });
  
      node
           .attr("cx", function (d) { return d.x+6; })
           .attr("cy", function(d) { return d.y-6; });
    }
  
  });
  
  
  </script>

Extracts of my json I created from igraph in R:我从 R 中的 igraph 创建的 json 的摘录:

{"nodes":[{"name":"1431","id":"1430"},{"name":"1630","id":"1629"},{"name":"1632","id":"1631"},{"name":"2373","id":"2372"},{"name":"3612","id":"3611"},{"name":"3634","id":"3633"},{"name":"4700","id":"4699"},{"name":"5075","id":"5074"},{"name":"5088","id":"5087"},{"name":"5361","id":"5360"},{"name":"5370","id":"5369"},{"name":"6696","id":"6695"},{"name":"6726","id":"6725"},{"name":"6807","id":"6806"},{"name":"6831","id":"6830"},{"name":"6832","id":"6831"},{"name":"7198","id":"7197"},{"name":"8529","id":"8528"},{"name":"12732","id":"12731"},{"name":"13619","id":"13618"},{"name":"13620","id":"13619"},{"name":"13625","id":"13624"}
[...]
{"source":"37078","target":"40968"},{"source":"26138","target":"41039"},{"source":"35165","target":"41066"},{"source":"35313","target":"41066"},{"source":"8030","target":"41135"},{"source":"13643","target":"41332"},

You have a lot of nodes to animate.你有很多节点要制作动画。 Just change the simulation call to run the ticked function on each tick event, not the end (that's why it stops):只需更改模拟调用以在每个滴答事件上运行滴答函数,而不是结束(这就是它停止的原因):

// Let's list the force we wanna apply on the network
var simulation = d3.forceSimulation(data.nodes)                 // Force algorithm is applied to data.nodes
  .force("link", d3.forceLink()                               // This force provides links between nodes
    .id(function(d) { return d.id; })                     // This provide  the id of a node
    .links(data.links)                                    // and this the list of links
  )
  .force("charge", d3.forceManyBody().strength(-400))         // This adds repulsion between nodes. Play with the -400 for the repulsion strength
  .force("center", d3.forceCenter(width / 2, height / 2))     // This force attracts nodes to the center of the svg area
  .on("tick", ticked);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM