|
@@ -1,8 +1,13 @@
|
|
|
<template>
|
|
|
<el-dialog v-model="dialogFormVisible" title="图谱节点详情" width="1100" height="600">
|
|
|
+ <!-- 新增按钮组 -->
|
|
|
+ <div class="zoom-controls">
|
|
|
+ <el-button @click="zoomIn">放大</el-button>
|
|
|
+ <el-button @click="zoomOut">缩小</el-button>
|
|
|
+ </div>
|
|
|
<div id="graph" class="graph">
|
|
|
|
|
|
- <svg id="mindSvg" ref="svgContainer" viewBox="0 0 900 600" width="900" height="600">
|
|
|
+ <svg id="mindSvg" ref="svgContainer" viewBox="0 0 900 600" width="1000" height="600">
|
|
|
<!-- 定义箭头 -->
|
|
|
<defs>
|
|
|
<marker id="arrow" viewBox="0 -5 10 10" refX="8" refY="0" markerWidth="6" markerHeight="6" orient="auto">
|
|
@@ -21,7 +26,7 @@
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
|
|
|
-import { ref, onMounted, nextTick } from 'vue'
|
|
|
+import { ref, onMounted, nextTick, watch } from 'vue'
|
|
|
import { getNodeNeighbors } from '@/api/GraphApi'
|
|
|
import svgPanZoom from 'svg-pan-zoom';
|
|
|
import { ElMessageBox } from 'element-plus';
|
|
@@ -29,12 +34,33 @@ const dialogFormVisible = ref(false)
|
|
|
const nodesData = ref([{ id: 1, label: 'Node 1', direction: "in" }])
|
|
|
const edgesData = ref([{ from: 1, to: 2, fromPos: { x: 100, y: 100 }, toPos: { x: 100, y: 100 } }])
|
|
|
const svgContainer = ref()
|
|
|
+const panZoomController = ref<any>(null)
|
|
|
+
|
|
|
const props = defineProps({
|
|
|
title: { type: String, required: true, default: '图谱节点详情' },
|
|
|
nodeId: { type: Number, default: 0 },
|
|
|
graphId: { type: Number, required: true, default: 0 }
|
|
|
-
|
|
|
})
|
|
|
+
|
|
|
+// 使用 watch 监听 svgContainer 的变化
|
|
|
+watch(svgContainer, (newValue) => {
|
|
|
+ if (newValue) {
|
|
|
+ initSvgPanZoom(newValue);
|
|
|
+ }
|
|
|
+}, { immediate: true });
|
|
|
+
|
|
|
+const initSvgPanZoom = (svgElement: any) => {
|
|
|
+ panZoomController.value = svgPanZoom(svgElement, {
|
|
|
+ zoomEnabled: true,
|
|
|
+ controlIconsEnabled: false,
|
|
|
+ fit: true,
|
|
|
+ center: true,
|
|
|
+ minZoom: 0.1, // 最小缩放比例
|
|
|
+ maxZoom: 10, // 最大缩放比例
|
|
|
+ });
|
|
|
+ console.log('panZoomController initialized:', panZoomController.value);
|
|
|
+}
|
|
|
+
|
|
|
const loadNodeNeighbors = (node_id: number) => {
|
|
|
nodesData.value.length = 0
|
|
|
edgesData.value.length = 0
|
|
@@ -43,20 +69,15 @@ const loadNodeNeighbors = (node_id: number) => {
|
|
|
const element = res.records[i];
|
|
|
console.log(element)
|
|
|
nodesData.value.push({ id: element.id, label: element.name, direction: element.direction })
|
|
|
-
|
|
|
}
|
|
|
drawGraph(node_id)
|
|
|
})
|
|
|
}
|
|
|
function handleNodeClick(nodeId: any) {
|
|
|
loadNodeNeighbors(Number(nodeId))
|
|
|
- // var result = ElMessageBox.confirm('是否加载该节点的邻居节点?', '提示', )
|
|
|
- // result.then(() => {
|
|
|
-
|
|
|
- // })
|
|
|
}
|
|
|
const drawGraph = (node_id: number) => {
|
|
|
- const svg = svgContainer.value //document.getElementById('mindSvg') as SVGElement | null;
|
|
|
+ const svg = svgContainer.value
|
|
|
if (svg == null) {
|
|
|
console.log("svg is null")
|
|
|
console.log(svgContainer.value)
|
|
@@ -174,20 +195,45 @@ const drawGraph = (node_id: number) => {
|
|
|
handleNodeClick(nodeId)
|
|
|
});
|
|
|
})
|
|
|
+// 绘制完成后重新初始化 svgPanZoom
|
|
|
+if (panZoomController.value) {
|
|
|
+ panZoomController.value.destroy();
|
|
|
+}
|
|
|
+initSvgPanZoom(svg);
|
|
|
|
|
|
}
|
|
|
-let panZoomController: any = null;
|
|
|
+// let panZoomController: any = null;
|
|
|
|
|
|
onMounted(() => {
|
|
|
nextTick(() => {
|
|
|
-
|
|
|
+ if (svgContainer.value) {
|
|
|
+ initSvgPanZoom(svgContainer.value);
|
|
|
+ }
|
|
|
});
|
|
|
});
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+// 新增放大函数
|
|
|
+const zoomIn = () => {
|
|
|
+ console.log('panZoomController', panZoomController.value)
|
|
|
+ if (panZoomController.value) {
|
|
|
+ panZoomController.value.zoomIn();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 新增缩小函数
|
|
|
+const zoomOut = () => {
|
|
|
+ if (panZoomController.value) {
|
|
|
+ panZoomController.value.zoomOut();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
const showDialog = (visible: boolean = true, nodeId: number) => {
|
|
|
dialogFormVisible.value = visible
|
|
|
-
|
|
|
loadNodeNeighbors(nodeId)
|
|
|
}
|
|
|
+
|
|
|
defineExpose({ showDialog })
|
|
|
</script>
|
|
|
<style scoped>
|
|
@@ -198,6 +244,8 @@ defineExpose({ showDialog })
|
|
|
flex-direction: column;
|
|
|
align-items: center;
|
|
|
justify-content: center;
|
|
|
+ /* 确保 SVG 元素可以正常缩放 */
|
|
|
+ overflow: hidden;
|
|
|
}
|
|
|
|
|
|
.edge_line {
|
|
@@ -213,4 +261,12 @@ defineExpose({ showDialog })
|
|
|
background-color: #cecece;
|
|
|
z-index: 10;
|
|
|
}
|
|
|
+
|
|
|
+/* 新增按钮样式 */
|
|
|
+.zoom-controls {
|
|
|
+ margin-bottom: 10px;
|
|
|
+ display: flex;
|
|
|
+ gap: 10px;
|
|
|
+ justify-content: center;
|
|
|
+}
|
|
|
</style>
|