diff --git a/vue/src/system/GraphBuilder.vue b/vue/src/system/GraphBuilder.vue index e5db356..80cf9ba 100644 --- a/vue/src/system/GraphBuilder.vue +++ b/vue/src/system/GraphBuilder.vue @@ -335,11 +335,13 @@ export default { allSelect(msg){ if (msg.entities && msg.entities.length > 0) { msg.entities.forEach(ent => { + ent.selected=true this.selectedEntities.push(ent); }); } if (msg.relations && msg.relations.length > 0) { msg.relations.forEach(rel => { + rel.selected=true this.selectedRelations.push(rel); }); } diff --git a/vue/src/system/GraphDemo.vue b/vue/src/system/GraphDemo.vue index fee8ee3..1439871 100644 --- a/vue/src/system/GraphDemo.vue +++ b/vue/src/system/GraphDemo.vue @@ -134,13 +134,6 @@
@@ -162,18 +155,14 @@ 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, GraphToolbar}, + components: {Menu}, data() { return { - _graph: null, G6: null, // 添加这个 // 节点样式 nodeShowLabel: true, @@ -212,41 +201,41 @@ export default { children: 'children', label: 'title' // 虽然用插槽,但 el-tree 内部仍会读取,可留空或任意 }, - typeRadio: "Disease", - DiseaseRadio: "ICD10", - drugTree: [], - diseaseDepartTree: [], - diseaseICD10Tree: [], - diseaseSZMTree: [], - checkTree: [], + typeRadio:"Disease", + DiseaseRadio:"ICD10", + drugTree:[], + diseaseDepartTree:[], + diseaseICD10Tree:[], + diseaseSZMTree:[], + checkTree:[], legendItems: [ - {key: 'Disease', label: '疾病', color: '#EF4444'}, - {key: 'Drug', label: '药品', color: '#91cc75'}, - {key: 'Check', label: '检查', color: '#336eee'}, - {key: 'Symptom', label: '症状', color: '#fac858'}, - {key: 'Other', label: '其他', color: '#59d1d4'} + { key: 'Disease', label: '疾病', color: '#EF4444' }, + { key: 'Drug', label: '药品', color: '#91cc75' }, + { key: 'Check', label: '检查', color: '#336eee' }, + { key: 'Symptom', label: '症状', color: '#fac858' }, + { key: 'Other', label: '其他', color: '#59d1d4' } ], visibleCategories: new Set(), // 先空着 - diseaseCount: 0, - drugCount: 0, - checkCount: 0, + diseaseCount:0, + drugCount:0, + checkCount:0, originalNodeStyles: new Map(), // 保存原始节点样式 originalEdgeStyles: new Map(), // 保存原始边样式 searchResults: { nodes: [], edges: [] }, - searchKeyword: "", - drugSubjectTree: [], - DrugRadio: "Subject", + searchKeyword:"", + drugSubjectTree:[], + DrugRadio:"Subject", isDropdownOpen: false, typeOptions: [ - {value: 'Disease', label: '疾病'}, - {value: 'Drug', label: '药品'}, - {value: 'Check', label: '检查'} + { value: 'Disease', label: '疾病' }, + { value: 'Drug', label: '药品' }, + { value: 'Check', label: '检查' } ], - configs: [], - parsedStyles: {}, + configs:[], + parsedStyles:{}, enToZhLabelMap: { Disease: '疾病', Drug: '药品', @@ -325,7 +314,7 @@ export default { this.loadDrugTreeData() this.loadCheckTreeData() this.loadDrugSubjectTreeData() - this.treeData = this.diseaseICD10Tree + this.treeData=this.diseaseICD10Tree await this.$nextTick(); try { await this.getDefault() @@ -367,7 +356,7 @@ export default { return { ...edge, id: edge.data?.relationship?.id || edge.id, - type: styleConf.edgeType || this.edgeType, + type: styleConf.edgeType ||this.edgeType, style: { endArrow: styleConf.edgeEndArrow !== undefined ? styleConf.edgeEndArrow : true, stroke: styleConf.edgeStroke || this.edgeStroke, @@ -443,7 +432,7 @@ export default { }, beforeUnmount() { - if (this._graph != null) { + if (this._graph!=null){ this._graph.stopLayout(); this.clearGraphState(); this._graph.destroy() @@ -482,7 +471,7 @@ export default { return {}; } }, - async getDefault() { + async getDefault(){ const response = await getGraphStyleActive(); const data = response.data; if (!Array.isArray(data) || data.length === 0) { @@ -650,7 +639,7 @@ export default { // 4️⃣ 聚焦第一个匹配项 const firstMatch = nodeIds[0] || edgeIds[0]; if (firstMatch && (this._graph.hasNode(firstMatch) || this._graph.hasEdge(firstMatch))) { - this._graph.focusElement(firstMatch, {animation: true, duration: 600}); + this._graph.focusElement(firstMatch, { animation: true, duration: 600 }); } }, clearSearchHighlight() { @@ -664,26 +653,26 @@ export default { this._graph.setElementState(id, 'normal', true); }); }, - getCount() { - getCount().then(res => { - this.diseaseCount = res.Disease - this.drugCount = res.Drug - this.checkCount = res.Check + getCount(){ + getCount().then(res=>{ + this.diseaseCount=res.Disease + this.drugCount=res.Drug + this.checkCount=res.Check console.log(res) }) }, buildCategoryIndex() { const index = {}; - if (this._graph != null) { + if (this._graph!=null){ const nodes = this._graph.getNodeData() // 获取所有节点 nodes.forEach(node => { console.log(node.data.label) const category = node.data.label; // 假设 label 是类别 - if (category == 'Drug' || category == 'Symptom' || - category == 'Disease' || category == 'Check') { + if(category=='Drug'||category=='Symptom'|| + category=='Disease'||category=='Check'){ if (!index[category]) index[category] = []; index[category].push(node.id); - } else { + }else{ if (!index["Other"]) index["Other"] = []; index["Other"].push(node.id); } @@ -693,7 +682,7 @@ export default { }, // 切换某个类别的显示状态 - toggleCategory(key) { + toggleCategory (key){ if (this.visibleCategories.has(key)) { this.visibleCategories.delete(key) } else { @@ -748,28 +737,28 @@ export default { } }, - changeTree() { - if (this.typeRadio == "Disease") { - if (this.DiseaseRadio == "ICD10") { - this.treeData = this.diseaseICD10Tree + changeTree(){ + if(this.typeRadio=="Disease"){ + if(this.DiseaseRadio=="ICD10") { + this.treeData=this.diseaseICD10Tree } - if (this.DiseaseRadio == "Department") { - this.treeData = this.diseaseDepartTree + if(this.DiseaseRadio=="Department") { + this.treeData=this.diseaseDepartTree } - if (this.DiseaseRadio == "SZM") { - this.treeData = this.diseaseSZMTree + if(this.DiseaseRadio=="SZM") { + this.treeData=this.diseaseSZMTree } } - if (this.typeRadio == "Drug") { - if (this.DrugRadio == "Subject") { - this.treeData = this.drugSubjectTree + if(this.typeRadio=="Drug") { + if(this.DrugRadio=="Subject") { + this.treeData=this.drugSubjectTree } - if (this.DrugRadio == "SZM") { - this.treeData = this.drugTree + if(this.DrugRadio=="SZM") { + this.treeData=this.drugTree } } - if (this.typeRadio == "Check") { - this.treeData = this.checkTree + if(this.typeRadio=="Check") { + this.treeData=this.checkTree } }, async loadDiseaseICD10TreeData() { @@ -829,15 +818,15 @@ export default { const response = await getGraph(data); // 等待 Promise 解析 this.formatData(response) } - if (data.level == "category" || - data.level == "subcategory" || - data.level == "diagnosis") { - data.type = "Disease" + if(data.level=="category"|| + data.level=="subcategory"|| + data.level=="diagnosis"){ + data.type="Disease" const response = await getGraph(data); // 等待 Promise 解析 this.formatData(response) } - if (data.type === "Disease") { - data.type = "Disease" + if(data.type === "Disease"){ + data.type="Disease" const response = await getGraph(data); // 等待 Promise 解析 this.formatData(response) } @@ -853,17 +842,17 @@ export default { // 1. 清除所有节点和边的状态 this._graph.getNodeData().forEach(node => { - this._graph.setElementState(node.id, []); + this._graph.setElementState(node.id,[]); }); this._graph.getEdgeData().forEach(edge => { - this._graph.setElementState(edge.id, []); + this._graph.setElementState(edge.id,[]); }); // 2. (可选)取消所有 pending 的交互 // 比如如果你有高亮定时器,这里 clearTimeout }, - formatData(data) { + formatData(data){ this._graph.stopLayout(); this.clearGraphState(); @@ -904,7 +893,7 @@ export default { return { ...edge, id: edge.data?.relationship?.id || edge.id, - type: styleConf.edgeType || this.edgeType, + type: styleConf.edgeType ||this.edgeType, style: { endArrow: styleConf.edgeEndArrow !== undefined ? styleConf.edgeEndArrow : true, stroke: styleConf.edgeStroke || this.edgeStroke, @@ -950,7 +939,7 @@ export default { }, initGraph() { - if (this._graph != null) { + if (this._graph!=null){ this._graph.destroy() this._graph = null; } @@ -961,7 +950,7 @@ export default { console.log(this._nodeLabelMap) const container = this.$refs.graphContainer; if (!container) return; - if (container != null) { + if (container!=null){ const width = container.clientWidth || 800; const height = container.clientHeight || 600; console.log(width) @@ -1001,8 +990,8 @@ export default { easing: 'ease-in-out', // 动画缓动函数 }, }, - behaviors: ['zoom-canvas', 'drag-element', - 'click-select', 'focus-element', { + behaviors: [ 'zoom-canvas', 'drag-element', + 'click-select','focus-element', { type: 'hover-activate', degree: 1, }, @@ -1049,7 +1038,7 @@ export default { shadowBlur: 10, opacity: 1 }, - highlight: { + highlight:{ stroke: '#FF5722', lineWidth: 4, opacity: 1 @@ -1057,7 +1046,7 @@ export default { inactive: { opacity: 0.8 }, - normal: { + normal:{ opacity: 1 } @@ -1105,14 +1094,14 @@ export default { inactive: { opacity: 0.8 }, - normal: { + normal:{ opacity: 1 } }, }, - data: this.defaultData, + data:this.defaultData, }); this.$nextTick(() => { @@ -1170,23 +1159,23 @@ export default { // }); graph.on('node:click', (evt) => { const nodeItem = evt.target.id; // 获取当前鼠标进入的节点元素 - let node = graph.getNodeData(nodeItem).data - let data = { - label: node.name, - type: node.label + let node=graph.getNodeData(nodeItem).data + let data={ + 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', @@ -1195,7 +1184,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; @@ -1206,73 +1195,16 @@ export default { const sourceName = sourceNode?.data.name || sourceId; const targetName = targetNode?.data.name || targetId; - const rel = data.relationship.properties.label || '关联'; + const rel = data.relationship.properties.label || '关联'; return `