<template>
<div class="graph-container">
<div v-if="loading" class="loading-state">Loading graph...</div>
<div v-if="error" class="error-state">{{ error }}</div>
<div ref="graph" class="graph-canvas"></div>
</div>
</template>
<script>
import { Network } from "vis-network/standalone/umd/vis-network.min.js";
import axios from "axios";
export default {
name: "DocumentGraph",
props: {
callCode: {
type: String,
required: true,
},
},
data() {
return {
network: null,
loading: false,
error: null,
};
},
watch: {
// Re-fetch data if the callCode prop changes
callCode: {
immediate: true,
handler(newVal) {
if (newVal) {
this.fetchAndRenderGraph();
}
},
},
},
methods: {
async fetchAndRenderGraph() {
this.loading = true;
this.error = null;
if (this.network) {
this.network.destroy();
}
try {
const response = await axios.get(`/api/documents/${this.callCode}/graph`);
const graphData = response.data;
if (graphData.nodes.length === 0) {
this.error = "No relationship data found for this document.";
return;
}
const container = this.$refs.graph;
const data = {
nodes: graphData.nodes,
edges: graphData.edges,
};
const options = {
layout: {
hierarchical: false,
},
physics: {
// Makes the graph stabilize faster
stabilization: { iterations: 150 },
},
nodes: {
shape: "box",
font: { size: 14, color: "#333" },
margin: 10,
},
edges: {
arrows: "to",
font: {
align: "middle",
},
},
// Example of styling nodes based on their label/group
groups: {
Document: { color: { background: '#f0ad4e', border: '#eea236' }, shape: 'ellipse' },
Version: { color: { background: '#5bc0de', border: '#46b8da' } }
}
};
this.network = new Network(container, data, options);
} catch (err) {
console.error("Failed to fetch graph data:", err);
this.error = "Could not load document relationship graph.";
} finally {
this.loading = false;
}
},
},
};
</script>
<style scoped>
.graph-container {
position: relative;
width: 100%;
height: 600px;
border: 1px solid #ccc;
background-color: #f9f9f9;
}
.graph-canvas {
width: 100%;
height: 100%;
}
.loading-state, .error-state {
display: flex;
justify-content: center;
align-items: center;
height: 100%;
font-size: 1.2em;
color: #777;
}
.error-state {
color: #d9534f;
}
</style>