ForcePilot/web/src/components/GraphContainer.vue

95 lines
1.8 KiB
Vue
Raw Normal View History

2024-09-18 21:03:12 +08:00
<template>
2025-02-23 16:39:52 +08:00
<div class="graph-container" ref="container"></div>
</template>
2024-09-18 21:03:12 +08:00
2025-02-23 16:39:52 +08:00
<script setup>
import { Graph } from "@antv/g6";
import { onMounted, watch, ref } from 'vue';
2024-09-18 21:03:12 +08:00
2025-02-23 16:39:52 +08:00
const props = defineProps({
graphData: {
type: Object,
required: true,
default: () => ({ nodes: [], edges: [] })
}
});
2024-09-18 21:03:12 +08:00
2025-02-23 16:39:52 +08:00
const container = ref(null);
let graphInstance = null;
2024-09-18 21:03:12 +08:00
2025-02-23 16:39:52 +08:00
const initGraph = () => {
graphInstance = new Graph({
container: container.value,
width: container.value.offsetWidth,
height: container.value.offsetHeight,
autoFit: true,
autoResize: true,
layout: {
type: 'd3-force',
preventOverlap: true,
kr: 20,
collide: {
strength: 1.0,
2024-09-18 21:03:12 +08:00
},
2025-02-23 16:39:52 +08:00
},
node: {
type: 'circle',
style: {
labelText: (d) => d.data.label,
size: 70,
2024-09-18 21:03:12 +08:00
},
2025-02-23 16:39:52 +08:00
palette: {
field: 'label',
color: 'tableau',
2024-09-18 21:03:12 +08:00
},
2025-02-23 16:39:52 +08:00
},
edge: {
type: 'line',
style: {
labelText: (d) => d.data.label,
labelBackground: '#fff',
endArrow: true,
},
},
behaviors: ['drag-element', 'zoom-canvas', 'drag-canvas'],
});
};
2024-09-18 21:03:12 +08:00
2025-02-23 16:39:52 +08:00
const renderGraph = () => {
if (!graphInstance) {
initGraph();
}
2024-09-18 21:03:12 +08:00
2025-02-23 16:39:52 +08:00
const formattedData = {
nodes: props.graphData.nodes.map(node => ({
id: node.id,
data: { label: node.name }
})),
edges: props.graphData.edges.map(edge => ({
source: edge.source_id,
target: edge.target_id,
data: { label: edge.type }
}))
2024-09-18 21:03:12 +08:00
};
2025-02-23 16:39:52 +08:00
graphInstance.setData(formattedData);
graphInstance.render();
};
2024-09-18 21:03:12 +08:00
2025-02-23 16:39:52 +08:00
onMounted(() => {
renderGraph();
window.addEventListener('resize', renderGraph);
});
2024-09-18 21:03:12 +08:00
2025-02-23 16:39:52 +08:00
watch(() => props.graphData, renderGraph, { deep: true });
</script>
<style scoped>
.graph-container {
background: #F7F7F7;
border-radius: 16px;
width: 100%;
height: 600px;
overflow: hidden;
}
</style>