Hi. I’d like to have a tree of nodes where I can collapse and expand any node to control the visibility of its children. But I’d also like to be able to draw links between any two nodes to indicate that they have a relationship. These auxiliary links would not cause anything to collapse; I don’t want the target node of one of these relationships to count as a “child” of the source node.
Right now I’m using GraphLinksModel and binding a boolean data property to the “isTreeLink” link property. I can successfully create a graph where some of the links have isTreeLink=true and some have isTreeLink=false. But when I call collapseTree() on a node, it doesn’t do what I want it to.
I’ve generated a minimal test case. Here’s a silly diagram illustrating my test data.
The green links are tree links and the blue link is a non-tree link.
Nodes A and B have “collapse” buttons because they have tree children.
If I click the collapse button on B, I expect just node C to become hidden. But that’s not what happens! Instead, C and A both become hidden. The documentation for collapseTree says “Links for which Link#isTreeLink is false are ignored.” but that’s not what I’m seeing here.
When I used a js debugger to examine my nodes, I noticed that node A has the property treeParentNode=C, even though the link connecting C to A has isTreeLink=false. That seems like an inconsistent state!
Is binding to “isTreeLink” not supported, or am I doing something wrong? Does anyone have any advice for how to get this to work, or for an alternative approach to getting the UI I want? I could just write equivalents to “collapseTree” and “expandTree” with my own graph traversal code in them, but I’d like to avoid doing that if possible.
Here is the sample program demonstrating the problem: click “Collapse B” and you’ll see C and A disappear.
<html>
<head>
<script src="go.js"></script>
<script id="code">
function init() {
var $ = go.GraphObject.make;
myDiagram = $(go.Diagram, "myDiagram", { initialContentAlignment: go.Spot.Center });
//stuff to make the nodes show up reasonably
myDiagram.nodeTemplate =
$(go.Node, "Auto",
$(go.Shape, "RoundedRectangle",
new go.Binding("fill", "color")),
$(go.TextBlock,
{ margin: 3 },
new go.Binding("text", "key"))
);
<span ="Apple-tab-span" style="white-space:pre"> </span>//link template that binds the isTreeLink data property to the isTreeLink node property
myDiagram.linkTemplate =
$(go.Link,
$(go.Shape),
$(go.Shape, { toArrow: "Standard" }),
<span ="Apple-tab-span" style="white-space:pre"> </span> new go.Binding("isTreeLink", "isTreeLink")
);
// my simple test data that doesn't do what I expect
myDiagram.model = new go.GraphLinksModel(
[
{ key: "A", color: "lightblue" },
{ key: "B", color: "lightblue" },
{ key: "C", color: "lightblue" }
],
[
{ from: "A", to: "B", isTreeLink: true },
{ from: "B", to: "C", isTreeLink: true },
{ from: "C", to: "A", isTreeLink: false }
]);
}
function collapseB() {
<span ="Apple-tab-span" style="white-space:pre"> </span>myDiagram.findNodeForKey("B").collapseTree();
}
function expandB() {
<span ="Apple-tab-span" style="white-space:pre"> </span>myDiagram.findNodeForKey("B").expandTree();
}
</script>
</head>
<body onload="init()">
<div id="myDiagram" style="border: solid 1px black; width:400px; height:400px"></div>
<button onclick="collapseB()">Collapse B</button>
<button onclick="expandB()">Expand B</button>
</body>
</html>
Thanks for any help