将不相交的力有向图放入 React 应用程序
Posted
技术标签:
【中文标题】将不相交的力有向图放入 React 应用程序【英文标题】:Put a disjoint force directed graph into React app 【发布时间】:2021-07-06 10:50:07 【问题描述】:所以我有一个包含节点和链接数组的 json 文件。节点包含一个电影名称,然后映射到其中播放的演员。链接将电影与演员结合起来。该文件存储在另一个目录中,文件路径为“../Data/nodes.json” 这是来自节点的 sn-p(只有一部电影,因为整个文件有 32k 行长)
"nodes": [
"name": "Guardians of the Galaxy",
"id": "1"
,
"name": "Chris Pratt"
,
"name": "Vin Diesel"
,
"name": "Bradley Cooper"
,
"name": "Zoe Saldana"
]
这是来自链接的sn-p
"links": [
"source": "Guardians of the Galaxy",
"target": "Chris Pratt"
,
"source": "Guardians of the Galaxy",
"target": "Vin Diesel"
,
"source": "Guardians of the Galaxy",
"target": "Bradley Cooper"
,
"source": "Guardians of the Galaxy",
"target": "Zoe Saldana"
]
我的目标是在使用 D3 制作后,尝试在 React GUI 上显示这个不相交的力有向图。我找不到任何可以提供帮助的教程。 这是我目前的 App.js...
import React from 'react';
import './App.css';
import * as d3 from 'd3';
import Fetch from 'react-request';
class App extends React.Component
constructor(props)
super(props);
this.myRef = React.createRef();
componentDidMount()
const nodes = new Request('../Data/nodes.json');
fetch(nodes).then(response => response.json()).then(data =>
//loops below just display contents of our nodes.json file in the browser's console
//it takes FOREVER to log these
/** for (const obj of data['nodes'])
console.log("Name: " + obj['name']);
for (const obj of data['links'])
console.log("source: " + obj['source']);
console.log("target: " + obj['target']);
*/
//create somewhere to put the force directed graph
let svg = d3.select("svg"),
width = +svg.attr("width"),
height = +svg.attr("height");
const nodes_data = data['nodes'];
//set up the simulation
//nodes only for now
let simulation = d3.forceSimulation()
//add nodes
.nodes(nodes_data);
//add forces
//we're going to add a charge to each node
//also going to add a centering force
simulation
.force("charge_force", d3.forceManyBody())
.force("center_force", d3.forceCenter(width / 2, height / 2));
//draw circles for the nodes
let node = svg.append("g")
.attr("class", "nodes")
.selectAll("circle")
.data(nodes_data)
.enter()
.append("circle")
.attr("r", 5)
.attr("fill", "red");
//add tick instructions:
simulation.on("tick", tickActions);
//Time for the links
//Create links data
const links_data = data['links'];
//Create the link force
//We need the id accessor to use named sources and targets
let link_force = d3.forceLink(links_data)
.id(function (d)
return d.name;
)
//Add a links force to the simulation
//Specify links in d3.forceLink argument
simulation.force("links", link_force)
//draw lines for the links
let link = svg.append("g")
.attr("class", "links")
.selectAll("line")
.data(links_data)
.enter().append("line")
.attr("stroke-width", 2);
function tickActions()
//update circle positions each tick of the simulation
node
.attr("cx", function (d)
return d.x;
)
.attr("cy", function (d)
return d.y;
);
//update link positions
//simply tells one end of the line to follow one node around
//and the other end of the line to follow the other node around
link
.attr("x1", function (d)
return d.source.x;
)
.attr("y1", function (d)
return d.source.y;
)
.attr("x2", function (d)
return d.target.x;
)
.attr("y2", function (d)
return d.target.y;
);
);
render()
return (
<div ref=this.myRef>
</div>
);
export default App;
如果可能的话,我还希望将来能够将我制作的 NavBar.js 类添加到 GUI 的顶部。
【问题讨论】:
【参考方案1】:您在安装时选择了“svg”,但此时它不存在。将其添加到渲染中:
<div ref=this.myRef>
<svg />
</div>
...然后在 mount 时正确选择 svg:
const svg = d3.select(this.myRef).select('svg')
【讨论】:
以上是关于将不相交的力有向图放入 React 应用程序的主要内容,如果未能解决你的问题,请参考以下文章
Treasure Exploration POJ - 2594 有向图路径可相交的最小路径覆盖模板题