Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
S
smart
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wangqinghua
smart
Commits
614773d0
Commit
614773d0
authored
Jan 29, 2019
by
wangqinghua
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
update
parent
f10fda0f
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
1369 additions
and
0 deletions
+1369
-0
jtopo.component.html
src/main/webapp/app/modal/jtopo/jtopo.component.html
+5
-0
jtopo.component.ts
src/main/webapp/app/modal/jtopo/jtopo.component.ts
+1364
-0
No files found.
src/main/webapp/app/modal/jtopo/jtopo.component.html
0 → 100644
View file @
614773d0
<div
#
topologyBody
class=
"topologyBody"
>
<canvas
class=
"topology-context"
id=
"topology-canvas"
#
topologyCanvas
style=
"height: 580px;width: 100%"
>
您的浏览器不支持HTML5!
</canvas>
</div>
src/main/webapp/app/modal/jtopo/jtopo.component.ts
0 → 100644
View file @
614773d0
import
{
Component
,
ElementRef
,
EventEmitter
,
HostListener
,
OnInit
,
Output
,
ViewChild
}
from
'@angular/core'
;
declare
let
JTopo
:
any
;
@
Component
({
selector
:
'app-root'
,
templateUrl
:
'./app.component.html'
,
styleUrls
:
[
'./app.component.css'
]
})
/**
* 提供拓扑图面板相关操作的函数集,编辑器继承其全部功能
*/
export
class
JtopoComponent
implements
OnInit
{
@
Output
()
clickNode
=
new
EventEmitter
<
any
>
();
@
Output
()
clickLink
=
new
EventEmitter
<
any
>
();
@
ViewChild
(
'topologyCanvas'
)
topologyCanvas
:
ElementRef
;
@
ViewChild
(
'topologyBody'
)
topologyBody
:
ElementRef
;
json
=
{
"version"
:
"0.4.8"
,
"wheelZoom"
:
"0.95"
,
"id"
:
"ST172.19.105.52015100809430700001"
,
"childs"
:
[
{
"id"
:
"S172.19.105.52015100809430700002"
,
"elementType"
:
"scene"
,
"translateX"
:
"106.5"
,
"translateY"
:
"20"
,
"scaleX"
:
"1"
,
"scaleY"
:
"1"
,
"childs"
:
[
{
"id"
:
"L172.19.105.52015100811153300001"
,
"elementType"
:
"link"
,
"x"
:
"0"
,
"y"
:
"0"
,
"width"
:
"32"
,
"height"
:
"32"
,
"rotate"
:
"0"
,
"scaleX"
:
"1"
,
"scaleY"
:
"1"
,
"text"
:
"undefined"
,
"nodeSrc"
:
"1136300297928.587"
,
"nodeDst"
:
"1406176935353.6848"
,
"lineType"
:
"line"
,
"zindex"
:
"2"
},
{
"id"
:
"L172.19.105.52015100811153300002"
,
"elementType"
:
"link"
,
"x"
:
"0"
,
"y"
:
"0"
,
"width"
:
"32"
,
"height"
:
"32"
,
"rotate"
:
"0"
,
"scaleX"
:
"1"
,
"scaleY"
:
"1"
,
"text"
:
"undefined"
,
"nodeSrc"
:
"1394105924967.951"
,
"nodeDst"
:
"1136300297928.587"
,
"lineType"
:
"line"
,
"zindex"
:
"2"
},
{
"id"
:
"L172.19.105.52015100811153300004"
,
"elementType"
:
"link"
,
"x"
:
"0"
,
"y"
:
"0"
,
"width"
:
"32"
,
"height"
:
"32"
,
"rotate"
:
"0"
,
"scaleX"
:
"1"
,
"scaleY"
:
"1"
,
"text"
:
"undefined"
,
"nodeSrc"
:
"564241624829.4331"
,
"nodeDst"
:
"318016674603.1266"
,
"lineType"
:
"line"
,
"zindex"
:
"2"
},
{
"id"
:
"L172.19.105.52015100811153300005"
,
"elementType"
:
"link"
,
"x"
:
"0"
,
"y"
:
"0"
,
"width"
:
"32"
,
"height"
:
"32"
,
"rotate"
:
"0"
,
"scaleX"
:
"1"
,
"scaleY"
:
"1"
,
"text"
:
"undefined"
,
"nodeSrc"
:
"1062340763210.1544"
,
"nodeDst"
:
"564241624829.4331"
,
"lineType"
:
"line"
,
"zindex"
:
"2"
},
{
"id"
:
"L172.19.105.52015100811153300006"
,
"elementType"
:
"link"
,
"x"
:
"0"
,
"y"
:
"0"
,
"width"
:
"32"
,
"height"
:
"32"
,
"rotate"
:
"0"
,
"scaleX"
:
"1"
,
"scaleY"
:
"1"
,
"text"
:
"undefined"
,
"nodeSrc"
:
"564241624829.4331"
,
"nodeDst"
:
"488323736331.2087"
,
"lineType"
:
"line"
,
"zindex"
:
"2"
},
{
"id"
:
"L172.19.105.52015100811153300007"
,
"elementType"
:
"link"
,
"x"
:
"0"
,
"y"
:
"0"
,
"width"
:
"32"
,
"height"
:
"32"
,
"rotate"
:
"0"
,
"scaleX"
:
"1"
,
"scaleY"
:
"1"
,
"text"
:
"undefined"
,
"nodeSrc"
:
"564241624829.4331"
,
"nodeDst"
:
"827722371280.0199"
,
"lineType"
:
"line"
,
"zindex"
:
"2"
},
{
"id"
:
"L172.19.105.52015100811153300008"
,
"elementType"
:
"link"
,
"x"
:
"0"
,
"y"
:
"0"
,
"width"
:
"32"
,
"height"
:
"32"
,
"rotate"
:
"0"
,
"scaleX"
:
"1"
,
"scaleY"
:
"1"
,
"text"
:
"undefined"
,
"nodeSrc"
:
"564241624829.4331"
,
"nodeDst"
:
"1045863334277.662"
,
"lineType"
:
"line"
,
"zindex"
:
"2"
},
{
"id"
:
"L172.19.105.52015100811153300009"
,
"elementType"
:
"link"
,
"x"
:
"0"
,
"y"
:
"0"
,
"width"
:
"32"
,
"height"
:
"32"
,
"rotate"
:
"0"
,
"scaleX"
:
"1"
,
"scaleY"
:
"1"
,
"text"
:
"undefined"
,
"nodeSrc"
:
"1262070648024.5728"
,
"nodeDst"
:
"564241624829.4331"
,
"lineType"
:
"line"
,
"zindex"
:
"2"
},
{
"id"
:
"L172.19.105.52015100811153300010"
,
"elementType"
:
"link"
,
"x"
:
"0"
,
"y"
:
"0"
,
"width"
:
"32"
,
"height"
:
"32"
,
"rotate"
:
"0"
,
"scaleX"
:
"1"
,
"scaleY"
:
"1"
,
"text"
:
"undefined"
,
"nodeSrc"
:
"1262070648024.5728"
,
"nodeDst"
:
"1136300297928.587"
,
"lineType"
:
"line"
,
"zindex"
:
"2"
},
{
"id"
:
"L172.19.105.52015100811214600001"
,
"elementType"
:
"link"
,
"x"
:
"0"
,
"y"
:
"0"
,
"width"
:
"32"
,
"height"
:
"32"
,
"rotate"
:
"0"
,
"scaleX"
:
"1"
,
"scaleY"
:
"1"
,
"text"
:
"undefined"
,
"nodeSrc"
:
"253209434749.73596"
,
"nodeDst"
:
"564241624829.4331"
,
"lineType"
:
"line"
,
"zindex"
:
"2"
},
{
"id"
:
"L172.19.105.52015100811214600002"
,
"elementType"
:
"link"
,
"x"
:
"0"
,
"y"
:
"0"
,
"width"
:
"32"
,
"height"
:
"32"
,
"rotate"
:
"0"
,
"scaleX"
:
"1"
,
"scaleY"
:
"1"
,
"text"
:
"undefined"
,
"nodeSrc"
:
"253209434749.73596"
,
"nodeDst"
:
"1136300297928.587"
,
"lineType"
:
"line"
,
"zindex"
:
"2"
},
{
"id"
:
"L172.19.105.52015100811214600003"
,
"elementType"
:
"link"
,
"x"
:
"0"
,
"y"
:
"0"
,
"width"
:
"32"
,
"height"
:
"32"
,
"rotate"
:
"0"
,
"scaleX"
:
"1"
,
"scaleY"
:
"1"
,
"text"
:
"undefined"
,
"nodeSrc"
:
"520008948580.8119"
,
"nodeDst"
:
"564241624829.4331"
,
"lineType"
:
"line"
,
"zindex"
:
"2"
},
{
"id"
:
"L172.19.105.52015100811214600004"
,
"elementType"
:
"link"
,
"x"
:
"0"
,
"y"
:
"0"
,
"width"
:
"32"
,
"height"
:
"32"
,
"rotate"
:
"0"
,
"scaleX"
:
"1"
,
"scaleY"
:
"1"
,
"text"
:
"undefined"
,
"nodeSrc"
:
"520008948580.8119"
,
"nodeDst"
:
"1136300297928.587"
,
"lineType"
:
"line"
,
"zindex"
:
"2"
},
{
"id"
:
"L172.19.105.52015100811512000002"
,
"elementType"
:
"link"
,
"x"
:
"0"
,
"y"
:
"0"
,
"width"
:
"32"
,
"height"
:
"32"
,
"rotate"
:
"0"
,
"scaleX"
:
"1"
,
"scaleY"
:
"1"
,
"text"
:
"undefined"
,
"nodeSrc"
:
"809054608657.865"
,
"nodeDst"
:
"1394105924967.951"
,
"lineType"
:
"line"
,
"zindex"
:
"2"
},
{
"id"
:
"L172.19.105.52015100811512000004"
,
"elementType"
:
"link"
,
"x"
:
"0"
,
"y"
:
"0"
,
"width"
:
"32"
,
"height"
:
"32"
,
"rotate"
:
"0"
,
"scaleX"
:
"1"
,
"scaleY"
:
"1"
,
"text"
:
"undefined"
,
"nodeSrc"
:
"1250687739831.9912"
,
"nodeDst"
:
"1062340763210.1544"
,
"lineType"
:
"line"
,
"zindex"
:
"2"
},
{
"id"
:
"L172.19.105.52015100911051100001"
,
"elementType"
:
"link"
,
"x"
:
"0"
,
"y"
:
"0"
,
"width"
:
"32"
,
"height"
:
"32"
,
"rotate"
:
"0"
,
"scaleX"
:
"1"
,
"scaleY"
:
"1"
,
"text"
:
"undefined"
,
"nodeSrc"
:
"564241624829.4331"
,
"nodeDst"
:
"597645745716.1871"
,
"lineType"
:
"line"
,
"zindex"
:
"2"
},
{
"elementType"
:
"node"
,
"x"
:
"198"
,
"y"
:
"315"
,
"width"
:
"32"
,
"height"
:
"32"
,
"rotate"
:
"0"
,
"scaleX"
:
"1"
,
"scaleY"
:
"1"
,
"text"
:
"attack-network"
,
"textPosition"
:
"Bottom_Center"
,
"nodeId"
:
"1136300297928.587"
,
"nodeType"
:
"EC"
,
"nodeImage"
:
"http://10.10.38.99:8888/file/icon/15474547275540202.png"
,
"zindex"
:
"3"
},
{
"id"
:
"N172.19.105.52015100809465000001"
,
"elementType"
:
"node"
,
"x"
:
"196"
,
"y"
:
"242"
,
"width"
:
"32"
,
"height"
:
"32"
,
"rotate"
:
"0"
,
"scaleX"
:
"1"
,
"scaleY"
:
"1"
,
"text"
:
"attackr-router"
,
"textPosition"
:
"Bottom_Center"
,
"nodeId"
:
"1394105924967.951"
,
"nodeType"
:
"VR"
,
"nodeImage"
:
"http://10.10.38.99:8888/file/icon/15474547275540202.png"
,
"zindex"
:
"3"
},
{
"id"
:
"N172.19.105.52015100809500700002"
,
"elementType"
:
"node"
,
"x"
:
"104"
,
"y"
:
"383.5"
,
"width"
:
"32"
,
"height"
:
"32"
,
"rotate"
:
"0"
,
"scaleX"
:
"1"
,
"scaleY"
:
"1"
,
"text"
:
"attack-client"
,
"textPosition"
:
"Bottom_Center"
,
"nodeId"
:
"1406176935353.6848"
,
"nodeType"
:
"VM"
,
"nodeImage"
:
"http://10.10.38.99:8888/file/icon/15474547275540202.png"
,
"zindex"
:
"3"
},
{
"id"
:
"N172.19.105.52015100810295700002"
,
"elementType"
:
"node"
,
"x"
:
"539"
,
"y"
:
"321.5"
,
"width"
:
"32"
,
"height"
:
"32"
,
"rotate"
:
"0"
,
"scaleX"
:
"1"
,
"scaleY"
:
"1"
,
"text"
:
"intert-networker"
,
"textPosition"
:
"Bottom_Center"
,
"nodeId"
:
"564241624829.4331"
,
"nodeType"
:
"EC"
,
"nodeImage"
:
"http://10.10.38.99:8888/file/icon/15474547275540202.png"
,
"zindex"
:
"3"
},
{
"id"
:
"N172.19.105.52015100810320100002"
,
"elementType"
:
"node"
,
"x"
:
"719"
,
"y"
:
"160.5"
,
"width"
:
"32"
,
"height"
:
"32"
,
"rotate"
:
"0"
,
"scaleX"
:
"1"
,
"scaleY"
:
"1"
,
"text"
:
"ws-manage"
,
"textPosition"
:
"Bottom_Center"
,
"nodeId"
:
"318016674603.1266"
,
"nodeType"
:
"VM"
,
"nodeImage"
:
"http://10.10.38.99:8888/file/icon/15474547275540202.png"
,
"zindex"
:
"3"
},
{
"id"
:
"N172.19.105.52015100810402700002"
,
"elementType"
:
"node"
,
"x"
:
"725"
,
"y"
:
"225.5"
,
"width"
:
"32"
,
"height"
:
"32"
,
"rotate"
:
"0"
,
"scaleX"
:
"1"
,
"scaleY"
:
"1"
,
"text"
:
"ws-browser"
,
"textPosition"
:
"Bottom_Center"
,
"nodeId"
:
"488323736331.2087"
,
"nodeType"
:
"VM"
,
"nodeImage"
:
"http://10.10.38.99:8888/file/icon/15474547275540202.png"
,
"zindex"
:
"3"
},
{
"id"
:
"N172.19.105.52015100810461200002"
,
"elementType"
:
"node"
,
"x"
:
"726"
,
"y"
:
"293.5"
,
"width"
:
"32"
,
"height"
:
"32"
,
"rotate"
:
"0"
,
"scaleX"
:
"1"
,
"scaleY"
:
"1"
,
"text"
:
"internal-mssql"
,
"textPosition"
:
"Bottom_Center"
,
"nodeId"
:
"827722371280.0199"
,
"nodeType"
:
"VM"
,
"nodeImage"
:
"http://10.10.38.99:8888/file/icon/15474547275540202.png"
,
"zindex"
:
"3"
},
{
"id"
:
"N172.19.105.52015100810485100002"
,
"elementType"
:
"node"
,
"x"
:
"726"
,
"y"
:
"361.5"
,
"width"
:
"32"
,
"height"
:
"32"
,
"rotate"
:
"0"
,
"scaleX"
:
"1"
,
"scaleY"
:
"1"
,
"text"
:
"internal-ossec"
,
"textPosition"
:
"Bottom_Center"
,
"nodeId"
:
"1045863334277.662"
,
"nodeType"
:
"VM"
,
"nodeImage"
:
"http://10.10.38.99:8888/file/icon/15474547275540202.png"
,
"zindex"
:
"3"
},
{
"id"
:
"N172.19.105.52015100810523500002"
,
"elementType"
:
"node"
,
"x"
:
"369"
,
"y"
:
"245.5"
,
"width"
:
"32"
,
"height"
:
"32"
,
"rotate"
:
"0"
,
"scaleX"
:
"1"
,
"scaleY"
:
"1"
,
"text"
:
"internet-www"
,
"textPosition"
:
"Bottom_Center"
,
"nodeId"
:
"1262070648024.5728"
,
"nodeType"
:
"ECVR"
,
"nodeImage"
:
"http://10.10.38.99:8888/file/icon/15474547275540202.png"
,
"zindex"
:
"3"
},
{
"id"
:
"N172.19.105.52015100811153300003"
,
"elementType"
:
"node"
,
"x"
:
"536"
,
"y"
:
"237.5"
,
"width"
:
"32"
,
"height"
:
"32"
,
"rotate"
:
"0"
,
"scaleX"
:
"1"
,
"scaleY"
:
"1"
,
"text"
:
"intert-router"
,
"textPosition"
:
"Bottom_Center"
,
"nodeId"
:
"1062340763210.1544"
,
"nodeType"
:
"VR"
,
"nodeImage"
:
"http://10.10.38.99:8888/file/icon/15474547275540202.png"
,
"zindex"
:
"3"
},
{
"id"
:
"N172.19.105.52015100811163200002"
,
"elementType"
:
"node"
,
"x"
:
"367.5"
,
"y"
:
"320"
,
"width"
:
"32"
,
"height"
:
"32"
,
"rotate"
:
"0"
,
"scaleX"
:
"1"
,
"scaleY"
:
"1"
,
"text"
:
"internet-blog"
,
"textPosition"
:
"Bottom_Center"
,
"nodeId"
:
"253209434749.73596"
,
"nodeType"
:
"ECVR"
,
"nodeImage"
:
"http://10.10.38.99:8888/file/icon/15474547275540202.png"
,
"zindex"
:
"3"
},
{
"id"
:
"N172.19.105.52015100811204100002"
,
"elementType"
:
"node"
,
"x"
:
"370.5"
,
"y"
:
"403"
,
"width"
:
"32"
,
"height"
:
"32"
,
"rotate"
:
"0"
,
"scaleX"
:
"1"
,
"scaleY"
:
"1"
,
"text"
:
"internet-vpn"
,
"textPosition"
:
"Bottom_Center"
,
"nodeId"
:
"520008948580.8119"
,
"nodeType"
:
"ECVR"
,
"nodeParams"
:
{},
"nodeImage"
:
"http://10.10.38.99:8888/file/icon/15474547275540202.png"
,
"zindex"
:
"3"
},
{
"id"
:
"N172.19.105.52015100811512000001"
,
"elementType"
:
"node"
,
"x"
:
"194.5"
,
"y"
:
"166"
,
"width"
:
"32"
,
"height"
:
"32"
,
"rotate"
:
"0"
,
"scaleX"
:
"1"
,
"scaleY"
:
"1"
,
"text"
:
"attack-firewall"
,
"textPosition"
:
"Bottom_Center"
,
"nodeId"
:
"809054608657.865"
,
"nodeType"
:
"FW"
,
"nodeParams"
:
{},
"nodeImage"
:
"http://10.10.38.99:8888/file/icon/15474547275540202.png"
,
"zindex"
:
"3"
},
{
"id"
:
"N172.19.105.52015100811512000003"
,
"elementType"
:
"node"
,
"x"
:
"534.5"
,
"y"
:
"163"
,
"width"
:
"32"
,
"height"
:
"32"
,
"rotate"
:
"0"
,
"scaleX"
:
"1"
,
"scaleY"
:
"1"
,
"text"
:
"intert-firewall"
,
"textPosition"
:
"Bottom_Center"
,
"nodeId"
:
"1250687739831.9912"
,
"nodeType"
:
"FW"
,
"nodeParams"
:
{},
"nodeImage"
:
"http://10.10.38.99:8888/file/icon/15474547275540202.png"
,
"zindex"
:
"3"
},
{
"id"
:
"N172.19.105.52015100911045400002"
,
"elementType"
:
"node"
,
"x"
:
"727.5"
,
"y"
:
"430"
,
"width"
:
"32"
,
"height"
:
"32"
,
"rotate"
:
"0"
,
"scaleX"
:
"1"
,
"scaleY"
:
"1"
,
"text"
:
"defend-client"
,
"textPosition"
:
"Bottom_Center"
,
"nodeId"
:
"597645745716.1871"
,
"nodeType"
:
"VM"
,
"nodeImage"
:
"http://10.10.38.99:8888/file/icon/15474547275540202.png"
,
"zindex"
:
"3"
}
]
}
]
};
utils
;
config
=
{
// Stage属性
stageFrames
:
500
,
// 舞台播放的帧数/秒
defaultScal
:
0.95
,
// 鼠标滚轮缩放比例
eagleEyeVsibleDefault
:
false
,
// 是否显示鹰眼对象
// Node属性
nodeAlpha
:
1
,
// 节点透明度,取值范围[0-1]
nodeStrokeColor
:
'22,124,255'
,
// 节点描边的颜色
nodeFillColor
:
'255,222,173'
,
// 节点填充颜色
nodeShadow
:
false
,
// 节点是否显示阴影
nodeShadowColor
:
'rgba(0,0,0,0.5)'
,
// 节点阴影的颜色
nodeFont
:
'12px Consolas'
,
// 节点字体
nodeFontColor
:
'black'
,
// 节点文字颜色,如"255,255,0"
nodeDefaultWidth
:
32
,
// 新建节点默认宽
nodeDefaultHeight
:
32
,
// 新建节点默认高
nodeBorderColor
:
'black'
,
// 节点容器边框颜色,如"255,255,0"
nodeBorderRadius
:
30
,
// 节点半径,非圆节点有此属性会变形
nodeRotateValue
:
0.5
,
// 节点旋转的角度(弧度)
nodeScale
:
0.2
,
// 节点缩放幅度(此处保证X和Y均等缩放)
// Link属性
linkAlpha
:
1
,
// 连线透明度,取值范围[0-1]
linkStrokeColor
:
'0,0,0'
,
// 连线的颜色
linkFillColor
:
'0,0,0'
,
linkShadow
:
false
,
// 是否显示连线阴影
linkShadowColor
:
'rgba(0,0,0,0.5)'
,
linkFont
:
'12px Consolas'
,
// 节点字体
linkFontColor
:
'black'
,
// 连线文字颜色,如"255,255,0"
linkArrowsRadius
:
0
,
// 线条箭头半径
linkDefaultWidth
:
3
,
// 连线宽度
linkOffsetGap
:
80
,
// 折线拐角处的长度
linkDirection
:
'vertical'
,
// 折线的方向
// Container属性
containerAlpha
:
1
,
containerStrokeColor
:
'22,124,255'
,
containerFillColor
:
'22,124,255'
,
containerShadow
:
false
,
containerShadowColor
:
'rgba(0,0,0,0.5)'
,
containerFont
:
'12px Consolas'
,
containerFontColor
:
'black'
,
containerBorderColor
:
'black'
,
containerBorderRadius
:
30
,
arrowsRadius
:
null
};
// 布局参数
layout
=
{};
// 绘图区属性
stage
=
null
;
scene
=
null
;
// 当前模式
stageMode
=
'edit'
;
// 默认连线类型
lineType
=
'line'
;
// 当前选择的节点对象
currentNode
=
null
;
// 当前选择的连线对象
currentLink
=
null
;
beginNode
=
null
;
link
=
null
;
isSelectedMode
;
tempNodeA
=
new
JTopo
.
Node
(
'tempA'
);
tempNodeZ
=
new
JTopo
.
Node
(
'tempZ'
);
constructor
(){}
ngOnInit
(){
this
.
init
(
'assets/img/backimg.png'
,
this
.
json
);
}
/**
* 编辑器初始化方法,根据请求返回结果加载空白的或者指定结构的拓扑编辑器
* @param backImg 背景图片
* @param topologyJson 拓扑JSON结构
*/
init
(
backImg
,
topologyJson
){
if
(
!
topologyJson
){
return
;
}
let
canvas
=
this
.
topologyCanvas
.
nativeElement
;
canvas
.
width
=
this
.
topologyBody
.
nativeElement
.
clientWidth
;
canvas
.
height
=
this
.
topologyBody
.
nativeElement
.
clientHeight
;
this
.
tempNodeA
.
setSize
(
1
,
1
);
this
.
tempNodeZ
.
setSize
(
1
,
1
);
let
self
=
this
;
if
(
topologyJson
===
'-1'
){
this
.
stage
=
new
JTopo
.
Stage
(
canvas
);
//定义舞台对象
this
.
scene
=
new
JTopo
.
Scene
(
this
.
stage
);
//定义场景对象
}
else
{
this
.
stage
=
JTopo
.
createStageFromJson
(
topologyJson
,
canvas
);
this
.
scene
=
this
.
stage
.
childs
[
0
];
}
this
.
getAllNodes
()[
0
].
alarm
=
"告警"
;
this
.
scene
.
mouseover
(
event
=>
{
//进入某个节点
// if(event.target != null && event.target instanceof JTopo.Node && event.target.nodeTooltip &&)
});
this
.
scene
.
click
(
event
=>
{
if
(
!
event
.
target
){
//单击空白处
return
;
}
if
(
event
.
target
instanceof
JTopo
.
Node
&&
this
.
stageMode
===
'normal'
){
}
else
if
(
event
.
target
instanceof
JTopo
.
Node
&&
this
.
stageMode
===
'edit'
){
}
else
if
(
event
.
target
instanceof
JTopo
.
Link
&&
this
.
stageMode
===
'normal'
){
}
else
if
(
event
.
target
instanceof
JTopo
.
Link
&&
this
.
stageMode
===
'edit'
){
}
});
//双击编辑事件
this
.
scene
.
dbclick
(
event
=>
{
if
(
!
event
.
target
){
//双击空白处
return
;
}
this
.
currentNode
=
event
.
target
;
if
(
event
.
target
instanceof
JTopo
.
Node
&&
this
.
stageMode
===
'normal'
){
}
else
if
(
event
.
target
instanceof
JTopo
.
Node
&&
this
.
stageMode
===
'edit'
){
console
.
log
(
event
.
target
);
}
else
if
(
event
.
target
instanceof
JTopo
.
Link
&&
this
.
stageMode
===
'normal'
){
}
else
if
(
event
.
target
instanceof
JTopo
.
Link
&&
this
.
stageMode
===
'edit'
){
console
.
log
(
event
.
target
);
}
})
//清楚起始节点不完整的拖放线
this
.
scene
.
mousedown
(
event
=>
{
if
(
!
event
.
target
){
return
;
}
if
(
this
.
link
&&
!
this
.
isSelectedMode
&&
(
event
.
target
==
null
||
event
.
target
===
this
.
beginNode
||
event
.
target
===
this
.
link
)){
this
.
scene
.
remove
(
this
.
link
);
}
});
//监听鼠标松开事件;
//处理右键菜单、左键连线
//event.button: 0-左键 1-中键 2-右键
this
.
scene
.
mouseup
(
event
=>
{
if
(
event
.
target
&&
event
.
target
instanceof
JTopo
.
Node
)
{
this
.
currentNode
=
event
.
target
}
else
if
(
event
.
target
&&
event
.
target
instanceof
JTopo
.
Link
)
{
this
.
currentLink
=
event
.
target
}
if
(
event
.
target
&&
event
.
target
instanceof
JTopo
.
Node
&&
event
.
target
.
layout
&&
event
.
target
.
layout
.
on
&&
event
.
target
.
layout
.
type
&&
event
.
target
.
layout
.
type
!==
'auto'
)
{
JTopo
.
layout
.
layoutNode
(
this
,
event
.
target
,
true
,
event
)
}
if
(
event
.
button
===
0
){
if
(
event
.
target
!=
null
&&
event
.
target
instanceof
JTopo
.
Node
&&
!
this
.
isSelectedMode
&&
this
.
stageMode
===
'edit'
)
{
if
(
this
.
beginNode
==
null
)
{
// 在起始节点处松开鼠标,创建动态的线条(临时节点A-Z)
this
.
beginNode
=
event
.
target
;
if
(
this
.
lineType
===
'line'
)
{
// 直线
self
.
link
=
new
JTopo
.
Link
(
self
.
tempNodeA
,
self
.
tempNodeZ
);
self
.
link
.
lineType
=
'line'
}
else
if
(
self
.
lineType
===
'foldLine'
)
{
// 折线
self
.
link
=
new
JTopo
.
FoldLink
(
self
.
tempNodeA
,
self
.
tempNodeZ
);
self
.
link
.
lineType
=
'foldLine'
;
self
.
link
.
direction
=
self
.
config
.
linkDirection
}
else
if
(
self
.
lineType
===
'flexLine'
)
{
// 二次折线
self
.
link
=
new
JTopo
.
FlexionalLink
(
self
.
tempNodeA
,
self
.
tempNodeZ
);
self
.
link
.
direction
=
self
.
config
.
linkDirection
;
self
.
link
.
lineType
=
'flexLine'
}
else
if
(
self
.
lineType
===
'curveLine'
)
{
// 曲线
self
.
link
=
new
JTopo
.
CurveLink
(
self
.
tempNodeA
,
self
.
tempNodeZ
);
self
.
link
.
lineType
=
'curveLine'
}
self
.
link
.
dashedPattern
=
2
;
self
.
link
.
lineWidth
=
self
.
config
.
linkDefaultWidth
;
self
.
link
.
shadow
=
self
.
config
.
linkShadow
;
self
.
link
.
strokeColor
=
JTopo
.
util
.
randomColor
();
this
.
scene
.
add
(
self
.
link
);
self
.
tempNodeA
.
setLocation
(
event
.
x
,
event
.
y
);
self
.
tempNodeZ
.
setLocation
(
event
.
x
,
event
.
y
);
}
else
if
(
event
.
target
&&
event
.
target
instanceof
JTopo
.
Node
&&
self
.
beginNode
!==
event
.
target
)
{
// 在终点节点处松开鼠标,则建立连线
let
endNode
=
event
.
target
;
let
link
;
if
(
self
.
lineType
===
'line'
)
{
link
=
new
JTopo
.
Link
(
self
.
beginNode
,
endNode
);
link
.
lineType
=
'line'
}
else
if
(
self
.
lineType
===
'foldLine'
)
{
link
=
new
JTopo
.
FoldLink
(
self
.
beginNode
,
endNode
);
link
.
direction
=
self
.
config
.
linkDirection
;
link
.
bundleOffset
=
self
.
config
.
linkOffsetGap
;
// 折线拐角处的长度
link
.
lineType
=
'foldLine'
}
else
if
(
self
.
lineType
===
'flexLine'
)
{
link
=
new
JTopo
.
FlexionalLink
(
self
.
beginNode
,
endNode
);
link
.
direction
=
self
.
config
.
linkDirection
;
link
.
lineType
=
'flexLine'
;
link
.
offsetGap
=
self
.
config
.
linkOffsetGap
;
}
else
if
(
self
.
lineType
===
'curveLine'
)
{
link
=
new
JTopo
.
CurveLink
(
self
.
beginNode
,
endNode
);
link
.
lineType
=
'curveLine'
;
}
// 保存线条所连接的两个节点ID
link
.
nodeSrc
=
self
.
beginNode
.
nodeId
;
link
.
nodeDst
=
endNode
.
nodeId
;
if
(
self
.
lineType
!==
'curveLine'
)
{
link
.
arrowsRadius
=
self
.
config
.
arrowsRadius
;
}
link
.
strokeColor
=
self
.
config
.
linkStrokeColor
;
link
.
lineWidth
=
self
.
config
.
linkDefaultWidth
;
console
.
log
(
this
);
this
.
scene
.
add
(
link
);
self
.
beginNode
=
null
;
this
.
scene
.
remove
(
self
.
link
);
self
.
link
=
null
;
}
else
{
self
.
beginNode
=
null
;
}
}
else
{
if
(
this
.
link
)
{
console
.
log
(
this
);
this
.
scene
.
remove
(
this
.
link
);
}
this
.
beginNode
=
null
;
}
}
});
//动态更新连线坐标
this
.
scene
.
mousemove
(
event
=>
{
if
(
!
self
.
isSelectedMode
&&
self
.
beginNode
){
self
.
tempNodeA
.
setLocation
(
event
.
x
,
event
.
y
);
}
});
this
.
scene
.
mousedrag
(
event
=>
{
if
(
!
self
.
isSelectedMode
&&
self
.
beginNode
)
{
self
.
tempNodeZ
.
setLocation
(
event
.
x
,
event
.
y
)
}
});
//鼠标移出舞台
this
.
stage
.
mouseout
(
event
=>
{
// 删掉节点带出来的连线
if
(
self
.
link
&&
!
self
.
isSelectedMode
&&
(
event
.
target
==
null
||
event
.
target
===
self
.
beginNode
||
event
.
target
===
self
.
link
))
{
self
.
scene
.
remove
(
self
.
link
)
}
})
this
.
scene
.
background
=
backImg
;
}
//键盘事件
@
HostListener
(
'window:keyup'
,[
'$event'
])
keyEvent
(
e
:
KeyboardEvent
){
if
(
e
.
shiftKey
)
{
// 组合键模式
switch
(
e
.
which
)
{
// 放大 ctrl+=
case
187
:
case
61
:
// 单个节点可以撤销操作
if
(
this
.
currentNode
instanceof
JTopo
.
Node
)
{
// 保存初始状态
this
.
utils
.
saveNodeInitState
();
this
.
utils
.
scalingBig
();
this
.
utils
.
saveNodeNewState
();
}
else
{
this
.
utils
.
scalingBig
();
}
break
;
// 缩小 ctrl+-
case
189
:
case
173
:
if
(
this
.
currentNode
instanceof
JTopo
.
Node
)
{
// 保存初始状态
this
.
utils
.
saveNodeInitState
();
this
.
utils
.
scalingSmall
();
this
.
utils
.
saveNodeNewState
();
}
else
{
this
.
utils
.
scalingSmall
();
}
break
case
70
:
// ctrl+f 全屏显示
this
.
utils
.
showInFullScreen
(
this
.
stage
.
canvas
,
'RequestFullScreen'
)
break
;
case
72
:
// h 帮助
// alert('帮助文档')
break
;
case
71
:
// ctrl+g 居中显示
this
.
utils
.
showInCenter
();
break
;
case
73
:
// shif+I 逆时针旋转
if
(
this
.
currentNode
instanceof
JTopo
.
Node
)
{
this
.
utils
.
saveNodeInitState
();
this
.
utils
.
rotateSub
();
this
.
utils
.
saveNodeNewState
();
}
break
;
case
67
:
this
.
utils
.
cloneSelectedNodes
();
break
;
case
80
:
// ctrl + p
this
.
utils
.
showPic
();
break
;
case
82
:
// 单个节点重做
if
(
this
.
currentNode
instanceof
JTopo
.
Node
)
{
this
.
utils
.
reMakeNodeAction
();
}
break
;
case
83
:
// ctrl+s 保存
this
.
saveTopology
(
true
);
break
;
case
85
:
// shif+U 顺时针旋转
if
(
this
.
currentNode
instanceof
JTopo
.
Node
)
{
this
.
utils
.
saveNodeInitState
();
this
.
utils
.
rotateAdd
();
this
.
utils
.
saveNodeNewState
()
}
break
;
case
87
:
// alert('ctrl + w 另存为')
break
case
89
:
// ctrl+y
this
.
utils
.
clearTopology
();
break
case
90
:
// 单个节点撤销
if
(
this
.
currentNode
instanceof
JTopo
.
Node
)
{
this
.
utils
.
cancleNodeAction
()
}
break
}
}
else
if
(
e
.
which
===
46
)
{
// 单独按下delete
this
.
utils
.
deleteSelectedNodes
()
}
else
if
(
e
.
which
===
17
)
{
// 单独按下ctrl
this
.
isSelectedMode
=
true
}
}
/**
* 图元拖放功能实现
* @param modeDiv 备选列表中的元素(各种样式的节点)
* @param drawArea 舞台区域
*/
drag
(
modeDiv
,
drawArea
,
text
){
if
(
!
text
){
text
=
''
;
}
let
self
=
this
;
// 拖拽开始,携带必要的参数
modeDiv
.
ondragstart
=
(
event
)
=>
{
event
=
event
||
window
.
event
;
let
dragSrc
=
this
;
// let backImg = $(dragSrc).find('img').eq(0).attr('src')
// backImg = backImg.substring(backImg.lastIndexOf('/') + 1)
// let nodeType = $(this).attr('topo-nodetype')
try
{
// IE只允许KEY为text和URL
// event.dataTransfer.setData('text', backImg + ';' + text + ';' + nodeType)
}
catch
(
ex
)
{
console
.
log
(
ex
)
}
};
// 阻止默认事件
drawArea
.
ondragover
=
(
event
)
=>
{
event
.
preventDefault
();
return
false
};
// 创建节点
drawArea
.
ondrop
=
(
event
)
=>
{
// 只读模式
if
(
this
.
stageMode
===
"normal"
)
{
return
;
}
event
=
event
||
window
.
event
;
let
data
=
event
.
dataTransfer
.
getData
(
'text'
);
let
img
,
text
,
nodeType
;
if
(
data
)
{
let
datas
=
data
.
split
(
';'
);
if
(
datas
&&
datas
.
length
===
3
)
{
img
=
datas
[
0
];
text
=
datas
[
1
];
nodeType
=
datas
[
2
];
let
node
=
new
JTopo
.
Node
();
node
.
fontColor
=
self
.
config
.
nodeFontColor
;
// 节点坐标
node
.
setBound
((
event
.
layerX
?
event
.
layerX
:
event
.
offsetX
)
-
self
.
scene
.
translateX
-
self
.
config
.
nodeDefaultWidth
/
2
,
(
event
.
layerY
?
event
.
layerY
:
event
.
offsetY
)
-
self
.
scene
.
translateY
-
self
.
config
.
nodeDefaultHeight
/
2
,
self
.
config
.
nodeDefaultWidth
,
self
.
config
.
nodeDefaultHeight
);
// 节点图片
node
.
setImage
(
img
);
// 节点数据
node
.
nodeId
=
generateUUID
;
node
.
nodeType
=
nodeType
;
node
.
text
=
text
;
node
.
nodeImage
=
img
;
self
.
scene
.
add
(
node
);
self
.
currentNode
=
node
;
}
}
}
}
/**
* 保存序列化的拓扑图成json
*/
saveTopology
(
url
){
let
self
=
this
;
// 保存container状态
let
containers
=
this
.
getContainers
();
for
(
let
c
=
0
;
c
<
containers
.
length
;
c
++
)
{
let
temp
=
[];
let
nodes
=
containers
[
c
].
childs
;
for
(
let
n
=
0
;
n
<
nodes
.
length
;
n
++
)
{
if
(
nodes
[
n
]
instanceof
JTopo
.
Node
)
{
temp
.
push
(
nodes
[
n
].
nodeId
)
}
}
containers
[
c
].
childNodes
=
temp
.
join
(
','
)
}
// 获取json
let
topologyJSON
=
this
.
stage
.
toJson
();
console
.
log
(
topologyJSON
);
}
/**
* 重置拓扑图
*/
resetTopology
(){
}
/**
* 传入JSON形式的拓扑图数据,绘制拓扑图。如果数据结构不正确,返回空拓扑图
* @param topologyJson json形式的拓扑结构数据
* @param backImg 拓扑图的背景图片
*/
loadTopologyByJson
(
topologyJson
,
backImg
){
this
.
init
(
backImg
,
topologyJson
);
}
//工具方法
/**
* 清空所有节点
*/
deleteAllNodes
(){
this
.
stage
.
childs
.
forEach
(
s
=>
{
s
.
clear
();
});
this
.
beginNode
=
null
;
this
.
link
=
null
;
}
//编辑模式
editTopology
(){
this
.
stageMode
=
'edit'
;
console
.
log
(
this
);
}
//只读模式
normalTopology
(){
this
.
stageMode
=
'normal'
;
}
//添加节点
addNode
(
img
,
text
){
if
(
this
.
stageMode
===
'normal'
){
return
;
}
if
(
!
img
){
img
=
'icon_virtual_host.png'
;
//默认图片
}
if
(
!
text
){
text
=
'主机'
;
}
let
node
=
new
JTopo
.
Node
();
node
.
fontColor
=
this
.
config
.
nodeFontColor
;
//节点坐标
node
.
setBound
(
20
,
20
,
50
,
50
);
//默认图片
node
.
setImage
(
img
);
//节点数据
node
.
nodeId
=
generateUUID
;
node
.
text
=
text
;
node
.
nodeImage
=
img
;
this
.
scene
.
add
(
node
);
}
//获取所以容器的内容
getContainers
(){
let
containers
=
[];
this
.
stage
.
childs
.
forEach
(
(
s
)
=>
{
s
.
childs
.
forEach
((
n
)
=>
{
if
(
n
.
elementType
===
'container'
)
{
containers
.
push
(
n
)
}
})
});
return
containers
;
}
// 获取所有节点
getAllNodes
()
{
return
this
.
stage
.
find
(
'node'
);
}
// 获取所有选择的节点实例
getSelectedNodes
()
{
let
selectedNodes
=
[];
let
nodes
=
this
.
scene
.
selectedElements
;
nodes
.
forEach
(
(
n
)
=>
{
if
(
n
.
elementType
===
'node'
)
{
selectedNodes
.
push
(
n
)
}
});
return
selectedNodes
}
// 节点分组合并
toMerge
()
{
let
selectedNodes
=
this
.
getSelectedNodes
();
// 不指定布局的时候,容器的布局为自动(容器边界随元素变化)
let
container
=
new
JTopo
.
Container
();
container
.
textPosition
=
'Top_Center'
;
container
.
fontColor
=
this
.
config
.
nodeFontColor
;
container
.
borderColor
=
this
.
config
.
nodeBorderColor
;
container
.
borderRadius
=
this
.
config
.
nodeBorderRadius
;
this
.
scene
.
add
(
container
);
selectedNodes
.
forEach
(
(
n
)
=>
{
container
.
add
(
n
)
})
}
// 分组拆除
toSplit
()
{
if
(
this
.
currentNode
instanceof
JTopo
.
Container
)
{
this
.
currentNode
.
removeAll
();
this
.
scene
.
remove
(
this
.
currentNode
)
}
}
// 删除连线
deleteLine
()
{
if
(
this
.
currentNode
instanceof
JTopo
.
Link
)
{
this
.
scene
.
remove
(
this
.
currentNode
);
// if (this.currentNode.id)
// this.deleteNodeById(this.currentNode.id, "link");
this
.
currentNode
=
null
;
}
}
// 删除节点
deleteNode
(
n
)
{
this
.
scene
.
remove
(
n
);
// if (n.id)
// this.deleteNodeById(n.id, n.elementType, n.dataType);
this
.
currentNode
=
null
;
// 连线重置
this
.
beginNode
=
null
;
if
(
this
.
link
)
{
this
.
scene
.
remove
(
this
.
link
)
}
this
.
link
=
null
}
// 删除选择的节点
deleteSelectedNodes
()
{
if
(
this
.
stageMode
!==
'edit'
)
{
return
false
}
let
self
=
this
;
let
nodes
=
this
.
scene
.
selectedElements
;
if
(
nodes
&&
nodes
.
length
>
0
)
{
for
(
let
i
=
0
;
i
<
nodes
.
length
;
i
++
)
{
self
.
deleteNode
(
nodes
[
i
])
}
}
}
//设置
// 放大
scalingBig
()
{
if
(
this
.
currentNode
instanceof
JTopo
.
Node
)
{
this
.
currentNode
.
scaleX
+=
this
.
config
.
nodeScale
;
this
.
currentNode
.
scaleY
+=
this
.
config
.
nodeScale
;
}
else
{
this
.
stage
.
zoomOut
(
this
.
stage
.
wheelZoom
)
}
}
// 缩小
scalingSmall
()
{
if
(
this
.
currentNode
instanceof
JTopo
.
Node
)
{
this
.
currentNode
.
scaleX
-=
this
.
config
.
nodeScale
;
this
.
currentNode
.
scaleY
-=
this
.
config
.
nodeScale
}
else
{
this
.
stage
.
zoomIn
(
this
.
stage
.
wheelZoom
);
}
}
// 顺时针旋转
rotateAdd
()
{
if
(
this
.
currentNode
instanceof
JTopo
.
Node
)
{
this
.
currentNode
.
rotate
+=
this
.
config
.
nodeRotateValue
}
}
// 逆时针旋转
rotateSub
()
{
if
(
this
.
currentNode
instanceof
JTopo
.
Node
)
{
this
.
currentNode
.
rotate
-=
this
.
config
.
nodeRotateValue
}
}
// 清空编辑器
clearTopology
()
{
// 删除节点表对应的节点记录
this
.
deleteAllNodes
()
}
// 拓扑图预览
showPic
()
{
this
.
stage
.
saveImageInfo
()
}
exportAsImage
()
{
this
.
stage
.
exportAsImage
()
}
setEditMode
()
{
this
.
stageMode
=
'edit'
}
setNormalMode
()
{
this
.
stageMode
=
'normal'
}
// 复制节点
cloneNode
(
n
)
{
if
(
n
instanceof
JTopo
.
Node
)
{
let
newNode
=
new
JTopo
.
Node
();
n
.
serializedProperties
.
forEach
(
(
i
)
=>
{
// 只复制虚拟机的模板属性
// if (i == "templateId" && n.dataType != "VM") return true;
newNode
[
i
]
=
n
[
i
]
})
newNode
.
nodeId
=
generateUUID
;
newNode
.
alpha
=
this
.
config
.
nodeAlpha
;
newNode
.
strokeColor
=
this
.
config
.
nodeStrokeColor
;
newNode
.
fillColor
=
this
.
config
.
nodeFillColor
;
newNode
.
shadow
=
this
.
config
.
nodeShadow
;
newNode
.
shadowColor
=
this
.
config
.
nodeShadowColor
;
newNode
.
font
=
this
.
config
.
nodeFont
;
newNode
.
fontColor
=
this
.
config
.
nodeFontColor
;
newNode
.
borderRadius
=
null
;
newNode
.
layout
=
n
.
layout
;
newNode
.
selected
=
false
;
// var deviceNum = ++this.modeIdIndex;
// newNode.deviceId = "device" + deviceNum;
newNode
.
setLocation
(
n
.
x
+
n
.
width
,
n
.
y
+
n
.
height
);
newNode
.
text
=
n
.
text
;
newNode
.
setImage
(
n
.
image
);
this
.
scene
.
add
(
newNode
);
}
}
// 复制选择的节点
cloneSelectedNodes
()
{
let
self
=
this
;
let
nodes
=
this
.
scene
.
selectedElements
;
nodes
.
forEach
((
n
)
=>
{
if
(
n
.
elementType
===
'node'
)
{
self
.
cloneNode
(
n
)
}
})
}
// 全屏显示
showInFullScreen
(
element
,
method
)
{
let
usablePrefixMethod
;
[
'webkit'
,
'moz'
,
'ms'
,
'o'
,
''
].
forEach
(
(
prefix
)
=>
{
if
(
usablePrefixMethod
)
{
return
}
if
(
prefix
===
''
)
{
// 无前缀,方法首字母小写
// method = method.slice(0, 1).toLowerCase() + method.slice(1)
}
let
typePrefixMethod
=
typeof
element
[
prefix
+
method
];
if
(
typePrefixMethod
+
''
!==
'undefined'
)
{
if
(
typePrefixMethod
===
'function'
)
{
usablePrefixMethod
=
element
[
prefix
+
method
]();
}
else
{
usablePrefixMethod
=
element
[
prefix
+
method
];
}
}
}
)
return
usablePrefixMethod
}
// 居中显示
showInCenter
()
{
this
.
stage
.
centerAndZoom
()
}
// 根据指定的key返回节点实例
getNodeByKey
(
key
,
value
)
{
let
node
=
null
this
.
stage
.
childs
.
forEach
(
(
s
)
=>
{
s
.
childs
.
forEach
(
(
n
)
=>
{
if
(
n
.
elementType
===
'node'
&&
n
[
key
]
===
value
)
{
node
=
n
return
node
}
})
});
return
node
}
// 撤销对节点的操作
cancleNodeAction
()
{
if
(
this
.
currentNode
.
currStep
<=
0
)
{
return
}
--
this
.
currentNode
.
currStep
;
for
(
let
p
in
this
.
currentNode
)
{
if
(
p
!==
'currStep'
)
{
this
.
currentNode
[
p
]
=
(
this
.
currentNode
.
historyStack
[
this
.
currentNode
.
currStep
])[
p
]
}
}
}
// 重做节点操作
reMakeNodeAction
()
{
if
(
this
.
currentNode
.
currStep
>=
this
.
currentNode
.
maxHistoryStep
||
this
.
currentNode
.
currStep
>=
this
.
currentNode
.
historyStack
.
length
-
1
)
{
return
}
this
.
currentNode
.
currStep
++
for
(
let
q
in
this
.
currentNode
)
{
if
(
q
!==
'currStep'
)
{
this
.
currentNode
[
q
]
=
(
this
.
currentNode
.
historyStack
[
this
.
currentNode
.
currStep
])[
q
]
}
}
}
// 保存节点新的状态
saveNodeNewState
()
{
// 如果历史栈超过最大可记录历史长度,丢弃第一个元素
if
(
this
.
currentNode
.
historyStack
.
length
>=
this
.
currentNode
.
maxHistoryStep
+
1
)
{
this
.
currentNode
.
historyStack
.
shift
()
}
this
.
currentNode
.
historyStack
.
push
(
JTopo
.
util
.
clone
(
this
.
currentNode
))
this
.
currentNode
.
currStep
=
this
.
currentNode
.
historyStack
.
length
-
1
}
// 保存节点初始状态,便于回退
saveNodeInitState
()
{
if
(
!
this
.
currentNode
.
hasInitStateSaved
)
{
this
.
currentNode
.
historyStack
.
push
(
JTopo
.
util
.
clone
(
this
.
currentNode
))
this
.
currentNode
.
hasInitStateSaved
=
true
}
}
// 取消出参数节点外所有节点的选中状态
unSelectAllNodeExcept
(
node
)
{
this
.
stage
.
childs
.
forEach
(
(
s
)
=>
{
s
.
childs
.
forEach
(
(
n
)
=>
{
// id属性无有效值,说明该节点没有保存到数据库
if
(
n
.
nodeId
!==
node
.
nodeId
)
{
n
.
selected
=
false
}
})
})
}
}
export
class
generateUUID
{
constructor
(){
let
d
=
new
Date
().
getTime
();
let
uuid
=
'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'
.
replace
(
/
[
xy
]
/g
,
(
c
)
=>
{
let
r
=
(
d
+
Math
.
random
()
*
16
)
%
16
|
0
;
d
=
Math
.
floor
(
d
/
16
);
return
(
c
===
'x'
?
r
:
(
r
&
0x3
|
0x8
)).
toString
(
16
)
});
return
uuid
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment