Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
V
vue-gojs
Overview
Overview
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
吴斌
vue-gojs
Commits
3c4cf820
Commit
3c4cf820
authored
Oct 30, 2023
by
吴斌
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
update:优化连线路径
parent
e5012b0e
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
299 additions
and
17 deletions
+299
-17
App.vue
src/App.vue
+49
-14
LinkTemplateKit.ts
src/kit/LinkTemplateKit.ts
+14
-3
PolylineLinkingTool.ts
src/kit/extensions/PolylineLinkingTool.ts
+236
-0
No files found.
src/App.vue
View file @
3c4cf820
...
@@ -3,7 +3,7 @@
...
@@ -3,7 +3,7 @@
<div
id=
"tool-bar"
class=
"pl-1 pr-1 bg-white h-10 flex items-center space-x-1 border-0.5 border-gray-500 border-solid rounded-t-[8px] p-1"
>
<div
id=
"tool-bar"
class=
"pl-1 pr-1 bg-white h-10 flex items-center space-x-1 border-0.5 border-gray-500 border-solid rounded-t-[8px] p-1"
>
<el-button
text
icon=
"Setting"
></el-button>
<el-button
text
icon=
"Setting"
></el-button>
<div
class=
"flex-1"
></div>
<div
class=
"flex-1"
></div>
<el-radio-group
v-model=
"diagramConfig.mode"
@
change=
"
diagramModeChanged
"
>
<el-radio-group
v-model=
"diagramConfig.mode"
@
change=
"
freshDiagramConfig
"
>
<el-radio-button
label=
"readonly"
>
<el-radio-button
label=
"readonly"
>
<template
#
default
>
<template
#
default
>
<el-icon>
<el-icon>
...
@@ -56,7 +56,7 @@
...
@@ -56,7 +56,7 @@
<div
id=
"inspector-property"
></div>
<div
id=
"inspector-property"
></div>
<el-divider
direction=
"horizontal"
></el-divider>
<el-divider
direction=
"horizontal"
></el-divider>
</div>
</div>
<div
v-show=
"ifSelectNode"
class=
"flex flex-col w-full"
>
<div
v-show=
"ifSelectNode"
class=
"flex flex-col w-full"
v-if=
"selectedNode"
>
<div
class=
"text-[16px] font-bold text-black"
>
端口
</div>
<div
class=
"text-[16px] font-bold text-black"
>
端口
</div>
<div
v-for=
"port in nodePortArray"
>
<div
v-for=
"port in nodePortArray"
>
<div
class=
"flex flex-row space-x-0"
@
mouseenter=
"highlightPort(port['portId'], true)"
@
mouseleave=
"highlightPort(port['portId'], false)"
>
<div
class=
"flex flex-row space-x-0"
@
mouseenter=
"highlightPort(port['portId'], true)"
@
mouseleave=
"highlightPort(port['portId'], false)"
>
...
@@ -183,10 +183,12 @@ import {uuid} from "vue3-uuid";
...
@@ -183,10 +183,12 @@ import {uuid} from "vue3-uuid";
import
{
SnapLinkReshapingTool
}
from
"./kit/extensions/SnapLinkReshapingTool.ts"
;
import
{
SnapLinkReshapingTool
}
from
"./kit/extensions/SnapLinkReshapingTool.ts"
;
import
{
Edit
,
View
}
from
"@element-plus/icons-vue"
;
import
{
Edit
,
View
}
from
"@element-plus/icons-vue"
;
import
{
ElMessage
}
from
"element-plus"
;
import
{
ElMessage
}
from
"element-plus"
;
import
{
PolylineLinkingTool
}
from
"./kit/extensions/PolylineLinkingTool.ts"
;
// 变量定义
// region
// 图表配置
// 图表配置
const
diagramConfig
=
ref
({
const
diagramConfig
=
ref
<
Record
<
string
,
any
>>
({
mode
:
"
readonly
"
,
mode
:
"
edit
"
,
})
})
// 是否模拟实时数据
// 是否模拟实时数据
...
@@ -244,6 +246,7 @@ const analyzePathsName = ref<Record<string, any>[][]>([])
...
@@ -244,6 +246,7 @@ const analyzePathsName = ref<Record<string, any>[][]>([])
// let inputSearchNode = ref('')
// let inputSearchNode = ref('')
// 用于计算源区域的滚动条区域高度
// 用于计算源区域的滚动条区域高度
let
nodeAreaHeight
=
ref
()
let
nodeAreaHeight
=
ref
()
// endregion
onMounted
(()
=>
{
onMounted
(()
=>
{
getNodeSourceScrollAreaHeight
()
getNodeSourceScrollAreaHeight
()
...
@@ -253,13 +256,13 @@ onMounted(()=>{
...
@@ -253,13 +256,13 @@ onMounted(()=>{
changeDataRealTime
()
changeDataRealTime
()
})
})
// 为了在页面大小变化时,让节点区域的滚动条区域高度自适应
function
getNodeSourceScrollAreaHeight
(
){
function
changeDiagramConfig
(
key
:
string
,
value
:
string
){
// 滚动区域高度为浏览器窗口高度 - 144px(固定的上方ToolBar + 本页面的输入框和最下方的按钮)
diagramConfig
.
value
[
key
]
=
value
nodeAreaHeight
.
value
=
window
.
innerHeight
-
144
+
'px'
freshDiagramConfig
()
}
}
function
diagramModeChanged
(){
function
freshDiagramConfig
(){
let
mode
=
diagramConfig
.
value
.
mode
let
mode
=
diagramConfig
.
value
.
mode
if
(
mode
===
'readonly'
){
if
(
mode
===
'readonly'
){
myDiagram
.
isReadOnly
=
true
myDiagram
.
isReadOnly
=
true
...
@@ -268,11 +271,13 @@ function diagramModeChanged(){
...
@@ -268,11 +271,13 @@ function diagramModeChanged(){
}
}
}
}
function
exportData
(){
console
.
log
(
myDiagram
.
model
.
toJson
())
}
// tool-bar 相关函数
// 素材区相关函数
// region
// endregion
// Toolbar 相关函数
// region
function
importData
(){
function
importData
(){
let
json
=
{
"class"
:
"GraphLinksModel"
,
let
json
=
{
"class"
:
"GraphLinksModel"
,
"copiesArrays"
:
true
,
"copiesArrays"
:
true
,
...
@@ -319,13 +324,21 @@ function importData(){
...
@@ -319,13 +324,21 @@ function importData(){
{
"from"
:
-
11
,
"to"
:
-
10
,
"fromPort"
:
"ec58dcb4-39fb-400e-bb0e-018ecee51d56"
,
"toPort"
:
"ba564564-2ac8-48da-a430-3af06ea4997d"
,
"category"
:
"Arrow"
,
'highlightColor'
:
'red'
,
'color'
:
'black'
,
"points"
:[
220
,
-
733.25
,
220
,
-
743.25
,
92.125
,
-
743.25
,
92.125
,
-
401.25
,
58.25
,
-
401.25
,
48.25
,
-
401.25
]}
{
"from"
:
-
11
,
"to"
:
-
10
,
"fromPort"
:
"ec58dcb4-39fb-400e-bb0e-018ecee51d56"
,
"toPort"
:
"ba564564-2ac8-48da-a430-3af06ea4997d"
,
"category"
:
"Arrow"
,
'highlightColor'
:
'red'
,
'color'
:
'black'
,
"points"
:[
220
,
-
733.25
,
220
,
-
743.25
,
92.125
,
-
743.25
,
92.125
,
-
401.25
,
58.25
,
-
401.25
,
48.25
,
-
401.25
]}
]}
]}
myDiagram
.
model
=
go
.
Model
.
fromJson
(
json
)
myDiagram
.
model
=
go
.
Model
.
fromJson
(
json
)
changeDiagramConfig
(
'mode'
,
'readonly'
)
}
function
exportData
(){
console
.
log
(
myDiagram
.
model
.
toJson
())
}
}
function
saveData
(){
function
saveData
(){
console
.
log
(
selectedNode
.
value
)
console
.
log
(
selectedNode
.
value
)
}
}
// endregion
// diagram 部分
// diagram 部分
// region
function
initDiagram
(){
function
initDiagram
(){
myDiagram
=
GO
(
go
.
Diagram
,
"myDiagram"
,
{
myDiagram
=
GO
(
go
.
Diagram
,
"myDiagram"
,
{
initialContentAlignment
:
go
.
Spot
.
Center
,
initialContentAlignment
:
go
.
Spot
.
Center
,
...
@@ -360,6 +373,7 @@ function initDiagram(){
...
@@ -360,6 +373,7 @@ function initDiagram(){
GO
(
go
.
Shape
,
"Diamond"
,
{
segmentIndex
:
0
,
cursor
:
"pointer"
,
desiredSize
:
new
go
.
Size
(
8
,
8
),
fill
:
"tomato"
,
stroke
:
"darkred"
}),
GO
(
go
.
Shape
,
"Diamond"
,
{
segmentIndex
:
0
,
cursor
:
"pointer"
,
desiredSize
:
new
go
.
Size
(
8
,
8
),
fill
:
"tomato"
,
stroke
:
"darkred"
}),
"relinkingTool.toHandleArchetype"
:
"relinkingTool.toHandleArchetype"
:
GO
(
go
.
Shape
,
"Diamond"
,
{
segmentIndex
:
-
1
,
cursor
:
"pointer"
,
desiredSize
:
new
go
.
Size
(
8
,
8
),
fill
:
"darkred"
,
stroke
:
"tomato"
}),
GO
(
go
.
Shape
,
"Diamond"
,
{
segmentIndex
:
-
1
,
cursor
:
"pointer"
,
desiredSize
:
new
go
.
Size
(
8
,
8
),
fill
:
"darkred"
,
stroke
:
"tomato"
}),
// 连接调整工具
"linkReshapingTool"
:
GO
(
SnapLinkReshapingTool
),
"linkReshapingTool"
:
GO
(
SnapLinkReshapingTool
),
"LinkReshaped"
:
e
=>
{
"LinkReshaped"
:
e
=>
{
e
.
subject
.
adjusting
=
go
.
Link
.
End
;
e
.
subject
.
adjusting
=
go
.
Link
.
End
;
...
@@ -376,10 +390,17 @@ function initDiagram(){
...
@@ -376,10 +390,17 @@ function initDiagram(){
})
})
// install the PortShiftingTool as a "mouse move" tool
// install the PortShiftingTool as a "mouse move" tool
myDiagram
.
toolManager
.
mouseMoveTools
.
insertAt
(
0
,
new
PortShiftingTool
());
myDiagram
.
toolManager
.
mouseMoveTools
.
insertAt
(
0
,
new
PortShiftingTool
());
// 暂时不用 有可能需要连接线可以自己规划路径而不是 连接端口自动产生
// let tool = new PolylineLinkingTool();
// tool.temporaryLink.routing = go.Link.Orthogonal; // optional, but need to keep link template in sync, below
// myDiagram.toolManager.linkingTool = tool;
myDiagram
.
model
.
linkFromPortIdProperty
=
"fromPort"
;
// necessary to remember portIds
myDiagram
.
model
.
linkFromPortIdProperty
=
"fromPort"
;
// necessary to remember portIds
myDiagram
.
model
.
linkToPortIdProperty
=
"toPort"
;
myDiagram
.
model
.
linkToPortIdProperty
=
"toPort"
;
myDiagram
.
model
.
copiesArrays
=
true
;
myDiagram
.
model
.
copiesArrays
=
true
;
myDiagram
.
model
.
copiesArrayObjects
=
true
;
myDiagram
.
model
.
copiesArrayObjects
=
true
;
//多种类型的连接线
//多种类型的连接线
myDiagram
.
linkTemplateMap
.
add
(
'Arrow'
,
ArrowLink
)
myDiagram
.
linkTemplateMap
.
add
(
'Arrow'
,
ArrowLink
)
myDiagram
.
linkTemplateMap
.
add
(
'Flow'
,
FlowLink
)
myDiagram
.
linkTemplateMap
.
add
(
'Flow'
,
FlowLink
)
...
@@ -388,6 +409,7 @@ function initDiagram(){
...
@@ -388,6 +409,7 @@ function initDiagram(){
myDiagram
.
nodeTemplateMap
.
add
(
'svg'
,
makeDiagramNodeTemplate
(
'svg'
))
myDiagram
.
nodeTemplateMap
.
add
(
'svg'
,
makeDiagramNodeTemplate
(
'svg'
))
myDiagram
.
nodeTemplateMap
.
add
(
'geometry'
,
makeDiagramNodeTemplate
(
'geometry'
))
myDiagram
.
nodeTemplateMap
.
add
(
'geometry'
,
makeDiagramNodeTemplate
(
'geometry'
))
myDiagram
.
nodeTemplateMap
.
add
(
'shape'
,
makeDiagramNodeTemplate
(
'shape'
))
myDiagram
.
nodeTemplateMap
.
add
(
'shape'
,
makeDiagramNodeTemplate
(
'shape'
))
}
}
function
listenDiagram
(){
function
listenDiagram
(){
...
@@ -398,6 +420,8 @@ function listenDiagram(){
...
@@ -398,6 +420,8 @@ function listenDiagram(){
})
})
//监听选中时间,用于右侧info-panel,展示选中节点的信息
//监听选中时间,用于右侧info-panel,展示选中节点的信息
myDiagram
.
addDiagramListener
(
'ChangedSelection'
,
()
=>
{
myDiagram
.
addDiagramListener
(
'ChangedSelection'
,
()
=>
{
selectedNode
.
value
=
null
selectedLink
.
value
=
null
let
currentSelected
=
myDiagram
.
selection
.
first
()
let
currentSelected
=
myDiagram
.
selection
.
first
()
if
(
currentSelected
===
null
)
{
if
(
currentSelected
===
null
)
{
ifSelectNode
.
value
=
false
ifSelectNode
.
value
=
false
...
@@ -462,8 +486,10 @@ function cancelHighlightPath(pathIndex:number){
...
@@ -462,8 +486,10 @@ function cancelHighlightPath(pathIndex:number){
cancelHighlightLink
(
path
[
i
],
path
[
i
+
1
],
myDiagram
)
cancelHighlightLink
(
path
[
i
],
path
[
i
+
1
],
myDiagram
)
}
}
}
}
// endregion
// 右侧info-panel相关函数
// 右侧info-panel相关函数
// region
function
initInspector
(){
function
initInspector
(){
// inspector =
// inspector =
new
Inspector
(
'inspector-property'
,
myDiagram
,
new
Inspector
(
'inspector-property'
,
myDiagram
,
...
@@ -631,12 +657,21 @@ function analyzeData(){
...
@@ -631,12 +657,21 @@ function analyzeData(){
analyzePathsName
.
value
.
push
(
pathName
)
analyzePathsName
.
value
.
push
(
pathName
)
}
}
}
}
//endregion
// 其他
// region
// 浏览器大小变化时
// 浏览器大小变化时
window
.
onresize
=
function
(){
window
.
onresize
=
function
(){
getNodeSourceScrollAreaHeight
()
getNodeSourceScrollAreaHeight
()
}
}
// 为了在页面大小变化时,让节点区域的滚动条区域高度自适应
function
getNodeSourceScrollAreaHeight
(){
// 滚动区域高度为浏览器窗口高度 - 144px(固定的上方ToolBar + 本页面的输入框和最下方的按钮)
nodeAreaHeight
.
value
=
window
.
innerHeight
-
144
+
'px'
}
// endregion
</
script
>
</
script
>
<
style
>
<
style
>
...
...
src/kit/LinkTemplateKit.ts
View file @
3c4cf820
...
@@ -57,15 +57,21 @@ MultiArrowLink.prototype.makeGeometry = function() {
...
@@ -57,15 +57,21 @@ MultiArrowLink.prototype.makeGeometry = function() {
export
var
FlowLink
=
export
var
FlowLink
=
GO
(
go
.
Link
,{
GO
(
go
.
Link
,{
routing
:
go
.
Link
.
AvoidsNodes
,
routing
:
go
.
Link
.
Orthogonal
,
curve
:
go
.
Link
.
JumpGap
,
curve
:
go
.
Link
.
JumpGap
,
corner
:
5
,
corner
:
5
,
toShortLength
:
4
,
toShortLength
:
4
,
relinkableFrom
:
true
,
relinkableFrom
:
true
,
relinkableTo
:
true
,
relinkableTo
:
true
,
reshapable
:
true
,
reshapable
:
true
,
adjusting
:
go
.
Link
.
Stretch
,
resegmentable
:
true
,
},
},
new
go
.
Binding
(
"points"
,
"points"
).
makeTwoWay
(),
new
go
.
Binding
(
"points"
,
"points"
).
makeTwoWay
(),
new
go
.
Binding
(
"routing"
,
"routing"
,
go
.
Binding
.
parseEnum
(
go
.
Link
,
go
.
Link
.
AvoidsNodes
))
.
makeTwoWay
(
go
.
Binding
.
toString
),
new
go
.
Binding
(
"adjusting"
,
"adjusting"
,
go
.
Binding
.
parseEnum
(
go
.
Link
,
go
.
Link
.
None
))
.
makeTwoWay
(
go
.
Binding
.
toString
),
GO
(
go
.
Shape
,
{
isPanelMain
:
true
,
strokeWidth
:
5
,
stroke
:
'gray'
}),
GO
(
go
.
Shape
,
{
isPanelMain
:
true
,
strokeWidth
:
5
,
stroke
:
'gray'
}),
GO
(
go
.
Shape
,
{
isPanelMain
:
true
,
strokeWidth
:
5
,
stroke
:
'black'
,
name
:
"FLOW"
,
strokeDashArray
:
[
10
,
10
]}),
GO
(
go
.
Shape
,
{
isPanelMain
:
true
,
strokeWidth
:
5
,
stroke
:
'black'
,
name
:
"FLOW"
,
strokeDashArray
:
[
10
,
10
]}),
);
);
...
@@ -90,10 +96,15 @@ export function animateFlow(myDiagram:go.Diagram){
...
@@ -90,10 +96,15 @@ export function animateFlow(myDiagram:go.Diagram){
export
var
ArrowLink
=
export
var
ArrowLink
=
GO
(
go
.
Link
,
GO
(
go
.
Link
,
{
selectable
:
true
,
selectionAdornmentTemplate
:
linkSelectionAdornmentTemplate
},
{
selectable
:
true
},
{
relinkableFrom
:
true
,
relinkableTo
:
true
,
reshapable
:
true
},
{
relinkableFrom
:
true
,
relinkableTo
:
true
,
reshapable
:
true
},
{
routing
:
go
.
Link
.
AvoidsNodes
,
curve
:
go
.
Link
.
JumpGap
,
toShortLength
:
4
},
{
routing
:
go
.
Link
.
Orthogonal
,
curve
:
go
.
Link
.
JumpGap
,
toShortLength
:
4
,
adjusting
:
go
.
Link
.
Stretch
},
{
resegmentable
:
true
},
new
go
.
Binding
(
"points"
,
"points"
).
makeTwoWay
(),
new
go
.
Binding
(
"points"
,
"points"
).
makeTwoWay
(),
new
go
.
Binding
(
"routing"
,
"routing"
,
go
.
Binding
.
parseEnum
(
go
.
Link
,
go
.
Link
.
AvoidsNodes
))
.
makeTwoWay
(
go
.
Binding
.
toString
),
new
go
.
Binding
(
"adjusting"
,
"adjusting"
,
go
.
Binding
.
parseEnum
(
go
.
Link
,
go
.
Link
.
None
))
.
makeTwoWay
(
go
.
Binding
.
toString
),
GO
(
go
.
Shape
,
// the link path shape
GO
(
go
.
Shape
,
// the link path shape
{
isPanelMain
:
true
,
strokeWidth
:
2
},
{
isPanelMain
:
true
,
strokeWidth
:
2
},
new
go
.
Binding
(
"stroke"
,
""
,
data
=>
linkColorBind
(
data
)),
new
go
.
Binding
(
"stroke"
,
""
,
data
=>
linkColorBind
(
data
)),
...
...
src/kit/extensions/PolylineLinkingTool.ts
0 → 100644
View file @
3c4cf820
/*
* Copyright (C) 1998-2021 by Northwoods Software Corporation. All Rights Reserved.
*/
/*
* This is an extension and not part of the main GoJS library.
* Note that the API for this class may change with any version, even point releases.
* If you intend to use an extension in production, you should copy the code to your own source directory.
* Extensions can be found in the GoJS kit under the extensions or extensionsTS folders.
* See the Extensions intro page (https://gojs.net/latest/intro/extensions.html) for more information.
*/
import
go
from
'gojs'
;
/**
* The PolylineLinkingTool class the user to draw a new {@link Link} by clicking where the route should go,
* until clicking on a valid target port.
*
* This tool supports routing both orthogonal and straight links.
* You can customize the {@link LinkingBaseTool#temporaryLink} as needed to affect the
* appearance and behavior of the temporary link that is shown during the linking operation.
* You can customize the {@link LinkingTool#archetypeLinkData} to specify property values
* that can be data-bound by your link template for the Links that are actually created.
*
* If you want to experiment with this extension, try the <a href="../../extensionsTS/PolylineLinking.html">Polyline Linking</a> sample.
* @category Tool Extension
*/
export
class
PolylineLinkingTool
extends
go
.
LinkingTool
{
private
_firstMouseDown
:
boolean
=
false
;
private
_horizontal
:
boolean
=
false
;
/**
* Constructs an PolylineLinkingTool, sets {@link #portGravity} to 0, and sets the name for the tool.
*/
constructor
()
{
super
();
this
.
portGravity
=
0
;
// must click on a target port in order to complete the link
this
.
name
=
'PolylineLinking'
;
}
/**
* @hidden @internal
* This internal method adds a point to the route.
* During the operation of this tool, the very last point changes to follow the mouse point.
* This method is called by {@link #doMouseDown} in order to add a new "last" point.
* @param {Point} p
*/
private
addPoint
(
p
:
go
.
Point
):
void
{
if
(
this
.
_firstMouseDown
)
return
;
const
pts
=
this
.
temporaryLink
.
points
.
copy
();
this
.
_horizontal
=
!
this
.
_horizontal
;
pts
.
add
(
p
.
copy
());
this
.
temporaryLink
.
points
=
pts
;
}
/**
* @hidden @internal
* This internal method moves the last point of the temporary Link's route.
* This is called by {@link #doMouseMove} and other methods that want to adjust the end of the route.
* @param {Point} p
*/
private
moveLastPoint
(
p
:
go
.
Point
):
void
{
if
(
this
.
_firstMouseDown
)
return
;
const
pts
=
this
.
temporaryLink
.
points
.
copy
();
if
(
this
.
temporaryLink
.
isOrthogonal
)
{
const
q
=
pts
.
elt
(
pts
.
length
-
3
).
copy
();
if
(
this
.
_horizontal
)
{
q
.
y
=
p
.
y
;
}
else
{
q
.
x
=
p
.
x
;
}
pts
.
setElt
(
pts
.
length
-
2
,
q
);
}
pts
.
setElt
(
pts
.
length
-
1
,
p
.
copy
());
this
.
temporaryLink
.
points
=
pts
;
}
/**
* @hidden @internal
* This internal method removes the last point of the temporary Link's route.
* This is called by the "Z" command in {@link #doKeyDown}
* and by {@link #doMouseUp} when a valid target port is found and we want to
* discard the current mouse point from the route.
*/
private
removeLastPoint
():
void
{
if
(
this
.
_firstMouseDown
)
return
;
const
pts
=
this
.
temporaryLink
.
points
.
copy
();
if
(
pts
.
length
===
0
)
return
;
pts
.
removeAt
(
pts
.
length
-
1
);
this
.
temporaryLink
.
points
=
pts
;
this
.
_horizontal
=
!
this
.
_horizontal
;
}
/**
* Use a "crosshair" cursor.
*/
public
doActivate
():
void
{
super
.
doActivate
();
this
.
diagram
.
currentCursor
=
'crosshair'
;
// until a mouse down occurs, allow the temporary link to be routed to the temporary node/port
this
.
_firstMouseDown
=
true
;
}
/**
* Add a point to the route that the temporary Link is accumulating.
*/
public
doMouseDown
():
void
{
if
(
!
this
.
isActive
)
{
this
.
doActivate
();
}
if
(
this
.
diagram
.
lastInput
.
left
)
{
if
(
this
.
_firstMouseDown
)
{
this
.
_firstMouseDown
=
false
;
// disconnect the temporary node/port from the temporary link
// so that it doesn't lose the points that are accumulating
if
(
this
.
isForwards
)
{
this
.
temporaryLink
.
toNode
=
null
;
}
else
{
this
.
temporaryLink
.
fromNode
=
null
;
}
const
pts
=
this
.
temporaryLink
.
points
;
const
ult
=
pts
.
elt
(
pts
.
length
-
1
);
const
penult
=
pts
.
elt
(
pts
.
length
-
2
);
this
.
_horizontal
=
(
ult
.
x
===
penult
.
x
);
}
// a new temporary end point, the previous one is now "accepted"
this
.
addPoint
(
this
.
diagram
.
lastInput
.
documentPoint
);
}
else
{
// e.g. right mouse down
this
.
doCancel
();
}
}
/**
* Have the temporary link reach to the last mouse point.
*/
public
doMouseMove
():
void
{
if
(
this
.
isActive
)
{
this
.
moveLastPoint
(
this
.
diagram
.
lastInput
.
documentPoint
);
super
.
doMouseMove
();
}
}
/**
* If this event happens on a valid target port (as determined by {@link LinkingBaseTool#findTargetPort}),
* we complete the link drawing operation. {@link #insertLink} is overridden to transfer the accumulated
* route drawn by user clicks to the new {@link Link} that was created.
*
* If this event happens elsewhere in the diagram, this tool is not stopped: the drawing of the route continues.
*/
public
doMouseUp
():
void
{
if
(
!
this
.
isActive
)
return
;
const
target
=
this
.
findTargetPort
(
this
.
isForwards
);
if
(
target
!==
null
)
{
if
(
this
.
_firstMouseDown
)
{
super
.
doMouseUp
();
}
else
{
let
pts
;
this
.
removeLastPoint
();
// remove temporary point
const
spot
=
this
.
isForwards
?
target
.
toSpot
:
target
.
fromSpot
;
if
(
spot
.
equals
(
go
.
Spot
.
None
))
{
const
pt
=
this
.
temporaryLink
.
getLinkPointFromPoint
(
target
.
part
as
go
.
Node
,
target
,
target
.
getDocumentPoint
(
go
.
Spot
.
Center
),
this
.
temporaryLink
.
points
.
elt
(
this
.
temporaryLink
.
points
.
length
-
2
),
!
this
.
isForwards
);
this
.
moveLastPoint
(
pt
);
pts
=
this
.
temporaryLink
.
points
.
copy
();
if
(
this
.
temporaryLink
.
isOrthogonal
)
{
pts
.
insertAt
(
pts
.
length
-
2
,
pts
.
elt
(
pts
.
length
-
2
));
}
}
else
{
// copy the route of saved points, because we're about to recompute it
pts
=
this
.
temporaryLink
.
points
.
copy
();
// terminate the link in the expected manner by letting the
// temporary link connect with the temporary node/port and letting the
// normal route computation take place
if
(
this
.
isForwards
)
{
this
.
copyPortProperties
(
target
.
part
as
go
.
Node
,
target
,
this
.
temporaryToNode
,
this
.
temporaryToPort
,
true
);
this
.
temporaryLink
.
toNode
=
target
.
part
as
go
.
Node
;
}
else
{
this
.
copyPortProperties
(
target
.
part
as
go
.
Node
,
target
,
this
.
temporaryFromNode
,
this
.
temporaryFromPort
,
false
);
this
.
temporaryLink
.
fromNode
=
target
.
part
as
go
.
Node
;
}
this
.
temporaryLink
.
updateRoute
();
// now copy the final one or two points of the temporary link's route
// into the route built up in the PTS List.
const
natpts
=
this
.
temporaryLink
.
points
;
const
numnatpts
=
natpts
.
length
;
if
(
numnatpts
>=
2
)
{
if
(
numnatpts
>=
3
)
{
const
penult
=
natpts
.
elt
(
numnatpts
-
2
);
pts
.
insertAt
(
pts
.
length
-
1
,
penult
);
if
(
this
.
temporaryLink
.
isOrthogonal
)
{
pts
.
insertAt
(
pts
.
length
-
1
,
penult
);
}
}
const
ult
=
natpts
.
elt
(
numnatpts
-
1
);
pts
.
setElt
(
pts
.
length
-
1
,
ult
);
}
}
// save desired route in temporary link;
// insertLink will copy the route into the new real Link
this
.
temporaryLink
.
points
=
pts
;
super
.
doMouseUp
();
}
}
}
/**
* This method overrides the standard link creation method by additionally
* replacing the default link route with the custom one laid out by the user.
*/
public
insertLink
(
fromnode
:
go
.
Node
,
fromport
:
go
.
GraphObject
,
tonode
:
go
.
Node
,
toport
:
go
.
GraphObject
):
go
.
Link
|
null
{
const
link
=
super
.
insertLink
(
fromnode
,
fromport
,
tonode
,
toport
);
if
(
link
!==
null
&&
!
this
.
_firstMouseDown
)
{
// ignore natural route by replacing with route accumulated by this tool
link
.
points
=
this
.
temporaryLink
.
points
;
}
return
link
;
}
/**
* This supports the "Z" command during this tool's operation to remove the last added point of the route.
* Type ESCAPE to completely cancel the operation of the tool.
*/
public
doKeyDown
():
void
{
if
(
!
this
.
isActive
)
return
;
const
e
=
this
.
diagram
.
lastInput
;
if
(
e
.
key
===
'Z'
&&
this
.
temporaryLink
.
points
.
length
>
(
this
.
temporaryLink
.
isOrthogonal
?
4
:
3
))
{
// undo
// remove a point, and then treat the last one as a temporary one
this
.
removeLastPoint
();
this
.
moveLastPoint
(
e
.
documentPoint
);
}
else
{
super
.
doKeyDown
();
}
}
}
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