1448 lines
55 KiB
Vue
1448 lines
55 KiB
Vue
<template>
|
||
|
||
<div class="all">
|
||
<div class="app-container">
|
||
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px" style="margin-left:10px;">
|
||
<el-form-item label="图谱名称" prop="kgId">
|
||
<el-select v-model="queryParams.kgId" placeholder="请选择">
|
||
<el-option
|
||
v-for="(mItem, mIndex) in kgList"
|
||
:key="mItem.kgId"
|
||
:label="mItem.kgName"
|
||
:value="mItem.kgId"
|
||
/>
|
||
</el-select>
|
||
</el-form-item>
|
||
<el-form-item label="实体名称" prop="entity">
|
||
<el-input
|
||
v-model="queryParams.entity"
|
||
placeholder="请输入实体名称"
|
||
clearable
|
||
@keyup.enter.native="handleQuery"
|
||
/>
|
||
</el-form-item>
|
||
<el-form-item label="关系名称" prop="relation">
|
||
<el-input
|
||
v-model="queryParams.relation"
|
||
placeholder="请输入关系名称"
|
||
clearable
|
||
@keyup.enter.native="handleQuery"
|
||
/>
|
||
</el-form-item>
|
||
<el-form-item label="属性名称" prop="property" v-show="false">
|
||
<el-input
|
||
v-model="queryParams.property"
|
||
placeholder="请输入属性名称"
|
||
clearable
|
||
@keyup.enter.native="handleQuery"
|
||
/>
|
||
</el-form-item>
|
||
<el-form-item>
|
||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
||
</el-form-item>
|
||
</el-form>
|
||
</div>
|
||
<div class="antv-content" v-loading="loading">
|
||
<el-col :span="18">
|
||
<div class="antv-wrapper">
|
||
<div ref="graphContent" id="wrapper"></div>
|
||
</div>
|
||
</el-col>
|
||
<el-col :span="6" v-show="editShow">
|
||
<div style="margin-top: 10px;">
|
||
<div>
|
||
<el-tabs type="border-card" v-model="activeName" @tab-click="handleClick">
|
||
<el-tab-pane name="nodeTab">
|
||
<span slot="label"><i class="el-icon-eleme"></i> 节点</span>
|
||
<el-form ref="form" :model="nodeProp" label-width="100px">
|
||
<div v-show="1">
|
||
<el-row :gutter="20">
|
||
<el-col :span="24" style="margin-bottom: 5px;">
|
||
<!-- <el-input v-model="nodeProp.label" placeholder="节点Label"></el-input>-->
|
||
<el-select v-model="nodeProp.label" placeholder="节点Label" clearable :disabled="labelDisabled">
|
||
<el-option
|
||
v-for="(item, index) in labelList"
|
||
:key="item.key"
|
||
:label="item.key"
|
||
:value="item.value"
|
||
/>
|
||
</el-select>
|
||
</el-col>
|
||
<el-col :span="24" style="margin-bottom: 5px;">
|
||
<el-input v-model="nodeProp.name" placeholder="节点名称" :disabled="labelDisabled"></el-input>
|
||
</el-col>
|
||
</el-row>
|
||
<el-row :gutter="20" v-for="(item, index) in nodeProp.props">
|
||
<el-col :span="10" style="margin-bottom: 5px;">
|
||
<el-input v-model="item.key" placeholder="属性名" readonly="true"></el-input>
|
||
</el-col>
|
||
<el-col :span="14">
|
||
<el-input v-model="item.value" placeholder="属性值" readonly="true"></el-input>
|
||
</el-col>
|
||
<!-- <el-col :span="4">
|
||
<el-button
|
||
@click="addOrDel(index)"
|
||
v-bind:type="index>0?'warning':'primary'"
|
||
v-bind:icon="index>0?'el-icon-minus':'el-icon-plus'"
|
||
circle
|
||
>
|
||
</el-button>
|
||
</el-col>-->
|
||
</el-row>
|
||
<div style="margin-top: 5px">
|
||
<el-input type="hidden" v-model="nodeProp.id"></el-input>
|
||
<el-button type="primary" icon="el-icon-add" size="mini" v-show="!btnDeleteNode" @click="submitEditNode">新增</el-button>
|
||
<el-button type="primary" icon="el-icon-add" size="mini" v-show="!btnDeleteNode" @click="resetEditNode">清空</el-button>
|
||
<!-- <el-button type="primary" icon="el-icon-add" size="mini" v-show="btnDeleteNode" @click="submitEditProp">修改属性</el-button>-->
|
||
<el-button type="warning" icon="el-icon-add" size="mini" v-show="btnDeleteNode" @click="submitDeleteNode">删除此节点</el-button>
|
||
</div>
|
||
</div>
|
||
</el-form>
|
||
</el-tab-pane>
|
||
<el-tab-pane name="edgeTab">
|
||
<span slot="label"><i class="el-icon-share"></i> 关系</span>
|
||
<el-form ref="form" :model="edgeProp" label-width="100px">
|
||
<div v-show="1">
|
||
<el-row :gutter="20">
|
||
<el-col :span="24" style="margin-bottom: 5px;">
|
||
<h5>请在图中“点击”选择两个节点</h5>
|
||
<!-- <el-input v-model="nodeProp.label" placeholder="节点Label"></el-input>-->
|
||
<el-select v-model="edgeProp.label1" placeholder="节点1Label" clearable :disabled="true">
|
||
<el-option
|
||
v-for="(item, index) in labelList"
|
||
:key="item.key"
|
||
:label="item.key"
|
||
:value="item.value"
|
||
/>
|
||
</el-select>
|
||
</el-col>
|
||
<el-col :span="24" style="margin-bottom: 5px;">
|
||
<el-input v-model="edgeProp.name1" placeholder="节点1名称" :disabled="true"></el-input>
|
||
</el-col>
|
||
</el-row>
|
||
<el-row :gutter="20">
|
||
<el-col :span="24" style="margin-bottom: 5px;">
|
||
<el-select v-model="edgeProp.label2" placeholder="节点2Label" clearable :disabled="true">
|
||
<el-option
|
||
v-for="(item, index) in labelList"
|
||
:key="item.key"
|
||
:label="item.key"
|
||
:value="item.value"
|
||
/>
|
||
</el-select>
|
||
</el-col>
|
||
<el-col :span="24" style="margin-bottom: 5px;">
|
||
<el-input v-model="edgeProp.name2" placeholder="节点2名称" :disabled="true"></el-input>
|
||
</el-col>
|
||
</el-row>
|
||
<el-col :span="24" style="margin-bottom: 5px;">
|
||
<el-radio-group v-model="edgeProp.opType" @input="chgRelOp">
|
||
<el-radio label="新增关系"></el-radio>
|
||
<el-radio label="删除关系"></el-radio>
|
||
</el-radio-group>
|
||
</el-col>
|
||
<el-col :span="24" v-show="relOpFlag" style="margin-bottom: 5px;">
|
||
<el-input v-model="edgeProp.newRel" placeholder="新增关系名称"></el-input>
|
||
</el-col>
|
||
<el-col :span="24" v-show="!relOpFlag" style="margin-bottom: 5px;">
|
||
<el-select v-model="edgeProp.deleteRel" placeholder="请选择需删除的关系" clearable :disabled="labelDisabled">
|
||
<el-option
|
||
v-for="(item, index) in edgeList"
|
||
:key="item.key"
|
||
:label="item.key"
|
||
:value="item.value"
|
||
/>
|
||
</el-select>
|
||
</el-col>
|
||
<div style="margin-top: 5px">
|
||
<el-input type="hidden" v-model="edgeProp.id1"></el-input>
|
||
<el-input type="hidden" v-model="edgeProp.id2"></el-input>
|
||
<el-button type="primary" icon="el-icon-add" size="mini" @click="submitEditEdge">确定</el-button>
|
||
<el-button type="primary" icon="el-icon-add" size="mini" @click="resetEditEdge">清空</el-button>
|
||
</div>
|
||
</div>
|
||
</el-form>
|
||
</el-tab-pane>
|
||
</el-tabs>
|
||
|
||
</div>
|
||
</div>
|
||
</el-col>
|
||
</div>
|
||
</div>
|
||
|
||
</template>
|
||
<script>
|
||
import G6 from '@antv/g6';
|
||
import insertCss from 'insert-css';
|
||
import { ForceLayout } from '@antv/layout'
|
||
import { configSetting, configNodeShape, configNodePorts, configEdgeLabel, graphBindKey } from '/static/js/antvSetting.js'
|
||
import axios from 'axios'
|
||
import { getToken } from '@/utils/auth'
|
||
import { setting } from '@/config'
|
||
import Vue from 'vue'
|
||
import { delKgModal } from '@/api/build/modal'
|
||
import { listKgBase } from '@/api/build/kgmgr'
|
||
Vue.prototype.$axios = axios
|
||
axios.defaults.baseURL = setting.apiUrl;
|
||
|
||
insertCss(`
|
||
.g6-component-tooltip {
|
||
border: 1px solid #e2e2e2;
|
||
border-radius: 4px;
|
||
font-size: 12px;
|
||
color: #000;
|
||
background-color: rgba(255, 255, 255, 0.9);
|
||
padding: 10px 8px;
|
||
box-shadow: rgb(174, 174, 174) 0px 0px 10px;
|
||
}
|
||
#contextMenu {
|
||
position: absolute;
|
||
list-style-type: none;
|
||
padding: 10px 8px;
|
||
left: -150px;
|
||
background-color: rgba(255, 255, 255, 0.9);
|
||
border: 1px solid #e2e2e2;
|
||
border-radius: 4px;
|
||
font-size: 12px;
|
||
color: #545454;
|
||
}
|
||
#contextMenu li {
|
||
cursor: pointer;
|
||
list-style-type:none;
|
||
list-style: none;
|
||
margin-left: 0px;
|
||
}
|
||
#contextMenu li:hover {
|
||
color: #aaa;
|
||
}
|
||
.g6-component-toolbar li {
|
||
list-style-type: none !important;
|
||
}
|
||
.g6-minimap-container {
|
||
border: 1px solid #e2e2e2;
|
||
}
|
||
.g6-minimap-viewport {
|
||
border: 2px solid rgb(25, 128, 255);
|
||
}
|
||
`);
|
||
|
||
|
||
|
||
export default {
|
||
name: "AntVG6",
|
||
/**
|
||
* 这个是作为子组件分别接受了两个数据一个是高度height,一个是反显图表数据tempGroupJson
|
||
* 作为子组件例子 <AntVXSix v-model="tempGroupJson" height="720px" />
|
||
*
|
||
*/
|
||
props: {
|
||
height: {
|
||
type: String,
|
||
default: '100vh' //'720px'
|
||
},
|
||
value: {
|
||
type: String,
|
||
default: ''
|
||
}
|
||
},
|
||
data() {
|
||
return {
|
||
graph: null,
|
||
isChange: false,
|
||
isPortsShow: false,
|
||
menuItem: '',
|
||
selectCell: '',
|
||
editDrawer: false,
|
||
editTitle: '',
|
||
form:{},
|
||
labelForm: {
|
||
fontColor: '#333',
|
||
fill: '#FFF',
|
||
stroke: '#555'
|
||
},
|
||
kgId: '',
|
||
kgName: '',
|
||
nodeData : {},
|
||
nodeProp: {"id":"","name":"","label":"","props":[{"key":"","value":""},{"key":"","value":""}]},
|
||
edgeProp: {"opType":"1"},
|
||
editShow: true,
|
||
labelList: [],
|
||
labelDisabled: false,
|
||
btnDeleteNode: false,
|
||
relOpFlag: true,
|
||
activeName: "nodeTab",
|
||
edgeList: [],
|
||
// 查询参数
|
||
queryParams: {
|
||
kgId: undefined,
|
||
kgName: undefined,
|
||
entity: undefined,
|
||
property: undefined,
|
||
relation: undefined
|
||
},
|
||
showSearch: true,
|
||
// 图谱表格数据
|
||
kgList: [],
|
||
|
||
nebulaEdgeList: [],
|
||
// 遮罩层
|
||
loading: false,
|
||
}
|
||
},
|
||
created() {
|
||
|
||
},
|
||
watch:{
|
||
value:{
|
||
handler: function(){
|
||
if(this.graph){
|
||
this.isChange = false
|
||
this.isPortsShow = false
|
||
this.menuItem = ''
|
||
this.selectCell = ''
|
||
this.editDrawer = false
|
||
//this.graph.dispose()
|
||
this.graph.destroy();
|
||
this.initGraph()
|
||
}
|
||
},
|
||
deep: true,
|
||
immediate: true
|
||
}
|
||
},
|
||
mounted() {
|
||
let paramKgId = this.$route.query.kgId ? this.$route.query.kgId : "";
|
||
this.kgId = paramKgId;
|
||
//this.queryParams.kgId = paramKgId;
|
||
//如果url中没带参数,则取数据表中第一个
|
||
//this.$set(this.queryParams,"kgId",parseInt(paramKgId, 10));
|
||
listKgBase(this.queryParams).then(response => {
|
||
console.log(this.queryParams);
|
||
console.log("listKgBase response:");
|
||
console.log(response);
|
||
this.kgList = response.rows;
|
||
for(let i=0; i<this.kgList.length; i++){
|
||
if(i == 0){
|
||
//如果url中没带参数,则取数据表中第一个,2025-07-24
|
||
if(paramKgId.length == 0){
|
||
this.$set(this.queryParams,"kgId",parseInt(this.kgList[i].kgId, 10));
|
||
this.$set(this.queryParams,"kgName",this.kgList[i].kgName);
|
||
}
|
||
}
|
||
if(parseInt(this.kgId, 10) === parseInt(this.kgList[i].kgId, 10)){
|
||
this.$set(this.queryParams,"kgId",parseInt(paramKgId, 10));
|
||
this.$set(this.queryParams,"kgName",this.kgList[i].kgName);
|
||
}
|
||
|
||
}
|
||
//初始化画布和图谱,相当于点击搜索
|
||
this.handleQuery();
|
||
});
|
||
|
||
},
|
||
beforeDestroy() {
|
||
//this.graph.dispose();
|
||
if(this.graph){
|
||
this.graph.destroy();
|
||
}
|
||
|
||
},
|
||
methods: {
|
||
// 链接桩的显示与隐藏,主要是照顾菱形
|
||
changePortsShow(val){
|
||
const container = document.getElementById('wrapper')
|
||
const ports = container.querySelectorAll('.x6-port-body')
|
||
for (let i = 0, len = ports.length; i < len; i = i + 1) {
|
||
ports[i].style.visibility = val ? 'visible' : 'hidden'
|
||
}
|
||
},
|
||
|
||
|
||
// 初始化渲染画布
|
||
initGraph(){
|
||
const colors = [
|
||
'#BDD2FD',
|
||
'#BDEFDB',
|
||
'#C2C8D5',
|
||
'#FBE5A2',
|
||
'#F6C3B7',
|
||
'#B6E3F5',
|
||
'#D3C6EA',
|
||
'#FFD8B8',
|
||
'#AAD8D8',
|
||
'#FFD6E7',
|
||
];
|
||
const strokes = [
|
||
'#5B8FF9',
|
||
'#5AD8A6',
|
||
'#5D7092',
|
||
'#F6BD16',
|
||
'#E8684A',
|
||
'#6DC8EC',
|
||
'#9270CA',
|
||
'#FF9D4D',
|
||
'#269A99',
|
||
'#FF99C3',
|
||
];
|
||
//小地图
|
||
const minimap = new G6.Minimap({
|
||
size: [150, 100],
|
||
});
|
||
//鱼眼
|
||
let fisheye = new G6.Fisheye({
|
||
r: 200,
|
||
showLabel: true,
|
||
});
|
||
/*const toolbar = new G6.ToolBar({
|
||
position: { x: 10, y: 10 },
|
||
});*/
|
||
const animateCfg = { duration: 200, easing: 'easeCubic' };
|
||
//自定义工具栏
|
||
const toolbar = new G6.ToolBar({
|
||
position: { x: 10, y: 10 },
|
||
getContent: () => `
|
||
<ul class='g6-component-toolbar'>
|
||
<li code='zoomOut' title="放大">
|
||
<svg class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" width="24" height="24">
|
||
<path d="M658.432 428.736a33.216 33.216 0 0 1-33.152 33.152H525.824v99.456a33.216 33.216 0 0 1-66.304 0V461.888H360.064a33.152 33.152 0 0 1 0-66.304H459.52V296.128a33.152 33.152 0 0 1 66.304 0V395.52H625.28c18.24 0 33.152 14.848 33.152 33.152z m299.776 521.792a43.328 43.328 0 0 1-60.864-6.912l-189.248-220.992a362.368 362.368 0 0 1-215.36 70.848 364.8 364.8 0 1 1 364.8-364.736 363.072 363.072 0 0 1-86.912 235.968l192.384 224.64a43.392 43.392 0 0 1-4.8 61.184z m-465.536-223.36a298.816 298.816 0 0 0 298.432-298.432 298.816 298.816 0 0 0-298.432-298.432A298.816 298.816 0 0 0 194.24 428.8a298.816 298.816 0 0 0 298.432 298.432z"></path>
|
||
</svg>
|
||
</li>
|
||
<li code='zoomIn' title="缩小">
|
||
<svg class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" width="24" height="24">
|
||
<path d="M639.936 416a32 32 0 0 1-32 32h-256a32 32 0 0 1 0-64h256a32 32 0 0 1 32 32z m289.28 503.552a41.792 41.792 0 0 1-58.752-6.656l-182.656-213.248A349.76 349.76 0 0 1 480 768 352 352 0 1 1 832 416a350.4 350.4 0 0 1-83.84 227.712l185.664 216.768a41.856 41.856 0 0 1-4.608 59.072zM479.936 704c158.784 0 288-129.216 288-288S638.72 128 479.936 128a288.32 288.32 0 0 0-288 288c0 158.784 129.216 288 288 288z" p-id="3853"></path>
|
||
</svg>
|
||
</li>
|
||
<li code='realZoom' title="还原">
|
||
<svg class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" width="20" height="24">
|
||
<path d="M384 320v384H320V320h64z m256 0v384H576V320h64zM512 576v64H448V576h64z m0-192v64H448V384h64z m355.968 576H92.032A28.16 28.16 0 0 1 64 931.968V28.032C64 12.608 76.608 0 95.168 0h610.368L896 192v739.968a28.16 28.16 0 0 1-28.032 28.032zM704 64v128h128l-128-128z m128 192h-190.464V64H128v832h704V256z"></path>
|
||
</svg>
|
||
</li>
|
||
<li code='autoZoom' title="中心">
|
||
<svg class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" width="20" height="24">
|
||
<path d="M684.288 305.28l0.128-0.64-0.128-0.64V99.712c0-19.84 15.552-35.904 34.496-35.712a35.072 35.072 0 0 1 34.56 35.776v171.008h170.944c19.648 0 35.84 15.488 35.712 34.432a35.072 35.072 0 0 1-35.84 34.496h-204.16l-0.64-0.128a32.768 32.768 0 0 1-20.864-7.552c-1.344-1.024-2.816-1.664-3.968-2.816-0.384-0.32-0.512-0.768-0.832-1.088a33.472 33.472 0 0 1-9.408-22.848zM305.28 64a35.072 35.072 0 0 0-34.56 35.776v171.008H99.776A35.072 35.072 0 0 0 64 305.216c0 18.944 15.872 34.496 35.84 34.496h204.16l0.64-0.128a32.896 32.896 0 0 0 20.864-7.552c1.344-1.024 2.816-1.664 3.904-2.816 0.384-0.32 0.512-0.768 0.768-1.088a33.024 33.024 0 0 0 9.536-22.848l-0.128-0.64 0.128-0.704V99.712A35.008 35.008 0 0 0 305.216 64z m618.944 620.288h-204.16l-0.64 0.128-0.512-0.128c-7.808 0-14.72 3.2-20.48 7.68-1.28 1.024-2.752 1.664-3.84 2.752-0.384 0.32-0.512 0.768-0.832 1.088a33.664 33.664 0 0 0-9.408 22.912l0.128 0.64-0.128 0.704v204.288c0 19.712 15.552 35.904 34.496 35.712a35.072 35.072 0 0 0 34.56-35.776V753.28h170.944c19.648 0 35.84-15.488 35.712-34.432a35.072 35.072 0 0 0-35.84-34.496z m-593.92 11.52c-0.256-0.32-0.384-0.768-0.768-1.088-1.088-1.088-2.56-1.728-3.84-2.688a33.088 33.088 0 0 0-20.48-7.68l-0.512 0.064-0.64-0.128H99.84a35.072 35.072 0 0 0-35.84 34.496 35.072 35.072 0 0 0 35.712 34.432H270.72v171.008c0 19.84 15.552 35.84 34.56 35.776a35.008 35.008 0 0 0 34.432-35.712V720l-0.128-0.64 0.128-0.704a33.344 33.344 0 0 0-9.472-22.848zM512 374.144a137.92 137.92 0 1 0 0.128 275.84A137.92 137.92 0 0 0 512 374.08z"></path>
|
||
</svg>
|
||
</li>
|
||
<!--<li code='addNode' title="添加节点">
|
||
<svg class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" width="20" height="24">
|
||
<path d="M684.288 305.28l0.128-0.64-0.128-0.64V99.712c0-19.84 15.552-35.904 34.496-35.712a35.072 35.072 0 0 1 34.56 35.776v171.008h170.944c19.648 0 35.84 15.488 35.712 34.432a35.072 35.072 0 0 1-35.84 34.496h-204.16l-0.64-0.128a32.768 32.768 0 0 1-20.864-7.552c-1.344-1.024-2.816-1.664-3.968-2.816-0.384-0.32-0.512-0.768-0.832-1.088a33.472 33.472 0 0 1-9.408-22.848zM305.28 64a35.072 35.072 0 0 0-34.56 35.776v171.008H99.776A35.072 35.072 0 0 0 64 305.216c0 18.944 15.872 34.496 35.84 34.496h204.16l0.64-0.128a32.896 32.896 0 0 0 20.864-7.552c1.344-1.024 2.816-1.664 3.904-2.816 0.384-0.32 0.512-0.768 0.768-1.088a33.024 33.024 0 0 0 9.536-22.848l-0.128-0.64 0.128-0.704V99.712A35.008 35.008 0 0 0 305.216 64z m618.944 620.288h-204.16l-0.64 0.128-0.512-0.128c-7.808 0-14.72 3.2-20.48 7.68-1.28 1.024-2.752 1.664-3.84 2.752-0.384 0.32-0.512 0.768-0.832 1.088a33.664 33.664 0 0 0-9.408 22.912l0.128 0.64-0.128 0.704v204.288c0 19.712 15.552 35.904 34.496 35.712a35.072 35.072 0 0 0 34.56-35.776V753.28h170.944c19.648 0 35.84-15.488 35.712-34.432a35.072 35.072 0 0 0-35.84-34.496z m-593.92 11.52c-0.256-0.32-0.384-0.768-0.768-1.088-1.088-1.088-2.56-1.728-3.84-2.688a33.088 33.088 0 0 0-20.48-7.68l-0.512 0.064-0.64-0.128H99.84a35.072 35.072 0 0 0-35.84 34.496 35.072 35.072 0 0 0 35.712 34.432H270.72v171.008c0 19.84 15.552 35.84 34.56 35.776a35.008 35.008 0 0 0 34.432-35.712V720l-0.128-0.64 0.128-0.704a33.344 33.344 0 0 0-9.472-22.848zM512 374.144a137.92 137.92 0 1 0 0.128 275.84A137.92 137.92 0 0 0 512 374.08z"></path>
|
||
</svg>
|
||
</li>
|
||
<li code='addEdge' title="添加边">
|
||
<svg class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" width="20" height="24">
|
||
<path d="M684.288 305.28l0.128-0.64-0.128-0.64V99.712c0-19.84 15.552-35.904 34.496-35.712a35.072 35.072 0 0 1 34.56 35.776v171.008h170.944c19.648 0 35.84 15.488 35.712 34.432a35.072 35.072 0 0 1-35.84 34.496h-204.16l-0.64-0.128a32.768 32.768 0 0 1-20.864-7.552c-1.344-1.024-2.816-1.664-3.968-2.816-0.384-0.32-0.512-0.768-0.832-1.088a33.472 33.472 0 0 1-9.408-22.848zM305.28 64a35.072 35.072 0 0 0-34.56 35.776v171.008H99.776A35.072 35.072 0 0 0 64 305.216c0 18.944 15.872 34.496 35.84 34.496h204.16l0.64-0.128a32.896 32.896 0 0 0 20.864-7.552c1.344-1.024 2.816-1.664 3.904-2.816 0.384-0.32 0.512-0.768 0.768-1.088a33.024 33.024 0 0 0 9.536-22.848l-0.128-0.64 0.128-0.704V99.712A35.008 35.008 0 0 0 305.216 64z m618.944 620.288h-204.16l-0.64 0.128-0.512-0.128c-7.808 0-14.72 3.2-20.48 7.68-1.28 1.024-2.752 1.664-3.84 2.752-0.384 0.32-0.512 0.768-0.832 1.088a33.664 33.664 0 0 0-9.408 22.912l0.128 0.64-0.128 0.704v204.288c0 19.712 15.552 35.904 34.496 35.712a35.072 35.072 0 0 0 34.56-35.776V753.28h170.944c19.648 0 35.84-15.488 35.712-34.432a35.072 35.072 0 0 0-35.84-34.496z m-593.92 11.52c-0.256-0.32-0.384-0.768-0.768-1.088-1.088-1.088-2.56-1.728-3.84-2.688a33.088 33.088 0 0 0-20.48-7.68l-0.512 0.064-0.64-0.128H99.84a35.072 35.072 0 0 0-35.84 34.496 35.072 35.072 0 0 0 35.712 34.432H270.72v171.008c0 19.84 15.552 35.84 34.56 35.776a35.008 35.008 0 0 0 34.432-35.712V720l-0.128-0.64 0.128-0.704a33.344 33.344 0 0 0-9.472-22.848zM512 374.144a137.92 137.92 0 1 0 0.128 275.84A137.92 137.92 0 0 0 512 374.08z"></path>
|
||
</svg>
|
||
</li>-->
|
||
</ul>`,
|
||
handleClick: (code, graph) => {
|
||
switch (code) {
|
||
case 'zoomOut':
|
||
graph.zoom(1.2, undefined, true, animateCfg);
|
||
break;
|
||
case 'zoomIn':
|
||
graph.zoom(0.8, undefined, true, animateCfg);
|
||
break;
|
||
case 'realZoom':
|
||
graph.zoomTo(1, undefined, true, animateCfg);
|
||
break;
|
||
case 'autoZoom':
|
||
graph.fitView(20, undefined, true, animateCfg);
|
||
break;
|
||
/*case 'addNode':
|
||
console.log("addNode");
|
||
break;
|
||
case 'addEdge':
|
||
console.log("addEdge");
|
||
break;*/
|
||
}
|
||
}
|
||
});
|
||
//悬浮框
|
||
const tooltip = new G6.Tooltip({
|
||
offsetX: 10,
|
||
offsetY: 10,
|
||
fixToNode: [1, 0.5],
|
||
// the types of items that allow the tooltip show up
|
||
// 允许出现 tooltip 的 item 类型
|
||
itemTypes: ['node', 'edge'],
|
||
// custom the tooltip's content
|
||
// 自定义 tooltip 内容
|
||
getContent: (e) => {
|
||
const outDiv = document.createElement('div');
|
||
outDiv.style.width = 'fit-content';
|
||
outDiv.style.height = 'fit-content';
|
||
const model = e.item.getModel();
|
||
//console.log("model=================");
|
||
//console.log(model);
|
||
if (e.item.getType() === 'node') {
|
||
outDiv.innerHTML = `${model.label}`;
|
||
} else {
|
||
const source = e.item.getSource();
|
||
const target = e.item.getTarget();
|
||
outDiv.innerHTML = `来源:${source.getModel().label}<br/>去向:${target.getModel().label}`;
|
||
}
|
||
return outDiv;
|
||
},
|
||
});
|
||
//右键菜单
|
||
const contextMenu = new G6.Menu({
|
||
getContent(evt) {
|
||
let header;
|
||
let id;
|
||
let label;
|
||
//console.log("evt============");
|
||
//console.log(evt);
|
||
if(evt.targetMarker && evt.isCanvas && evt.target.isCanvas()){
|
||
header = "Canvas ContextMenu";
|
||
}else if (evt.item) {
|
||
const itemType = evt.item.getType();
|
||
header = `${itemType.toUpperCase()} ContextMenu`;
|
||
id = evt.item.getModel().id;
|
||
label = evt.item.getModel().label;
|
||
}
|
||
if(header === undefined){
|
||
return `
|
||
<h3>操作</h3>
|
||
<ul>
|
||
<li style="cursor: pointer" onclick="editNodeItem()">添加节点</li>
|
||
<li style="cursor: pointer" onclick="editEdgeItem()">添加边</li>
|
||
</ul>
|
||
`;
|
||
}else{
|
||
return `
|
||
<h3>${header}</h3>
|
||
<ul>
|
||
<li>id:${id}</li>
|
||
<li>标签:${label}</li>
|
||
</ul>
|
||
`;
|
||
}
|
||
|
||
},
|
||
handleMenuClick: ((target, item) => {
|
||
console.log(target, item);
|
||
}),
|
||
// offsetX and offsetY include the padding of the parent container
|
||
// 需要加上父级容器的 padding-left 16 与自身偏移量 10
|
||
offsetX: 16 + 10,
|
||
// 需要加上父级容器的 padding-top 24 、画布兄弟元素高度、与自身偏移量 10
|
||
offsetY: 0,
|
||
// the types of items that allow the menu show up
|
||
// 在哪些类型的元素上响应
|
||
itemTypes: ['node', 'edge', 'canvas'],
|
||
});
|
||
|
||
console.log("handleQuery______________22222");
|
||
console.log("queryParams");
|
||
console.log(this.queryParams);
|
||
|
||
//return false;
|
||
|
||
axios.post("kg/base/getnebuladata",
|
||
{
|
||
"kgId":this.kgId,
|
||
"entity": this.queryParams.entity?this.queryParams.entity:"",
|
||
"property": this.queryParams.property?this.queryParams.property:"",
|
||
"relation": this.queryParams.relation?this.queryParams.relation:""
|
||
},
|
||
{
|
||
headers: {
|
||
'Authorization': 'Bearer ' + getToken()
|
||
}
|
||
},
|
||
)
|
||
.then(res => {
|
||
console.log("res_getnebuladata================");
|
||
console.log(res);
|
||
if(res.status === 200){
|
||
const nodes = res.data.nodeList;
|
||
const edges = res.data.edgeList;
|
||
this.nebulaEdgeList = res.data.edgeList;
|
||
let legendData = res.data.legend;
|
||
let labelList = res.data.labelList;
|
||
this.labelList = labelList;
|
||
const clusterMap = new Map();
|
||
let clusterId = 0;
|
||
//console.log(nodes);
|
||
|
||
nodes.forEach(function(node) {
|
||
//cluster
|
||
if(node.cluster && clusterMap.get(node.cluster) === undefined){
|
||
clusterMap.set(node.cluster, clusterId);
|
||
clusterId++;
|
||
}
|
||
const cid = clusterMap.get(node.cluster);
|
||
if(!node.style){
|
||
node.style = {};
|
||
}
|
||
node.style.fill = colors[cid % colors.length];
|
||
node.style.stroke = strokes[cid % strokes.length];
|
||
});
|
||
|
||
edges.forEach(edge => {
|
||
//cluster
|
||
if(edge.cluster && clusterMap.get(edge.cluster) === undefined){
|
||
clusterMap.set(edge.cluster, clusterId);
|
||
clusterId++;
|
||
}
|
||
const cid = clusterMap.get(edge.cluster);
|
||
if(!edge.style){
|
||
edge.style = {};
|
||
}
|
||
edge.style = {
|
||
stroke: colors[cid % colors.length]
|
||
}
|
||
});
|
||
//console.log(clusterMap);
|
||
//console.log(clusterMap.get("Film"));
|
||
|
||
legendData.nodes.forEach(node => {
|
||
//console.log(node);
|
||
//console.log("legend.nodes====="+node.id);
|
||
const cid = clusterMap.get(node.id);
|
||
//console.log(cid);
|
||
node.style = {
|
||
fill: colors[cid % colors.length],
|
||
stroke: strokes[cid % strokes.length]
|
||
};
|
||
});
|
||
legendData.edges.forEach(node => {
|
||
//console.log(node);
|
||
//console.log("legend.nodes====="+node.id);
|
||
const cid = clusterMap.get(node.id);
|
||
//console.log("legend.cid====="+cid);
|
||
node.style = {
|
||
fill: colors[cid % colors.length],
|
||
stroke: strokes[cid % strokes.length]
|
||
};
|
||
});
|
||
const legend = new G6.Legend({
|
||
data: legendData,
|
||
align: 'center',
|
||
layout: 'horizontal', // vertical
|
||
position: 'bottom-right',
|
||
vertiSep: 12,
|
||
horiSep: 24,
|
||
offsetY: -24,
|
||
padding: [4, 16, 8, 16],
|
||
containerStyle: {
|
||
fill: '#ccc',
|
||
lineWidth: 1
|
||
},
|
||
title: 'Legend',
|
||
titleConfig: {
|
||
position: 'center',
|
||
offsetX: 0,
|
||
offsetY: 12,
|
||
},
|
||
filter: {
|
||
enable: true,
|
||
multiple: true,
|
||
trigger: 'click',
|
||
graphActiveState: 'activeByLegend',
|
||
graphInactiveState: 'inactiveByLegend',
|
||
/*filterFunctions: legendData.nodes.forEach(node=>{
|
||
console.log("node0202020===========");
|
||
console.log(node);
|
||
if(node.id === 'Film') return true;
|
||
return false;
|
||
}),*/
|
||
filterFunctions: {
|
||
'Film': (d) => {
|
||
if(d.legendType === 'Film') return true;
|
||
return false;
|
||
},
|
||
'Person': (d) => {
|
||
if(d.legendType === 'Person') return true;
|
||
return false;
|
||
},
|
||
'导演': (d) => {
|
||
if(d.legendType === '导演') return true;
|
||
return false;
|
||
},
|
||
'主演': (d) => {
|
||
if(d.legendType === '主演') return true;
|
||
return false;
|
||
},
|
||
}
|
||
}
|
||
});
|
||
const width = document.getElementById('wrapper').scrollWidth;
|
||
const height = document.getElementById('wrapper').scrollHeight || 560;
|
||
const graph = new G6.Graph({
|
||
container: document.getElementById('wrapper'),
|
||
width,
|
||
height,
|
||
layout: {
|
||
type: 'forceAtlas2',//force2 防重叠
|
||
//type: 'force2',//force2 防重叠
|
||
preventOverlap: true,
|
||
linkDistance: d => {
|
||
if(d.source.id === 'node0'){
|
||
return 100;
|
||
}
|
||
return 30;
|
||
},
|
||
nodeStrength: d => {
|
||
if(d.isLeaf){
|
||
return -50;
|
||
}
|
||
return -10;
|
||
},
|
||
edgeStrength: d => {
|
||
if(d.source.id === 'node1' || d.source.id === 'node2' || d.source.id === 'node3'){
|
||
return 0.7;
|
||
}
|
||
return 0.1;
|
||
},
|
||
},
|
||
//划过弹出提示栏,右键菜单
|
||
plugins: [tooltip, contextMenu, legend, toolbar, minimap],//fisheye 鱼眼
|
||
animate: true,
|
||
defaultNode: {
|
||
//color: '#5B8FF9',
|
||
style: {
|
||
lineWidth: 2,
|
||
//fill: '#C6E5FF',
|
||
fill: '#DEE9FF',
|
||
stroke: '#5B8FF9',
|
||
}
|
||
},
|
||
defaultEdge: {
|
||
//type: 'arc',
|
||
//type: 'quadratic',//指定边的形状为二阶贝塞尔曲线,同方向的多条边还是重合
|
||
size: 1,
|
||
color: '#E2E2E2'
|
||
},
|
||
/** 自定义高亮显示 start **/
|
||
modes: {
|
||
//default: ['drag-canvas', 'activate-relations']
|
||
default: ['drag-canvas', 'drag-node']
|
||
},
|
||
nodeStateStyles: {
|
||
highlight: {
|
||
opacity: 1,
|
||
},
|
||
dark: {
|
||
opacity: 0.2
|
||
},
|
||
activeByLegend: {
|
||
lineWidth: 10,
|
||
strokeOpacity: 0.5
|
||
},
|
||
inactiveByLegend: {
|
||
opacity: 0.5
|
||
}
|
||
},
|
||
edgeStateStyles: {
|
||
highlight: {
|
||
stroke: '#999'
|
||
},
|
||
activeByLegend: {
|
||
lineWidth: 3
|
||
},
|
||
inactiveByLegend: {
|
||
opacity: 0.5
|
||
}
|
||
},
|
||
/** 自定义高亮显示 end **/
|
||
});
|
||
|
||
//防止同方向边重合,2023-11-30
|
||
G6.Util.processParallelEdges(res.data.edgeList);
|
||
|
||
graph.data({
|
||
nodes: nodes.map(function(node, j){
|
||
//console.log("node=========");
|
||
//console.log(node);
|
||
//node.color = "#A2B1C3";
|
||
node.legendType = node.legendType;
|
||
node.cluster = node.legendType;
|
||
//console.log("legendType========="+node.legendType);
|
||
//return Object.assign(node,{...typeConfigs[node.legendType]});
|
||
return Object.assign(node,{});
|
||
}),
|
||
edges: res.data.edgeList.map(function(edge, i){
|
||
edge.id = 'edge' + i;
|
||
/*edge.attrs("line/stroke",'#A2B1C3');
|
||
edge.attrs("line.strokeWidth",2);
|
||
edge.attrs("line.targetMarker",null);*/
|
||
return Object.assign({}, edge);
|
||
}),
|
||
|
||
});
|
||
graph.render();
|
||
|
||
graph.on('node:dragstart', function(e) {
|
||
graph.layout();
|
||
refreshDragedNodePosition(e);
|
||
});
|
||
graph.on('node:drag', function(e) {
|
||
refreshDragedNodePosition(e);
|
||
});
|
||
graph.on('node:dragend', function(e) {
|
||
e.item.get('model').fx = null;
|
||
e.item.get('model').fy = null;
|
||
});
|
||
let that = this;
|
||
graph.on('node:click', function(e) {
|
||
let activeName = that.activeName;
|
||
//console.log("activeName=======" + that.activeName);
|
||
//console.log("id1==="+that.edgeProp.id1);
|
||
if(activeName === "nodeTab"){
|
||
const item = e.item.getModel();
|
||
//console.log(item);
|
||
//获取当前节点数据信息
|
||
let CellId = e.item._cfg.id;
|
||
let ChildId = e.item._cfg.model.cellid;
|
||
let NodeState = e.item._cfg.model.state;
|
||
//console.log("click a node named: " + item.id);
|
||
//console.log("show====="+that.editShow);
|
||
//console.log(item);
|
||
let tmpLabel = item.label;
|
||
that.$set(that.nodeProp, "name", tmpLabel);
|
||
that.$set(that.nodeProp, "id", item.id);
|
||
that.$set(that.nodeProp, "label", item.cluster);
|
||
that.$set(that.nodeProp, "props", item.props);
|
||
//console.log(e);
|
||
that.labelDisabled = true;
|
||
that.btnDeleteNode = true;
|
||
}else if(activeName === "edgeTab"){
|
||
const item = e.item.getModel();
|
||
let edgeProp = that.edgeProp;
|
||
//console.log("that.edgeProp================");
|
||
//console.log(that.edgeProp);
|
||
if(that.edgeProp.id1 === "" || that.edgeProp.id1 === undefined){
|
||
that.$set(that.edgeProp, "name1", item.label);
|
||
that.$set(that.edgeProp, "id1", item.id);
|
||
that.$set(that.edgeProp, "label1", item.cluster);
|
||
}else if(that.edgeProp.id2 === "" || that.edgeProp.id2 === undefined){
|
||
that.$set(that.edgeProp, "name2", item.label);
|
||
that.$set(that.edgeProp, "id2", item.id);
|
||
that.$set(that.edgeProp, "label2", item.cluster);
|
||
}else {
|
||
that.$modal.msgSuccess("已经选中了两个节点,如需重选请先“清空”!");
|
||
}
|
||
this.chgRelOp("新增关系");
|
||
}
|
||
//console.log("that.nodeProp=======================");
|
||
//console.log(that.nodeProp);
|
||
|
||
});
|
||
|
||
function refreshDragedNodePosition(e) {
|
||
const model = e.item.get('model');
|
||
model.fx = e.x;
|
||
model.fy = e.y;
|
||
}
|
||
/** 自定义高亮显示 start **/
|
||
function clearAllStats() {
|
||
graph.setAutoPaint(false);
|
||
graph.getNodes().forEach(function (node) {
|
||
graph.clearItemStates(node);
|
||
});
|
||
graph.getEdges().forEach(function (edge) {
|
||
graph.clearItemStates(edge);
|
||
});
|
||
graph.paint();
|
||
graph.setAutoPaint(true);
|
||
}
|
||
|
||
graph.on('node:mouseenter', function (e) {
|
||
const item = e.item;
|
||
graph.setAutoPaint(false);
|
||
graph.getNodes().forEach(function (node) {
|
||
graph.clearItemStates(node);
|
||
graph.setItemState(node, 'dark', true);
|
||
});
|
||
graph.setItemState(item, 'dark', false);
|
||
graph.setItemState(item, 'highlight', true);
|
||
graph.getEdges().forEach(function (edge) {
|
||
if (edge.getSource() === item) {
|
||
graph.setItemState(edge.getTarget(), 'dark', false);
|
||
graph.setItemState(edge.getTarget(), 'highlight', true);
|
||
graph.setItemState(edge, 'highlight', true);
|
||
edge.toFront();
|
||
} else if (edge.getTarget() === item) {
|
||
graph.setItemState(edge.getSource(), 'dark', false);
|
||
graph.setItemState(edge.getSource(), 'highlight', true);
|
||
graph.setItemState(edge, 'highlight', true);
|
||
edge.toFront();
|
||
} else {
|
||
graph.setItemState(edge, 'highlight', false);
|
||
}
|
||
});
|
||
graph.paint();
|
||
graph.setAutoPaint(true);
|
||
});
|
||
graph.on('node:mouseleave', clearAllStats);
|
||
graph.on('canvas:click', clearAllStats);
|
||
/** 自定义高亮显示 end **/
|
||
|
||
this.graph = graph;
|
||
}
|
||
})
|
||
.catch(function (error) {
|
||
console.log(error)
|
||
});
|
||
|
||
|
||
|
||
|
||
},
|
||
addOrDel(index){
|
||
let obj = this.nodeProp.props;
|
||
let newObj = {};
|
||
if(index==0){//add
|
||
for(let k1 in obj){
|
||
if(k1==0){
|
||
for(let k2 in obj[k1]){
|
||
newObj[k2] = "";
|
||
}
|
||
}
|
||
}
|
||
obj.push(newObj)
|
||
}else{//delete
|
||
obj.splice(index,1);
|
||
}
|
||
this.nodeProp.props = obj;
|
||
},
|
||
editNodeItem(){
|
||
this.editShow = true;
|
||
},
|
||
editEdgeItem(){
|
||
this.editShow = true;
|
||
},
|
||
submitEditEdge(){
|
||
//console.log(this.edgeProp);
|
||
//console.log("addEdge");
|
||
console.log("kgId="+this.kgId);
|
||
console.log(this.kgList);
|
||
for(let i=0; i<this.kgList.length; i++){
|
||
if(parseInt(this.kgId, 10) === parseInt(this.kgList[i].kgId, 10)){
|
||
this.$set(this.queryParams,"kgId",parseInt(this.kgId, 10));
|
||
this.$set(this.queryParams,"kgName",this.kgList[i].kgName);
|
||
this.$set(this.queryParams,"kgCode",this.kgList[i].kgCode);
|
||
}
|
||
}
|
||
this.$set(this.edgeProp, "space", this.queryParams.kgCode);
|
||
this.$set(this.edgeProp, "type", "edge");
|
||
this.$set(this.edgeProp, "tagEdgeName", this.edgeProp.newRel);
|
||
this.$set(this.edgeProp, "tagEdgeComment", this.edgeProp.newRel);
|
||
this.$set(this.edgeProp, "color", "string");
|
||
this.$set(this.edgeProp, "srcVid", this.edgeProp.id1);
|
||
this.$set(this.edgeProp, "dstVid", this.edgeProp.id2);
|
||
this.$set(this.edgeProp, "propertyType", "string");
|
||
this.$set(this.edgeProp, "isNull", "NULL");
|
||
this.$set(this.edgeProp, "defaultValue", "");
|
||
let propertyList = [
|
||
{
|
||
"propertyName": "name",
|
||
"propertyType": "string",
|
||
"propertyComment": this.edgeProp.newRel,
|
||
"isNull": "NULL",
|
||
"defaultValue": "NULL"
|
||
}
|
||
]
|
||
this.$set(this.edgeProp, "propertyList", propertyList);
|
||
console.log("this.edgeProp==================================");
|
||
console.log(this.edgeProp);
|
||
//return false;
|
||
this.loading = true;
|
||
if(this.edgeProp.opType === "新增关系"){
|
||
axios.post("kg/base/editnebulaedge",
|
||
{
|
||
"edgeProp":this.edgeProp,
|
||
},
|
||
{
|
||
headers: {
|
||
'Authorization': 'Bearer ' + getToken()
|
||
}
|
||
},
|
||
)
|
||
.then(res => {
|
||
//console.log("res_editneo4jedge================");
|
||
//console.log(res);
|
||
if (res.status === 200) {
|
||
//console.log(res.data);
|
||
this.$modal.msgSuccess("新增关系成功!");
|
||
this.$set(this.nodeProp, "id", "");
|
||
this.$set(this.nodeProp, "name", "");
|
||
this.$set(this.nodeProp, "label", "");
|
||
this.$set(this.nodeProp, "props", [{}]);
|
||
this.labelDisabled = false;
|
||
this.btnDeleteNode = false;
|
||
this.$set(this.edgeProp, "id1", "");
|
||
this.$set(this.edgeProp, "label1", "");
|
||
this.$set(this.edgeProp, "name1", "");
|
||
this.$set(this.edgeProp, "id2", "");
|
||
this.$set(this.edgeProp, "label2", "");
|
||
this.$set(this.edgeProp, "name2", "");
|
||
this.$set(this.edgeProp, "newRel", "");
|
||
this.$set(this.edgeProp, "deleteRel", "");
|
||
this.$set(this.edgeProp, "opType", "新增关系");
|
||
//操作完成,刷新页面,载入新数据
|
||
//window.location.reload();
|
||
const url = new URL(window.location.href);
|
||
url.searchParams.set("kgId", this.kgId);
|
||
window.location.href = url.toString();
|
||
console.log("href======="+window.location.href);
|
||
//this.loading = false;
|
||
}
|
||
});
|
||
}else{
|
||
let modalIds = this.edgeProp.deleteRel;
|
||
console.log("modalIds========="+modalIds);
|
||
console.log(this.edgeProp);
|
||
let that = this;
|
||
this.$modal.confirm('是否确认删除关系为"' + modalIds + '"的数据项?').then(function() {
|
||
console.log("after confirm=====");
|
||
|
||
axios.post("kg/base/editnebulaedge",
|
||
{
|
||
"edgeProp":that.edgeProp,
|
||
},
|
||
{
|
||
headers: {
|
||
'Authorization': 'Bearer ' + getToken()
|
||
}
|
||
},
|
||
)
|
||
.then(res => {
|
||
//console.log("res_editneo4jedge================");
|
||
//console.log(res);
|
||
if (res.status === 200) {
|
||
console.log(res.data);
|
||
that.$modal.msgSuccess("删除关系成功!");
|
||
that.$set(that.nodeProp, "id", "");
|
||
that.$set(that.nodeProp, "name", "");
|
||
that.$set(that.nodeProp, "label", "");
|
||
that.$set(that.nodeProp, "props", [{}]);
|
||
that.labelDisabled = false;
|
||
that.btnDeleteNode = false;
|
||
that.$set(that.edgeProp, "id1", "");
|
||
that.$set(that.edgeProp, "label1", "");
|
||
that.$set(that.edgeProp, "name1", "");
|
||
that.$set(that.edgeProp, "id2", "");
|
||
that.$set(that.edgeProp, "label2", "");
|
||
that.$set(that.edgeProp, "name2", "");
|
||
that.$set(that.edgeProp, "newRel", "");
|
||
that.$set(that.edgeProp, "deleteRel", "");
|
||
that.$set(that.edgeProp, "opType", "新增关系");
|
||
//操作完成,刷新页面,载入新数据
|
||
//window.location.reload();
|
||
const url = new URL(window.location.href);
|
||
url.searchParams.set("kgId", that.kgId);
|
||
window.location.href = url.toString();
|
||
//that.loading = false;
|
||
}
|
||
});
|
||
}).then(() => {
|
||
//this.getList();
|
||
//that.$modal.msgSuccess("删除关系成功");
|
||
}).catch(() => {});
|
||
}
|
||
|
||
|
||
|
||
},
|
||
submitEditNode(){
|
||
console.log(this.nodeProp);
|
||
console.log(this.kgList);
|
||
for(let i=0; i<this.kgList.length; i++){
|
||
if(parseInt(this.kgId, 10) === parseInt(this.kgList[i].kgId, 10)){
|
||
this.$set(this.queryParams,"kgId",parseInt(this.kgId, 10));
|
||
this.$set(this.queryParams,"kgName",this.kgList[i].kgName);
|
||
this.$set(this.queryParams,"kgCode",this.kgList[i].kgCode);
|
||
}
|
||
}
|
||
this.$set(this.nodeProp, "space", this.queryParams.kgCode);
|
||
this.$set(this.nodeProp, "tagName", this.nodeProp.label);
|
||
|
||
this.$set(this.nodeProp, "pointName", this.nodeProp.name);
|
||
//return false;
|
||
let id = this.nodeProp.id;
|
||
|
||
console.log("add");
|
||
|
||
this.loading = true;
|
||
axios.post("kg/base/addnebulanode",
|
||
{
|
||
"nodeProp":this.nodeProp,
|
||
},
|
||
{
|
||
headers: {
|
||
'Authorization': 'Bearer ' + getToken()
|
||
}
|
||
},
|
||
)
|
||
.then(res => {
|
||
//console.log("res_addneo4jnode================");
|
||
//console.log(res);
|
||
if (res.status === 200) {
|
||
//console.log(res.data);
|
||
this.$modal.msgSuccess("添加成功!");
|
||
this.$set(this.nodeProp, "id", "");
|
||
this.$set(this.nodeProp, "name", "");
|
||
this.$set(this.nodeProp, "label", "");
|
||
this.$set(this.nodeProp, "props", [{}]);
|
||
this.labelDisabled = false;
|
||
this.btnDeleteNode = false;
|
||
//操作完成,刷新页面,载入新数据
|
||
//window.location.reload();
|
||
const url = new URL(window.location.href);
|
||
url.searchParams.set("kgId", this.kgId);
|
||
window.location.href = url.toString();
|
||
//this.loading = false;
|
||
}
|
||
});
|
||
|
||
},
|
||
submitDeleteNode() {
|
||
const modalIds = this.nodeProp.id;
|
||
const modalName = this.nodeProp.name;
|
||
console.log(this.nodeProp);
|
||
for(let i=0; i<this.kgList.length; i++){
|
||
if(parseInt(this.kgId, 10) === parseInt(this.kgList[i].kgId, 10)){
|
||
this.$set(this.queryParams,"kgId",parseInt(this.kgId, 10));
|
||
this.$set(this.queryParams,"kgName",this.kgList[i].kgName);
|
||
this.$set(this.queryParams,"kgCode",this.kgList[i].kgCode);
|
||
}
|
||
}
|
||
this.$set(this.nodeProp, "space", this.queryParams.kgCode);
|
||
this.$set(this.nodeProp, "vid", this.nodeProp.id);
|
||
console.log("nodeProp===============");
|
||
console.log(this.nodeProp);
|
||
//return false;
|
||
/*axios.post("kg/base/deletenebulanode",
|
||
{
|
||
"nodeProp":this.nodeProp,
|
||
},
|
||
{
|
||
headers: {
|
||
'Authorization': 'Bearer ' + getToken()
|
||
}
|
||
},
|
||
)
|
||
.then(res => {
|
||
console.log("res_deleteneo4jnode================");
|
||
console.log(res);
|
||
if (res.status === 200) {
|
||
//console.log(res.data);
|
||
this.$modal.msgSuccess("删除成功!");
|
||
this.$set(this.nodeProp, "id", "");
|
||
this.$set(this.nodeProp, "name", "");
|
||
this.$set(this.nodeProp, "label", "");
|
||
this.$set(this.nodeProp, "props", [{}]);
|
||
this.labelDisabled = false;
|
||
this.btnDeleteNode = false;
|
||
//操作完成,刷新页面,载入新数据
|
||
//window.location.reload();
|
||
}
|
||
});*/
|
||
let that = this;
|
||
this.$modal.confirm('是否确认删除编号为"' + modalIds + '('+modalName+')"的数据项?').then(function() {
|
||
console.log("in confirm");
|
||
console.log(that.nodeProp);
|
||
axios.post("kg/base/deletenebulanode",
|
||
{
|
||
"nodeProp":that.nodeProp,
|
||
},
|
||
{
|
||
headers: {
|
||
'Authorization': 'Bearer ' + getToken()
|
||
}
|
||
},
|
||
)
|
||
.then(res => {
|
||
console.log("res_deleteneo4jnode================");
|
||
console.log(res);
|
||
if (res.status === 200) {
|
||
//console.log(res.data);
|
||
that.$modal.msgSuccess("删除成功!");
|
||
that.$set(that.nodeProp, "id", "");
|
||
that.$set(that.nodeProp, "name", "");
|
||
that.$set(that.nodeProp, "label", "");
|
||
that.$set(that.nodeProp, "props", [{}]);
|
||
that.labelDisabled = false;
|
||
that.btnDeleteNode = false;
|
||
//操作完成,刷新页面,载入新数据
|
||
//window.location.reload();
|
||
const url = new URL(window.location.href);
|
||
url.searchParams.set("kgId", that.kgId);
|
||
window.location.href = url.toString();
|
||
}
|
||
});
|
||
}).then(() => {
|
||
//this.getList();
|
||
//this.$modal.msgSuccess("删除成功");
|
||
}).catch(() => {});
|
||
},
|
||
chgRelOp(chkName) {
|
||
//console.log("chkName=========="+chkName)
|
||
if(chkName === "新增关系"){
|
||
this.relOpFlag = true;
|
||
}else{
|
||
console.log("this.nebulaEdgeList=================");
|
||
console.log(this.nebulaEdgeList);
|
||
/*axios.post("kg/base/getnebulaedge",
|
||
{
|
||
"edgeProp":this.edgeProp,
|
||
},
|
||
{
|
||
headers: {
|
||
'Authorization': 'Bearer ' + getToken()
|
||
}
|
||
},
|
||
)
|
||
.then(res => {
|
||
//console.log("res_getneo4jedge================");
|
||
//console.log(res);
|
||
if (res.status === 200) {
|
||
//console.log(res.data);
|
||
let edges = res.data.edges;
|
||
this.edgeList = edges;
|
||
}
|
||
});*/
|
||
let edgeNodeArr = [];
|
||
edgeNodeArr.push(this.edgeProp.id1);
|
||
edgeNodeArr.push(this.edgeProp.id2);
|
||
console.log("edgeNodeArr============");
|
||
console.log(edgeNodeArr);
|
||
let edgeTypeArr = [];
|
||
for(let k=0; k<this.nebulaEdgeList.length; k++){
|
||
let tmpEdge = this.nebulaEdgeList[k];
|
||
console.log("tmpEdge["+k+"]:");
|
||
console.log(tmpEdge);
|
||
console.log(tmpEdge.source + "--" + tmpEdge.target);
|
||
let tmpSource = tmpEdge.source;
|
||
let tmpTarget = tmpEdge.target;
|
||
if(edgeNodeArr.indexOf(tmpSource) !== -1 && edgeNodeArr.indexOf(tmpTarget) !== -1){
|
||
let tmpObj = {};
|
||
this.$set(tmpObj, "key", tmpEdge.label);
|
||
this.$set(tmpObj, "value", tmpEdge.label);
|
||
edgeTypeArr.push(tmpObj);
|
||
}
|
||
this.edgeList = edgeTypeArr;
|
||
}
|
||
this.relOpFlag = false;
|
||
}
|
||
},
|
||
handleClick(tab, event) {
|
||
//console.log(this.activeName);
|
||
this.nodeProp = {"id":"","name":"","label":"","props":[{"key":"","value":""},{"key":"","value":""}]};
|
||
this.edgeProp = {"opType":"新增关系"};
|
||
},
|
||
resetEditEdge() {
|
||
this.edgeProp = {"opType":"新增关系"};
|
||
},
|
||
resetEditNode() {
|
||
this.nodeProp = {"id":"","name":"","label":"","props":[{"key":"","value":""},{"key":"","value":""}]};
|
||
this.btnDeleteNode = false;
|
||
this.labelDisabled = false;
|
||
},
|
||
/**
|
||
* 按图谱名称(kgId)可视化图谱
|
||
*/
|
||
handleQuery() {
|
||
//清除画布
|
||
if(this.graph){
|
||
this.graph.destroy();
|
||
}
|
||
console.log("handleQuery______________00000");
|
||
//重置参数
|
||
this.$route.query.kgId = this.queryParams.kgId;
|
||
this.kgId = this.queryParams.kgId;
|
||
console.log("handleQuery______________11111");
|
||
//绘制关系图
|
||
this.initGraph();
|
||
},
|
||
resetQuery() {
|
||
this.queryParams.kgName = undefined;
|
||
this.queryParams.entity = undefined;
|
||
this.queryParams.relation = undefined;
|
||
this.queryParams.property = undefined;
|
||
}
|
||
}
|
||
}
|
||
|
||
</script>
|
||
<style lang="scss">
|
||
@keyframes ant-line {
|
||
to {
|
||
stroke-dashoffset: -1000
|
||
}
|
||
}
|
||
</style>
|
||
<style lang="scss" scoped="scoped">
|
||
.all{
|
||
border-radius: 8px;
|
||
overflow: hidden;
|
||
}
|
||
.antv-content{
|
||
//background: #0A2052;
|
||
display: flex;
|
||
overflow: hidden;
|
||
position: relative;
|
||
.antv-menu{
|
||
width: 200px;
|
||
//border-right: 1px solid #196AA1;
|
||
padding: 10px;
|
||
h3{
|
||
padding: 10px;
|
||
};
|
||
li{
|
||
padding: 10px;
|
||
border-radius: 8px;
|
||
border: 1px solid #555;
|
||
background: #196AA1;
|
||
margin: 5px 10px;
|
||
font-size: 12px;
|
||
display: flex;
|
||
align-items: center;
|
||
cursor: pointer;
|
||
transition: all 0.5s ease;
|
||
&:hover{
|
||
box-shadow: 0 0 5px rgba($color: #000000, $alpha: 0.3);
|
||
}
|
||
i{
|
||
font-size: 18px;
|
||
margin-right: 10px;
|
||
}
|
||
strong{
|
||
flex: 1;
|
||
}
|
||
}
|
||
}
|
||
.antv-wrapper{
|
||
flex: 1;
|
||
position: relative;
|
||
.wrapper-canvas{
|
||
position: relative;
|
||
height: 100vh;
|
||
min-height: 720px;
|
||
}
|
||
.wrapper-tips{
|
||
padding: 10px;
|
||
display: flex;
|
||
align-items: center;
|
||
position: absolute;
|
||
top: 0;
|
||
left: 0;
|
||
.wrapper-tips-item{
|
||
span{
|
||
padding-left: 10px;
|
||
font-size: 12px;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
i.icon-oval{
|
||
display: inline-block;
|
||
width: 16px;
|
||
height: 10px;
|
||
border-radius: 10px;
|
||
border: 2px solid #eee;
|
||
}
|
||
i.icon-square{
|
||
display: inline-block;
|
||
width: 16px;
|
||
height: 10px;
|
||
border: 2px solid #eee;
|
||
}
|
||
i.icon-ysquare{
|
||
display: inline-block;
|
||
width: 16px;
|
||
height: 10px;
|
||
border-radius: 4px;
|
||
border: 2px solid #eee;
|
||
}
|
||
i.icon-rhombus{
|
||
display: inline-block;
|
||
width: 10px;
|
||
height: 10px;
|
||
border: 2px solid #eee;
|
||
transform: rotate(45deg);
|
||
}
|
||
i.icon-rhomboid{
|
||
display: inline-block;
|
||
width: 10px;
|
||
height: 10px;
|
||
border: 2px solid #eee;
|
||
transform: skew(-30deg);
|
||
}
|
||
i.icon-circle{
|
||
display: inline-block;
|
||
width: 16px;
|
||
height: 16px;
|
||
border-radius: 16px;
|
||
border: 2px solid #eee;
|
||
}
|
||
.edit-main{
|
||
position: absolute;
|
||
right: 0;
|
||
top: 0;
|
||
height: 100%;
|
||
width: 280px;
|
||
border-left: 1px solid #196AA1;
|
||
box-shadow: 0 -10px 10px rgba($color: #000000, $alpha: 0.3);
|
||
padding: 20px;
|
||
//background: #fff;
|
||
background: #0A2052;
|
||
|
||
box-sizing: border-box;
|
||
.edit-main-title{
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
h3{
|
||
flex: 1;
|
||
}
|
||
i{
|
||
cursor: pointer;
|
||
font-size: 20px;
|
||
opacity: 0.7;
|
||
&:hover{
|
||
opacity: 1;
|
||
}
|
||
}
|
||
}
|
||
|
||
.form-main{
|
||
padding: 20px 0;
|
||
.label-style{
|
||
background: #f2f2f2;
|
||
padding: 0 10px;
|
||
p{
|
||
display: flex;
|
||
align-items: center;
|
||
font-size: 12px;
|
||
}
|
||
}
|
||
}
|
||
.edit-btn{
|
||
}
|
||
.see-box{
|
||
padding: 20px;
|
||
background: #0A2052;
|
||
h5{
|
||
padding-bottom: 10px;
|
||
}
|
||
.see-item{
|
||
padding: 10px 30px;
|
||
border: 2px solid #333;
|
||
text-align: center;
|
||
}
|
||
}
|
||
}
|
||
.wrapper-btn{
|
||
text-align: center;
|
||
padding: 20px;
|
||
button{
|
||
width: 100%;
|
||
}
|
||
}
|
||
</style>
|