我在使用d3.js画力导向图时,出现了画出了圆,但是不是力导向图,并且圆也只是在角落里。无论我怎么改变forceCenter的参数,都没有用,感觉只是canvas生效而d3的force没有生效。
实现后的截图:
具体代码如下:
<template>
<div id='force_graph'>
<h1>hello</h1>
<div id='graph_canvas'>
<canvas ref="canvas" height=600 width=1300></canvas>
</div>
</div>
</template>
<script>
import * as d3 from 'd3'
export default {
name: 'forceGraph',
data () {
return {
nodes: [
{id: 1, name: 'javascript', color: 'pink'},
{id: 2, name: 'java', color: 'green'},
{id: 3, name: 'c++', color: 'blue'},
{id: 4, name: 'python', color: 'grey'},
{id: 5, name: 'php', color: 'red'}
],
edges: [
{source: 1, target: 3},
{source: 2, target: 4},
{source: 3, target: 5},
{source: 4, target: 5}
],
graph: null,
width: 1300,
height: 600,
strength: -20,
link_distance: 30,
canvas: document.querySelector('canvas'),
e: null
}
},
methods: {
render (e) {
e.clearRect(0, 0, this.height, this.width)
e.lineWidth = 2
e.strokeStyle = 'white'
e.beginPath()
this.edges.forEach(function (a) {
e.moveTo(a.source.x, a.source.y)
e.lineTo(a.target.x, a.target.y)
})
e.stroke()
e.lineWidth = 3
e.strokeStyle = 'black'
this.nodes.forEach(function (a) {
e.fillStyle = a.color
e.beginPath()
e.arc(a.x, a.y, 200, 0, 2 * Math.PI)
e.fill()
e.stroke()
})
e.font = '14px Comic Sans MS'
e.fillStyle = 'black'
e.textAlign = 'center'
this.nodes.forEach(function (a) {
e.fillText(a.name, a.x, a.y + 2.5 * 12)
})
},
force_graph_init () {
const canvas = document.querySelector('canvas')
console.log(canvas)
console.log('ah:nodes')
console.log(this.nodes)
this.nodes.push({id: 6, name: 'c', color: 'brown'})
this.e = canvas.getContext('2d')
this.width = canvas.width
this.height = canvas.height
this.graph = d3.forceSimulation().force('center', d3.forceCenter(-1000, -1000))
console.log('graph')
console.log(this.graph)
this.graph.force('charge', d3.forceManyBody())
.force('collide', d3.forceCollide(1.2 * 12))
.force('link', d3.forceLink().id(function (d) { return d.id }).distance(this.link_distance))
console.log('be:nodes')
console.log(this.nodes)
this.graph.nodes(this.nodes).on('tick', this.render(this.e))
// this.graph.force('link', d3.forceLink().id(function (a) { return a.id }).distance(this.link_distance))
this.graph.force('link').links(this.edges)
// d3.select(canvas).call(d3.drag().container(canvas).subject(function () { return this.graph.find(d3.event.x, d3.event.y) })
// .on('start', function () {
// d3.event.active || this.graph.alphTarget(0.3).restart()
// d3.event.subject.fx = d3.event.subject.x
// d3.event.subject.fy = d3.event.subject.y
// }).on('drag', function () {
// d3.event.subject.fx = d3.event.x
// d3.event.subject.fy = d3.event.y
// }).on('end', function () {
// d3.event.active || this.graph.alphaTarget(0)
// d3.event.subject.fx = null
// d3.event.subject.fy = null
// }))
this.restart()
console.log(this.graph)
console.log('nodes:')
console.log(this.nodes)
console.log('edges')
console.log(this.edges)
// this.pause()
},
initDrag () {
},
run () {
this.graph.restart()
},
restart () {
this.graph.alpha(1)
this.run()
},
pause () {
this.graph.stop()
}
},
mounted () {
this.force_graph_init()
}
}
</script>
<style scoped>
#graph_canvas{
width: 900px;
margin: 20px auto;
}
</style>
ps:注释部分是可拖拽部分,所以就先注释了。
主要是你的render加了括号,这就不是传入函数而是将它执行且执行一次而已,所以节点都画在了圆点,另外一些参数有点错误或者需要优化。