参考http://t.csdn.cn/VYezb此篇文章跟方便理解配置项
Step 1: 使用命令行在项目目录下执行以下命令:
npm install --save @antv/g6
Step 2: 在需要用的 G6 的 JS 文件中导入:
import G6 from '@antv/g6';
import insertCss from 'insert-css'
Step1:创建一个容器
<div id="container"></div>
Step2:绘制树状图函数
showChart() {
insertCss(`
.g6-component-tooltip {
background-color: rgba(0,0,0, 0.65);
padding: 10px;
box-shadow: rgb(174, 174, 174) 0px 0px 10px;
width: fit-content;
color: #fff;
border-radius = 4px;
}
`)
document.getElementById('container')
const defaultConfig = {
width: 1600,
height: 600,
modes: {
default: ['zoom-canvas', 'drag-canvas']
},
animate: true,
defaultNode: {
type: 'flow-rect'
},
defaultEdge: {
type: 'cubic-horizontal',
style: {
stroke: '#CED4D9'
}
},
layout: {
type: 'indented',
direction: 'LR',
dropCap: false,
indent: 450,
center: [800, 300],
getHeight: () => {
return 60
}
}
}
const colors = {
1: '#F46649',
2: '#BBB7B7',
3: '#5BD8A6'
}
// 自定义节点、边
const registerFn = () => {
/**
* 自定义节点
*/
G6.registerNode(
'flow-rect',
{
shapeType: 'flow-rect',
draw(cfg, group) {
const {
name = '',
files,
projectId,
branchName,
confirmPerson,
confirmTime,
whiteString,
command,
subsystem,
isHighRiskCommandAlarms,
highRiskCommandAlarmNum,
whiteStringNum,
controllableParameters,
functionName,
children,
collapsed,
called,
status,
calls,
fuid,
tracingContext
} = cfg
const grey = '#CED4D9'
// 逻辑不应该在这里判断
const rectConfig = {
width: 200,
height: 60,
lineWidth: 1,
fontSize: 12,
fill: '#fff',
radius: 4,
stroke: grey,
opacity: 1
}
const nodeOrigin = {
x: rectConfig.width / 2,
y: rectConfig.height / 2
}
const textConfig = {
textAlign: 'left',
textBaseline: 'bottom'
}
const rect = group.addShape('rect', {
attrs: {
x: nodeOrigin.x,
y: nodeOrigin.y,
...rectConfig,
cursor: 'pointer',
stroke: whiteString === true || isHighRiskCommandAlarms === true ? '#F2AB3F' : '#eee'
},
name: 'main'
})
const rectBBox = rect.getBBox()
// price
group.addShape('text', {
attrs: {
...textConfig,
x: rectBBox.maxX - 100,
y: rectBBox.maxY - 20,
text: functionName.length > 10 ? functionName.substr(0, 10) + '...' : functionName,
fontSize: 16,
textAlign: 'center',
fill: '#000',
opacity: 0.85,
cursor: 'pointer'
},
name: 'title'
})
// bottom percent
group.addShape('rect', {
attrs: {
x: rectBBox.maxX - 170,
y: rectBBox.maxY - 35,
width: 12,
height: 12,
radius: [6, 6, 6, 6],
fill: colors[status]
}
})
// collapse rect
if (cfg.called) {
group.addShape('rect', {
attrs: {
x: rectConfig.width / 2 + rectConfig.width - 8,
y: rectConfig.height - 8,
width: 16,
height: 16,
stroke: 'rgba(0, 0, 0, 0.25)',
cursor: 'pointer',
fill: '#fff'
},
name: 'collapse-back',
modelId: cfg.id
})
// collpase text
group.addShape('text', {
attrs: {
x: rectConfig.width / 2 + rectConfig.width,
y: rectConfig.height,
textAlign: 'center',
textBaseline: 'middle',
text: children && children.length > 0 ? '-' : '+',
fontSize: 16,
cursor: 'pointer',
fill: 'rgba(0, 0, 0, 0.25)'
},
name: 'collapse-text',
modelId: cfg.id
})
}
this.drawLinkPoints(cfg, group)
return rect
},
update(cfg, item) {
const group = item.getContainer()
this.updateLinkPoints(cfg, group)
},
setState(name, value, item) {
if (name === 'collapse') {
const group = item.getContainer()
const collapseText = group.find((e) => e.get('name') === 'collapse-text')
if (collapseText) {
if (!value) {
collapseText.attr({
text: '-'
})
} else {
collapseText.attr({
text: '+'
})
}
}
}
},
getAnchorPoints() {
return [
[0, 0.5],
[1, 0.5]
]
}
},
'rect'
)
G6.registerEdge(
'flow-cubic',
{
getControlPoints(cfg) {
let controlPoints = cfg.controlPoints // 指定controlPoints
if (!controlPoints || !controlPoints.length) {
const { startPoint, endPoint, sourceNode, targetNode } = cfg
const { x: startX, y: startY, coefficientX, coefficientY } = sourceNode
? sourceNode.getModel()
: startPoint
const { x: endX, y: endY } = targetNode ? targetNode.getModel() : endPoint
let curveStart = (endX - startX) * coefficientX
let curveEnd = (endY - startY) * coefficientY
curveStart = curveStart > 40 ? 40 : curveStart
curveEnd = curveEnd < -30 ? curveEnd : -30
controlPoints = [
{ x: startPoint.x + 200 + curveStart, y: startPoint.y },
{ x: endPoint.x + 200 + curveEnd, y: endPoint.y }
]
}
return controlPoints
},
getPath(points) {
const path = []
path.push(['M', points[0].x, points[0].y])
path.push([
'C',
points[1].x,
points[1].y,
points[2].x,
points[2].y,
points[3].x,
points[3].y
])
return path
}
},
'single-line'
)
}
registerFn()
// 组件props
const props = {
data: this.mockData,
config: {
padding: [20, 50],
defaultLevel: 3,
defaultZoom: 0.8,
modes: { default: ['zoom-canvas', 'drag-canvas'] }
}
}
const { data } = props
const initGraph = (data) => {
if (!data) {
return
}
const { onInit, config } = props
const tooltip = new G6.Tooltip({
offsetX: 20,
offsetY: 30,
itemTypes: ['node'],
getContent: (e) => {
const outDiv = document.createElement('div')
const nodeName = e.item.getModel().functionName
let formatedNodeName = ''
for (let i = 0; i < nodeName.length; i++) {
formatedNodeName = `${formatedNodeName}${nodeName[i]}`
if (i !== 0 && i % 20 === 0) formatedNodeName = `${formatedNodeName}<br/>`
}
outDiv.innerHTML = `${formatedNodeName}`
return outDiv
},
shouldBegin: (e) => {
if (e.target.get('name') === 'main') return true
if (e.target.get('name') === 'title') return true
return false
}
})
this.graph = new G6.TreeGraph({
container: 'container',
...defaultConfig,
...config,
plugins: [tooltip]
})
if (typeof onInit === 'function') {
onInit(this.graph)
}
this.graph.data(data)
this.graph.render()
this.graph.zoom(config.defaultZoom || 1)
const handleCollapse = (e) => {
const target = e.target
const id = target.get('modelId')
const item = this.graph.findById(id)
const nodeModel = item.getModel()
if (nodeModel.called && nodeModel.children === null) {
if (nodeModel.status === '3' || nodeModel.status === 3) {
this.$message.error('当前节点已标记为安全,不支持展开!')
} else {
queryCommandInjectionChildNext({
called: nodeModel.called,
calls: nodeModel.calls,
id: nodeModel.id,
functionName: nodeModel.functionName,
product: nodeModel.product,
status: nodeModel.status,
version:nodeModel.version,
fuid: nodeModel.fuid,
subsystem: nodeModel.subsystem,
tracingContext: nodeModel.tracingContext
}).then(
(res) => {
if (res.code === '0') {
nodeModel.children = res.data
nodeModel.collapsed = false
this.graph.layout()
this.graph.setItemState(item, 'collapse', nodeModel.collapsed)
}
}
)
}
} else {
nodeModel.collapsed = !nodeModel.collapsed
this.graph.layout()
this.graph.setItemState(item, 'collapse', nodeModel.collapsed)
}
}
this.graph.on('collapse-text:click', (e) => {
handleCollapse(e)
})
this.graph.on('collapse-back:click', (e) => {
handleCollapse(e)
})
this.graph.on('main:click', (ev) => {
this.cunData = ev.item._cfg.model
const data = ev.item._cfg.model
this.handleForm(data)
})
this.graph.on('title:click', (ev) => {
this.cunData = ev.item._cfg.model
const data = ev.item._cfg.model
this.handleForm(data)
})
}
initGraph(data)
}