|
|
@ -8,6 +8,33 @@ |
|
|
<div id="graph-panel" style="width: 100%;height: 100%;"></div> |
|
|
<div id="graph-panel" style="width: 100%;height: 100%;"></div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
<!-- 弹窗 --> |
|
|
|
|
|
<div v-if="isModalVisible" class="modal-overlay" @click.self="closeModal"> |
|
|
|
|
|
<div class="modal-content"> |
|
|
|
|
|
<h3>请输入分支内容</h3> |
|
|
|
|
|
<label for="fileId">fileId:</label> |
|
|
|
|
|
<input type="text" id="fileId" v-model="newBranchFileId" /> |
|
|
|
|
|
|
|
|
|
|
|
<label for="txtName">节点名称:</label> |
|
|
|
|
|
<input type="text" id="txtName" v-model="newBranchContent" /> |
|
|
|
|
|
|
|
|
|
|
|
<label for="TxtValue">节点内容:</label> |
|
|
|
|
|
<textarea id="TxtValue" v-model="newBranchValue"></textarea> |
|
|
|
|
|
|
|
|
|
|
|
<label for="parentId">父级节点ID:</label> |
|
|
|
|
|
<input type="text" id="parentId" v-model="newBranchParentId" /> |
|
|
|
|
|
|
|
|
|
|
|
<label for="relation">关系:</label> |
|
|
|
|
|
<input type="text" id="relation" v-model="newBranchRelation" |
|
|
|
|
|
@input="newBranchRelation = $event.target.value.replace(/[^a-zA-Z\u4e00-\u9fa5]/g, '')" /> |
|
|
|
|
|
|
|
|
|
|
|
<label for="level">层级:</label> |
|
|
|
|
|
<input type="number" id="level" v-model="newBranchLevel" /> |
|
|
|
|
|
|
|
|
|
|
|
<button @click="addNewBranch">提交</button> |
|
|
|
|
|
</div> |
|
|
|
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
</template> |
|
|
</template> |
|
|
@ -16,6 +43,7 @@ import {getgraphInfo, test, userLogin} from "@/api/login"; |
|
|
import VisGraph from '@/assets/js/graphvis.min.20241008.js' |
|
|
import VisGraph from '@/assets/js/graphvis.min.20241008.js' |
|
|
import LayoutFactory from '@/assets/js/graphvis.layout.min.js' |
|
|
import LayoutFactory from '@/assets/js/graphvis.layout.min.js' |
|
|
import {config} from '@/assets/defaultConfig.js' |
|
|
import {config} from '@/assets/defaultConfig.js' |
|
|
|
|
|
import {addNode} from "@/api/file"; |
|
|
|
|
|
|
|
|
export default { |
|
|
export default { |
|
|
// eslint-disable-next-line vue/multi-word-component-names |
|
|
// eslint-disable-next-line vue/multi-word-component-names |
|
|
@ -29,6 +57,17 @@ export default { |
|
|
links: [] |
|
|
links: [] |
|
|
}, |
|
|
}, |
|
|
config, |
|
|
config, |
|
|
|
|
|
visGraph: null, // 组件中保存VisGraph实例 |
|
|
|
|
|
isModalVisible: false, |
|
|
|
|
|
newBranchContent: '', |
|
|
|
|
|
selectedNode: null, |
|
|
|
|
|
|
|
|
|
|
|
newBranchValue: '', |
|
|
|
|
|
newBranchFileId: '', |
|
|
|
|
|
newBranchLevel: null, |
|
|
|
|
|
newBranchParentId: '', |
|
|
|
|
|
newBranchRelation:'' |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
}, |
|
|
}, |
|
|
methods:{ |
|
|
methods:{ |
|
|
@ -65,10 +104,77 @@ export default { |
|
|
// this.goCenter(); |
|
|
// this.goCenter(); |
|
|
} |
|
|
} |
|
|
this.loading = false; |
|
|
this.loading = false; |
|
|
|
|
|
|
|
|
}, |
|
|
}, |
|
|
// 创建全局绘图客户端对象 |
|
|
// 创建全局绘图客户端对象 |
|
|
createGraph() { |
|
|
createGraph() { |
|
|
this.visGraph = new VisGraph(document.getElementById('graph-panel'), this.config) |
|
|
const configWithEvents = { |
|
|
|
|
|
...this.config, |
|
|
|
|
|
node: { |
|
|
|
|
|
...this.config.node, |
|
|
|
|
|
ondblClick: (event, node) => { |
|
|
|
|
|
this.showPopup(node); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
}; |
|
|
|
|
|
this.visGraph = new VisGraph(document.getElementById('graph-panel'), configWithEvents); |
|
|
|
|
|
}, |
|
|
|
|
|
showPopup(node) { |
|
|
|
|
|
this.selectedNode = node; |
|
|
|
|
|
this.newBranchParentId = node.properties.docId; |
|
|
|
|
|
this.newBranchLevel = node.properties.level - 1; |
|
|
|
|
|
this.isModalVisible = true; // 显示模态框 |
|
|
|
|
|
}, |
|
|
|
|
|
closeModal() { |
|
|
|
|
|
this.isModalVisible = false; |
|
|
|
|
|
this.newBranchContent = ''; |
|
|
|
|
|
this.selectedNode = null; |
|
|
|
|
|
}, |
|
|
|
|
|
async addNewBranch() { |
|
|
|
|
|
const content = this.newBranchContent.trim(); |
|
|
|
|
|
const value = this.newBranchValue.trim(); |
|
|
|
|
|
const fileId = this.newBranchFileId.trim(); |
|
|
|
|
|
const relation = this.newBranchRelation.trim(); |
|
|
|
|
|
|
|
|
|
|
|
if (this.selectedNode && content && value) { |
|
|
|
|
|
// 构造数据 |
|
|
|
|
|
const data = { |
|
|
|
|
|
fileId: fileId, |
|
|
|
|
|
txtName: content, |
|
|
|
|
|
TxtValue: value, |
|
|
|
|
|
relation: relation, |
|
|
|
|
|
parentId: this.newBranchParentId, |
|
|
|
|
|
level: this.newBranchLevel |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
|
await addNode(data); |
|
|
|
|
|
|
|
|
|
|
|
// 创建新节点 |
|
|
|
|
|
const newNodeId = Date.now().toString(); // 使用时间戳作为唯一ID |
|
|
|
|
|
const newNode = { |
|
|
|
|
|
id: newNodeId, |
|
|
|
|
|
label: content, |
|
|
|
|
|
properties: { name: content, docId: newNodeId, level: this.newBranchLevel }, |
|
|
|
|
|
...this.getNodeStyle(this.newBranchLevel) // 根据层级应用样式 |
|
|
|
|
|
}; |
|
|
|
|
|
const newLink = { |
|
|
|
|
|
source: this.selectedNode.id, |
|
|
|
|
|
target: newNodeId, |
|
|
|
|
|
type: '', |
|
|
|
|
|
}; |
|
|
|
|
|
this.graphData.nodes.push(newNode); |
|
|
|
|
|
this.graphData.links.push(newLink); |
|
|
|
|
|
|
|
|
|
|
|
// 刷新图谱 |
|
|
|
|
|
this.visGraph.drawData(this.graphData); |
|
|
|
|
|
this.reLayout(); |
|
|
|
|
|
this.closeModal(); // 关闭模态框 |
|
|
|
|
|
} catch (error) { |
|
|
|
|
|
console.error('Failed to add new branch:', error); |
|
|
|
|
|
alert('Failed to add new branch. Please try again.'); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
}, |
|
|
}, |
|
|
// 执行布局算法 |
|
|
// 执行布局算法 |
|
|
reLayout(alpha) { |
|
|
reLayout(alpha) { |
|
|
@ -123,103 +229,15 @@ export default { |
|
|
|
|
|
|
|
|
var allOne = nodeList[0].docId |
|
|
var allOne = nodeList[0].docId |
|
|
for (let a = 0; a < nodeList.length; a++) { |
|
|
for (let a = 0; a < nodeList.length; a++) { |
|
|
if (nodeList[a].group == '0') { |
|
|
const group = parseInt(nodeList[a].group, 10); |
|
|
const aaa = {name: nodeList[a].name, docId: nodeList[a].docId, parent: allOne} |
|
|
const style = this.getNodeStyle(group); |
|
|
nodes.push({ |
|
|
|
|
|
id: nodeList[a].id, |
|
|
|
|
|
label: nodeList[a].name, |
|
|
|
|
|
properties: aaa, |
|
|
|
|
|
size: 450, |
|
|
|
|
|
color: '227,203,0', |
|
|
|
|
|
font: 'normal 70px Arial', |
|
|
|
|
|
fontColor: '255,255,255' |
|
|
|
|
|
}) |
|
|
|
|
|
} |
|
|
|
|
|
if (nodeList[a].group == '1') { |
|
|
|
|
|
const aaa = {name: nodeList[a].name, docId: nodeList[a].docId, parent: allOne} |
|
|
|
|
|
nodes.push({ |
|
|
|
|
|
id: nodeList[a].id, |
|
|
|
|
|
label: nodeList[a].name, |
|
|
|
|
|
properties: aaa, |
|
|
|
|
|
size: 350, |
|
|
|
|
|
width:350, |
|
|
|
|
|
height:300, |
|
|
|
|
|
color: '47,47,230', |
|
|
|
|
|
font: 'normal 68px Arial', |
|
|
|
|
|
fontColor: '255,255,255' |
|
|
|
|
|
}) |
|
|
|
|
|
} |
|
|
|
|
|
if (nodeList[a].group == '2') { |
|
|
|
|
|
const aaa = {name: nodeList[a].name, docId: nodeList[a].docId, parent: allOne} |
|
|
|
|
|
nodes.push({ |
|
|
|
|
|
id: nodeList[a].id, |
|
|
|
|
|
label: nodeList[a].name, |
|
|
|
|
|
properties: aaa, |
|
|
|
|
|
size: 300, |
|
|
|
|
|
width:300, |
|
|
|
|
|
height:250, |
|
|
|
|
|
color: '255,138,0', |
|
|
|
|
|
font: 'normal 50px Arial', |
|
|
|
|
|
fontColor: '255,255,255' |
|
|
|
|
|
}) |
|
|
|
|
|
} |
|
|
|
|
|
if (nodeList[a].group == '3') { |
|
|
|
|
|
const aaa = {name: nodeList[a].name, docId: nodeList[a].docId, parent: allOne} |
|
|
|
|
|
nodes.push({ |
|
|
|
|
|
id: nodeList[a].id, |
|
|
|
|
|
label: nodeList[a].name, |
|
|
|
|
|
properties: aaa, |
|
|
|
|
|
size: 250, |
|
|
|
|
|
width:250, |
|
|
|
|
|
height:250, |
|
|
|
|
|
color: '30,255,0', |
|
|
|
|
|
font: 'normal 40px Arial', |
|
|
|
|
|
fontColor: '0,0,0' |
|
|
|
|
|
}) |
|
|
|
|
|
} |
|
|
|
|
|
if (nodeList[a].group == '4') { |
|
|
|
|
|
const aaa = {name: nodeList[a].name, docId: nodeList[a].docId, parent: allOne} |
|
|
|
|
|
nodes.push({ |
|
|
|
|
|
id: nodeList[a].id, |
|
|
|
|
|
label: nodeList[a].name, |
|
|
|
|
|
properties: aaa, |
|
|
|
|
|
size: 200, |
|
|
|
|
|
width:200, |
|
|
|
|
|
height:200, |
|
|
|
|
|
color: '248,143,248', |
|
|
|
|
|
font: 'normal 32px Arial', |
|
|
|
|
|
fontColor: '255,255,255' |
|
|
|
|
|
}) |
|
|
|
|
|
} |
|
|
|
|
|
if (nodeList[a].group == '5') { |
|
|
|
|
|
const aaa = {name: nodeList[a].name, docId: nodeList[a].docId, parent: allOne} |
|
|
|
|
|
nodes.push({ |
|
|
|
|
|
id: nodeList[a].id, |
|
|
|
|
|
label: nodeList[a].name, |
|
|
|
|
|
properties: aaa, |
|
|
|
|
|
size: 150, |
|
|
|
|
|
width:150, |
|
|
|
|
|
height:150, |
|
|
|
|
|
color: '65,154,255', |
|
|
|
|
|
font: 'normal 30px Arial', |
|
|
|
|
|
fontColor: '255,255,255' |
|
|
|
|
|
}) |
|
|
|
|
|
} |
|
|
|
|
|
if (nodeList[a].group == '6') { |
|
|
|
|
|
const aaa = {name: nodeList[a].name, docId: nodeList[a].docId, parent: allOne} |
|
|
|
|
|
nodes.push({ |
|
|
|
|
|
id: nodeList[a].id, |
|
|
|
|
|
label: nodeList[a].name, |
|
|
|
|
|
properties: aaa, |
|
|
|
|
|
size: 100, |
|
|
|
|
|
width:100, |
|
|
|
|
|
height:100, |
|
|
|
|
|
color: '0,228,255', |
|
|
|
|
|
font: 'normal 28px Arial', |
|
|
|
|
|
fontColor: '0,0,0' |
|
|
|
|
|
}) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
nodes.push({ |
|
|
|
|
|
id: nodeList[a].id, |
|
|
|
|
|
label: nodeList[a].name, |
|
|
|
|
|
properties: { name: nodeList[a].name, docId: nodeList[a].docId, parent: allOne }, |
|
|
|
|
|
...style // 展开 style 对象以应用样式属性 |
|
|
|
|
|
}); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -242,7 +260,19 @@ export default { |
|
|
} |
|
|
} |
|
|
this.drawGraphData(); |
|
|
this.drawGraphData(); |
|
|
}, |
|
|
}, |
|
|
|
|
|
getNodeStyle(group) { |
|
|
|
|
|
const styles = [ |
|
|
|
|
|
{ size: 450, color: '227,203,0', font: 'normal 70px Arial', fontColor: '255,255,255' }, |
|
|
|
|
|
{ size: 350, width: 350, height: 300, color: '47,47,230', font: 'normal 68px Arial', fontColor: '255,255,255' }, |
|
|
|
|
|
{ size: 300, width: 300, height: 250, color: '255,138,0', font: 'normal 50px Arial', fontColor: '255,255,255' }, |
|
|
|
|
|
{ size: 250, width: 250, height: 250, color: '30,255,0', font: 'normal 40px Arial', fontColor: '0,0,0' }, |
|
|
|
|
|
{ size: 200, width: 200, height: 200, color: '248,143,248', font: 'normal 32px Arial', fontColor: '255,255,255' }, |
|
|
|
|
|
{ size: 150, width: 150, height: 150, color: '65,154,255', font: 'normal 30px Arial', fontColor: '255,255,255' }, |
|
|
|
|
|
{ size: 100, width: 100, height: 100, color: '0,228,255', font: 'normal 28px Arial', fontColor: '0,0,0' } |
|
|
|
|
|
]; |
|
|
|
|
|
|
|
|
|
|
|
return styles[group] || {}; |
|
|
|
|
|
}, |
|
|
doLogin(){ |
|
|
doLogin(){ |
|
|
userLogin().then((res)=>{ |
|
|
userLogin().then((res)=>{ |
|
|
console.log(res); |
|
|
console.log(res); |
|
|
|