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
相关产品推荐
相关产品推荐

