const COLLAPSE_ICON = function COLLAPSE_ICON(x, y, r) {
return [
['M', x - r, y - r],
['a', r, r, 0, 1, 0, r * 2, 0],
['a', r, r, 0, 1, 0, -r * 2, 0],
['M', x + 2 - r, y - r],
['L', x + r - 2, y - r],
]
}
const EXPAND_ICON = function EXPAND_ICON(x, y, r) {
return [
['M', x - r, y - r],
['a', r, r, 0, 1, 0, r * 2, 0],
['a', r, r, 0, 1, 0, -r * 2, 0],
['M', x + 2 - r, y - r],
['L', x + r - 2, y - r],
['M', x, y - 2 * r + 2],
['L', x, y - 2],
]
}
const getIcon = function getIcon(cfg) {
if (cfg.hasChildren && cfg.collapsed === undefined) {
return EXPAND_ICON
} else {
return cfg.collapsed ? EXPAND_ICON : COLLAPSE_ICON
}
}
drawGqTree(data) {
G6.registerNode('icon-node', {
options: {
size: [60, 20],
stroke: '
fill: '
},
draw(cfg, group) {
const styles = this.getShapeStyle(cfg)
const {labelCfg = {}} = cfg
const w = styles.width
const h = styles.height
const keyShape = group.addShape('rect', {
attrs: {
...styles,
},
})
if (cfg.hasChildren) {
group.addShape('marker', {
attrs: {
x: 66,
y: 6,
r: 6,
stroke: '
fill: '
cursor: 'pointer',
symbol: getIcon(cfg),
click: function (params) {
// console.log(params)
}
},
name: 'collapse-icon'
})
}
if (cfg.name) {
/** 判断文字位置,折行等 **/
let textY
let content = cfg.name
if (cfg.name.length < 8) {
textY = 6
} else {
textY = 32 - h / 2
}
let UpXy = {
y: 32,
}
let DownXy = {
y: -24,
}
let Y
if (cfg.showDirection === "in") {
Y = UpXy.y
} else if (cfg.showDirection === "out") {
Y = DownXy.y
}
if (cfg.name.length > 8 && cfg.name.length <= 16) {
content = content.slice(0, 8) + '\n' + content.slice(8)
} else if (cfg.name.length > 16) {
content = content.slice(0, 8) + '\n' + content.slice(8, 16) + '...'
}
/**添加节点名称**/
group.addShape('text', {
attrs: {
...labelCfg.style,
text: content,
textAlign: 'center',
x: 60 - w / 2,
y: textY,
},
})
/**持股比例信息**/
group.addShape('text', {
attrs: {
fill: '
fontSize: 10,
text: cfg.percent,
textAlign: 'center',
x: 32,
y: Y,
},
})
// /**持股比例信息文字**/
// group.addShape('text', {
// attrs: {
// fill: '
// fontSize: 10,
// text: cfg.leftText,
// textAlign: 'center',
// x: -28,
// y: Y,
// },
// })
}
return keyShape
},
update: undefined,
},
'rect',
)
G6.registerEdge('flow-line', {
draw(cfg, group) {
const startPoint = cfg.startPoint
const endPoint = cfg.endPoint
const {style} = cfg
let isEnt
if (cfg.targetNode._cfg.model.showDirection === "out") {
//out代表对外投资
isEnt = true
let shape = group.addShape('path', {
attrs: {
stroke: style.stroke,
endArrow: style.endArrow ,
path: [
['M', startPoint.x, startPoint.y],
['L', startPoint.x, (startPoint.y + endPoint.y) / 2],
['L', endPoint.x, (startPoint.y + endPoint.y) / 2],
['L', endPoint.x, endPoint.y - 2],
],
},
})
return shape
} else {
isEnt = false
let shape = group.addShape('path', {
attrs: {
stroke: style.stroke,
endArrow: style.reverseArrow,
path: [
['M', startPoint.x, startPoint.y],
['L', startPoint.x, (startPoint.y + endPoint.y) / 2],
['L', endPoint.x, (startPoint.y + endPoint.y) / 2],
['L', endPoint.x, endPoint.y + 28],
],
},
})
return shape
}
},
})
const defaultStateStyles = {
hover: {
stroke: '
lineWidth: 1.6,
},
}
const defaultNodeStyle = {
fill: '
stroke: '
radius: 2,
lineWidth: 1,
}
const defaultEdgeStyle = {
stroke: '
endArrow: {
path: "M 0,0 L 8, 3 L 8,0 L 8, -3 Z",
fill: '
stroke: '
d:-20,
},
reverseArrow: {
path: 'M 8,0 L 0, 3 L 0,0 L 0, -3 Z',
fill: '
stroke: '
d: -20,
}
}
const defaultLayout = {
type: 'compactBox',
direction: 'V', //V 垂直分布 H 水平分布
getId: function getId(d) {
return d.id
},
getHeight: function getHeight() {
return 16
},
getWidth: function getWidth() {
return 16
},
getVGap: function getVGap() {
return 50
},
getHGap: function getHGap() {
return 70
},
getSide: (d) => {
/**上下布局,此处判断在节点上还是下**/
if (d.data.showDirection === "out") {
return 'right'
} else {
return 'left'
}
}
}
const defaultLabelCfg = {
style: {
fill: '
fontSize: 11,
},
}
const container = document.getElementById('container')
const width = container.scrollWidth
const height = document.body.clientHeight -240
const graph = new G6.TreeGraph({
container: 'container',
width,
height,
linkCenter: true,
modes: {
default: ['drag-canvas', 'zoom-canvas'],
},
defaultNode: {
type: 'icon-node',
size: [120, 40],
style: defaultNodeStyle,
labelCfg: defaultLabelCfg,
},
defaultEdge: {
type: 'flow-line',
style: defaultEdgeStyle,
},
nodeStateStyles: defaultStateStyles,
edgeStateStyles: defaultStateStyles,
layout: defaultLayout,
})
graph.data(data)
graph.render()
graph.fitCenter()
graph.on('node:mouseenter', (evt) => {
// console.log(evt)
})
//
graph.on('node:mouseleave', (evt) => {
// const {item} = evt
// graph.setItemState(item, 'hover', false)
})
graph.on('node:click', async (evt) => {
let {item, target} = evt
let targetType = target.get('type')
const name = target.get('name')
const model = item.getModel()
if(targetType === 'marker'){
if (target.attr('symbol') === EXPAND_ICON) { //判断点击为'+'号
if (name === 'collapse-icon') {
if (!model.children) {
model.children = []
}
let params = {
type: model.showDirection,
name: model.name
}
let result = await PlantformService.getInvestRelationSearch(params)
if (result.message.code === 0) {
if (result.data && result.data.children) {
result.data.children.forEach((item, index) => {
//beInvestFlag type为in时判断 beInvestFlag 是否有子节点
if (model.showDirection === 'in') {
if (item.properties.beInvestFlag === "true") {
item.hasChildren = true
} else {
item.hasChildren = false
}
} else if (model.showDirection === 'out') {
if (item.properties.investFlag === "true") {
item.hasChildren = true
} else {
item.hasChildren = false
}
}
item.name = item.properties.name
item.oldId = item.id
let date = new Date().getTime()
const reserveId = `${date}${Math.random()}`
item.id = reserveId
item.percent = accMul(item.properties.stockPercent.substring(0, 4),100) + "%"
// item.percent = (item.properties.stockPercent.substring(0, 4)) * 100 + "%"
item.showDirection = params.type
// item.leftText = '控股'
})
model.children = result.data.children
}
}
const icon = item.get('group').find(element => element.get('name') === 'collapse-icon')
icon.attr('symbol', COLLAPSE_ICON)
model.collapsed = false
graph.focusItem(model.id)
graph.updateChild(model, model.id)
}
} else if (target.attr('symbol') === COLLAPSE_ICON) {
model.children = []
const icon = item.get('group').find(element => element.get('name') === 'collapse-icon')
icon.attr('symbol', EXPAND_ICON)
model.collapsed = true
graph.focusItem(model.id)
graph.updateChild(model, model.id)
}
}else if (targetType === 'text'){ // 点击节点
alert(model.name)
}
})
if (typeof window !== 'undefined')
window.onresize = () => {
if (!graph || graph.get('destroyed')) return
if (!container || !container.scrollWidth || !container.scrollHeight) return
graph.changeSize(container.scrollWidth, container.scrollHeight)
}
}