【问题标题】:Release all sticky nodes释放所有粘性节点
【发布时间】:2018-06-08 11:45:34
【问题描述】:

如何修改以下example,以便在按下按钮时释放所有粘性节点?我已经看到通过双击 (here) 来释放(解开)节点,但我想同时释放它们(我的计划是将其包含在图形的 restart() 函数中)。

<!DOCTYPE html>
<meta charset="utf-8">
<style>
  .links line {
    stroke: #999;
    stroke-opacity: 0.6;
  }
  
  .nodes circle {
    stroke: #fff;
    stroke-width: 1.5px;
  }
</style>
<svg width="960" height="600"></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
  //create somewhere to put the force directed graph
  var svg = d3.select("svg"),
    width = +svg.attr("width"),
    height = +svg.attr("height");


  var nodes_data = [{
      "name": "Travis",
      "sex": "M"
    },
    {
      "name": "Rake",
      "sex": "M"
    },
    {
      "name": "Diana",
      "sex": "F"
    },
    {
      "name": "Rachel",
      "sex": "F"
    },
    {
      "name": "Shawn",
      "sex": "M"
    },
    {
      "name": "Emerald",
      "sex": "F"
    }
  ]
  var links_data = [{
      "source": "Travis",
      "target": "Rake"
    },
    {
      "source": "Diana",
      "target": "Rake"
    },
    {
      "source": "Diana",
      "target": "Rachel"
    },
    {
      "source": "Rachel",
      "target": "Rake"
    },
    {
      "source": "Rachel",
      "target": "Shawn"
    },
    {
      "source": "Emerald",
      "target": "Rachel"
    }
  ]
  //set up the simulation 
  var simulation = d3.forceSimulation()
    //add nodes
    .nodes(nodes_data);


  //add forces
  //we're going to add a charge to each node 
  //also going to add a centering force
  //and a link force
  var link_force = d3.forceLink(links_data)
    .id(function(d) {
      return d.name;
    });
  simulation
    .force("charge_force", d3.forceManyBody())
    .force("center_force", d3.forceCenter(width / 2, height / 2))
    .force("links", link_force);

  //add tick instructions: 
  simulation.on("tick", tickActions);
  //draw circles for the links 
  var node = svg.append("g")
    .attr("class", "nodes")
    .selectAll("circle")
    .data(nodes_data)
    .enter()
    .append("circle")
    .attr("r", 10)
    .attr("fill", "red");
  //draw lines for the links 
  var link = svg.append("g")
    .attr("class", "links")
    .selectAll("line")
    .data(links_data)
    .enter().append("line")
    .attr("stroke-width", 2);


  var drag_handler = d3.drag()
    .on("start", drag_start)
    .on("drag", drag_drag)
    .on("end", drag_end);

  //same as using .call on the node variable as in https://bl.ocks.org/mbostock/4062045 
  drag_handler(node)
  //drag handler
  //d is the node 
  function drag_start(d) {
    if (!d3.event.active) simulation.alphaTarget(0.3).restart();
    d.fx = d.x;
    d.fy = d.y;
  }

  function drag_drag(d) {
    d.fx = d3.event.x;
    d.fy = d3.event.y;
  }

  function drag_end(d) {
    if (!d3.event.active) simulation.alphaTarget(0);
    d.fx = d.x;
    d.fy = d.y;
  }

  function tickActions() {
    //update circle positions each tick of the simulation 
    node
      .attr("cx", function(d) {
        return d.x;
      })
      .attr("cy", function(d) {
        return d.y;
      });

    //update link positions 
    //simply tells one end of the line to follow one node around
    //and the other end of the line to follow the other node around
    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;
      });
  }
</script>

【问题讨论】:

    标签: d3.js graph force-layout


    【解决方案1】:

    这不是博斯托克的块,没有双击释放节点。

    不管怎样,你只需要删除fxfy属性,然后重新加热模拟:

    d3.select("button").on("click", function() {
        node.each(function(d) {
            d.fx = d.fy = null;
        })
        simulation.alphaTarget(0.3).restart();
    })
    

    我正在使用alphaTarget,因为这是您的代码中的内容,但您应该考虑改用alpha

    这是更改后的代码:

    <!DOCTYPE html>
    <meta charset="utf-8">
    <style>
      .links line {
        stroke: #999;
        stroke-opacity: 0.6;
      }
      
      .nodes circle {
        stroke: #fff;
        stroke-width: 1.5px;
      }
    </style>
    <button>Release</button>
    <svg width="600" height="400"></svg>
    <script src="https://d3js.org/d3.v4.min.js"></script>
    <script>
      //create somewhere to put the force directed graph
      var svg = d3.select("svg"),
        width = +svg.attr("width"),
        height = +svg.attr("height");
    
    
      var nodes_data = [{
          "name": "Travis",
          "sex": "M"
        },
        {
          "name": "Rake",
          "sex": "M"
        },
        {
          "name": "Diana",
          "sex": "F"
        },
        {
          "name": "Rachel",
          "sex": "F"
        },
        {
          "name": "Shawn",
          "sex": "M"
        },
        {
          "name": "Emerald",
          "sex": "F"
        }
      ]
      var links_data = [{
          "source": "Travis",
          "target": "Rake"
        },
        {
          "source": "Diana",
          "target": "Rake"
        },
        {
          "source": "Diana",
          "target": "Rachel"
        },
        {
          "source": "Rachel",
          "target": "Rake"
        },
        {
          "source": "Rachel",
          "target": "Shawn"
        },
        {
          "source": "Emerald",
          "target": "Rachel"
        }
      ]
      //set up the simulation 
      var simulation = d3.forceSimulation()
        //add nodes
        .nodes(nodes_data);
    
    
      //add forces
      //we're going to add a charge to each node 
      //also going to add a centering force
      //and a link force
      var link_force = d3.forceLink(links_data)
        .id(function(d) {
          return d.name;
        });
      simulation
        .force("charge_force", d3.forceManyBody())
        .force("center_force", d3.forceCenter(width / 2, height / 2))
        .force("links", link_force);
    
      //add tick instructions: 
      simulation.on("tick", tickActions);
      //draw circles for the links 
      var node = svg.append("g")
        .attr("class", "nodes")
        .selectAll("circle")
        .data(nodes_data)
        .enter()
        .append("circle")
        .attr("r", 10)
        .attr("fill", "red");
      //draw lines for the links 
      var link = svg.append("g")
        .attr("class", "links")
        .selectAll("line")
        .data(links_data)
        .enter().append("line")
        .attr("stroke-width", 2);
    
    
      var drag_handler = d3.drag()
        .on("start", drag_start)
        .on("drag", drag_drag)
        .on("end", drag_end);
    
      //same as using .call on the node variable as in https://bl.ocks.org/mbostock/4062045 
      drag_handler(node)
      //drag handler
      //d is the node 
      function drag_start(d) {
        if (!d3.event.active) simulation.alphaTarget(0.3).restart();
        d.fx = d.x;
        d.fy = d.y;
      }
    
      function drag_drag(d) {
        d.fx = d3.event.x;
        d.fy = d3.event.y;
      }
    
      function drag_end(d) {
        if (!d3.event.active) simulation.alphaTarget(0);
        d.fx = d.x;
        d.fy = d.y;
      }
    
      function tickActions() {
        //update circle positions each tick of the simulation 
        node
          .attr("cx", function(d) {
            return d.x;
          })
          .attr("cy", function(d) {
            return d.y;
          });
    
        //update link positions 
        //simply tells one end of the line to follow one node around
        //and the other end of the line to follow the other node around
        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;
          });
      }
    
      d3.select("button").on("click", function() {
        node.each(function(d) {
          d.fx = d.fy = null;
        })
        simulation.alphaTarget(0.3).restart();
      })
    </script>

    【讨论】:

    • 工作就像一个魅力,谢谢!你是对的alpha。我只是以这段代码为例,但在我的实际代码中,我使用的是alpha 而不是alphaTarget
    猜你喜欢
    • 1970-01-01
    • 2017-05-02
    • 1970-01-01
    • 2012-09-11
    • 1970-01-01
    • 1970-01-01
    • 2013-07-23
    • 1970-01-01
    • 2021-11-23
    相关资源
    最近更新 更多