Commit b9257356 authored by 郭铭瑶's avatar 郭铭瑶 🤘

删除边及选择性高亮功能

parent 2227c5ee
......@@ -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',
......
......@@ -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 10px
left 14px
.tag
cursor not-allowed
box-sizing border-box
border 2px solid transparent
&.click-able
cursor pointer
&.on
&:hover
box-shadow 0 0 4px 1px rgba(0,0,0,0.3)
&.on
border-color rgba(0,0,0,0.3)
</style>
<style lang="stylus">
......
......@@ -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,
......
......@@ -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.dependsLinkAndText = []
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.dependsLinkAndText = 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.dependsLinkAndText = []
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
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment