Update Demo GoJS Sample

This sample has two Diagrams, named "blueDiagram" and "greenDiagram", that display the same Model. Each diagram uses its own templates for its nodes and links, causing the appearance of each diagram to be different. However making a change in one diagram that changes the model causes those model changes to be reflected in the other diagram.

This sample also shows, next to the blue diagram, almost all of the ChangedEvents that the shared model undergoes. (For clarity it leaves out some of the Transaction-oriented events.) The model Changed listener adds a line for each ChangedEvent to the "modelChangedLog" DIV. Transaction notification events start with an asterisk "*", while property changes and collection insertions and removals start with an exclamation mark "!".

Next to the green diagram there is a tree view display of the UndoManager's history. The UndoManager.history is a List of Transactions, where each Transaction.changes property holds all of the ChangedEvents that occurred due to some command or tool operation. These ChangedEvents are reflective of both changes to the model (prefixed with "!m") and to the diagram (prefixed with "!d"). You will note that there are often several diagram changes for each model change.

This demo is different from the Two Diagrams sample, which is an example of two Diagrams, each sharing/showing a different Model, but sharing the same UndoManager.

Many of the other samples demonstrate saving the whole model by calling Model.toJson. If you want to save incrementally, you should do so at the end of each transaction, when ChangedEvent.isTransactionFinished. The ChangedEvent.object may be a Transaction or null if there were no recorded changes. Look through the Transaction.changes list for the model changes that you want to save. This code demonstrates the basic idea:

      model.addChangedListener(e => {
        if (e.isTransactionFinished) {
          const tx = e.object;
          if (tx instanceof go.Transaction) {
            console.log(tx.toString());
            tx.changes.each(c => {
              // consider which ChangedEvents to record
              if (c.model) console.log("  " + c.toString());
            });
          }
        }
      });

### GoJS Features in this sample

#### Tree Layout

This predefined layout is used for placing Nodes of a tree-structured graph in layers (rows or columns). For discussion and examples of the most commonly used properties of the TreeLayout, see the Trees page in the Introduction. More information can be found in the GoJS Intro.

Related samples

#### Buttons

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

#### HTML Interaction

GoJS Diagrams can be used alongside other HTML elements in a webapp. For custom Text Editors, Context Menus, and ToolTips, which are invoked and hidden via GoJS tool operations, it is best to use the HTMLInfo class.

More information can be found in the GoJS Intro.

Related samples