So I have a json file that contains a nodes and link array. The nodes contains a movie name which then maps to the actors who played in it. The links combines the movie to the actor. This file is stored in another directory and the file path is "../Data/nodes.json" Here is a snippet from nodes (Just one movie because the entire file is 32k lines long)
"nodes": [
{
"name": "Guardians of the Galaxy",
"id": "1"
},
{
"name": "Chris Pratt"
},
{
"name": "Vin Diesel"
},
{
"name": "Bradley Cooper"
},
{
"name": "Zoe Saldana"
}
]
And here's a snippet from links
"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"
}
]
My goal is to try and have this disjoint force directed graph showing up on a React GUI after making it with D3. I haven't been able to find any tutorials that could help. Here is my App.js currently...
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;
I'd also like to be able to add a NavBar.js class I made to the top of the GUI in the future as well if possible.