You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

d3.js Force simulation 力导向模拟拖拽无法跟随鼠标移动问题

问题原因

你使用的是D3 v6及以上版本,该版本对事件回调的参数顺序做了不兼容更新:拖拽事件触发时,第一个传入参数是事件对象,第二个才是节点绑定的数据对象。你现有代码中两个参数顺序写反,无法正确给节点的固定坐标属性fx/fy赋值,因此拖拽功能无法生效。

修复方案

仅需要调整dragged1和dragended1两个回调函数的参数顺序即可,修改后完整代码如下:

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.7.0/d3.min.js"></script>
test()
function test() {
  var data1 ={ 
    "nodes":  [
      {"id": "A"},
      {"id": "B"},
      {"id": "C"},
      {"id":"D"}],  
    "links":  [
      {"source": "A", "target": "B"},    
      {"source": "B", "target": "C"},   
      {"source": "C", "target": "A"},   
      {"source": "D", "target": "A"}]}

  var height = 250; var width = 400;

  var svg = d3.select("body").append("svg")   
  .attr("width",width)
  .attr("height",height)
  .style('border','1px solid red')

  var simulation1 = d3.forceSimulation()
  .force("link", d3.forceLink().id(function(d) { return d.id; }).distance(50))
  .force("charge", d3.forceManyBody())
  .force("center", d3.forceCenter(width / 3, height / 2));

  var link1 = svg.append("g")
  .selectAll("line")
  .data(data1.links)
  .enter().append("line")
  .attr("stroke","black");

  var node1 = svg.append("g")
  .selectAll("circle")
  .data(data1.nodes)
  .enter().append("circle")
  .attr("r", 10)
  .call(d3.drag()
        .on("drag", dragged1)
        .on("end", dragended1))
  .attr("fill","crimson");

  simulation1.nodes(data1.nodes)
    .on("tick", ticked1)
    .alphaDecay(0)
    .force("link")
    .links(data1.links);

  function ticked1() {
    link1
      .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; });
    node1
      .attr("cx", function(d) { return d.x; })
      .attr("cy", function(d) { return d.y; });
  }    

  // 仅调整此处参数顺序,事件对象在前,数据d在后
  function dragged1(event, d) {
    d.fx = event.x;
    d.fy = event.y;
  }

  // 仅调整此处参数顺序,事件对象在前,数据d在后
  function dragended1(event, d) {
    d.fx = null;
    d.fy = null;
  }

}

内容的提问来源于stack exchange,提问作者lucky1928

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.18 01:36:03