data_set = [ {name:"aaa",fx:400,fy:200}, {name:"bbb"} ] ; link_set = [ {source:"aaa", target:"bbb"}, ]; var width=600, height=300; d3.select("#content") .append("rect") .attr("x",380) .attr("y",30) .attr("width", 40) .attr("height",40) .attr('fill', 'rgba(0,0,0,0)') .attr('stroke', 'red') ; var force_g = d3.select("#content").append("g") ; var links = force_g.selectAll(".link") .data(link_set) .enter() .append("line") .attr("class", "link") .attr("stroke", "none") .attr("stroke-weight", 1) ; var circles = force_g.selectAll("circle") .data(data_set) .enter() .append("circle") .attr("class",function(d){ return "circle-"+d.name }) .attr("r", 15) .attr("fill","lightblue") .call(d3.drag() .on("start", dragstarted) .on("drag", dragged) .on("end", dragended) ) ; var line_force = d3.forceSimulation() .nodes(data_set) .on("tick", ticked) .force("link", d3.forceLink(link_set) .id(function(d){ return d.name ; }) .distance(0) .strength(0.5)) .force('charge', d3.forceManyBody().strength(0.8)) .force("collision", d3.forceCollide(0)) ; function dragstarted(d) { if (!d3.event.active) line_force.alphaTarget(0.9).restart(); d.fx = d.x; d.fy = d.y; } function dragged(d) { d.fx = d3.event.x; d.fy = d3.event.y; } function dragended(d) { if (!d3.event.active) line_force.alphaTarget(0); d.fx = null; d.fy = null; var a = d3.select(".circle-aaa") ; a.datum().fy=50; a.datum().fx=400; } function ticked(){ circles .attr("cx", function(d){ return d.x; }) .attr("cy", function(d){ return d.y; }) ; links .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 src="https://d3js.org/d3.v4.min.js" charset="utf-8"></script> <svg id="content" width="640" height="400" ></svg>