Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
R
relation-graph
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
郭铭瑶
relation-graph
Commits
b9257356
Commit
b9257356
authored
Aug 23, 2021
by
郭铭瑶
🤘
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
删除边及选择性高亮功能
parent
2227c5ee
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
162 additions
and
30 deletions
+162
-30
api.js
src/ajax/api.js
+1
-1
d3.vue
src/components/d3.vue
+48
-6
main.vue
src/components/main.vue
+28
-0
useD3.js
src/util/useD3.js
+85
-23
No files found.
src/ajax/api.js
View file @
b9257356
...
...
@@ -11,7 +11,7 @@ export default {
GET_RELATIONS
:
'/relations'
,
POST_SUBJECT
:
'/subject'
,
POST_NODE
:
'/node/relation'
,
DELETE_RELATION
:
'/node/relation'
,
DELETE_RELATION
:
'/node/relation
/{id}
'
,
GET_NODES
:
'/node/relations'
,
DELETE_NODE
:
'/node/{id}'
,
GET_SYSTEMS
:
'/systems'
,
...
...
src/components/d3.vue
View file @
b9257356
...
...
@@ -6,9 +6,15 @@
<n-tag
v-for=
"n in nodeList"
:key=
"n.name"
class=
"tag"
:class=
"
{
on: curTagKey === n.key,
'click-able': n.key.indexOf('Property') >= 0,
}"
size="small"
round
:color="n.color || defaultColor"
@click="onTagClick(n)"
>
{{
`${n.name
}
(${n.val
}
)`
}}
<
/n-tag
>
...
...
@@ -48,7 +54,7 @@ export default {
}
,
}
,
}
,
emits
:
[
'link'
,
'add'
,
'del'
,
'branch'
,
'curNode'
],
emits
:
[
'link'
,
'add'
,
'del'
,
'branch'
,
'curNode'
,
'del-link'
],
setup
(
props
,
ctx
)
{
const
colorList
=
{
default
:
'skyblue'
,
...
...
@@ -89,9 +95,19 @@ export default {
title
:
'删除'
,
}
,
]
const
curTagKey
=
ref
(
null
)
const
setCurNode
=
(
type
)
=>
{
if
(
type
.
nodeLabel
!==
'Subject'
)
{
curTagKey
.
value
=
null
}
ctx
.
emit
(
'curNode'
,
type
)
}
const
handleLinkClick
=
(
d
)
=>
{
if
(
d
.
target
.
nodeLabel
===
'System'
)
{
ctx
.
emit
(
'del-link'
,
d
)
}
}
function
init
()
{
if
(
!
container
.
value
)
return
...
...
@@ -124,7 +140,8 @@ export default {
props
.
config
,
menuData
,
colorList
,
setCurNode
setCurNode
,
handleLinkClick
)
}
setLegend
(
data
)
...
...
@@ -152,13 +169,13 @@ export default {
case
'Property_property'
:
return
'属性'
case
'Property_produce'
:
return
'生产'
return
'生产
行为
'
case
'Property_manage'
:
return
'管理'
return
'管理
行为
'
case
'Property_service'
:
return
'服务'
return
'服务
行为
'
case
'Property_use'
:
return
'使用'
return
'使用
行为
'
default
:
return
'未知'
}
...
...
@@ -206,6 +223,7 @@ export default {
const
nodeResult
=
[]
for
(
const
key
in
nodeKey
)
{
nodeResult
.
push
({
key
,
name
:
switchName
(
key
),
val
:
nodeKey
[
key
],
color
:
{
...
...
@@ -228,6 +246,17 @@ export default {
nodeList
.
value
=
nodeResult
linkList
.
value
=
linkResult
}
function
onTagClick
({
key
}
)
{
if
(
key
.
indexOf
(
'Property'
)
<
0
)
return
if
(
curTagKey
.
value
===
key
)
{
curTagKey
.
value
=
null
}
else
{
curTagKey
.
value
=
key
}
if
(
!
instance
.
setHighlights
(
curTagKey
.
value
))
{
curTagKey
.
value
=
null
}
}
return
{
colorList
,
container
,
...
...
@@ -239,6 +268,8 @@ export default {
textColor
:
'#fff'
,
borderColor
:
'#a5abb6'
,
}
,
curTagKey
,
onTagClick
,
}
}
,
}
...
...
@@ -253,6 +284,17 @@ export default {
position
absolute
top
10
px
left
14
px
.
tag
cursor
not
-
allowed
box
-
sizing
border
-
box
border
2
px
solid
transparent
&
.
click
-
able
cursor
pointer
&
.
on
&
:
hover
box
-
shadow
0
0
4
px
1
px
rgba
(
0
,
0
,
0
,
0.3
)
&
.
on
border
-
color
rgba
(
0
,
0
,
0
,
0.3
)
<
/style
>
<
style
lang
=
"stylus"
>
...
...
src/components/main.vue
View file @
b9257356
...
...
@@ -11,6 +11,7 @@
@
curNode=
"curNode = $event"
@
del=
"deleteNode"
@
link=
"showLinkDrawer = true"
@
del-link=
"deleteLink"
/>
<Side
style=
"grid-area: side"
/>
<Footer
...
...
@@ -282,6 +283,32 @@ export default {
})
}
function
deleteLink
(
data
)
{
const
{
source
,
target
}
=
data
dialog
.
error
({
title
:
'删除关联'
,
content
:
`确定是否删除 '
${
source
.
propertyName
}
_
${
target
.
systemName
}
' 关联关系?`
,
positiveText
:
'确定'
,
negativeText
:
'取消'
,
maskClosable
:
false
,
onPositiveClick
:
()
=>
{
ajax
.
delete
({
url
:
api
.
DELETE_RELATION
.
replace
(
'{id}'
,
data
.
id
),
})
.
then
(()
=>
{
graphData
.
value
=
{
nodes
:
graphData
.
value
.
nodes
,
links
:
graphData
.
value
.
links
.
filter
(
(
link
)
=>
link
.
id
!=
data
.
id
),
}
message
.
success
(
'删除成功!'
)
})
},
})
}
const
subjectFormRef
=
ref
(
null
)
const
showSubjectDrawer
=
ref
(
false
)
const
subjectData
=
ref
({
subjectName
:
null
})
...
...
@@ -425,6 +452,7 @@ export default {
rules
,
curNode
,
deleteNode
,
deleteLink
,
showSubjectDrawer
,
subjectFormRef
,
subjectData
,
...
...
src/util/useD3.js
View file @
b9257356
...
...
@@ -109,9 +109,18 @@ const defaultConfig = {
let
menu
=
null
export
default
class
RelationGraph
{
constructor
(
selector
,
data
,
configs
=
{},
menuData
,
colorList
,
setCurNode
)
{
constructor
(
selector
,
data
,
configs
=
{},
menuData
,
colorList
,
setCurNode
,
handleLinkClick
)
{
this
.
menuData
=
menuData
this
.
setCurNode
=
setCurNode
this
.
handleLinkClick
=
handleLinkClick
const
mapW
=
selector
.
offsetWidth
const
mapH
=
selector
.
offsetHeight
...
...
@@ -134,7 +143,7 @@ export default class RelationGraph {
// 需要高亮的node和link
this
.
dependsNode
=
[]
this
.
dependsLink
AndText
=
[]
this
.
dependsLink
=
[]
this
.
tooltip
=
d3
.
select
(
'body'
)
...
...
@@ -233,6 +242,7 @@ export default class RelationGraph {
})
.
on
(
'click'
,
function
(
e
,
d
)
{
console
.
log
(
'线click'
)
self
.
handleLinkClick
(
d
)
})
.
attr
(
'fill'
,
(
d
)
=>
d
.
color
||
this
.
config
.
linkColor
)
...
...
@@ -321,6 +331,9 @@ export default class RelationGraph {
// self.tooltip.style('opacity', 0)
})
.
on
(
'click'
,
function
(
e
,
d
)
{
//阻止事件冒泡 阻止事件默认行为
e
.
stopPropagation
?
e
.
stopPropagation
()
:
(
e
.
cancelBubble
=
true
)
e
.
preventDefault
?
e
.
preventDefault
()
:
(
e
.
returnValue
=
false
)
// self.tooltip.style('opacity', 0)
if
(
menu
&&
menu
.
curNodeData
==
d
)
{
self
.
closeMenu
(
true
)
...
...
@@ -332,9 +345,6 @@ export default class RelationGraph {
self
.
openMenu
(
this
,
d
,
[
'del'
,
'branch'
])
}
}
//阻止事件冒泡 阻止事件默认行为
e
.
stopPropagation
?
e
.
stopPropagation
()
:
(
e
.
cancelBubble
=
true
)
e
.
preventDefault
?
e
.
preventDefault
()
:
(
e
.
returnValue
=
false
)
})
.
on
(
'contextmenu'
,
function
(
e
)
{
// 取消鼠标右键菜单默认行为
...
...
@@ -429,7 +439,7 @@ export default class RelationGraph {
.
nodes
(
this
.
config
.
nodes
)
.
force
(
'link'
,
d3
.
forceLink
(
this
.
config
.
links
))
.
force
(
'charge'
,
null
)
.
alpha
(
0.
1
)
.
alpha
(
0.
3
)
.
restart
()
}
...
...
@@ -448,6 +458,9 @@ export default class RelationGraph {
d
)
}
if
(
this
.
curHighlightKey
)
{
this
.
setHighlights
(
this
.
curHighlightKey
)
}
}
clearFixedPosition
()
{
this
.
curActiveNode
&&
(
this
.
curActiveNode
.
fx
=
null
)
...
...
@@ -570,42 +583,44 @@ export default class RelationGraph {
if
(
obj
)
{
const
objIndex
=
obj
.
index
this
.
dependsNode
=
this
.
dependsNode
.
concat
([
objIndex
])
this
.
dependsLink
AndText
=
this
.
dependsLinkAndText
.
concat
([
objIndex
])
this
.
dependsLink
=
[]
this
.
config
.
links
.
forEach
((
link
)
=>
{
if
(
objIndex
==
link
.
source
.
index
)
{
this
.
dependsNode
=
this
.
dependsNode
.
concat
([
link
.
target
.
index
])
this
.
dependsNode
.
push
(
link
.
target
.
index
)
this
.
dependsLink
.
push
(
link
.
index
)
}
else
if
(
objIndex
==
link
.
target
.
index
)
{
this
.
dependsNode
=
this
.
dependsNode
.
concat
([
link
.
source
.
index
])
this
.
dependsNode
.
push
(
link
.
source
.
index
)
this
.
dependsLink
.
push
(
link
.
index
)
}
})
/** 二级节点也要展示 不展示可以删除 */
const
secondNodes
=
this
.
dependsNode
.
filter
((
e
)
=>
e
!==
objIndex
)
this
.
dependsLinkAndText
.
push
(...
secondNodes
)
this
.
config
.
links
.
forEach
((
link
)
=>
{
if
(
secondNodes
.
indexOf
(
link
.
source
.
index
)
>=
0
)
{
this
.
dependsNode
=
this
.
dependsNode
.
concat
([
link
.
target
.
index
])
this
.
dependsNode
.
push
(
link
.
target
.
index
)
this
.
dependsLink
.
push
(
link
.
index
)
}
else
if
(
secondNodes
.
indexOf
(
link
.
target
.
index
)
>=
0
)
{
this
.
dependsNode
=
this
.
dependsNode
.
concat
([
link
.
source
.
index
])
this
.
dependsNode
.
push
(
link
.
source
.
index
)
this
.
dependsLink
.
push
(
link
.
index
)
}
})
this
.
dependsNode
=
Array
.
from
(
new
Set
(
this
.
dependsNode
))
this
.
dependsLink
=
Array
.
from
(
new
Set
(
this
.
dependsLink
))
// 隐藏节点
this
.
SVG
.
selectAll
(
'circle'
)
.
filter
((
d
)
=>
this
.
dependsNode
.
indexOf
(
d
.
index
)
==
-
1
)
.
transition
()
.
style
(
'opacity'
,
0.
1
)
.
style
(
'opacity'
,
0.
3
)
// 隐藏线
this
.
SVG
.
selectAll
(
'.edge'
)
.
filter
(
(
d
)
=>
this
.
dependsLinkAndText
.
indexOf
(
d
.
source
.
index
)
==
-
1
&&
this
.
dependsLinkAndText
.
indexOf
(
d
.
target
.
index
)
==
-
1
)
.
filter
((
d
)
=>
this
.
dependsLink
.
indexOf
(
d
.
index
)
==
-
1
)
.
transition
()
.
style
(
'opacity'
,
0.
1
)
.
style
(
'opacity'
,
0.
3
)
}
else
{
// 取消高亮
// 恢复隐藏的线
...
...
@@ -615,7 +630,7 @@ export default class RelationGraph {
this
.
SVG
.
selectAll
(
'.edge'
).
transition
().
style
(
'opacity'
,
1
)
this
.
dependsNode
=
[]
this
.
dependsLink
AndText
=
[]
this
.
dependsLink
=
[]
}
}
...
...
@@ -633,17 +648,64 @@ export default class RelationGraph {
return
d
.
index
!=
sourceIndex
&&
d
.
index
!=
targetIndex
})
.
transition
()
.
style
(
'opacity'
,
0.
1
)
.
style
(
'opacity'
,
0.
3
)
// 隐藏线
this
.
SVG
.
selectAll
(
'.edge'
)
.
filter
((
d
)
=>
d
.
id
!=
obj
.
id
)
.
transition
()
.
style
(
'opacity'
,
0.
1
)
.
style
(
'opacity'
,
0.
3
)
}
else
{
this
.
SVG
.
selectAll
(
'circle'
).
transition
().
style
(
'opacity'
,
1
)
this
.
SVG
.
selectAll
(
'.edge'
).
transition
().
style
(
'opacity'
,
1
)
}
}
setHighlights
(
key
)
{
this
.
curHighlightKey
=
key
this
.
config
.
isHighLight
=
false
this
.
SVG
.
selectAll
(
'circle'
).
transition
().
style
(
'opacity'
,
1
)
this
.
SVG
.
selectAll
(
'.edge'
).
transition
().
style
(
'opacity'
,
1
)
this
.
dependsNode
=
[]
this
.
dependsLink
=
[]
if
(
!
key
||
this
.
curActiveNode
.
nodeLabel
!==
'Subject'
)
{
this
.
curHighlightKey
=
null
this
.
config
.
isHighLight
=
true
key
=
null
// return false
}
this
.
highlightObject
(
this
.
curActiveNode
)
this
.
dependsNode
=
[
this
.
curActiveNode
.
index
]
this
.
config
.
links
.
forEach
((
link
)
=>
{
const
index
=
this
.
dependsLink
.
indexOf
(
link
.
index
)
if
(
index
<
0
)
return
if
(
link
.
target
.
_label_key
!=
key
&&
link
.
source
.
_label_key
!=
key
)
{
this
.
dependsLink
.
splice
(
index
,
1
)
}
else
if
(
link
.
target
.
_label_key
==
key
&&
link
.
source
.
id
!=
this
.
curActiveNode
.
id
)
{
this
.
dependsLink
.
splice
(
index
,
1
)
}
else
{
this
.
dependsNode
.
push
(
link
.
target
.
index
)
this
.
dependsNode
.
push
(
link
.
source
.
index
)
}
})
// 隐藏节点
this
.
SVG
.
selectAll
(
'circle'
)
.
filter
((
d
)
=>
this
.
dependsNode
.
indexOf
(
d
.
index
)
<
0
)
.
transition
()
.
style
(
'opacity'
,
0.3
)
// 隐藏线
this
.
SVG
.
selectAll
(
'.edge'
)
.
filter
((
d
)
=>
this
.
dependsLink
.
indexOf
(
d
.
index
)
<
0
)
.
transition
()
.
style
(
'opacity'
,
0.3
)
return
true
}
}
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