[Bug]: indented layout:the expansion and collapse of a node cause the positions of the other nodes to change.
- Dominant language
- TypeScript
- Stars
- 12.3k
- Forks
- 1.6k
- PR merge metrics
- No merged PRs in 30d
Description
### Describe the bug / 问题描述
缩进树布局(indented)下,节点折叠展开操作,引发图内节点位置变动;
配置:
```
class TreeNode extends Rect {
get data() {
return this.context.model.getNodeLikeDatum(this.id);
}
get childrenData() {
return this.context.model.getChildrenData(this.id);
}
getKeyStyle(attributes, container = {}) {
const [width, height] = this.getSize(attributes, container);
return {
...super.getKeyStyle(attributes, container),
width,
height,
size: [width, height],
stroke: "#000000",
fill: "#ffffff",
lineWidth: 1,
};
}
getLabelStyle(attributes) {
const [width, height] = this.getSize(attributes);
return {
text: "name",
fontWeight: 500,
fontSize: 14,
fill: "#333333",
lineHeight: 22,
textAlign: "right",
x: width / 2 - 11,
y: height / 2 - 14,
};
}
getCollapseStyle(attributes, container) {
if (this.childrenData.length === 0) return false;
const { collapsed } = attributes;
const [width, height] = this.getSize(attributes, container);
return {
fill: "#F6F6F6",
lineWidth: 1,
stroke: "#D9D9D9",
size: 14,
x: width / 2 + 7,
y: 0,
icon: true,
iconFill: "#666666",
iconText: collapsed ? "+" : "-",
iconFontSize: 16,
iconFontWeight: 600,
iconHeight: 8,
iconWidth: 8,
cursor: "pointer",
iconTextAlign: "center",
iconTextBaseline: "middle",
};
}
drawCollapseShape(attributes, container) {
const collapseStyle = this.getCollapseStyle(attributes, container);
const btn = this.upsert("collapse", Circle, collapseStyle, container);
if (btn && !Reflect.has(btn, "__bind__")) {
Reflect.set(btn, "__bind__", true);
btn.addEventListener(CommonEvent.CLICK, () => {
const { collapsed } = this.attributes;
const graph = this.context.graph;
if (collapsed) {
graph.expandElement(this.id);
} else {
graph.collapseElement(this.id);
}
});
}
}
render(attributes = this.parsedAttributes, container) {
super.render(attributes, container);
this.drawCollapseShape(attributes, container);
this.drawKeyShape(attributes, container);
}
}
register(ExtensionCategory.NODE, "tree-node", TreeNode);
const drawTreeGraph = data => {
graph = new Graph({
container: containerRef.value,
height: 380,
data: tData,
background: "#fff",
autoResize: true,
zoom: 1,
zoomRange: [0.6, 1.6],
node: {
type: "tree-node",
style: d => {
const style = {
radius: 4,
ports: [{ placement: "left" }, { placement: "right" }],
};
const size = [200, 32];
Object.assign(style, {
size,
});
return style;
},
},
edge: {
type: "quadratic",
style: d => {
const style = {
labelAutoRotate: false,
curvePosition: 0.5,
curveOffset: -19,
labelText: d.trace_data_count,
labelFill: "#666666",
labelBackground: true,
labelBackgroundFill: "#fff",
labelBackgroundShadowColor: "#fff",
};
return style;
},
},
layout: {
type: "indented",
direction: "LR",
dropCap: false,
indent: 300,
getHeight: () => 32,
preLayout: true,
},
behaviors: ["drag-canvas"],
autoFit: "view",
});
graph.render();
};
```
bug现象录屏:
https://github.com/user-attachments/assets/74b1af51-b01c-443b-845c-f11e705dd308
### Reproduction link / 复现链接
_No response_
### Steps to Reproduce the Bug or Issue / 重现步骤
点击折叠,且被点击的节点拥有较多子节点
### Version / 版本
🆕 5.x
### OS / 操作系统
- [ ] macOS
- [x] Windows
- [ ] Linux
- [ ] Others / 其他
### Browser / 浏览器
- [x] Chrome
- [x] Edge
- [x] Firefox
- [x] Safari (Limited support / 有限支持)
- [ ] IE (Nonsupport / 不支持)
- [ ] Others / 其他
Contributor guide
No contributing guide indexed for this repository
Research direction
Start by reproducing the issue with the provided indented layout configuration and the custom TreeNode collapse handler, focusing on graph.collapseElement and graph.expandElement. Compare node positions before and after collapsing a node with many children; done means unrelated nodes retain their expected positions in the affected layout.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- data-visualization
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100