如何让D3.js力导向图的圆形节点支持区域拖拽而非仅边框拖拽
解决D3.js圆形节点拖拽仅边框生效的问题
当前代码中圆形节点拖拽仅在点击边框时触发,原因是你给circle元素设置了fill: none——SVG元素只有填充区域和描边区域会响应鼠标事件,填充为none时,只有边框(描边)能触发拖拽。
要让整个圆形区域都能触发拖拽,只需将填充改为透明色即可,这样既保持视觉上的空心效果,又能让整个圆形区域响应鼠标事件:
修改核心代码
将节点创建部分的.attr('fill', 'none')替换为透明填充:
.attr('fill', 'rgba(0, 0, 0, 0)')
也可以使用transparent关键字,效果完全一致:
.attr('fill', 'transparent')
完整修改后的代码
demo() function demo() { function dragstarted(event,d) { if (!event.active) simulation.alphaTarget(0.3).restart(); d.fx = d.x; d.fy = d.y; } function dragged(event,d) { d.fx = event.x; d.fy = event.y; } function dragended(event,d) { // if (!event.active) simulation.alphaTarget(0); // d.fx = null; // d.fy = null; } var data = { "nodes":[{ "id":1, "influence": 1 },{ "id": 2, "influence": 2 }], "links":[{ "source": 1, "target": 2, "weight": 3 }] } var width = 200 var height = 200 const simulation = d3.forceSimulation(data.nodes) .force('charge', d3.forceManyBody().strength(-100)) .force('link', d3.forceLink(data.links).id(d => d.id) .distance(150)) .force('center', d3.forceCenter(width/2, height/2)) const svg = d3.select('body') .append("svg") .attr("viewBox", [0,0,width,height]); var path = ['M',2,6,'L',2,2,10,6,2,10,'z'].join(' ') svg .append('defs') .append('marker') .attr('id', 'arr1') .attr('viewBox', [0, 0, 12, 12]) .attr('refX', 10) .attr('refY', 6) .attr('markerWidth', 12) .attr('markerHeight', 12) .attr('orient', 'auto-start-reverse') .append('path') .attr('d',path) .attr('stroke', 'black') .attr('fill','black') var r = 35 const node = svg.selectAll('circle') .data(data.nodes) .enter() .append('circle') .attr('r', r) .attr('stroke','black') .attr('stroke-width',4) .attr('fill', 'rgba(0, 0, 0, 0)') // 修改为透明填充 .call(d3.drag() .on("start", dragstarted) .on("drag", dragged) .on("end", dragended)); const link = svg .selectAll('path.link') .data(data.links) .enter() .append('line') .attr('stroke', 'black') .attr('fill', 'none'); simulation.on('tick', () => { node.attr('cx', d => d.x); node.attr('cy', d => d.y); link.attr('x1', d => { var sx = d.source.x var sy = d.source.y var tx = d.target.x var ty = d.target.y var dx = tx - sx var dy = ty - sy var length = Math.sqrt((dx * dx) + (dy * dy)) var x = r*dx/length var y = r*dy/length d.source.bx = sx + x d.source.by = sy + y d.target.bx = tx - x d.target.by = ty - y return d.source.bx }) .attr('y1',d => d.source.by) .attr('x2',d => d.target.bx) .attr('y2',d => d.target.by) link.attr('marker-end', 'url(#arr1)') }); }
<script src="https://unpkg.com/d3@7.0.4/dist/d3.min.js"></script>
内容的提问来源于stack exchange,提问作者lucky1928
相关产品推荐
相关产品推荐

