diff --git a/nezha-fronted/package-lock.json b/nezha-fronted/package-lock.json
index aeb4e0641..2c356909e 100644
--- a/nezha-fronted/package-lock.json
+++ b/nezha-fronted/package-lock.json
@@ -4716,8 +4716,7 @@
"ansi-regex": {
"version": "2.1.1",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"aproba": {
"version": "1.2.0",
@@ -4738,14 +4737,12 @@
"balanced-match": {
"version": "1.0.0",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"brace-expansion": {
"version": "1.1.11",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@@ -4760,20 +4757,17 @@
"code-point-at": {
"version": "1.1.0",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"concat-map": {
"version": "0.0.1",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"console-control-strings": {
"version": "1.1.0",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"core-util-is": {
"version": "1.0.2",
@@ -4890,8 +4884,7 @@
"inherits": {
"version": "2.0.3",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"ini": {
"version": "1.3.5",
@@ -4903,7 +4896,6 @@
"version": "1.0.0",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"number-is-nan": "^1.0.0"
}
@@ -4918,7 +4910,6 @@
"version": "3.0.4",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"brace-expansion": "^1.1.7"
}
@@ -4926,14 +4917,12 @@
"minimist": {
"version": "0.0.8",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"minipass": {
"version": "2.3.5",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"safe-buffer": "^5.1.2",
"yallist": "^3.0.0"
@@ -4952,7 +4941,6 @@
"version": "0.5.1",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"minimist": "0.0.8"
}
@@ -5033,8 +5021,7 @@
"number-is-nan": {
"version": "1.0.1",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"object-assign": {
"version": "4.1.1",
@@ -5046,7 +5033,6 @@
"version": "1.4.0",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"wrappy": "1"
}
@@ -5132,8 +5118,7 @@
"safe-buffer": {
"version": "5.1.2",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"safer-buffer": {
"version": "2.1.2",
@@ -5169,7 +5154,6 @@
"version": "1.0.2",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
@@ -5189,7 +5173,6 @@
"version": "3.0.1",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"ansi-regex": "^2.0.0"
}
@@ -5233,14 +5216,12 @@
"wrappy": {
"version": "1.0.2",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"yallist": {
"version": "3.0.3",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
}
}
},
diff --git a/nezha-fronted/src/components/charts/addLine.vue b/nezha-fronted/src/components/charts/addLine.vue
new file mode 100644
index 000000000..1507550f5
--- /dev/null
+++ b/nezha-fronted/src/components/charts/addLine.vue
@@ -0,0 +1,72 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 提交
+ 取消
+
+
+
+
+
+
+
diff --git a/nezha-fronted/src/components/charts/addNode.vue b/nezha-fronted/src/components/charts/addNode.vue
new file mode 100644
index 000000000..6f9363bc4
--- /dev/null
+++ b/nezha-fronted/src/components/charts/addNode.vue
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 提交
+ 取消
+
+
+
+
+
+
+
diff --git a/nezha-fronted/src/components/charts/chart-list.vue b/nezha-fronted/src/components/charts/chart-list.vue
index c2ada986a..7b57b1101 100644
--- a/nezha-fronted/src/components/charts/chart-list.vue
+++ b/nezha-fronted/src/components/charts/chart-list.vue
@@ -660,7 +660,7 @@
panelId: 0,
title: this.$t("alert.config.chart.alertNumTrend"),
span: 8,
- height: 350,
+ height: 800,
type: "topology",
prev: -11,
next: -1,
diff --git a/nezha-fronted/src/components/charts/visNetwork.vue b/nezha-fronted/src/components/charts/visNetwork.vue
index 472b46dc1..4d80c180b 100644
--- a/nezha-fronted/src/components/charts/visNetwork.vue
+++ b/nezha-fronted/src/components/charts/visNetwork.vue
@@ -1,5 +1,5 @@
-
+
@@ -38,9 +38,27 @@
-
-
-
+
+
+
+
+
请选择两个节点
@@ -50,12 +68,21 @@
- 1111111111
+
+
+
+
+
+
+
+
@@ -67,11 +94,15 @@
import chartDataFormat from './chartDataFormat'
import loading from "../common/loading";
import timePicker from '../common/timePicker'
+ import addNode from './addNode'
+ import addLine from './addLine'
export default {
name: 'home',
components: {
'loading': loading,
- 'time-picker':timePicker
+ 'time-picker':timePicker,
+ 'add-model':addNode,
+ 'add-line':addLine,
},
props:{
chartIndex:{
@@ -83,6 +114,12 @@
},
},
watch:{
+ NodeArr(n){
+ if(n.length==2){
+ this.addLineShow=true;
+ this.selectNodeTitle=false;
+ }
+ }
},
data () {
return {
@@ -129,6 +166,7 @@
dragTitleShow:false,
dropdownMenuShow:false,
divFirstShow:false,
+ selectNodeTitle:false,
columns: [
{
title:'Element',
@@ -150,39 +188,46 @@
searchTime: [new Date().setHours(new Date().getHours() - 1), new Date()],//全屏显示的时间
oldSearchTime: [],
-
+ // 拓扑图工具
+ networkPopTop:0,
+ networkPopLeft:0,
+ networkPopShow:false,
+ addNodeShow:false,
+ addLineShow:false,
+ cursorMove:false,
+ NodeArr:[],
+ selNodeId:'',
+ lineData:{},
+ nodeData:{},
+ //viewsCenter
+ viewsCenter:{
+ x:0,y:0
+ },
// 拓扑图数据
-
nodes:[],
edges:[],
// network:null,
container:null,
nodesArray:[
- { id: 0, label: "model",
- image: 'https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=1906469856,4113625838&fm=26&gp=0.jpg', shape:'image',shapeProperties:{useImageSize:false},
- chosen:{
- node:(values, id, selected, hovering)=>{
- console.log(values, id, selected, hovering);
- }
- },
- physics:false,
- x:0,y:0
+ { id: 1, label: "model",
+ image: 'https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=1906469856,4113625838&fm=26&gp=0.jpg',
+ shape:'image',shapeProperties:{useImageSize:false},
+ x:0,y:0,
},
- {id: 1, label: "model", x:0,y:10, physics:false,image: png, shape:'image',shapeProperties:{useImageSize:false}},
- {id: 2, label: "model", x:10,y:20, physics:false,image: png, shape:'image',shapeProperties:{useImageSize:false}},
- {id: 3, label: "model", x:10,y:30, physics:false,image: png, shape:'image',shapeProperties:{useImageSize:false}},
- {id: 4, label: "model", x:0,y:40, physics:false,image: png, shape:'image',shapeProperties:{useImageSize:false}},
- {id: 5, label: "model", x:0,y:50, physics:false,image: png, shape:'image',shapeProperties:{useImageSize:false}},
- {id: 6, label: "model", x:10,y:50, physics:false,image: png, shape:'image',shapeProperties:{useImageSize:false}},
+ {id: 2, label: "model", x:-254,y:-59, image: png, shape:'image',shapeProperties:{useImageSize:false}},
+ {id: 3, label: "model", x:114,y:-36, image: png, shape:'image',shapeProperties:{useImageSize:false}},
+ {id: 4, label: "model", x:-126,y:54, image: png, shape:'image',shapeProperties:{useImageSize:false}},
+ {id: 5, label: "model", x:125,y:67, image: png, shape:'image',shapeProperties:{useImageSize:false}},
+ {id: 6, label: "model", x:-211,y:0, image: png, shape:'image',shapeProperties:{useImageSize:false}},
+ {id: 7, label: "model", x:200,y:100, image: png, shape:'image',shapeProperties:{useImageSize:false}},
],
-
edgesArray:[
- {id: 0,from: 1, to: 0,label:"hahah",arrows:'from;to'},
- {id: 1,from: 2, to: 0},
- {id: 2,from: 4, to: 3},
- {id: 3,from: 3, to: 0},
- {id: 4,from: 3, to: 5},
- {id: 5,from: 0, to: 6},
+ {id: 0,from: 2, to: 1,label:"hahah",arrows:'from;to', color: {color:'red',highlight:'red',hover:'red',opacity:1.0},},
+ {id: 1,from: 3, to: 1,label:"hahah",arrows:'from'},
+ {id: 2,from: 5, to: 4,label:"hahah",arrows:'to'},
+ {id: 3,from: 4, to: 1,label:"hahah",arrows:'from;to'},
+ {id: 4,from: 4, to: 6,label:"hahah",arrows:'from;to'},
+ {id: 5,from: 1, to: 7,label:"hahah",arrows:'from;to'},
],
options:{},
data:{}
@@ -193,17 +238,20 @@
methods:{
//拓扑图方法
- init(){
+ init(type){
let this_ = this;
this_.nodes = new Vis.DataSet(this_.nodesArray);
this_.edges = new Vis.DataSet(this_.edgesArray);
this_.container = document.getElementById('network_id');
+ this_.containermodal = document.getElementById('network_id2');
+ this_.networkPop = document.getElementById('networkPop');
this_.data = {
nodes: this_.nodes,
edges: this_.edges
};
this_.options = {
autoResize: true,
+ clickToUse:true,
groups:{
useDefaultGroups: true,
myGroupId:{
@@ -212,18 +260,26 @@
},
nodes: {
shape: 'dot',
- size: 30,
+ size: 40,
font: {
- size: 32,
+ size: 16,
},
- borderWidth: 2
+ borderWidth: 2,
+ // chosen:{
+ // node:(values, id, selected, hovering)=>{
+ // console.log(values, id, selected, hovering);
+ // if(hovering){
+ // this_.cursorMove=true;
+ // }
+ // }
+ // }
},
edges: {
width: 2,
smooth:{ //设置两个节点之前的连线的状态
enabled: false //默认是true,设置为false之后,两个节点之前的连线始终为直线,不会出现贝塞尔曲线
- }
+ },
},
layout:{
randomSeed: 666,
@@ -242,13 +298,13 @@
interaction:{
dragNodes: true, //是否能拖动节点
- dragView: false, //是否能拖动画布
+ dragView: true, //是否能拖动画布
hover: true, //鼠标移过后加粗该节点和连接线
multiselect: false, //按 ctrl 多选
selectable: true, //是否可以点击选择
selectConnectedEdges: false, //选择节点后是否显示连接线
hoverConnectedEdges: true, //鼠标滑动节点后是否显示连接线
- zoomView: true, //是否能缩放画布
+ zoomView: false, //是否能缩放画布
navigationButtons:true,
},
@@ -256,9 +312,28 @@
enabled: false,
},
};
- this_.network = new Vis.Network(this_.container, this_.data, this_.options);
+ if(type==='modal'){
+ this_.network = new Vis.Network(this_.container, this_.data, this_.options);
+ this_.network.moveTo({
+ position: this_.viewsCenter,
+ scale: 1,
+ offset: {x:0, y:0},
+ })
+ }
+ if(type=== 'screenModal'){
+ if(!this_.networkScreenModal){
+ this_.networkScreenModal= new Vis.Network(this_.containermodal, this_.data, this_.options);
+ }else{
+ this_.nodes = new Vis.DataSet(this_.nodesArray);
+ this_.edges = new Vis.DataSet(this_.edgesArray);
+ this_.networkScreenModal.setData({
+ nodes:this_.nodes,
+ edges: this_.edges
+ });
+ };
+ }
+ this_.containerCanvas=document.querySelectorAll("#network_id canvas")[0];
},
-
resetAllNodes() {
let this_ = this;
this_.nodes.clear();
@@ -286,44 +361,76 @@
nodes:this_.nodes,
edges: this_.edges
});
+ this_.network.moveTo({
+ position: this_.viewsCenter,
+ scale: 1,
+ offset: {x:0, y:0},
+ })
},
- addModel(){ // 添加model
- console.log(this.network);
- let model={
- id: 7,
- label: "model",
- group: 0,
- image: 'https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=1906469856,4113625838&fm=26&gp=0.jpg',
- shape:'image',
- shapeProperties:{useImageSize:false},
- chosen:{
- node:(values, id, selected, hovering)=>{
- console.log(values, id, selected, hovering);
- }
- },
- x:-100,
- y:-100,
- physics:false,
- };
+ addModel(model){ // 添加model
+ this.addNodeShow=false;
+ if(!model){return}
+ model={...model,...this.network.DOMtoCanvas({x:model.x,y:model.y})};
+ if(!model.image){
+ model.image=png
+ }
this.nodesArray.push(model);
- // this.resetAllNodes();
+
this.setNetworkData(this.nodesArray,this.edgesArray);
},
- addLine(){ // 添加line
- let edges= {id: 7,from: 7, to: 0,label:"hahah",arrows:'from;to'};
+ addModelShow(){ // 显示添加节点弹窗
+ this.addNodeShow=true;
+ },
+ addLine(edges){ // 添加line
+ this.addLineShow=false;
+ console.log(edges);
+ if(!edges){return}
+ edges.from=this.NodeArr[0];
+ edges.to=this.NodeArr[1];
this.edgesArray.push(edges);
this.setNetworkData(this.nodesArray,this.edgesArray);
+ this.NodeArr=[];
+ },
+ addLineTitleShow(){ // 显示添加线弹窗
+ // this.addLineShow=true;
+ this.selectNodeTitle=true;
+ },
+ closeAddLine(){
+ this.selectNodeTitle=false;
+ this.NodeArr=[];
},
-
setNodePosition(selId){ // 移动节点后 设置节点坐标
let position = this.network.getPositions([selId]);
let selItem = this.nodesArray.find((item)=>item.id===selId);
- console.log(selItem);
+ this.nodeData = selItem;
selItem.x=position[selId].x;
selItem.y=position[selId].y;
},
-
-
+ setPopPosition(selId,params){//设置节点工具栏位置
+ let position=this.network.canvasToDOM(this.network.getPositions(params.nodes)[selId]);
+ this.networkPop.style.top = position.y - 70 +'px';
+ this.networkPop.style.left = position.x - 30 +'px';
+ this.networkPopShow=true;
+ },
+ networkPopClose(){//关闭节点工具栏
+ this.networkPopShow=false;
+ },
+ //工具栏
+ nodeDel(){
+ console.log(this.selNodeId)
+ this.nodesArray=this.nodesArray.filter((item)=>item.id!==this.selNodeId);
+ this.edgesArray=this.edgesArray.filter((item)=>item.from!==this.selNodeId || this.to!==this.selNodeId);
+ this.setNetworkData(this.nodesArray, this.edgesArray);
+ },
+ nodeEdit(){
+ console.log('edit')
+ },
+ lineDel(){
+ if(!this.lineData.id){return}
+ this.edgesArray=this.edgesArray.filter((item)=>item.id!==this.lineData.id);
+ console.log(this.lineData.id);
+ this.setNetworkData(this.nodesArray, this.edgesArray);
+ },
// 其他
filterShowData(source,pageObj){
return source.slice((pageObj.pageNo-1)*pageObj.pageSize,pageObj.pageNo*pageObj.pageSize)
@@ -441,6 +548,9 @@
this.seriesItemScreen = this.seriesItem;
this.screenModal = true;
+ this.$nextTick(()=>{
+ this.init('screenModal');
+ })
},
// 设置数据, filter区分
setData(chartItem, seriesItem, panelId, filter,area,errorMsg) {
@@ -540,22 +650,61 @@
mounted(){
this.firstLoad = false;
setTimeout(()=>{
- let this_=this
- this.init();
+ let this_=this;
+ this.init('modal');
this.network.on("click", function (params) {
// params.event = "[original event]";
// document.getElementById('eventSpan').innerHTML = '
Click event:
' + JSON.stringify(params, null, 4);
- console.log('click event, getNodeAt returns: ' + this.getNodeAt(params.pointer.DOM),params);
+ console.log(params);
+ let selId=params.nodes[0];
+ this_.networkPopClose();
+ if(selId){
+ this_.selNodeId=selId;
+ this_.cursorMove=true;
+ this_.nodeData=this_.nodesArray.find((item)=>item.id==selId);
+ this_.setPopPosition(selId,params);
+ if(this_.selectNodeTitle){
+ this_.NodeArr.push(selId);
+ this_.network.selectNodes(this_.NodeArr,true)
+ }
+ }
});
- this.network.on("dragEnd", function (params) {
+
+ this.network.on("selectEdge", function (params) {
+ this_.lineData.id=params.edges[0];
+ console.log(this_.lineData.id);
+ });
+
+ this.network.on("dragStart", function (params) {//节点移动开始
// params.event = "[original event]";
// document.getElementById('eventSpan').innerHTML = 'Click event:
' + JSON.stringify(params, null, 4);
- console.log('click event, getNodeAt returns: ' + this.getNodeAt(params.pointer.DOM),params);
- console.log( this_.network.getPositions());
- let selId=params.nodes[0];
- this_.setNodePosition(selId)
+ // console.log('click event, getNodeAt returns: ' + this.getNodeAt(params.pointer.DOM),params);
+ // console.log( this_.network.getPositions());
+ this_.networkPopShow=false;
});
- })
+
+ this.network.on("dragging", function (params,event) {//节点移动中
+
+ });
+
+ this.network.on("dragEnd", function (params) {//节点移动结束
+ this_.viewsCenter=this_.network.getViewPosition();
+ let selId=params.nodes[0];
+ if(selId){
+ this_.setPopPosition(selId,params)
+ this_.setNodePosition(selId)
+ }
+ });
+ this.network.on("hoverNode", function (params) {//hoverNode
+ this_.cursorMove=true;
+ console.log(params);
+ });
+ this.network.on("blurNode", function (params) {//blurNode
+ this_.cursorMove=false;
+ // console.log(params);
+ });
+ });
+
}
}
@@ -569,6 +718,62 @@
height: calc(100% - 30px);
}
.network{
+ display: flex;
height: calc(100% - 30px);
+ position: relative;
+ }
+ .networkPop{
+ position: absolute;
+ z-index: 10;
+ border: 1px solid #e6e6e6;
+ border-radius: 5px;
+ height: 32px;
+ background: #fff;
+ padding: 0 3px;
+ line-height: 32px;
+ }
+ .btmTriangle{
+ position: absolute;
+ width: 0;
+ height: 0;
+ border-width: 10px;
+ border-style: solid;
+ border-color:#e6e6e6 transparent transparent transparent;
+ bottom: -20px;
+ left: 50%;
+ transform: translateX(-50%);
+ }
+ .btmTriangle:after{
+ content: '';
+ display:block;
+ width:0;
+ height:0;
+ border-width: 10px;
+ border-style:solid;
+ border-color:#fff transparent transparent transparent;
+ position:absolute;
+ bottom: -7px;
+ left: -9px;
+ }
+ #network_id{
+ width: 60%;
+ }
+ .cursorMove{
+ cursor: move;
+ }
+ #network_id2{
+ height: 100%;
+ }
+ .networkContent{
+ width: 40%;
+ }
+ .nz-icon-delete{
+ cursor: pointer;
+ color: #ee6723;
+ margin-left: 10px;
+ }
+ .nz-icon-edit{
+ font-size: 14px;
+ cursor: pointer;
}