This repository has been archived on 2025-09-14. You can view files and clone it, but cannot push or open issues or pull requests.
Files
nezha-nezha-fronted/nezha-fronted/src/components/common/project/visNetwork.vue

452 lines
13 KiB
Vue
Raw Normal View History

2020-08-19 11:44:26 +08:00
<template>
<div class="nz-chart-resize">
<div class="resize-shadow" ref="resizeShadow"></div>
<div class="resize-box resize-box-table" ref="resizeBox">
<div class="vis-network" :id="'chartTableDiv'+chartIndex" @mouseenter="caretShow=true" @mouseleave="caretShow=false">
<loading :ref="'localLoading'+chartIndex"></loading>
2020-09-04 10:04:41 +08:00
<div class="clearfix text-right" :class="{'dragTitle':dragTitleShow}" :id="'chartTitle'+chartIndex">
2020-08-19 11:44:26 +08:00
<el-popover
v-if="isError"
:close-delay=10
placement="top-start"
trigger="hover"
popper-class="chart-error-popper">
<div >{{errorContent}}</div>
<span slot="reference" style="" class="panel-info-corner panel-info-corner--error">
<i class="nz-icon nz-icon-warning fa"></i>
<span class="panel-info-corner-inner"></span>
</span>
</el-popover>
<span class="el-dropdown-link chart-title" @click="dropdownMenuShow=!dropdownMenuShow">
<span></span>
<span>
2020-08-24 15:02:23 +08:00
<!--<span class="chart-title-text">{{chartData.title}}</span>-->
2020-08-19 11:44:26 +08:00
<!--<span class="chart-title-icon"><i class="el-icon-caret-bottom el-icon&#45;&#45;right" :class="{'visible':caretShow,'hidden':!caretShow}"></i></span>-->
</span>
2020-09-04 10:04:41 +08:00
<div style="height: 24px">
<i class="nz-icon nz-icon-edit float-right" @click="editVisNetworkChange(true)" v-show="!editVisNetwork"></i>
<i class="nz-icon nz-icon-refresh float-right" @click="reload" v-show="!editVisNetwork"></i>
2020-08-20 11:31:51 +08:00
<!--<i class="nz-icon nz-icon-zoomin float-right"></i>-->
<!--<i class="nz-icon nz-icon-exit-full-screen float-right"></i>-->
2020-09-04 10:04:41 +08:00
</div>
2020-08-19 11:44:26 +08:00
</span>
</div>
<div class="vis-network-content">
2020-08-24 15:02:23 +08:00
<!--project主要信息-->
<div class="facade-top" v-if="!editVisNetwork">
2020-08-24 15:02:23 +08:00
<div class="facade-top-left" v-loading="projectInfo.loading">
<div class="facade-top-title">
2020-09-09 15:32:44 +08:00
Project information
2020-08-24 15:02:23 +08:00
</div>
<div>
<!--<span><span class="label">Id :</span>{{projectInfo.id}}</span>-->
<span><span class="label">Name :</span>{{projectInfo.name}}</span>
2020-08-24 15:02:23 +08:00
</div>
<div>
<span><span class="label">Description :</span>{{projectInfo.remark?projectInfo.remark:'--'}}</span>
</div>
<!--<div>-->
<!--<span>-->
<!--<span class="label">Alert state :</span>-->
<!--<div class="active-icon" style="background: #B7464A 100%;"></div>{{projectInfo.alertStat[0]}}-->
<!--<div class="active-icon" style="background: #E64E4E 100%;"></div>{{projectInfo.alertStat[1]}}-->
<!--<div class="active-icon" style="background: #F7B500 100%;"></div>{{projectInfo.alertStat[2]}}-->
<!--</span>-->
<!--</div>-->
2020-08-24 15:02:23 +08:00
<div>
<span><span class="label">Module Mum :</span>{{projectInfo.moduleMum}}</span>
</div>
</div>
2020-09-09 15:32:44 +08:00
<div class="facade-top-right" v-loading="projectInfo.loading" style="padding: 20px 20px 0 20px;height: calc(100% - 20px);">
2020-08-24 15:02:23 +08:00
<div class="facade-top-title">
<span class="label" style="padding-left: 0;">Alert :</span>
{{total}}
2020-08-24 15:02:23 +08:00
</div>
<div class="facade-top-right-content">
<div>
<div class="content-high-title">
{{returnSeverityLabel('high')}}
</div>
<div>
{{projectInfo.alertStat[0] || 0}}
</div>
2020-08-24 15:02:23 +08:00
</div>
<div>
<div class="content-medium-title">
{{returnSeverityLabel('medium')}}
</div>
<div>
{{projectInfo.alertStat[1] || 0}}
</div>
2020-08-24 15:02:23 +08:00
</div>
2020-09-09 15:32:44 +08:00
<div style="margin-bottom: 20px;">
<div class="content-low-title">
{{returnSeverityLabel('low')}}
</div>
<div>
{{projectInfo.alertStat[2] || 0}}
</div>
2020-08-24 15:02:23 +08:00
</div>
</div>
</div>
</div>
<!--拓扑图-->
2020-08-20 14:47:14 +08:00
<topology
:editVisNetwork="editVisNetwork"
:nodesArray="nodesArray"
:edgesArray="edgesArray"
@setTopologyData="setTopologyData"
:isFullScreen="false"
ref="topology"
:allModuleInfo="allModuleInfo"
2020-08-20 17:09:22 +08:00
v-loading="topologyLoading"
@editVisNetworkChange="editVisNetworkChange"
2020-09-01 14:31:03 +08:00
@reload="reload"
2020-08-20 14:47:14 +08:00
>
</topology>
2020-09-09 15:32:44 +08:00
<!--<other />-->
2020-08-19 11:44:26 +08:00
</div>
</div>
</div>
</div>
</template>
<script>
import loading from "@/components/common/loading";
import timePicker from '@/components/common/timePicker';
import topology from './topology'
2020-09-09 15:32:44 +08:00
import other from './other'
2020-08-19 11:44:26 +08:00
export default {
name: 'visNetwork',
components: {
'loading': loading,
'time-picker':timePicker,
'topology':topology,
2020-09-09 15:32:44 +08:00
other
2020-08-19 11:44:26 +08:00
},
props:{
chartIndex:{
type: Number,
default: 0,
},
chartData: {
type: Object
},
2020-08-24 15:02:23 +08:00
allModuleInfo:{},
projectInfo:{},
2020-08-19 11:44:26 +08:00
},
2020-08-20 17:09:22 +08:00
watch:{
2020-08-26 14:51:45 +08:00
// allModuleInfo:{
// immediate: true,
// deep: true,
// handler(n){
// this.getNetworkData(n);
// },
// },
2020-08-24 15:02:23 +08:00
projectInfo:{
immediate: true,
handler(n){
this.getNetworkData(n);
this.total=this.projectInfo.alertStat[0]+this.projectInfo.alertStat[1]+this.projectInfo.alertStat[2];
if(!this.total){
this.total=0;
}
2020-08-24 15:02:23 +08:00
},
},
2020-08-26 14:51:45 +08:00
// alertData:{
// immediate: true,
// deep: true,
// handler(n){
// this.getNetworkData(n);
// },
// },
2020-08-20 17:09:22 +08:00
},
2020-08-19 11:44:26 +08:00
data () {
return {
firstLoad:false,
2020-08-19 11:44:26 +08:00
//其他
isError:false,
2020-08-20 11:31:51 +08:00
nodesArray:[],
nodesArrayOther:[],
2020-08-20 11:31:51 +08:00
edgesArray:[],
edgesArrayOther:[],
dragTitleShow:false,
dropdownMenuShow:false,
2020-08-20 11:31:51 +08:00
editVisNetwork:false,
2020-08-20 17:09:22 +08:00
topologyLoading:false,
total:1,
2020-08-19 11:44:26 +08:00
}
},
methods:{
// 设置拓扑图数据
setTopologyData(nodesArr,edgesArr){
this.nodesArray=nodesArr;
this.edgesArray=edgesArr;
},
2020-08-20 17:09:22 +08:00
getNetworkData(n){
this.topologyLoading=true;
this.editVisNetwork=false;
2020-08-26 14:51:45 +08:00
this.$get('/project/topo',{projectId:n.id}).then(res=>{
2020-09-02 09:38:26 +08:00
if(res.data.topo&&res.data.topo.nodes&&res.data.topo.nodes.length>0){
this.nodesArray=[];
this.edgesArray=[];
2020-09-01 14:31:03 +08:00
this.nodesArrayOther=this.formatNodesArr(res.data.topo.nodes);
this.edgesArrayOther=this.formatEdgesArr(res.data.topo.lines);
}else{
this.nodesArray=[];
this.edgesArray=[];
setTimeout(()=>{
this.topologyLoading=false;
this.$refs['topology'].setData();
},500)
}
this.$refs['topology'].viewsCenter=res.data.topo.viewsCenter?res.data.topo.viewsCenter:{x:0,y:0};
this.$refs['topology'].zoom=res.data.topo.zoom?res.data.topo.zoom:1;
this.$refs['topology'].selNodeId='';
2020-09-01 14:31:03 +08:00
})
},
reload(){
this.topologyLoading=true;
this.editVisNetwork=false;
this.$get('/project/topo',{projectId:this.projectInfo.id}).then(res=>{
2020-09-02 09:38:26 +08:00
if(res.data.topo&&res.data.topo.nodes&&res.data.topo.nodes.length>0){
2020-09-01 14:31:03 +08:00
this.nodesArray=[];
this.edgesArray=[];
this.nodesArrayOther=this.formatNodesArr(res.data.topo.nodes);
this.edgesArrayOther=this.formatEdgesArr(res.data.topo.lines);
}else{
2020-08-26 14:51:45 +08:00
this.nodesArray=[];
this.edgesArray=[];
setTimeout(()=>{
this.topologyLoading=false;
this.$refs['topology'].setData();
},500)
}
this.$refs['topology'].viewsCenter=res.data.topo.viewsCenter?res.data.topo.viewsCenter:{x:0,y:0};
this.$refs['topology'].zoom=res.data.topo.zoom?res.data.topo.zoom:1;
this.$refs['topology'].selNodeId='';
2020-08-26 14:51:45 +08:00
})
},
formatNodesArr(arr){
let arr1=[];
if(!arr || arr.length==0){
this.topologyLoading=false;
return arr1
}
arr.forEach((item,index)=>{
item.shape='image';
item.id=item.moduleId;
if(this.allModuleInfo.module){
item.label=this.allModuleInfo.module.find(item1=>item1.id===item.id).name;
}
this.dealImg(`/project/topo/icon/${item.iconId}`).then((data)=>{
item.image=data;
if(index===arr.length-1){
setTimeout(()=>{
this.nodesArray=[...this.nodesArrayOther];
this.edgesArray=[...this.edgesArrayOther];
setTimeout(()=>{
this.topologyLoading=false;
this.$refs['topology'].setData();
},500)
})
}
})
});
return arr
},
formatEdgesArr(arr){
let arr1=[];
if(!arr){return arr1}
arr.forEach((item)=>{
item.from=item.source;
item.to=item.target;
item.label=item.name;
});
return arr
},
dealImg(url) {
// 处理后端传过来的图片流乱码问题
if (url) {
return new Promise((resolve,reject)=>{
this.$axios
.get(url, {
responseType: "arraybuffer"
})
.then(res => {
return ("data:image/jpeg;base64," +btoa(new Uint8Array(res.data).reduce((data, byte) => data + String.fromCharCode(byte), "")));
})
.then(data => {
resolve(data)
})
.catch(err => {
});
})
}
},
// Severity Label
returnSeverityLabel(key){
return this.$CONSTANTS.alertMessage.severityData.find(s => {return s.value == key}).label
},
editVisNetworkChange(flag){
this.editVisNetwork=flag;
if(flag){
this.$refs.topology.popDataShowUpdate('',true);
}
if(!flag){
// this.reload();
}
2020-08-20 17:09:22 +08:00
}
2020-08-19 11:44:26 +08:00
},
mounted(){
this.firstLoad = false;
}
}
</script>
<style lang="scss">
@import './chart.scss';
</style>
<style scoped>
2020-08-25 15:12:29 +08:00
.facade-top /deep/.active-icon{
margin-top: 0;
}
2020-08-24 18:03:53 +08:00
.nz-icon-edit{
margin-right: 5px;
}
2020-09-04 10:04:41 +08:00
.vis-network .nz-icon-refresh{
margin-right: 15px;
color: #ee9d3f;
}
2020-08-19 11:44:26 +08:00
.table-container{
height: calc(100% - 30px);
}
.nz-icon{
cursor: pointer;
}
.resize-box .vis-network .text-right{
text-align: right;
}
.resize-box .vis-network .chartTitle .chart-title{
justify-content: space-between;
align-items: stretch;
}
.vis-network-content{
height: 100%;
}
2020-08-24 15:02:23 +08:00
.facade-top{
min-height: 138px;
display: flex;
margin: 12px 0;
height: calc(16% - 40px);
font-size: 12px;
position: absolute;
top: 15px;
left: 15px;
z-index: 10;
}
.facade-top > div{
height: calc(100% - 40px);
width: 18%;
min-width: 315px;
background: #FFFFFF;
margin-right: 9px;
padding: 20px;
border: 1px solid #FFFFFF;
box-shadow: 1px 2px 4px 0 rgba(0,0,0,0.12), -1px 1px 9px -1px rgba(205,205,205,0.77);
}
.facade-top-title{
font-size: 16px;
color: #333333;
font-weight: bold;
padding: 5px 0;
}
.facade-top-left{
display: flex;
flex-direction: column;
justify-content: space-around;
}
.special.label{
margin-left: 30px;
}
.facade-top .facade-top-right{
width: 5%;
2020-09-08 15:19:45 +08:00
min-width: 100px;
2020-08-24 15:02:23 +08:00
}
.facade-top-right-content{
display: flex;
justify-content: space-around;
justify-items: center;
flex-direction: column;
2020-08-24 15:02:23 +08:00
height: calc(100% - 30px);
align-items:flex-start;
}
.facade-top-right-content > div{
width: 80px;
height: 22px;
display: flex;
justify-content: space-between;
color: #fff;
text-align: center;
2020-09-09 15:32:44 +08:00
margin-bottom: 5px;
}
.facade-top-right-content > div > div:last-child{
text-align: center;
border-radius: 0 4px 4px 0;
flex: 1;
height: calc(100% - 2px);
}
.content-high-title{
background: #F2866E;
border-radius: 4px 0 0 4px;
width: 44px;
height: 100%;
}
.content-high-title + div{
border: 1px solid #F4907A;
font-size: 12px;
color: #F4907A;
}
.content-medium-title{
background: #F89984;
border-radius: 4px 0 0 4px;
width: 54px;
height: 100%;
}
.content-medium-title + div{
border: 1px solid #F9A28F;
font-size: 12px;
color: #F9A28F;
}
.content-low-title{
background: #F7BA78;
border-radius: 4px 0 0 4px;
width: 44px;
height: 100%;
}
.content-low-title + div{
border: 1px solid #F7BA78;
font-size: 12px;
color: #F7BA78;
}
.right-content-high{
border: 1px solid ;
2020-08-24 15:02:23 +08:00
}
.align--center{
text-align: center;
}
.label{
padding: 0 15px;
}
2020-08-19 11:44:26 +08:00
</style>