子节点收缩
javascript
const collapseIcon = (x, y, r) => {
// 折叠
return [
['M', x - r, y],
['a', r, r, 0, 1, 0, r * 2, 0],
['a', r, r, 0, 1, 0, -r * 2, 0],
['M', x - r + 4, y],
['L', x - r + 2 * r - 4, y]
]
}
const expandIcon = (x, y, r) => {
// 拓展
return [
['M', x - r, y],
['a', r, r, 0, 1, 0, r * 2, 0],
['a', r, r, 0, 1, 0, -r * 2, 0],
['M', x - r + 4, y],
['L', x - r + 2 * r - 4, y],
['M', x - r + r, y - r + 4],
['L', x, y + r - 4]
]
}
draw(cfg, group) {
const { noSubsetSty, collapsed } = cfg
if (noSubsetSty) { // 需要折叠的节点标志,在数据中处理添加标记
group.addShape('circle', {
attrs: {
x: size,
y: 0,
r: 13,
fill: 'rgba(47, 84, 235, 0.15)',
opacity: 0,
zIndex: -2
},
name: 'collapse-icon-bg'
})
group.addShape('marker', {
attrs: {
x: size,
y: 0,
r: 7,
symbol: collapsed ? collapseIcon : expandIcon,
stroke: 'rgba(0,0,0,1)',
fill: 'rgba(0,0,0,0)',
lineWidth: 1,
cursor: 'pointer'
},
name: 'collapse-icon'
})
}
},
afterDraw(cfg, group) {
const icon = group.find(
element => element.get('name') === 'collapse-icon'
)
if (icon) {
const bg = group.find(
element => element.get('name') === 'collapse-icon-bg'
)
icon.on('mouseenter', () => {
bg.attr('opacity', 1)
})
icon.on('mouseleave', () => {
bg.attr('opacity', 0)
})
}
},
setState(name, value, item) {
const group = item.getContainer()
if (group.get('children')) {
if (name === 'collapsed') {
const marker = item
.get('group')
.findAll(ele => ele.get('name') === 'collapse-icon')
marker[0] &&
marker[0].attr('symbol', value ? collapseIcon : expandIcon)
if (item._cfg.model.depth === 0) {
marker[1] &&
marker[1].attr('symbol', value ? collapseIcon : expandIcon)
}
}
}
}
javascript
this.graph.on('node:click', e => {
// 处理子节点展示问题 + -
if (e.target.get('name') === 'collapse-icon') {
const item = e.item
const nodeId = item.get('id')
const children = selectedWorks(nodeId, regroup.nodes, regroup.edges) // 查询相关子节点
let newNodes = children.nodes
if (newNodes.length) {
if (e.item._cfg.model.collapsed) {
for (let i = 0; i < newNodes.length; i++) {
this.hiddenElements.push(newNodes[i].id)
const item = this.graph.findById(newNodes[i].id)
this.graph.hideItem(item, true)
this.graph.paint()
}
} else {
for (let i = 0; i < newNodes.length; i++) {
this.hiddenElements.splice(
this.hiddenElements.indexOf(newNodes[i].id),
1
)
const item = this.graph.findById(newNodes[i].id)
this.graph.showItem(item, true)
this.graph.paint()
}
}
}
this.graph.layout({
type: 'force',
nodeSize: 50,
preventOverlap: true,
animate: false,
linkDistance: d => {
return 80
},
nodeStrength: -150,
onTick: () => {
this.graph.refreshPositions()
},
nodeSpacing: d => {
return 80
}
})
e.item._cfg.model.collapsed = !e.item._cfg.model.collapsed
this.graph.setItemState(
e.item,
'collapsed',
e.item._cfg.model.collapsed
)
this.graph.paint()
}
})
节点查找方法
javascript
/**
* 只有被指向的点并且没有指向的点 找最末端的点,并且被指向的方向只有一个
* source ----> target
*/
export function noSubsetHandle(nodeID, edges) {
let idT = edges.map(i => i.target)
let idS = edges.map(i => i.source)
Array.prototype.countCertainElements = function(value) {
return this.reduce((sum, element) => (element == value ? sum + 1 : sum), 0)
}
let index = idT.countCertainElements(nodeID)
let results =
idT.indexOf(nodeID + '') > -1 &&
index === 1 &&
idS.indexOf(nodeID + '') === -1
return results
}
/**
* @description 依据节点ID 查询 子集 和 相关 边
* @param {*} nodeID
* @param {*} nodes
* @param {*} edges
*/
export function selectedWorks(nodeID, nodes, edges) {
let edgesV = []
let nodesV = []
edges.map(e => {
if (+e.source === +nodeID) {
edgesV.push({ ...e })
}
})
if (edgesV.length > 0) {
nodes.map(e => {
if (edgesV.findIndex(x => +x.target === +e.id) > -1) {
if (noSubsetHandle(+e.id, edges)) {
nodesV.push({ ...e })
}
}
})
}
let edgesVv= []
edgesV.length && edgesV.map(i => {
if (nodesV.findIndex(x => +x.id === +i.target) > -1) {
edgesVv.push({...i})
}
})
let obj = {}
obj.nodes = nodesV
obj.edges = edgesVv
return obj
}