diff --git a/vue/src/system/GraphDemo.vue b/vue/src/system/GraphDemo.vue index 93e1a9a..f80e6ee 100644 --- a/vue/src/system/GraphDemo.vue +++ b/vue/src/system/GraphDemo.vue @@ -112,32 +112,39 @@
-
- - +
-
-
-
- - +
+ +
+ +
+
+ + @@ -155,14 +162,17 @@ import { import {Graph, Tooltip} from '@antv/g6'; import Menu from "@/components/Menu.vue"; import {a} from "vue-router/dist/devtools-EWN81iOl.mjs"; +import GraphToolbar from "@/components/GraphToolbar.vue"; import Fuse from 'fuse.js'; +import {ElMessage} from "element-plus"; import {getGraphStyleActive} from "@/api/style"; export default { name: 'Display', - components: {Menu}, + components: {Menu,GraphToolbar}, data() { return { + _graph: null, G6: null, // 添加这个 // 节点样式 nodeShowLabel: true, @@ -1164,18 +1174,18 @@ export default { label:node.name, type:node.label } - getGraph(data).then(response=>{ + getGraph(data).then(response => { console.log(response) this.formatData(response) }); // 等待 Promise 解析 }); graph.once('afterlayout', () => { if (!graph.destroyed) { - graph.fitCenter({ padding: 40, duration: 1000 }); + graph.fitCenter({padding: 40, duration: 1000}); } }); this._graph = graph - this._graph.setPlugins([ { + this._graph.setPlugins([{ type: 'tooltip', // 只对节点启用,边不显示tooltip enable: (e) => e.targetType === 'edge', @@ -1184,7 +1194,7 @@ export default { console.log(e) const edge = items[0]; // 当前悬停的边 if (!edge) return ''; - const data=items[0].data + const data = items[0].data const sourceId = edge.source; const targetId = edge.target; @@ -1201,10 +1211,72 @@ export default { ${sourceName} — ${rel} —> ${targetName} `; }, - },]) + }, + { + type: 'toolbar', + onClick: (id) => + { + if (id === 'reset') { + // 1. 如果是重置,直接在本地执行方法 + this.localResetGraph(); + } + else if (this.$refs.toolbarRef) { + // 2. 其他功能(放大、导出等)继续交给组件处理 + this.$refs.toolbarRef.handleToolbarAction(id); + } + }, + getItems: () => { + return [ + { id: 'zoom-in', value: 'zoom-in', title: '放大' }, + { id: 'zoom-out', value: 'zoom-out', title: '缩小' }, + { id: 'undo', value: 'undo', title: '撤销' }, + { id: 'redo', value: 'redo', title: '重做' }, + { id: 'auto-fit', value: 'auto-fit', title: '聚焦' }, + { id: 'reset', value: 'reset', title: '重置' }, + { id: 'export', value: 'export', title: '导出图谱' }, + ]; + }, + }, + // 如果需要撤销重做功能,必须加上 history 插件 + { type: 'history', key: 'history' }]) + } + }, + localResetGraph() { + // 1. 检查图表实例和数据是否存在 + if (!this._graph) return; + + if (!this.defaultData || !this.defaultData.nodes) { + this.$message.warning("未找到可重置的数据源"); + return; } + try { + // 2. 彻底清理鼠标指针状态 + const canvas = this._graph.getCanvas(); + if (canvas && typeof canvas.setCursor === 'function') { + canvas.setCursor('default'); + } + + // 3. 彻底销毁当前图谱实例 + // 销毁会移除所有 DOM 节点和事件监听,彻底解决 EventBoundary 问题 + this._graph.destroy(); + this._graph = null; + // 4. 重新初始化 + this.$nextTick(() => { + // initGraph 内部会自动读取 this.defaultData + this.initGraph(); + + // 5. 重新构建分类索引(因为 destroy 也会清空之前的交互索引) + this.buildCategoryIndex(); + + this.$message.success("图谱已重置"); + }); + } catch (err) { + console.error('重置图谱失败:', err); + // 降级处理:如果销毁失败,尝试刷新页面(可选) + // location.reload(); + } }, updateGraph(data) { @@ -1241,7 +1313,7 @@ export default { if (!this._graph) return const updatedEdges = this.defaultData.edges.map(edge => ({ ...edge, - type:this.edgeType, + type: this.edgeType, style: { endArrow: this.edgeEndArrow, stroke: this.edgeStroke, @@ -1524,12 +1596,14 @@ button:hover { padding: 0 2px 0px 15px; justify-content: space-between; } -.d-title{ + +.d-title { display: flex; align-items: center; font-size: 13px; } -.d-count{ + +.d-count { font-size: 9px; background-color: #5989F0; border-radius: 7px; @@ -1576,19 +1650,21 @@ button:hover { text-align: left; font-size: 12px; } -.disease-body{ + +.disease-body { width: 360px; overflow: scroll; height: 74vh; } + /* 隐藏滚动条,但允许滚动 */ .disease-body { /* Firefox */ scrollbar-width: none; /* 'auto' | 'thin' | 'none' */ /* Webkit (Chrome, Safari, Edge) */ - -ms-overflow-style: none; /* IE and Edge */ - scrollbar-width: none; /* Firefox */ + -ms-overflow-style: none; /* IE and Edge */ + scrollbar-width: none; /* Firefox */ padding-bottom: 9px; } @@ -1606,12 +1682,12 @@ button:hover { /deep/ .radio-drug .el-radio__input.is-checked .el-radio__inner { background: #52c41a; /* 检查的颜色 */ - border-color:#52c41a; + border-color: #52c41a; } /deep/ .radio-check .el-radio__input.is-checked .el-radio__inner { background: #1890ff; /* 药品的颜色 */ - border-color:#1890ff; + border-color: #1890ff; } @@ -1624,25 +1700,26 @@ button:hover { /deep/ .radio-drug .el-radio__input.is-checked .el-radio__inner:hover { background: #52c41a; /* 检查的颜色 */ - border-color:#52c41a; + border-color: #52c41a; } /deep/ .radio-check .el-radio__input.is-checked .el-radio__inner:hover { background: #1890ff; /* 药品的颜色 */ - border-color:#1890ff; + border-color: #1890ff; } /* 自定义选中后的样式 */ -/deep/ .radio-disease .el-radio__input.is-checked+.el-radio__label { +/deep/ .radio-disease .el-radio__input.is-checked + .el-radio__label { color: rgb(153, 10, 0); } -/deep/ .radio-drug .el-radio__input.is-checked+.el-radio__label { +/deep/ .radio-drug .el-radio__input.is-checked + .el-radio__label { color: #52c41a; } -/deep/ .radio-check .el-radio__input.is-checked+.el-radio__label { + +/deep/ .radio-check .el-radio__input.is-checked + .el-radio__label { color: #1890ff; } /* 自定义下拉样式 */ diff --git a/vue/src/system/GraphQA.vue b/vue/src/system/GraphQA.vue index 1400339..5c1860f 100644 --- a/vue/src/system/GraphQA.vue +++ b/vue/src/system/GraphQA.vue @@ -63,6 +63,12 @@
+ +
@@ -73,21 +79,21 @@ \ No newline at end of file diff --git a/vue/src/system/KGData.vue b/vue/src/system/KGData.vue index 868823a..cf7aedb 100644 --- a/vue/src/system/KGData.vue +++ b/vue/src/system/KGData.vue @@ -84,8 +84,8 @@
搜索 - 导入 - 导出 + 导入 + 导出 新增节点
@@ -178,6 +178,8 @@
查询 + 导入 + 导出 新增关系
@@ -222,7 +224,90 @@ - + + + +
+
+ + + + + + + +
+ +
+
+

正在分析数据冲突...

+

系统正在检查 JSON 文件中的重复数据。

+
+ +
+

+ 检测到非法数据 + 检测到数据冲突 + 预检通过 +

+ +

+ 本次导入包含 {{ importReport.summary.total }} 条数据。 + + 其中 {{ importReport.invalid.length }} 条数据由于节点不存在无法导入。 + + + 另有 {{ importReport.conflicts.length }} 条已存在。 + + + 可导入 {{ importReport.summary.valid }} 条。 + +

+ +
+ 处理策略: + + 跳过重复 + 覆盖更新 + +
+ + + + + + +
+ +
+

正在写入数据库...

+ +
+
+
+ + +
+ + {{ currentDetail.id }}