Add child to parent node(treeview) when object is dropped in mydiagram

I have a palette from which I can drag a shape(eg roundedrectangle) into my diagram on right side and a tree node present on the left side. As soon as the shape is dragged into myDiagram, shape should be added as a child to the parent node and also Tree should be interacting with the mydiagram panel.

There are a lot of possibilities in your empty diagrams. It’s hard to guess what you want.

Have you seen ?

But beware that it is complex due to its specific nature, and I don’t know if that is what you want.

Yes Walter I have seen

I have tried the below using i.e., whenever user drops object into the parent group, tree is updated , similarly i want the dropped object to get added as child when it is dropped in the diagram panel instead of the parent group .

This is want to achieve this below steps
1.user can enter a parent name in the popup/textbox which will be updated as tree parent node in the left panel.
2.When user drops the shape(rounded rectangle) from right panel to diagram panel instead of parent group(i.e., I need the whole diagram panel should act as parent group), the shape has to get added as a child to the parent node which is already present and so on.
3. Whenever a tree is modified it should sync with the diagram.



If you copied the code from the Regrouping Tree View sample, you have almost all of the functionality that you want.

If you want users to be able to drag-and-drop in the tree view diagram, you will need to implement mouseDrop event handlers on the nodes in that diagram and on the diagram itself for when the user drops in the background. See for example the Node.mouseDrop handler in

  1. You can either set the Part.containingGroup in the grouping diagram or in the tree view diagram you can set the Link.fromNode of the Node.findTreeParentLink() if it exists, or if it doesn’t exist you can create a new link. This is demonstrated in the mouseDrop handler in the Org Chart Editor. Remember to execute everything within a transaction.

  2. I don’t understand what you want to do, if it isn’t what is already implemented by the Regrouping Tree View sample.

  3. That is what the “ModelChanged” listener does in each of the two diagrams.

Hi Walter,

I have tried the below code snippet of “ModelChanged” Listener and i am able to add the child to the tree node but I am facing the below issues

1.When the object is dropped into the diagram panel it is getting added under the parent in the treeview , whenever i try to edit the text of the dropped item in the diagram panel it is not getting updated into the treeview and vice versa.

2.Also whenever Delete the object in diagram it is not getting deleted from the treeview and vice versa.

Code of addChangedListener(sorry indent is not working):

myDiagram.model.addChangedListener(function(e, obj) {
    var int_state_name;
    if (e.model.skipsUndoManager) return;
    // don't need to start/commit a transaction because the UndoManager is shared with myTreeView
    if (e.modelChange === "nodeGroupKey" || e.modelChange === "nodeParentKey") {
        // handle structural change: group memberships
        var treenode = myTreeView.findNodeForData(e.object);
        if (treenode !== null) treenode.updateRelationshipsFromData();
    } else if (e.change === go.ChangedEvent.Property) {
        var treenode = myTreeView.findNodeForKey(e.oldValue);
        myTreeView.startTransaction("add node and link");
        myTreeView.model.setDataProperty(treenode, "text", e.newValue);
        myTreeView.commitTransaction("add node and link");
        //alert('oldParam : ' + e.object.toString() + ' newValue:' + e.newValue); 
    } else if (e.change === go.ChangedEvent.Insert && e.propertyName === "nodeDataArray") {
        alert('Insert : ' + e.newParam);
        // pretend the new data isn't already in the nodeDataArray for myTreeView
        // now add to the myTreeView model using the normal mechanisms
        int_state_name = 'NoName_' + state_cnt;
        var childNode = {
            "key": int_state_name,
            "parent": "StateMachine",
            "text": int_state_name
        //myTreeView.model.nodeDataArray.splice(e.newParam, 1);
        myTreeView.startTransaction("add node and link");
        myTreeView.commitTransaction("add node and link");
    } else if (e.change === go.ChangedEvent.Remove && e.propertyName === "nodeDataArray") {
        var treenode = myTreeView.findNodeForKey(e.oldValue);
        myTreeView.startTransaction("remove node and link");
        myTreeView.commitTransaction("remove node and link");
        // remove the corresponding node from myTreeView 


Ankith Jain.

In this forum you need to surround your code with triple-backquotes in order to format your code.

In the Regrouping Tree View,, it is already the case that editing the text in one view updates the other view, and that deleting a node in one view deletes it in the other view. Is your code not starting with the same code as that sample?

  1. We have a Panel where GraphModel will be displayed in drawing area(at the center) and another tree view(on left panel) containing its own set of nodeDataArray.
    nodeDataArray of GraphModel(of drawing area) is not the same as the nodeDataArray of Tree(view). Only few of the nodes dropped onto the drawing area get
    inserted into the tree. And tree has other source from where its nodes can get filled.
    How can we implement this ?
    Most of the examples in goJS samples have common nodeDataArray between GraphModel and TreeModel. It doesnt suit us.

We did try implementing addChangedListener to get all events(Node added, text changed, node removed).
We faced following issue ->

a. Node Insertions is fine. We get e.newParam and we use this as the Key to insert into the Tree.
b. When text of a node is modified (We are expected to update the tree node also) we get this event
e.change === go.ChangedEvent.Property
But e.oldParam is not available, which is the key for us to dip into TreeModel.
As per your documentation:
" Other kinds of changed events include ChangedEvent.Insert and ChangedEvent.Remove. In addition to all of the previously mentioned ChangedEvent properties used to record a property change, the ChangedEvent.oldParam and ChangedEvent.newParam provide the “index” information needed to be able to properly undo and redo the change."
So we are not able to update text on tree Node.

c. Same case where e.change === go.ChangedEvent.Remove
e.oldParam is not available. So we are not able to delete the node from Tree.

  1. The same GraphModel (as described in 1. above) has a nodeDataArray being sourced from an external .json file.
    And we can work on that model by adding new nodes/modifying text etc.
    In our application, user can decide to open another model using another .json file, then we need to minimize the
    current openend GraphModel and replace the drawing area with GraphModel from newly chosen .json file.
    Now there are 2 graphmodels available and user should be able to switch between them (we are planning to provide a button tab
    below the drawing are to switch between them).
    Our doubt is how to keep these windows active? User should be able to switch to miminized graphModel and should be able to
    undo, redo etc.,
    How about other edit options like cut, paste? Will clipboard operations be supported across these multiple windows.
    I mean we should be able to cut from one window and paste onto another.


This is very confusing. It appears that you are asking multiple questions, but I still cannot tell what you have implemented so far. If you have questions about different topics, please create separate forum topics for them.

Actually, the only sample that has two models sharing the same nodeDataArray is that Regrouping Tree View sample. I believe all other samples that have multiple models also have separate nodeDataArrays. Since it appears that your requirements are different, let’s forget about that Regrouping Tree View sample.

I believe you do want to set up Model Changed listeners in order to keep the other Model (and thus the other Diagram) up-to-date.

When the user edits some text and there is a TwoWay Binding on TextBlock.text to some node data property, there will be a “Property” ChangedEvent for the model where the ChangedEvent.object will be the node data object, the ChangedEvent.propertyName will be your chosen property name for that text string, the ChangedEvent.oldValue will be the previous string value, and the ChangedEvent.newValue will be the new string value. Are you looking for any other information? The ChangedEvent is always sufficient to describe the change, because undo and redo work.

When node data is added or removed from the Model.nodeDataArray, there is an “Insert” or “Remove” ChangedEvent, and the ChangedEvent.propertyName and the ChangedEvent.modelChange will be “nodeDataArray”.

When inserting, the ChangedEvent.newValue will be the new node data object and the ChangedEvent.newParam will be the index into the array.

Similarly, when removing, the ChangedEvent.oldValue will be the old node data object and the ChangedEvent.oldParam will be the former index into the array.

This is all described in more detail at

It sounds to me that you want to keep multiple Models around in memory while re-using the same Diagram. Just set Diagram.model when you want to switch.