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
fd9e315f
Commit
fd9e315f
authored
Jan 04, 2019
by
wangqinghua
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
重构 jtopo
parent
3aa3544f
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
729 additions
and
0 deletions
+729
-0
jtopo.component.html
src/main/webapp/app/jtopo/jtopo.component.html
+66
-0
jtopo.component.ts
src/main/webapp/app/jtopo/jtopo.component.ts
+663
-0
No files found.
src/main/webapp/app/jtopo/jtopo.component.html
0 → 100644
View file @
fd9e315f
<div
class=
"layui-layout layui-layout-admin"
>
<div
class=
"layui-header header-bar"
>
<span
(
click
)="
addDevice
()"
>
添加设备
</span>
<span
(
click
)="
addCheck
()"
>
添加监测点
</span>
<span
(
click
)="
showAddImg
()"
>
添加图片
</span>
<span
onClick=
"editor.utils.deleteSelectedNodes()"
>
移除
</span>
<!-- 顶部工具栏 -->
<div
class=
"layui-nav layui-layout-right"
style=
"color: #6097b7"
>
<span
aria-hidden=
"true"
title=
"全屏查看"
onClick=
"editor.utils.showInFullScreen(editor.stage.canvas,'RequestFullScreen')"
>
全屏查看
</span>
<span
aria-hidden=
"true"
title=
"居中显示"
onClick=
"editor.utils.showInCenter()"
>
居中显示
</span>
<span
aria-hidden=
"true"
title=
"保存"
(
click
)="
update
()"
>
保存
</span>
<span
aria-hidden=
"true"
title=
"清空"
onClick=
"editor.utils.clearTopology()"
>
清空
</span>
<span
aria-hidden=
"true"
title=
"放大"
onClick=
"editor.utils.scalingBig()"
>
放大
</span>
<span
caria-hidden=
"true"
title=
"缩小"
onClick=
"editor.utils.scalingSmall()"
>
缩小
</span>
</div>
</div>
<div
class=
"container"
>
<div
class=
"layui-row"
>
<div
class=
"layui-col-md12"
>
<div
#
topologyBody
id=
"topology-body"
class=
"topology-context"
>
<!-- 鼠标悬浮显示节点信息 -->
<div
class=
"node-infobox"
style=
"display: none;"
>
<span>
节点名称:
<label
name=
"node_name"
></label></span>
<span>
当前时间:
<label
name=
"current_time"
></label></span>
</div>
<canvas
class=
"topology-context"
id=
"topology-canvas"
#
topologyCanvas
style=
"height: 580px;"
>
您的浏览器不支持HTML5!
</canvas>
<div
class=
"checkList"
>
<p
*
ngFor=
"let item of checkJson;let i = index;"
>
<span
[
style
.
fontSize
]="
item
.
fontSize
+'
px
'"
>
{{item.name}}
</span><i
(
click
)="
deleteCheck
(
i
)"
class=
"minus anticon anticon-minus-circle-o"
></i>
</p>
</div>
</div>
</div>
</div>
</div>
</div>
<!--添加图片-->
<nz-modal
[(
nzVisible
)]="
isDevice
"
nzTitle=
"添加图片"
(
nzOnCancel
)="
handleCancel
()"
(
nzOnOk
)="
handleOk
()"
>
<form
nz-form
>
<nz-form-item>
<nz-form-label
[
nzSpan
]="
7
"
nzRequired
nzFor=
"group"
>
选择图片
</nz-form-label>
<nz-form-control
[
nzSpan
]="
12
"
>
<input
nz-input
type=
"text"
>
</nz-form-control>
</nz-form-item>
</form>
</nz-modal>
<!--添加拓扑图-->
<smart-topology
#
smartTopology
(
done
)="
getList
()"
></smart-topology>
<!--添加监测点-->
<smart-check
#
smartCheck
(
done
)="
setCheckList
($
event
)"
></smart-check>
<!--选择资源-->
<smart-select-group
#
smartSelectGroup
(
done
)="
setImg
($
event
)"
></smart-select-group>
\ No newline at end of file
src/main/webapp/app/jtopo/jtopo.component.ts
0 → 100644
View file @
fd9e315f
import
{
Component
,
ElementRef
,
OnInit
,
ViewChild
}
from
'@angular/core'
;
declare
let
editor
:
any
;
declare
let
JTopo
:
any
;
@
Component
({
selector
:
'smart-jtopo'
,
templateUrl
:
'./jtopo.component.html'
,
styles
:
[
`
.layui-side-scroll {
width: initial;
}
.layui-layout-right {
color: #666666;
}
.layui-header span {
margin-right: 15px;
cursor: pointer;
}
.header-bar {
line-height: 60px;
color: #6097b7;
padding: 0 20px;
background-color: #ddd;
}
.tips {
position: absolute;
top: 10px;
left: 20px;
color: #ca0814;
font-size: 20px;
}
.checkList {
position: absolute;
top: 10px;
right: 20px;
color: #666666;
font-size: 20px;
}
.layui-form-label {
width: 110px;
}
.minus {
vertical-align: middle;
color: red;
font-size: 15px;
margin-left: 12px;
cursor: pointer;
}
`
]
})
export
class
JtopoComponent
implements
OnInit
{
@
ViewChild
(
'topologyCanvas'
)
topologyCanvas
:
ElementRef
;
@
ViewChild
(
'topologyBody'
)
topologyBody
:
ElementRef
;
isDevice
=
false
;
config
;
// 布局参数
layout
=
{};
// 绘图区属性
stage
=
null
;
scene
=
null
;
// 当前模式
stageMode
=
'normal'
;
// 默认连线类型
lineType
=
'line'
;
// 当前选择的节点对象
currentNode
=
null
;
// 当前选择的连线对象
currentLink
=
null
;
topologyGuid
;
tempNodeA
;
tempNodeZ
;
beginNode
;
link
;
constructor
()
{
}
ngOnInit
()
{
this
.
initTopologyPanel
();
}
initTopologyPanel
()
{
let
initTopologyJson
=
{
'version'
:
'0.4.8'
,
'wheelZoom'
:
0.95
,
'width'
:
972
,
'height'
:
569
,
'id'
:
'ST172.19.105.52015100809430700001'
,
'childs'
:
[
{
'elementType'
:
'scene'
,
'id'
:
'S172.19.105.52015100809430700002'
,
'translateX'
:
-
121.82
,
'translateY'
:
306.72
,
'scaleX'
:
1.26
,
'scaleY'
:
1.26
,
'childs'
:
[]
}
]
};
editor
.
init
(
''
,
'img/backimg.png'
,
initTopologyJson
,
''
);
}
TopologyEditor
()
{
this
.
config
=
{
// Stage属性
stageFrames
:
500
,
// 舞台播放的帧数/秒
defaultScal
:
0.95
,
// 鼠标滚轮缩放比例
eagleEyeVsibleDefault
:
false
,
// 是否显示鹰眼对象
// Node属性
nodeAlpha
:
1
,
// 节点透明度,取值范围[0-1]
nodeStrokeColor
:
'22,124,255'
,
// 节点描边的颜色
nodeFillColor
:
'22,124,255'
,
// 节点填充颜色
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
:
'123,165,241'
,
// 连线的颜色
linkFillColor
:
'123,165,241'
,
linkShadow
:
false
,
// 是否显示连线阴影
linkShadowColor
:
'rgba(0,0,0,0.5)'
,
linkFont
:
'12px Consolas'
,
// 节点字体
linkFontColor
:
'black'
,
// 连线文字颜色,如"255,255,0"
linkArrowsRadius
:
0
,
// 线条箭头半径
linkDefaultWidth
:
3
,
// 连线宽度
linkOffsetGap
:
40
,
// 折线拐角处的长度
linkDirection
:
'horizontal'
,
// 折线的方向 竖直 vertical 水平 horizontal
// 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
};
// 布局参数
this
.
layout
=
{};
// 绘图区属性
this
.
stage
=
null
;
this
.
scene
=
null
;
// 当前模式
this
.
stageMode
=
'normal'
;
// 默认连线类型
this
.
lineType
=
'line'
;
// 当前选择的节点对象
this
.
currentNode
=
null
;
// 当前选择的连线对象
this
.
currentLink
=
null
;
}
// 拓扑图初始化
initCanvas
(
topologyGuid
,
backImg
,
topologyJson
)
{
if
(
!
topologyJson
)
{
// alert('加载拓扑编辑器失败!')
return
;
}
this
.
topologyGuid
=
topologyGuid
;
// 创建jTopo舞台屏幕对象
let
canvas
=
this
.
topologyCanvas
.
nativeElement
;
canvas
.
width
=
this
.
topologyBody
.
nativeElement
.
width
();
canvas
.
height
=
this
.
topologyBody
.
nativeElement
.
height
();
// 加载空白的编辑器
if
(
topologyJson
===
'-1'
)
{
this
.
stage
=
new
JTopo
.
Stage
(
canvas
);
// 定义舞台对象
this
.
scene
=
new
JTopo
.
Scene
(
this
.
stage
);
// 定义场景对象
}
else
{
this
.
stage
=
JTopo
.
createStageFromJson
(
topologyJson
,
canvas
);
// 根据保存好的jsonStr(拓扑结构)创建舞台对象
this
.
scene
=
this
.
stage
.
childs
[
0
];
// 场景对象列表,childs是舞台的属性
}
// 滚轮缩放
this
.
stage
.
frames
=
this
.
config
.
stageFrames
;
// 设置当前舞台播放的帧数/秒
this
.
stage
.
wheelZoom
=
this
.
config
.
defaultScal
;
// 鼠标滚轮缩放操作比例
this
.
stage
.
eagleEye
.
visible
=
this
.
config
.
eagleEyeVsibleDefault
;
// 是否开启鹰眼
this
.
stage
.
mode
=
this
.
stageMode
;
// 设置舞台模式
// 背景由样式指定
// this.scene.background = backImg;
// 用来连线的两个节点
this
.
tempNodeA
=
new
JTopo
.
Node
(
'tempA'
);
this
.
tempNodeA
.
setSize
(
1
,
1
);
this
.
tempNodeZ
=
new
JTopo
.
Node
(
'tempZ'
);
this
.
tempNodeZ
.
setSize
(
1
,
1
);
this
.
beginNode
=
null
;
this
.
link
=
null
;
let
self
=
this
;
// 模拟告警
// editor.utils.getAllNodes()[0].alarm = '告警';
// 鼠标进入事件
this
.
scene
.
mouseover
(
function
(
event
)
{
Timer
.
start
();
// 进入某个节点
if
(
event
.
target
!=
null
&&
event
.
target
instanceof
JTopo
.
Node
&&
event
.
target
.
nodeTooltip
&&
editor
.
stageMode
!==
'edit'
)
{
// $('.node-tooltip span').html(event.target.nodeTooltip);
// 记录鼠标触发位置在canvas中的相对位置
let
menuY
=
event
.
layerY
?
event
.
layerY
:
event
.
offsetY
;
let
menuX
=
event
.
layerX
?
event
.
layerX
:
event
.
offsetX
;
// 判断边界出是否能完整显示弹出菜单
if
(
menuX
+
$
(
'.node-tooltip'
).
width
()
>=
self
.
stage
.
width
)
{
menuX
-=
$
(
'.node-tooltip'
).
width
();
}
if
(
menuY
+
$
(
'.node-tooltip'
).
height
()
>=
self
.
stage
.
height
)
{
menuY
-=
$
(
'.node-tooltip'
).
height
();
}
$
(
'.link-tooltip'
).
css
(
'display'
,
'none'
);
$
(
'.node-tooltip'
).
css
({
'display'
:
'block'
,
'margin-top'
:
menuY
,
'margin-left'
:
menuX
,
'cursor'
:
'pointer'
});
// 进入某个连线
}
else
if
(
event
.
target
!=
null
&&
event
.
target
instanceof
JTopo
.
Link
&&
event
.
target
.
linkTooltip
&&
editor
.
stageMode
!==
'edit'
)
{
$
(
'.link-tooltip span'
).
html
(
event
.
target
.
linkTooltip
);
// 记录鼠标触发位置在canvas中的相对位置
let
menuY
=
event
.
layerY
?
event
.
layerY
:
event
.
offsetY
;
let
menuX
=
event
.
layerX
?
event
.
layerX
:
event
.
offsetX
;
// 判断边界出是否能完整显示弹出菜单
if
(
menuX
+
$
(
'.link-tooltip'
).
width
()
>=
self
.
stage
.
width
)
{
menuX
-=
$
(
'.link-tooltip'
).
width
();
}
if
(
menuY
+
$
(
'.link-tooltip'
).
height
()
>=
self
.
stage
.
height
)
{
menuY
-=
$
(
'.link-tooltip'
).
height
();
}
$
(
'.node-tooltip'
).
css
(
'display'
,
'none'
);
$
(
'.link-tooltip'
).
css
({
'display'
:
'block'
,
'margin-top'
:
menuY
,
'margin-left'
:
menuX
,
'cursor'
:
'pointer'
});
}
else
{
// 鼠标进入别的地方
}
});
// 鼠标离开事件
this
.
scene
.
mouseout
(
function
(
event
)
{
let
timeSpan
=
Timer
.
pause
();
// 消抖
if
(
timeSpan
>
100
)
{
$
(
'.node-tooltip'
).
css
(
'display'
,
'none'
);
$
(
'.link-tooltip'
).
css
(
'display'
,
'none'
);
Timer
.
stop
();
}
});
// 鼠标单击节点事件
this
.
scene
.
click
(
function
(
event
)
{
if
(
!
event
.
target
)
{
// 单击舞台空白处
$
(
'.node-tooltip'
).
css
(
'display'
,
'none'
);
return
;
}
self
.
currentNode
=
event
.
target
;
// 只读模式下单击节点
if
(
event
.
target
instanceof
JTopo
.
Node
&&
editor
.
stageMode
===
'normal'
)
{
console
.
log
(
self
.
currentNode
);
}
else
if
(
event
.
target
instanceof
JTopo
.
Node
&&
editor
.
stageMode
===
'edit'
)
{
console
.
log
(
self
.
currentNode
);
}
else
if
(
event
.
target
instanceof
JTopo
.
Link
&&
editor
.
stageMode
===
'normal'
)
{
console
.
log
(
self
.
currentNode
);
}
else
if
(
event
.
target
instanceof
JTopo
.
Link
&&
editor
.
stageMode
===
'edit'
)
{
console
.
log
(
self
.
currentNode
);
}
else
{
// 单击别的地方
$
(
'.node-tooltip'
).
css
(
'display'
,
'none'
);
}
});
// 双击编辑事件
this
.
scene
.
dbclick
(
function
(
event
)
{
if
(
!
event
.
target
)
{
// 单击舞台空白处
$
(
'.node-tooltip'
).
css
(
'display'
,
'none'
);
return
;
}
self
.
currentNode
=
event
.
target
;
// 只处理双击节点事件
if
(
event
.
target
instanceof
JTopo
.
Node
&&
editor
.
stageMode
===
'edit'
)
{
console
.
log
(
event
.
target
);
// alert('双击了节点')
// 查询单个节点的信息, 回填数据
layer
.
open
({
title
:
'编辑设备'
,
type
:
1
,
area
:
[
'600px'
,
'500px'
],
content
:
$
(
'#node-dialog'
),
btn
:
[
'应用'
,
'删除'
,
'取消'
],
yes
:
function
(
index
,
layero
)
{
let
param
=
getParam
(
'node-form'
);
self
.
currentNode
.
text
=
param
.
text
;
self
.
currentNode
.
textPosition
=
param
.
textPosition
;
self
.
currentNode
.
setLocation
(
param
.
x
,
param
.
y
);
},
btn2
:
function
()
{
editor
.
utils
.
deleteNode
(
self
.
currentNode
);
}
});
}
else
if
(
event
.
target
instanceof
JTopo
.
Link
&&
editor
.
stageMode
===
'edit'
)
{
layer
.
open
({
title
:
'编辑线'
,
type
:
1
,
area
:
[
'600px'
,
'500px'
],
content
:
$
(
'#link-dialog'
),
btn
:
[
'应用'
,
'删除'
,
'取消'
],
yes
:
function
(
index
,
layero
)
{
let
param
=
getParam
(
'link-form'
);
self
.
currentNode
.
text
=
param
.
text
;
self
.
currentNode
.
textPosition
=
param
.
textPosition
;
self
.
currentNode
.
setLocation
(
param
.
x
,
param
.
y
);
},
btn2
:
function
()
{
editor
.
utils
.
deleteNode
(
self
.
currentNode
);
}
});
}
});
// 清除起始节点不完整的拖放线
this
.
scene
.
mousedown
(
function
(
e
)
{
if
(
self
.
link
&&
!
self
.
isSelectedMode
&&
(
e
.
target
==
null
||
e
.
target
===
self
.
beginNode
||
e
.
target
===
self
.
link
))
{
this
.
remove
(
self
.
link
);
}
});
// 监听鼠标松开事件
// 处理右键菜单、左键连线
// event.button: 0-左键 1-中键 2-右键
this
.
scene
.
mouseup
(
function
(
event
)
{
if
(
event
.
target
&&
event
.
target
instanceof
JTopo
.
Node
)
{
self
.
currentNode
=
event
.
target
;
}
else
if
(
event
.
target
&&
event
.
target
instanceof
JTopo
.
Link
)
{
self
.
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
===
2
)
{
// 右键菜单
$
(
'div[id$=
\'
-menu
\'
]'
).
hide
();
let
menuY
=
event
.
layerY
?
event
.
layerY
:
event
.
offsetY
;
let
menuX
=
event
.
layerX
?
event
.
layerX
:
event
.
offsetX
;
// 记录鼠标触发位置在canvas中的相对位置
self
.
xInCanvas
=
menuX
;
self
.
yInCanvas
=
menuY
;
if
(
event
.
target
)
{
if
(
event
.
target
instanceof
JTopo
.
Node
)
{
// 处理节点右键菜单事件
let
selectedNodes
=
self
.
utils
.
getSelectedNodes
();
// 如果是节点多选状态弹出分组菜单
if
(
selectedNodes
&&
selectedNodes
.
length
>
1
)
{
// 判断边界出是否能完整显示弹出菜单
if
(
menuX
+
self
.
groupMangeMenu
.
width
()
>=
self
.
stage
.
width
)
{
menuX
-=
self
.
groupMangeMenu
.
width
();
}
if
(
menuY
+
self
.
groupMangeMenu
.
height
()
>=
self
.
stage
.
height
)
{
menuY
-=
self
.
groupMangeMenu
.
height
();
}
self
.
groupMangeMenu
.
css
({
top
:
menuY
,
left
:
menuX
}).
show
();
}
else
{
// 判断边界出是否能完整显示弹出菜单
if
(
menuX
+
self
.
nodeMenu
.
width
()
>=
self
.
stage
.
width
)
{
menuX
-=
self
.
nodeMenu
.
width
();
}
if
(
menuY
+
self
.
nodeMenu
.
height
()
>=
self
.
stage
.
height
)
{
menuY
-=
self
.
nodeMenu
.
height
();
}
self
.
nodeMenu
.
css
({
top
:
menuY
,
left
:
menuX
}).
show
();
}
}
else
if
(
event
.
target
instanceof
JTopo
.
Link
)
{
// 连线右键菜单
self
.
lineMenu
.
css
({
top
:
event
.
layerY
?
event
.
layerY
:
event
.
offsetY
,
left
:
event
.
layerX
?
event
.
layerX
:
event
.
offsetX
}).
show
();
}
else
if
(
event
.
target
instanceof
JTopo
.
Container
)
{
// 容器右键菜单
self
.
containerMangeMenu
.
css
({
top
:
event
.
layerY
?
event
.
layerY
:
event
.
offsetY
,
left
:
event
.
layerX
?
event
.
layerX
:
event
.
offsetX
}).
show
();
}
}
else
{
// 判断边界出是否能完整显示弹出菜单
if
(
menuX
+
self
.
mainMenu
.
width
()
>=
self
.
stage
.
width
)
{
menuX
-=
self
.
mainMenu
.
width
();
}
if
(
menuY
+
self
.
mainMenu
.
height
()
>=
self
.
stage
.
height
)
{
menuY
-=
self
.
mainMenu
.
height
();
}
self
.
mainMenu
.
css
({
top
:
menuY
,
left
:
menuX
}).
show
();
}
}
else
if
(
event
.
button
===
1
)
{
// 中键
}
else
if
(
event
.
button
===
0
)
{
// 左键松开事件
if
(
event
.
target
!=
null
&&
event
.
target
instanceof
JTopo
.
Node
&&
!
self
.
isSelectedMode
&&
editor
.
stageMode
===
'edit'
)
{
if
(
self
.
beginNode
==
null
)
{
// 在起始节点处松开鼠标,创建动态的线条(临时节点A-Z)
self
.
beginNode
=
event
.
target
;
if
(
self
.
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
.
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
;
// 判断两个节点是否有循环引用
/** ***************** 我这里允许循环引用 *************************
for (var el = 0; el < endNode.outLinks.length; el++) {
// 存在循环引用,线条变红
if (endNode.outLinks[el].nodeZ === self.beginNode) {
if (self.link)
this.remove(self.link);
self.beginNode = null;
return;
}
}
*****************************************************************/
// 判断节点间是否有重复连线,即起点到终点有两条以上连线
/** ***************** 我这里允许它有两条连线 *************************
for (var el2 = 0; el2 < self.beginNode.outLinks.length; el2++) {
// 起始节点已经有一条线指向目标节点
if (self.beginNode.outLinks[el2].nodeZ === endNode) {
if (self.link)
this.remove(self.link);
self.beginNode = null;
return;
}
}
*****************************************************************/
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
;
this
.
add
(
link
);
self
.
beginNode
=
null
;
this
.
remove
(
self
.
link
);
self
.
link
=
null
;
}
else
{
self
.
beginNode
=
null
;
}
}
else
{
if
(
self
.
link
)
{
this
.
remove
(
self
.
link
);
}
self
.
beginNode
=
null
;
}
}
});
// 动态更新连线坐标(创建连线时的临时节点A-Z)
this
.
scene
.
mousemove
(
function
(
event
)
{
if
(
!
self
.
isSelectedMode
&&
self
.
beginNode
)
{
self
.
tempNodeZ
.
setLocation
(
event
.
x
,
event
.
y
);
}
});
this
.
scene
.
mousedrag
(
function
(
event
)
{
if
(
!
self
.
isSelectedMode
&&
self
.
beginNode
)
{
self
.
tempNodeZ
.
setLocation
(
event
.
x
,
event
.
y
);
}
});
// 单击编辑器隐藏右键菜单
this
.
stage
.
click
(
function
(
event
)
{
if
(
event
.
button
===
0
)
{
// 关闭弹出菜单(div)
$
(
'div[id$=
\'
-menu
\'
]'
).
hide
();
}
});
// 鼠标移出舞台
this
.
stage
.
mouseout
(
function
(
event
)
{
// 删掉节点带出来的连线
if
(
self
.
link
&&
!
self
.
isSelectedMode
&&
(
event
.
target
==
null
||
event
.
target
===
self
.
beginNode
||
event
.
target
===
self
.
link
))
{
self
.
scene
.
remove
(
self
.
link
);
}
});
// 按下ctrl进入多选模式,此时选择节点不能画线
$
(
document
).
keydown
(
function
(
e
)
{
if
(
e
.
shiftKey
)
{
// 组合键模式
switch
(
e
.
which
)
{
// 放大 ctrl+=
case
187
:
case
61
:
// 单个节点可以撤销操作
if
(
editor
.
currentNode
instanceof
JTopo
.
Node
)
{
// 保存初始状态
editor
.
utils
.
saveNodeInitState
();
editor
.
utils
.
scalingBig
();
editor
.
utils
.
saveNodeNewState
();
}
else
{
editor
.
utils
.
scalingBig
();
}
break
;
// 缩小 ctrl+-
case
189
:
case
173
:
if
(
editor
.
currentNode
instanceof
JTopo
.
Node
)
{
// 保存初始状态
editor
.
utils
.
saveNodeInitState
();
editor
.
utils
.
scalingSmall
();
editor
.
utils
.
saveNodeNewState
();
}
else
{
editor
.
utils
.
scalingSmall
();
}
break
;
case
70
:
// ctrl+f 全屏显示
editor
.
utils
.
showInFullScreen
(
editor
.
stage
.
canvas
,
'RequestFullScreen'
);
break
;
case
72
:
// h 帮助
// alert('帮助文档')
break
;
case
71
:
// ctrl+g 居中显示
editor
.
utils
.
showInCenter
();
break
;
case
73
:
// shif+I 逆时针旋转
if
(
editor
.
currentNode
instanceof
JTopo
.
Node
)
{
editor
.
utils
.
saveNodeInitState
();
editor
.
utils
.
rotateSub
();
editor
.
utils
.
saveNodeNewState
();
}
break
;
case
67
:
editor
.
utils
.
cloneSelectedNodes
();
break
;
case
80
:
// ctrl + p
editor
.
utils
.
showPic
();
break
;
case
82
:
// 单个节点重做
if
(
editor
.
currentNode
instanceof
JTopo
.
Node
)
{
editor
.
utils
.
reMakeNodeAction
();
}
break
;
case
83
:
// ctrl+s 保存
editor
.
saveTopology
(
true
);
break
;
case
85
:
// shif+U 顺时针旋转
if
(
editor
.
currentNode
instanceof
JTopo
.
Node
)
{
editor
.
utils
.
saveNodeInitState
();
editor
.
utils
.
rotateAdd
();
editor
.
utils
.
saveNodeNewState
();
}
break
;
case
87
:
// alert('ctrl + w 另存为')
break
;
case
89
:
// ctrl+y
editor
.
utils
.
clearTopology
();
break
;
case
90
:
// 单个节点撤销
if
(
editor
.
currentNode
instanceof
JTopo
.
Node
)
{
editor
.
utils
.
cancleNodeAction
();
}
break
;
}
}
else
if
(
e
.
which
===
46
)
{
// 单独按下delete
editor
.
utils
.
deleteSelectedNodes
();
}
else
if
(
e
.
which
===
17
)
{
// 单独按下ctrl
self
.
isSelectedMode
=
true
;
}
});
$
(
document
).
keyup
(
function
(
e
)
{
if
(
e
.
which
===
17
)
{
self
.
isSelectedMode
=
false
;
return
false
;
}
});
// 第一次进入拓扑编辑器,生成stage和scene对象
if
(
topologyJson
===
'-1'
)
{
this
.
saveTopology
(
false
);
}
}
}
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