本文介绍了如何在d3.js中的JavaScript中获取拖动事件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下是使用d3.js在JavaScript中绘制力向图的代码

Following is the code for drawing a force directed graph in javascript using d3.js

const graph = {
  nodes: [{
      name: 'john',
      age: 35
    },
    {
      name: 'simon',
      age: 37
    },
    {
      name: 'manjoor',
      age: 35
    },
    {
      name: 'lorg',
      age: 34
    },
    {
      name: 'kilvin',
      age: 32
    },
  ],
  links: [{
      source: 'john',
      target: 'simon'
    },
    {
      source: 'john',
      target: 'manjoor'
    },
    {
      source: 'simon',
      target: 'lorg'
    },
    {
      source: 'simon',
      target: 'kilvin'
    },
    {
      source: 'manjoor',
      target: 'kilvin'
    },
    {
      source: 'lorg',
      target: 'john'
    },
    {
      source: 'lorg',
      target: 'manjoor'
    },
    {
      source: 'kilvin',
      target: 'manjoor'
    },
  ]
}


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, 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(d3.event.x, d3.event.y)
}

function drawNode(d) {

  ctx.fillStyle = color(d.party)
  ctx.moveTo(d.x, d.y)
  ctx.arc(d.x, d.y, r, 0, 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>

我正在画布上绘制图形。

I'm getting the graph on the canvas.

但是我遇到以下错误:

&当我调试时,我可以看到这里是发生错误的地方 return Simulation.find(d3.event.x,d3.event.y) ...似乎缺少事件...有办法解决这个问题。这发生在拖曳...&

& when I debug I can see that here is where error occurs return simulation.find(d3.event.x, d3.event.y) ... seems like event is missing... is there a way to solve this. this happens on drag... & so dragging each node is not working.

或者有人可以建议一种拖动节点的方法...

or can someone suggest a way to drag nodes...

推荐答案

您正在使用d3版本6。 d3.event 已被删除。请仔细阅读,降级d3版本,或查看

You're using d3 version 6. d3.event has been removed. Please read the change log carefully, downgrade your d3 version, or look for more up to date examples.

const graph = {
  nodes: [{
      name: 'john',
      age: 35
    },
    {
      name: 'simon',
      age: 37
    },
    {
      name: 'manjoor',
      age: 35
    },
    {
      name: 'lorg',
      age: 34
    },
    {
      name: 'kilvin',
      age: 32
    },
  ],
  links: [{
      source: 'john',
      target: 'simon'
    },
    {
      source: 'john',
      target: 'manjoor'
    },
    {
      source: 'simon',
      target: 'lorg'
    },
    {
      source: 'simon',
      target: 'kilvin'
    },
    {
      source: 'manjoor',
      target: 'kilvin'
    },
    {
      source: 'lorg',
      target: 'john'
    },
    {
      source: 'lorg',
      target: 'manjoor'
    },
    {
      source: 'kilvin',
      target: 'manjoor'
    },
  ]
}


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, 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, 0, 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>

这篇关于如何在d3.js中的JavaScript中获取拖动事件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-31 05:21