I’m creating an application that retrieves result of query from Neo4J Database and putting them into Sigma.js to visualize. I’m using template code from the tutorial with modifications. Currently I’m stuck because accessing individual member of myGraph returns undefined, despite the object not being empty.
App.tsx
import { FC, useEffect, useMemo } from "react";
import { UndirectedGraph, UsageGraphError } from "graphology";
import erdosRenyi from "graphology-generators/random/erdos-renyi";
import { faker } from "@faker-js/faker";
//import { Settings } from "sigma/settings";
import { SigmaContainer, useLoadGraph } from "@react-sigma/core";
import neo4j, { graph, Result } from 'neo4j-driver'
import QueryNeo4j from "./Neo4j";
const MyGraph: FC = () => {
const loadGraph = useLoadGraph();
const randomColor = useMemo(() => {
return (): string => {
const digits = "0123456789abcdef";
let code = "#";
for (let i = 0; i < 6; i++) {
code += digits.charAt(Math.floor(Math.random() * 16));
}
return code;
};
}, []);
//Putting the graph objet that already filled with neo4j values
let myGraph = QueryNeo4j();
console.log(myGraph.nodes)
console.log(myGraph.nodes[0])
useEffect(() => {
const graph = erdosRenyi(UndirectedGraph, {
order: 100,
probability: 0.1,
});
if(myGraph == null){
console.log("MyGraph is null")
}
else{
graph.nodes().forEach((node: string) => {
//Putting the Neo4j graph values into graphology node values
graph.mergeNodeAttributes(node, {
label: myGraph.nodes[0] ,
size: faker.datatype.number({ min: 4, max: 20, precision: 1 }),
color: randomColor(),
x: Math.random(),
y: Math.random(),
});
});
graph.edges().forEach((edge: string) => {
graph.mergeEdgeAttributes(edge, {
weight: Math.random(),
});
});
}
loadGraph(graph);
}, [loadGraph, randomColor]);
return null;
};
export const App: FC = () => {
return (
<div>
<h1>Just an example</h1>
<SigmaContainer style={{ height: "100vh" }}>
<MyGraph />
</SigmaContainer>
</div>
);
};
Neo4j.tsx
import neo4j from 'neo4j-driver'
const QueryNeo4j = () => {
//Neo4j config and query
const driver = neo4j.driver('bolt://44.202.213.247:7687',
neo4j.auth.basic('neo4j', 'forks-eddies-acid'),
{/* encrypted: 'ENCRYPTION_OFF' */});
const query =
`
MATCH (m:Movie)<-[r:ACTED_IN]-(p:Person)
RETURN m, r, p LIMIT 25
`;
const params = {"favorite": "The Matrix"};
const session = driver.session({database:"neo4j"});
/*interface Node {
id: string,
labels: string,
properties: any,
x: number,
y: number,
size: number,
color: string,
label: string
}
interface NeoGraph {
nodes: Node[],
edges: string[]
}*/
//The graph object to contain the query result
let myGraph = {
nodes: [] as any,
edges: [] as any
}
//Putting Neo4j data into an object for sigma.js use
const transformToSigmaNode = (node:any) => {
var sNode = {
id: node.identity.toString(),
labels: node.labels,
properties: node.properties,
x: Math.random(),
y: Math.random(),
size: 5,
color: '#000',
label: node.identity.toString()
}
return sNode
}
//Running the query and putting the value into myGraph, currently only done for nodes
session.run(query)
.then((result) => {
result.records.forEach((record) => {
record.forEach((value, key) => {
if(value && value.hasOwnProperty('labels')) {
myGraph.nodes.push(transformToSigmaNode(value))
//console.log(myGraph.nodes[myGraph.nodes.length - 1].labels)
//console.log(myGraph.nodes[myGraph.nodes.length - 1].properties?.tagline)
//console.log(record);
}
})
});
session.close();
driver.close();
console.log('Neo4jGraph successfully exported')
})
.catch((error) => {
console.error(error);
});
console.log(myGraph)
return myGraph;
}
export default QueryNeo4j
I assume it might be related due to how session are run asynchronously, but i don’t understand more than it and I can’t find more clues regarding this specific implementation.
The result of the above code so far are
Program result