如何解决如何在javascript中的d3.js中拖动节点?
以下是使用d3.js制作力向图的代码:
如何仅在拖动节点时使节点拖动??
当前的原因是,当您在舞台上的任何位置拖动时,附近的某些节点将被拖动。相反,如何约束拖动仅在拖动真实节点(而不是周围区域)时发生
我又如何使舞台可缩放和拖动?
const graph = {
nodes: [{
name: 'john',age: 35
},{
name: 'simon',age: 37
},{
name: 'manjoor',{
name: 'lorg',age: 34
},{
name: 'kilvin',age: 32
},],links: [{
source: 'john',target: 'simon'
},{
source: 'john',target: 'manjoor'
},{
source: 'simon',target: 'lorg'
},target: 'kilvin'
},{
source: 'manjoor',{
source: 'lorg',target: 'john'
},{
source: 'kilvin',]
}
const canvas = d3.select('#network')
const width = canvas.attr('width')
const height = canvas.attr('height')
const r = 30
const ctx = canvas.node().getContext('2d')
const color = d3.scaleOrdinal(d3.schemeAccent);
const simulation = d3.forceSimulation()
.force('x',d3.forceX(width / 2))
.force('y',d3.forceY(height / 2))
.force('collide',d3.forceCollide(r + 20))
.force('charge',d3.forceManyBody().strength(-100))
.force('link',d3.forceLink().id(node => node.name))
.on('tick',update)
simulation.nodes(graph.nodes)
simulation.force('link').links(graph.links)
canvas.call(d3.drag()
.container(canvas.node())
.subject(dragsubject).on('start',dragstarted)
.on('drag',dragged).on('end',dragended)
)
function update() {
ctx.clearRect(0,width,height)
ctx.beginPath()
ctx.globalAlpha = 0.5
ctx.strokeStyle = 'blue'
graph.links.forEach(drawLink)
ctx.stroke()
ctx.beginPath()
ctx.globalAlpha = 1
graph.nodes.forEach(drawNode)
ctx.fill()
}
function dragsubject(event) {
return simulation.find(event.x,event.y);
}
function drawNode(d) {
ctx.fillStyle = color(d.party)
ctx.moveto(d.x,d.y)
ctx.arc(d.x,d.y,r,Math.PI * 2)
}
function drawLink(l) {
ctx.moveto(l.source.x,l.source.y)
ctx.lineto(l.target.x,l.target.y)
}
function dragstarted(event) {
if (!event.active) simulation.alphaTarget(0.3).restart();
event.subject.fx = event.subject.x;
event.subject.fy = event.subject.y;
}
function dragged(event) {
event.subject.fx = event.x;
event.subject.fy = event.y;
}
function dragended(event) {
if (!event.active) simulation.alphaTarget(0);
event.subject.fx = null;
event.subject.fy = null;
}
update()
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.2.0/d3.js"></script>
<canvas id="network" width="600" height="300"></canvas>
解决方法
simulation.find(x,y [,radius])- 返回具有给定搜索半径的最接近位置⟨x,y⟩的节点。如果未指定radius,则默认为无穷大。如果搜索区域内没有节点,则返回undefined。
传递r
的半径(与球的半径相同)使得仅当动作是从节点中心到r
时才记录拖动。
const graph = {
nodes: [{
name: 'john',age: 35
},{
name: 'simon',age: 37
},{
name: 'manjoor',{
name: 'lorg',age: 34
},{
name: 'kilvin',age: 32
},],links: [{
source: 'john',target: 'simon'
},{
source: 'john',target: 'manjoor'
},{
source: 'simon',target: 'lorg'
},target: 'kilvin'
},{
source: 'manjoor',{
source: 'lorg',target: 'john'
},{
source: 'kilvin',]
}
const canvas = d3.select('#network')
const width = canvas.attr('width')
const height = canvas.attr('height')
const r = 30
const ctx = canvas.node().getContext('2d')
const color = d3.scaleOrdinal(d3.schemeAccent);
const simulation = d3.forceSimulation()
.force('x',d3.forceX(width / 2))
.force('y',d3.forceY(height / 2))
.force('collide',d3.forceCollide(r + 20))
.force('charge',d3.forceManyBody().strength(-100))
.force('link',d3.forceLink().id(node => node.name))
.on('tick',update)
simulation.nodes(graph.nodes)
simulation.force('link').links(graph.links)
canvas.call(d3.drag()
.container(canvas.node())
.subject(dragsubject)
.on('start',dragstarted)
.on('drag',dragged)
.on('end',dragended)
)
function update() {
ctx.clearRect(0,width,height)
ctx.beginPath()
ctx.globalAlpha = 0.5
ctx.strokeStyle = 'blue'
graph.links.forEach(drawLink)
ctx.stroke()
ctx.beginPath()
ctx.globalAlpha = 1
graph.nodes.forEach(drawNode)
ctx.fill()
}
function dragsubject(event) {
return simulation.find(event.x,event.y,r);
}
function drawNode(d) {
ctx.fillStyle = color(d.party)
ctx.moveTo(d.x,d.y)
ctx.arc(d.x,d.y,r,Math.PI * 2)
}
function drawLink(l) {
ctx.moveTo(l.source.x,l.source.y)
ctx.lineTo(l.target.x,l.target.y)
}
function dragstarted(event) {
if (!event.active) simulation.alphaTarget(0.3).restart();
event.subject.fx = event.subject.x;
event.subject.fy = event.subject.y;
}
function dragged(event) {
event.subject.fx = event.x;
event.subject.fy = event.y;
}
function dragended(event) {
if (!event.active) simulation.alphaTarget(0);
event.subject.fx = null;
event.subject.fy = null;
}
update()
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.2.0/d3.js"></script>
<canvas id="network" width="600" height="300"></canvas>
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。