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
cee5ea2c
Commit
cee5ea2c
authored
Aug 16, 2021
by
郭铭瑶
🤘
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
汉化
parent
1bfbe53f
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
195 additions
and
46 deletions
+195
-46
d3.vue
src/components/d3.vue
+80
-13
footer.vue
src/components/footer.vue
+81
-16
main.vue
src/components/main.vue
+4
-3
useD3.js
src/util/useD3.js
+30
-14
No files found.
src/components/d3.vue
View file @
cee5ea2c
...
@@ -55,6 +55,11 @@ export default {
...
@@ -55,6 +55,11 @@ export default {
System
:
'#58b2dc'
,
System
:
'#58b2dc'
,
Property
:
'#ffb11b'
,
Property
:
'#ffb11b'
,
Subject
:
'#42b983'
,
Subject
:
'#42b983'
,
Property_property
:
'#f582ae'
,
Property_produce
:
'#f3d2c1'
,
Property_manage
:
'#abd1c6'
,
Property_service
:
'#f9bc60'
,
Property_use
:
'#d9d4e7'
,
}
}
let
instance
=
null
let
instance
=
null
const
container
=
ref
(
null
)
const
container
=
ref
(
null
)
...
@@ -89,19 +94,40 @@ export default {
...
@@ -89,19 +94,40 @@ export default {
}
}
function
init
()
{
function
init
()
{
if
(
!
container
.
value
)
return
if
(
!
container
.
value
)
return
const
data
=
{
links
:
props
.
data
.
links
,
nodes
:
props
.
data
.
nodes
.
map
((
node
)
=>
{
let
key
=
node
.
nodeLabel
if
(
key
===
'Property'
)
{
const
relation
=
props
.
data
.
links
.
find
((
link
)
=>
{
let
targetId
=
link
.
target
if
(
link
.
target
.
id
)
{
targetId
=
link
.
target
.
id
}
return
targetId
==
node
.
id
}
)
if
(
relation
)
{
key
=
switchRelation
(
relation
.
name
)
}
}
node
.
_label_key
=
key
return
node
}
),
}
if
(
instance
)
{
if
(
instance
)
{
instance
.
update
(
props
.
data
)
instance
.
update
(
data
)
}
else
{
}
else
{
instance
=
new
RelationGraph
(
instance
=
new
RelationGraph
(
container
.
value
,
container
.
value
,
props
.
data
,
data
,
props
.
config
,
props
.
config
,
menuData
,
menuData
,
colorList
,
colorList
,
setCurNode
setCurNode
)
)
}
}
setLegend
()
setLegend
(
data
)
}
}
function
setKey
(
key
)
{
function
setKey
(
key
)
{
...
@@ -117,21 +143,60 @@ export default {
...
@@ -117,21 +143,60 @@ export default {
const
nodeList
=
ref
([])
const
nodeList
=
ref
([])
const
linkList
=
ref
([])
const
linkList
=
ref
([])
function
setLegend
()
{
function
switchName
(
key
)
{
const
{
nodes
,
links
}
=
props
.
data
switch
(
key
)
{
case
'Subject'
:
return
'主体'
case
'System'
:
return
'系统'
case
'Property_property'
:
return
'属性'
case
'Property_produce'
:
return
'生产'
case
'Property_manage'
:
return
'管理'
case
'Property_service'
:
return
'服务'
case
'Property_use'
:
return
'使用'
default
:
return
'未知'
}
}
function
switchRelation
(
name
)
{
switch
(
name
)
{
case
'属性'
:
return
'Property_property'
case
'生产行为'
:
return
'Property_produce'
case
'管理行为'
:
return
'Property_manage'
case
'服务行为'
:
return
'Property_service'
case
'使用行为'
:
return
'Property_use'
default
:
return
'未知'
}
}
function
setLegend
(
data
)
{
const
{
nodes
,
links
}
=
data
if
(
!
nodes
||
!
links
)
return
if
(
!
nodes
||
!
links
)
return
const
nodeKey
=
{
}
const
nodeKey
=
{
}
const
linkKey
=
{
}
const
linkKey
=
{
}
nodes
.
forEach
((
node
)
=>
{
nodes
.
forEach
((
node
)
=>
{
if
(
nodeKey
.
hasOwnProperty
(
node
.
nodeLabel
))
{
const
key
=
node
.
_label_key
nodeKey
[
node
.
nodeLabel
]
+=
1
if
(
nodeKey
.
hasOwnProperty
(
key
))
{
nodeKey
[
key
]
+=
1
}
else
{
}
else
{
nodeKey
[
node
.
nodeLabel
]
=
1
nodeKey
[
key
]
=
1
}
}
}
)
}
)
links
.
forEach
((
link
)
=>
{
links
.
forEach
((
link
)
=>
{
const
key
=
`${link.source.
nodeLabel
}
_${link.target.nodeLabel
}
`
const
key
=
`${link.source.
_label_key
}
-${link.target._label_key
}
`
if
(
linkKey
.
hasOwnProperty
(
key
))
{
if
(
linkKey
.
hasOwnProperty
(
key
))
{
linkKey
[
key
]
+=
1
linkKey
[
key
]
+=
1
}
else
{
}
else
{
...
@@ -141,7 +206,7 @@ export default {
...
@@ -141,7 +206,7 @@ export default {
const
nodeResult
=
[]
const
nodeResult
=
[]
for
(
const
key
in
nodeKey
)
{
for
(
const
key
in
nodeKey
)
{
nodeResult
.
push
({
nodeResult
.
push
({
name
:
key
,
name
:
switchName
(
key
)
,
val
:
nodeKey
[
key
],
val
:
nodeKey
[
key
],
color
:
{
color
:
{
color
:
colorList
[
key
],
color
:
colorList
[
key
],
...
@@ -150,10 +215,12 @@ export default {
...
@@ -150,10 +215,12 @@ export default {
}
,
}
,
}
)
}
)
}
}
const
linkResult
=
[]
const
linkResult
=
[]
for
(
const
key
in
linkKey
)
{
for
(
const
key
in
linkKey
)
{
const
name
=
key
.
split
(
'-'
)
linkResult
.
push
({
linkResult
.
push
({
name
:
key
,
name
:
`${switchName(name[0])
}
_${switchName(name[1])
}
`
,
val
:
linkKey
[
key
],
val
:
linkKey
[
key
],
}
)
}
)
}
}
...
@@ -184,8 +251,8 @@ export default {
...
@@ -184,8 +251,8 @@ export default {
position
relative
position
relative
.
legend
.
legend
position
absolute
position
absolute
top
2
0
px
top
1
0
px
left
20
px
left
14
px
<
/style
>
<
/style
>
<
style
lang
=
"stylus"
>
<
style
lang
=
"stylus"
>
...
...
src/components/footer.vue
View file @
cee5ea2c
...
@@ -22,18 +22,18 @@
...
@@ -22,18 +22,18 @@
</svg>
</svg>
</n-icon>
</n-icon>
</
template
>
</
template
>
Add Subject
新增主体
</n-button>
</n-button>
<n-input-group
size=
"small"
class=
"search-bar"
>
<n-input-group
size=
"small"
class=
"search-bar"
>
<n-select
<n-select
v-model:value=
"searchType"
v-model:value=
"searchType"
style=
"width: 25%"
style=
"width: 25%"
placeholder=
"请选择"
placeholder=
"请选择
节点类型
"
:options=
"nodeOptions"
:options=
"nodeOptions"
/>
/>
<n-input
<n-input
v-model:value=
"searchKey"
v-model:value=
"searchKey"
placeholder=
"
Search Something
..."
placeholder=
"
请输入关键词
..."
clearable
clearable
:on-clear=
"clear"
:on-clear=
"clear"
@
keypress
.
enter=
"search"
@
keypress
.
enter=
"search"
...
@@ -42,7 +42,7 @@
...
@@ -42,7 +42,7 @@
</n-input-group>
</n-input-group>
<n-space>
<n-space>
<n-tag
v-show=
"nodeVal"
size=
"small"
round
:color=
"color"
>
<n-tag
v-show=
"nodeVal"
size=
"small"
round
:color=
"color"
>
{{
nodeVal
&&
nodeVal.nodeLabel
}}
{{
switchName(nodeVal
&&
nodeVal._label_key)
}}
</n-tag>
</n-tag>
<n-button
<n-button
v-for=
"name in list"
v-for=
"name in list"
...
@@ -60,7 +60,6 @@
...
@@ -60,7 +60,6 @@
<
script
>
<
script
>
import
{
defineComponent
,
ref
,
computed
}
from
'vue'
import
{
defineComponent
,
ref
,
computed
}
from
'vue'
import
add
from
'@/assets/images/add.svg'
export
default
defineComponent
({
export
default
defineComponent
({
name
:
'Footer'
,
name
:
'Footer'
,
...
@@ -71,6 +70,10 @@ export default defineComponent({
...
@@ -71,6 +70,10 @@ export default defineComponent({
nodeLabel
:
'Subject'
,
nodeLabel
:
'Subject'
,
}),
}),
},
},
data
:
{
type
:
Object
,
default
:
()
=>
{},
},
},
},
emits
:
[
'set'
,
'add'
,
'search'
],
emits
:
[
'set'
,
'add'
,
'search'
],
setup
(
props
,
ctx
)
{
setup
(
props
,
ctx
)
{
...
@@ -79,19 +82,60 @@ export default defineComponent({
...
@@ -79,19 +82,60 @@ export default defineComponent({
System
:
'#58b2dc'
,
System
:
'#58b2dc'
,
Property
:
'#ffb11b'
,
Property
:
'#ffb11b'
,
Subject
:
'#42b983'
,
Subject
:
'#42b983'
,
Property_property
:
'#f582ae'
,
Property_produce
:
'#f3d2c1'
,
Property_manage
:
'#abd1c6'
,
Property_service
:
'#f9bc60'
,
Property_use
:
'#d9d4e7'
,
}
}
const
nodeVal
=
computed
(
function
switchRelation
(
name
)
{
()
=>
switch
(
name
)
{
props
.
node
||
{
case
'属性'
:
nodeLabel
:
'Subject'
,
return
'Property_property'
case
'生产行为'
:
return
'Property_produce'
case
'管理行为'
:
return
'Property_manage'
case
'服务行为'
:
return
'Property_service'
case
'使用行为'
:
return
'Property_use'
default
:
return
'未知'
}
}
const
nodeVal
=
computed
(()
=>
{
if
(
!
props
.
node
||
!
props
.
data
||
props
.
data
.
links
.
length
===
0
||
props
.
data
.
nodes
.
length
===
0
)
{
return
{
_label_key
:
'Subject'
}
}
const
node
=
{
...
props
.
node
}
let
key
=
props
.
node
.
nodeLabel
if
(
key
===
'Property'
)
{
const
relation
=
props
.
data
.
links
.
find
((
link
)
=>
{
let
targetId
=
link
.
target
if
(
link
.
target
.
id
)
{
targetId
=
link
.
target
.
id
}
return
targetId
==
node
.
id
})
if
(
relation
)
{
key
=
switchRelation
(
relation
.
name
)
}
}
)
}
node
.
_label_key
=
key
return
node
})
const
color
=
computed
(()
=>
{
const
color
=
computed
(()
=>
{
if
(
!
nodeVal
.
value
)
return
{}
if
(
!
nodeVal
.
value
)
return
{}
return
{
return
{
color
:
colorList
[
nodeVal
.
value
.
nodeLabel
],
color
:
colorList
[
nodeVal
.
value
.
_label_key
],
textColor
:
'#fff'
,
textColor
:
'#fff'
,
borderColor
:
colorList
[
nodeVal
.
value
.
nodeLabel
],
borderColor
:
colorList
[
nodeVal
.
value
.
_label_key
],
}
}
})
})
const
curKey
=
ref
(
''
)
const
curKey
=
ref
(
''
)
...
@@ -119,10 +163,31 @@ export default defineComponent({
...
@@ -119,10 +163,31 @@ export default defineComponent({
}
}
const
nodeOptions
=
ref
([
const
nodeOptions
=
ref
([
{
label
:
'
Subject
'
,
value
:
'Subject'
},
{
label
:
'
主体
'
,
value
:
'Subject'
},
{
label
:
'
Property
'
,
value
:
'Property'
},
{
label
:
'
附属节点
'
,
value
:
'Property'
},
{
label
:
'
System
'
,
value
:
'System'
},
{
label
:
'
系统
'
,
value
:
'System'
},
])
])
function
switchName
(
key
)
{
switch
(
key
)
{
case
'Subject'
:
return
'主体'
case
'System'
:
return
'系统'
case
'Property_property'
:
return
'属性'
case
'Property_produce'
:
return
'生产'
case
'Property_manage'
:
return
'管理'
case
'Property_service'
:
return
'服务'
case
'Property_use'
:
return
'使用'
default
:
return
'未知'
}
}
return
{
return
{
curKey
,
curKey
,
setKey
,
setKey
,
...
@@ -135,7 +200,7 @@ export default defineComponent({
...
@@ -135,7 +200,7 @@ export default defineComponent({
search
,
search
,
clear
,
clear
,
nodeOptions
,
nodeOptions
,
add
,
switchName
,
}
}
},
},
})
})
...
...
src/components/main.vue
View file @
cee5ea2c
...
@@ -15,9 +15,10 @@
...
@@ -15,9 +15,10 @@
<Footer
<Footer
style=
"grid-area: footer"
style=
"grid-area: footer"
:node=
"curNode"
:node=
"curNode"
:data=
"graphData"
@
add=
"showSubjectDrawer = true"
@
add=
"showSubjectDrawer = true"
@
set=
"setLabelKey"
@
set=
"setLabelKey"
@
search=
"search
Subject
"
@
search=
"search
Nodes
"
/>
/>
</div>
</div>
<n-drawer
v-model:show=
"showDrawer"
:width=
"400"
placement=
"left"
>
<n-drawer
v-model:show=
"showDrawer"
:width=
"400"
placement=
"left"
>
...
@@ -274,7 +275,7 @@ export default {
...
@@ -274,7 +275,7 @@ export default {
})
})
}
}
const
search
Subject
=
(
type
,
key
)
=>
{
const
search
Nodes
=
(
type
,
key
)
=>
{
if
(
!
key
)
{
if
(
!
key
)
{
fetchSubjects
()
fetchSubjects
()
return
return
...
@@ -338,7 +339,7 @@ export default {
...
@@ -338,7 +339,7 @@ export default {
subjectFormRef
,
subjectFormRef
,
subjectData
,
subjectData
,
addSubject
,
addSubject
,
search
Subject
,
search
Nodes
,
}
}
},
},
}
}
...
...
src/util/useD3.js
View file @
cee5ea2c
...
@@ -77,7 +77,7 @@ const defaultConfig = {
...
@@ -77,7 +77,7 @@ const defaultConfig = {
chargeStrength
:
-
100
,
// 万有引力
chargeStrength
:
-
100
,
// 万有引力
collide
:
80
,
// 碰撞力的大小 (节点之间的间距)
collide
:
80
,
// 碰撞力的大小 (节点之间的间距)
alphaDecay
:
0.4
,
// 控制力学模拟衰减率
alphaDecay
:
0.4
,
// 控制力学模拟衰减率
r
:
45
,
// 圈圈的半径 [30 - 45]
r
:
34
,
// 圈圈的半径 [30 - 45]
nodeColor
:
'skyblue'
,
// 圈圈节点背景颜色
nodeColor
:
'skyblue'
,
// 圈圈节点背景颜色
fontColor
:
'#2c3e50'
,
// 圈圈内文字的颜色
fontColor
:
'#2c3e50'
,
// 圈圈内文字的颜色
linkSrc
:
30
,
// 划线时候的弧度
linkSrc
:
30
,
// 划线时候的弧度
...
@@ -89,6 +89,11 @@ const defaultConfig = {
...
@@ -89,6 +89,11 @@ const defaultConfig = {
System
:
'#58b2dc'
,
System
:
'#58b2dc'
,
Property
:
'#ffb11b'
,
Property
:
'#ffb11b'
,
Subject
:
'#42b983'
,
Subject
:
'#42b983'
,
// Property_property: '#f582ae',
// Property_produce: '#f3d2c1',
// Property_manage: '#8bd3dd',
// Property_service: '#ffd803',
// Property_use: '#004643',
},
},
}
}
...
@@ -97,7 +102,6 @@ let menu = null
...
@@ -97,7 +102,6 @@ let menu = null
export
default
class
RelationGraph
{
export
default
class
RelationGraph
{
constructor
(
selector
,
data
,
configs
=
{},
menuData
,
colorList
,
setCurNode
)
{
constructor
(
selector
,
data
,
configs
=
{},
menuData
,
colorList
,
setCurNode
)
{
this
.
menuData
=
menuData
this
.
menuData
=
menuData
this
.
colorLIst
=
colorList
this
.
setCurNode
=
setCurNode
this
.
setCurNode
=
setCurNode
const
mapW
=
selector
.
offsetWidth
const
mapW
=
selector
.
offsetWidth
...
@@ -115,7 +119,8 @@ export default class RelationGraph {
...
@@ -115,7 +119,8 @@ export default class RelationGraph {
width
:
mapW
,
width
:
mapW
,
height
:
mapH
,
height
:
mapH
,
},
},
configs
configs
,
{
colorList
}
)
)
// 需要高亮的node和link
// 需要高亮的node和link
...
@@ -175,7 +180,7 @@ export default class RelationGraph {
...
@@ -175,7 +180,7 @@ export default class RelationGraph {
.
attr
(
.
attr
(
'fill'
,
'fill'
,
(
d
)
=>
(
d
)
=>
(
d
&&
this
.
config
.
colorList
[
d
.
nodeLabel
||
'default'
])
||
(
d
&&
this
.
config
.
colorList
[
d
.
_label_key
||
'default'
])
||
this
.
config
.
nodeColor
this
.
config
.
nodeColor
)
)
...
@@ -404,7 +409,7 @@ export default class RelationGraph {
...
@@ -404,7 +409,7 @@ export default class RelationGraph {
openMenu
(
self
,
d
,
types
)
{
openMenu
(
self
,
d
,
types
)
{
this
.
setCurNode
(
d
)
this
.
setCurNode
(
d
)
menu
=
new
RadialMenu
().
radius
(
50
).
thickness
(
4
0
).
appendTo
(
self
.
parentNode
)
menu
=
new
RadialMenu
().
radius
(
38
).
thickness
(
3
0
).
appendTo
(
self
.
parentNode
)
if
(
!
types
)
{
if
(
!
types
)
{
menu
.
show
(
this
.
menuData
,
d
)
menu
.
show
(
this
.
menuData
,
d
)
}
else
{
}
else
{
...
@@ -532,11 +537,23 @@ export default class RelationGraph {
...
@@ -532,11 +537,23 @@ export default class RelationGraph {
const
objIndex
=
obj
.
index
const
objIndex
=
obj
.
index
this
.
dependsNode
=
this
.
dependsNode
.
concat
([
objIndex
])
this
.
dependsNode
=
this
.
dependsNode
.
concat
([
objIndex
])
this
.
dependsLinkAndText
=
this
.
dependsLinkAndText
.
concat
([
objIndex
])
this
.
dependsLinkAndText
=
this
.
dependsLinkAndText
.
concat
([
objIndex
])
this
.
config
.
links
.
forEach
((
lkItem
)
=>
{
if
(
objIndex
==
lkItem
.
source
.
index
)
{
this
.
config
.
links
.
forEach
((
link
)
=>
{
this
.
dependsNode
=
this
.
dependsNode
.
concat
([
lkItem
.
target
.
index
])
if
(
objIndex
==
link
.
source
.
index
)
{
}
else
if
(
objIndex
==
lkItem
.
target
.
index
)
{
this
.
dependsNode
=
this
.
dependsNode
.
concat
([
link
.
target
.
index
])
this
.
dependsNode
=
this
.
dependsNode
.
concat
([
lkItem
.
source
.
index
])
}
else
if
(
objIndex
==
link
.
target
.
index
)
{
this
.
dependsNode
=
this
.
dependsNode
.
concat
([
link
.
source
.
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
])
}
else
if
(
secondNodes
.
indexOf
(
link
.
target
.
index
)
>=
0
)
{
this
.
dependsNode
=
this
.
dependsNode
.
concat
([
link
.
source
.
index
])
}
}
})
})
...
@@ -548,12 +565,11 @@ export default class RelationGraph {
...
@@ -548,12 +565,11 @@ export default class RelationGraph {
// 隐藏线
// 隐藏线
this
.
SVG
.
selectAll
(
'.edge'
)
this
.
SVG
.
selectAll
(
'.edge'
)
.
filter
(
(
d
)
=>
{
.
filter
(
return
(
(
d
)
=>
this
.
dependsLinkAndText
.
indexOf
(
d
.
source
.
index
)
==
-
1
&&
this
.
dependsLinkAndText
.
indexOf
(
d
.
source
.
index
)
==
-
1
&&
this
.
dependsLinkAndText
.
indexOf
(
d
.
target
.
index
)
==
-
1
this
.
dependsLinkAndText
.
indexOf
(
d
.
target
.
index
)
==
-
1
)
)
})
.
transition
()
.
transition
()
.
style
(
'opacity'
,
0.1
)
.
style
(
'opacity'
,
0.1
)
}
else
{
}
else
{
...
...
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