antvis/G6


Do you want to work on this issue?
You can request for a bounty in order to promote it!
[Bug]: Overlapping nodes after collapse issue - Indent tree layout does not recalculate node spacing correctly after collapse/expand operation #6751
TifaXu131 posted onGitHub
Describe the bug / 问题描述
在使用 G6 紧凑树(indent)布局时,当执行节点折叠操作后,部分节点出现重叠现象,有时候会前后颠倒
重现步骤: 点击折叠
G6 版本:5.0.42
<template>
<div id="container"></div>
</template>
<script setup>
import { onMounted, onUnmounted } from 'vue'
import { Rect as GRect, Text as GText } from '@antv/g'
import { Graph, GraphEvent, register, treeToGraphData, Badge, CommonEvent, ExtensionCategory } from '@antv/g6'
import { getTaskRelationTree } from '@/service/apis/task'
// 自定义节点:只保留 label 和折叠按钮逻辑
class TreeNode extends GRect {
// 获取 label 样式
getLabelStyle(attributes) {
const [width, height] = this.getSize(attributes)
return {
name: 'label',
x: -width / 2 + 8,
y: -height / 2 + 50,
text: this.data?.label,
fontSize: 12,
fill: '#000',
cursor: 'pointer'
}
}
// 绘制 label
drawLabelShape(attributes, container) {
const labelStyle = this.getLabelStyle(attributes)
const label = this.upsert('label', GText, labelStyle, container)
if (label && !Reflect.has(label, '__bind__')) {
Reflect.set(label, '__bind__', true)
label.addEventListener(CommonEvent.CLICK, () => {
// 点击 label 可执行跳转或其他操作
})
}
}
// 获取折叠按钮样式
getCollapseStyle(attributes) {
if (this.childrenData.length === 0) return false
const { collapsed } = attributes
const [width] = this.getSize(attributes)
return {
fill: '#D2D6DA',
fontSize: 16,
text: collapsed ? '+' : '-',
x: width / 2,
y: 0,
cursor: 'pointer'
}
}
// 绘制折叠按钮
drawCollapseShape(attributes, container) {
const collapseStyle = this.getCollapseStyle(attributes)
const btn = this.upsert('collapse', Badge, collapseStyle, container)
if (btn && !Reflect.has(btn, '__bind__')) {
Reflect.set(btn, '__bind__', true)
btn.addEventListener(CommonEvent.CLICK, () => {
try {
const { collapsed } = this.attributes
const graph = this.context.graph
if (collapsed) graph.expandElement(this.id)
else graph.collapseElement(this.id)
} catch (error) {
console.error(error)
}
})
}
}
// 重写 render,仅绘制 label 和折叠按钮
render(attributes = this.parsedAttributes, container) {
super.render(attributes, container)
this.drawCollapseShape(attributes, container)
this.drawLabelShape(attributes, container)
}
}
register(ExtensionCategory.NODE, 'tree-node', TreeNode)
let graph
let mindMapData = []
const getData = async () => {
// 此处替换为实际任务编码
const data = await getTaskRelationTree('some-task-code')
mindMapData = data
}
onMounted(async () => {
await getData()
graph = new Graph({
container: 'container',
data: treeToGraphData(mindMapData, {
getNodeData: (datum) => {
const nodeData = {
...datum,
id: datum.nodeId,
label: datum.name,
style: { collapsed: false }
}
if (datum.children && datum.children.length) {
nodeData.children = datum.children.map(child => child.nodeId)
}
return nodeData
},
getId: (d) => d.nodeId,
getEdgeData: (source, target) => ({
id: `${source.nodeId}-${target.nodeId}`,
source: source.nodeId,
target: target.nodeId
})
}),
node: {
type: 'tree-node',
style: {
size: [260, 80],
radius: 4
}
},
edge: {
type: 'cubic-horizontal',
style: {
stroke: '#D2D6DA',
lineWidth: 1,
controlPoints: true
}
},
layout: {
type: 'indented',
direction: 'LR',
dropCap: false,
indent: 340,
controlPoints: true,
getHeight: () => 60,
nodesep: 40,
ranksep: 120,
preLayout: false
},
behaviors: ['zoom-canvas', 'drag-canvas', 'drag-element']
})
graph.render()
graph.once(GraphEvent.AFTER_RENDER, () => {
graph.fitCenter()
})
})
onUnmounted(() => {
if (graph) graph.destroy()
mindMapData = null
graph = null
})
</script>
<style scoped>
#container {
position: relative;
height: 100%;
}
</style>
Reproduction link / 复现链接
No response
Steps to Reproduce the Bug or Issue / 重现步骤
点击折叠
G6 Version / G6 版本
Please select / 请选择
OS / 操作系统
- macOS
- Windows
- Linux
- Others / 其他
Browser / 浏览器
- Chrome
- Edge
- Firefox
- Safari (Limited support / 有限支持)
- IE (Nonsupport / 不支持)
- Others / 其他