Closed Krusty84 closed 1 year ago
Hi @Krusty84, I have tried to write a simple example!
<script setup lang="ts">
import { Nodes, Edges, defineConfigs, Edge } from "v-network-graph";
import { ForceLayout, ForceNodeDatum, ForceEdgeDatum } from "v-network-graph/lib/force-layout";
import { onMounted, ref, watch } from "vue";
// Constants and functions for retrieving data from neo4j ------------------------
const dbName = "neo4j";
const txUrl = `http://localhost:7474/db/${dbName}/tx/commit`;
const username = "neo4j";
const password = "neo4j";
async function cypher<T>(statement: string, parameters: object) {
const method = "POST";
const headers = {
Authorization: "Basic " + btoa(`${username}:${password}`),
Accept: "application/json; charset=UTF-8",
"Content-Type": "application/json",
};
const body = JSON.stringify({ statements: [{ statement, parameters }] });
const r = await fetch(txUrl, { method, headers, body });
return (await r.json()) as T;
}
async function fetchFromNeo4j() {
return await cypher<Neo4JQueryResult<MovieQueryResult>>(
`MATCH p = (actor:Person)-[r:ACTED_IN]->(movie)
WHERE actor.name = $name1 OR actor.name = $name2
RETURN p`,
{ name1: "Tom Hanks", name2: "Meg Ryan" }
);
}
// Type definitions --------------------------------------------------------------
interface Neo4jMeta {
id: number;
elementId: string;
type: string;
deleted: boolean;
}
type Neo4JQueryResultData<Row> = { row: Row[]; meta: Neo4jMeta[][] }[];
interface Neo4JQueryResult<Row> {
errors: { code: number; message: string }[];
results: { columns: string[]; data: Neo4JQueryResultData<Row> }[];
}
interface Person {
name: string;
born: number;
}
interface Movie {
title: string;
released: number;
}
interface PersonMovieRelationship {
roles: string[];
}
type MovieQueryResult = [Person, PersonMovieRelationship, Movie];
// Setup v-network-graph ------------------------------------------------------
const nodes = ref<Nodes>({});
const edges = ref<Edges>({});
const configs = defineConfigs({
view: {
layoutHandler: new ForceLayout({
positionFixedByDrag: false,
positionFixedByClickWithAltKey: true,
createSimulation: (d3, nodes, edges) => {
const forceLink = d3
.forceLink<ForceNodeDatum, ForceEdgeDatum>(edges)
.id((d: Edge) => d.id);
return d3
.forceSimulation(nodes)
.force("edge", forceLink.distance(200))
.force("charge", d3.forceManyBody())
.force("collide", d3.forceCollide(50).strength(0.1))
.force("center", d3.forceCenter().strength(0.05))
.alphaMin(0.001);
},
}),
},
node: {
normal: {
radius: (node) => (node.type === "actor" ? 32 : 24),
color: (node) => (node.type === "actor" ? "#ffccaa" : "#aaccff"),
},
label: {
visible: true,
text: "name",
direction: "center",
},
},
edge: {
label: {
fontSize: 7,
},
},
});
const neo4jQueryResult = ref<Neo4JQueryResultData<MovieQueryResult>>([]);
onMounted(async () => {
const result = await fetchFromNeo4j();
if (result.errors.length > 0) {
// FIXME: error handling
return;
}
neo4jQueryResult.value = result.results[0].data;
});
watch(neo4jQueryResult, () => {
// Translate neo4j model => v-network-graph model
const data = neo4jQueryResult.value;
const graphNodes: Nodes = {};
const graphEdges: Edges = {};
data.forEach((row) => {
const [actor, relation, movie] = row.row[0];
const [actorMeta, relationMeta, movieMeta] = row.meta[0];
graphNodes[actorMeta.elementId] = {
name: actor.name,
born: actor.born,
type: "actor",
};
graphNodes[movieMeta.elementId] = {
name: movie.title,
released: movie.released,
type: "movie",
};
graphEdges[relationMeta.elementId] = {
source: actorMeta.elementId,
target: movieMeta.elementId,
roles: relation.roles.join("\n"),
};
});
nodes.value = graphNodes;
edges.value = graphEdges;
});
</script>
<template>
<v-network-graph :nodes="nodes" :edges="edges" :configs="configs">
<template #edge-label="{ edge, ...slotProps }">
<v-edge-label
:text="edge.roles"
align="center"
vertical-align="above"
v-bind="slotProps"
/>
</template>
</v-network-graph>
</template>
Screenshot:
I hope it can be helpful.
You are amazing! Arigato so much!
Hello Dear @dash14 ! Thank you for amazing component! But, maybe do you have some snippets about using neo4j and v-network-graph together?
Thank you!