This diagram demonstrates the expansion of a tree where nodes are only created "on-demand", when the user clicks on the "expand" Button. As you expand the tree, it automatically performs a force-directed layout, which will make some room for the additional nodes.

The data for each node is implemented by a JavaScript object held by the Diagram's model. Each node data has an everExpanded property that indicates whether we have already created all of its "child" data and added them to the model. The everExpanded property defaults to false, to match the initial value of Node.isTreeExpanded in the node template, which specifies that the nodes start collapsed.

When the user clicks on the "expand" Button, the button click event handler finds the corresponding data object by going up the visual tree to find the Node via the GraphObject.part property and then getting the node data that the Node is bound to via If everExpanded is false, the code creates a random number of child data for that node, each with a random color property. Then the button click event handler changes the value of Node.isExpandedTree, thereby expanding or collapsing the node.

Some initial node expansions result in there being no children at all. In this case the Button is made invisible.

All changes are performed within a transaction. You should always surround your code with calls to Model.startTransaction and Model.commitTransaction, or the same methods on Diagram.

The diagram's Diagram.layout is an instance of ForceDirectedLayout. The standard conditions under which the layout will be performed include when nodes or links or group-memberships are added or removed from the model, or when they change visibility. In this case that means that when the user expands or collapses a node, another force-directed layout occurs again, even upon repeated expansions or collapses.

GoJS Features in this sample

Force Directed Layout

This predefined layout treats the graph as if it were a system of physical bodies with forces acting on and between them. The layout iteratively moves nodes and links to minimize the total sum of forces on each node. The resulting layout will normally not contain overlapping Nodes, excluding cases where the graph is densely interconnected. More information can be found in the GoJS Intro.

Related samples


GoJS defines several Panels for common uses. These include "Button", "TreeExpanderButton", "SubGraphExpanderButton", "PanelExpanderButton", "ContextMenuButton", and "CheckBoxButton". "ContextMenuButton"s are typically used inside of "ContextMenu" Panels; "CheckBoxButton"s are used in the implementation of "CheckBox" Panels.

These predefined panels can be used as if they were Panel-derived classes in calls to GraphObject.make. They are implemented as simple visual trees of GraphObjects in Panels, with pre-set properties and event handlers.

More information can be found in the GoJS Intro.

Related samples