Vue.js 和 D3.js - 力模拟
Posted
技术标签:
【中文标题】Vue.js 和 D3.js - 力模拟【英文标题】:Vue.js and D3.js - force-simualtion 【发布时间】:2022-01-14 07:39:48 【问题描述】:我目前正在尝试使用 Restful-Api 调用并使用信息来进行 d3.js 强制模拟。问题是,如果我使用来自 API 的数据,如果什么都没有,调用模拟处理它。如果我等待下一个滴答声this.$nextTick(simu)
,所有位置最终都会变成NaN
。这种行为有原因吗?
const URL = 'https://jsonplaceholder.typicode.com/posts';
new Vue(
el: '#app',
data()
return
webGraph:
nodes: [],
edges: []
,
graph1:
nodes:[
url:2,
url:3,
],
edges:[
source:2, target:3,
]
,
created()
axios.get(URL).then((response) =>
let node1 =
url: response.data[1].id
let node2 =
url: response.data[2].id
let edge =
source: url:response.data[1].id,
target: url:response.data[2].id
this.webGraph.nodes.push(node1)
this.webGraph.nodes.push(node2)
this.webGraph.edges.push(edge)
)
d3.forceSimulation(this.webGraph.nodes)
.force("charge", d3.forceManyBody().strength(-25))
.force("link", d3.forceLink().id(d => d.url).links(this.webGraph.edges))
.on('end', function()
console.log("done")
);
d3.forceSimulation(this.graph1.nodes)
.force("charge", d3.forceManyBody().strength(-25))
.force("link", d3.forceLink().id(d => d.url).links(this.graph1.edges))
.on('end', function()
console.log("done")
);
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.2.0/d3.min.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<h6>webGraph</h6>
<br>
<h6>graph1</h6>
</div>
【问题讨论】:
【参考方案1】:webGraph
和graphData1
产生不同结果的原因是webGraph
的模拟在它有数据之前就开始了。如果您将simulation
代码移到axios.get().then
内,那么您会看到它按预期工作。
const URL = 'https://jsonplaceholder.typicode.com/posts';
new Vue(
el: '#app',
data()
return
webGraph:
nodes: [],
edges: []
,
graph1:
nodes:[
url:2,
url:3,
],
edges:[
source:2, target:3,
]
,
created()
axios.get(URL).then((response) =>
let node1 =
url: response.data[1].id
let node2 =
url: response.data[2].id
let edge =
source: node1,
target: node2
this.webGraph =
nodes: [node1, node2],
edges: [edge]
;
d3.forceSimulation(this.webGraph.nodes)
.force("charge", d3.forceManyBody().strength(-25))
.force("link", d3.forceLink().id(d => d.url).links(this.webGraph.edges))
.on('end', function()
console.log("done")
);
)
d3.forceSimulation(this.graph1.nodes)
.force("charge", d3.forceManyBody().strength(-25))
.force("link", d3.forceLink().id(d => d.url).links(this.graph1.edges))
.on('end', function()
console.log("done")
);
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.2.0/d3.min.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<h6>webGraph</h6>
<br>
<h6>graph1</h6>
</div>
在您的代码中,我还更改了edge
的初始化。它表明您需要查看 variables 和 references 之间的区别。
使用let edge = source: url:response.data[1].id, target: url:response.data[2].id
,如果node1
更改,edge.source
不会。所以edge.source
不知道指向哪里。使用let edge = source: node1, target: node2
,代码不仅更短,而且如果node1
更改,edge.source
始终是最新的。
【讨论】:
以上是关于Vue.js 和 D3.js - 力模拟的主要内容,如果未能解决你的问题,请参考以下文章