OK, here are the changes you can make to the Incremental Tree sample – let’s call it Incremental Parent.
First, I’ll add a “Button” to the node template:
),
// add a parent
$("Button",
{ alignment: go.Spot.TopLeft, click: addParent },
$(go.TextBlock, "P"),
new go.Binding("visible", "parent", function(k) { return k === undefined; })
),
// the expand/collapse button, at the top-right corner
I have positioned the new button to be at the top-left of the node, but of course you can position it any way you like. You can also customize the appearance to be whatever you like, instead of a dead-simple “P”.
Note also that there is a data Binding on the button’s GraphObject.visible property, so that the button becomes invisible if there is a parent key on the node data.
The behavior of the button (i.e. its GraphObject.click event handler) is defined by the addParent function:
function addParent(e, button) {
var diagram = button.diagram;
var model = diagram.model;
var node = button.part;
// don't add parent if it already exists
if (model.getParentKeyForNodeData(node.data) === undefined) {
model.startTransaction("add parent node");
// add parent node by adding new data object to model
var parentdata = {
key: model.nodeDataArray.length, // this is optional
//everExpanded: true, // not to automatically createSubTree on first expansion
color: go.Brush.randomColor() // add whatever properties you need for each node
};
model.addNodeData(parentdata);
// initialize parent Node
var parentnode = diagram.findNodeForData(parentdata);
parentnode.isTreeExpanded = true; // must be expanded, since child is already present
parentnode.location = node.location; // locate the new parent node close to this node
// create link between new parent node and this node
model.setParentKeyForNodeData(node.data, model.getKeyForNodeData(parentdata));
model.commitTransaction("add parent node");
}
}
Note that specifying the key property on each new node data object is not required, either here or in the createSubTree function. The model will automatically assign a unique key to each new node data. In case you do not assign the key yourself, the code to create a link between the nodes, TreeModel.setParentKeyForNodeData, uses the Model.getKeyForNodeData method to get the key for the new node data object after it has been added to the model.
Specific to this sample, the everExpanded property on the data can be either true or false, depending on whether you want to allow users to create new child nodes for the new parent node.