我正在为Power BI自定义可视化开发一个可折叠的树。我想实现一个切换功能,当我单击它时,它将允许我向上或向下钻取节点。下面我提供了当前用于渲染树的代码和当单击节点时执行的其他方法。我认为当单击节点时,renderTree方法再次从click方法中调用,结果再次渲染整个树。因此,我无法看到正在切换的节点。为此,我需要什么更改或任何其他方法。提前感谢。
以下是我到目前为止尝试的方法,但它没有给予我正确的结果。在这种情况下,测量的数据实际上是一个json树,并且tree()和diagonal()已经在类Visual的全局范围内声明,就像这样:
// Declare an interface for the links/connections
interface LinkCoords {
x: number;
y: number;
}
// Declare an interface for a tree node
interface TreeNode {
name: string;
children?: TreeNode[];
// Dynamic addition of any incoming columns from analyze by data role
[key: string]: number | string | undefined | TreeNode[];
}
// Create a tree layout
private tree = d3
.tree()
// Height and width of the separations
.nodeSize([50, 300])
// Wether or not the nodes have same parent, there should be a separation of 2 units between nodes
.separation(function separation(a, b) {
return a.parent == b.parent ? 2 : 2;
});
// Links properties
private diagonal = d3
.linkHorizontal<{}, LinkCoords>()
.x((d) => d.y)
.y((d) => d.x);
// Function that would render the tree on the canvas
private renderTree(measuredData: TreeNode) {
// Compute the hierarchy
const root = d3.hierarchy(measuredData);
// Call the tree function
this.tree(root);
// Node variable
const node = this.treeContainer
.selectAll(".node")
.data(root.descendants())
.enter()
.append("g")
.attr("transform", function (d: any) {
return "translate(" + (d.y + 20) + "," + (d.x + 307) + ")";
})
.attr("font-size", 10)
.on("click", (event, d) => this.click(d.data));
// Node properties
node
.append("rect")
.attr("width", 150)
.attr("height", 50)
.style("stroke", function (d) {
return d.children ? "#5CCE8A" : "#D45F5F";
})
.attr("fill", "grey");
// Node text properties
node
.append("text")
.attr("x", 70)
.attr("y", 25)
.attr("text-anchor", "middle")
.text(
(d) => `name: ${d.data.name}, value: ${d.data.V}, import: ${d.data.I}`
)
.attr("fill", "white");
// Create links
const link = this.treeContainer
.selectAll(".link")
.data(root.links())
.enter();
// Define the path source and target for the links
link
.append("path")
.attr("class", "link")
.attr("fill", "none")
.attr("stroke", "white")
.attr("d", (d) => {
// Define the source
const source: LinkCoords = {
x: (d.source as any).x + 332,
y: (d.source as any).y + 170,
};
// Define the target
const target: LinkCoords = {
x: (d.target as any).x + 332,
y: (d.target as any).y + 20,
};
return this.diagonal({ source, target });
})
.attr("stroke-width", "1px")
.attr("stroke-dasharray", "1, 0");
}
// Toggle the node
private click(d: any) {
if (d.children) {
// If the clicked node has children
d._children = d.children; // Hide its children
d.children = null;
} else {
// If the clicked node does not have children
d.children = d._children; // Show its children
d._children = null;
}
this.renderTree(d);
}
1条答案
按热度按时间wydwbb8l1#
你不能看到被切换的节点的原因是因为每次你点击一个节点,你都在用更新的数据重新渲染整个树。你应该通过更新需要切换的节点的属性来修改现有的树,而不是重新渲染整个树。
为了实现这一点,您可以为每个节点添加一个“collapsed”属性,该属性将根据节点是折叠还是展开而设置为true或false。然后,在click函数中,您可以切换单击的节点及其子节点的“collapsed”属性,然后更新SVG中相应节点的属性。
你可以改变一些东西,