Model class

Models hold the essential data of a diagram, describing the basic entities and their properties and relationships without specifying the appearance and behavior of the Nodes and Links and Groups that represent them visually. Models tend to hold only relatively simple data, making them easy to persist by serialization as JSON or XML formatted text.

Models hold simple data objects, not Parts such as Nodes or Links. Node data is normally represented in a Diagram by instances of Node, but they could be represented by simple Parts or by Groups. A Diagram constructs Parts for its Diagram#model's data by copying templates. Templates are Panels of GraphObjects that get some property values from the model data, accessible via the Panel#data property, using data Binding. See Using Models and Data Binding for an introduction.

This Model class only supports holding an array of node data and interpreting properties on that data to be able to refer to them using unique key values. To support simple tree-structured graphs, use a TreeModel, which inherits from this class. To support links and grouping, use a GraphLinksModel.

Each node data object is assumed to have a unique key value. The #nodeKeyProperty property names the property on the node data whose value is the unique key for that node data object. The default value for this property is "key". You should not have a TwoWay data binding on the node key property, because that might cause the property value to be set to a duplicate key value.

The key values must be either strings or numbers or undefined. If the key is undefined, or if there are duplicate key values, the model will automatically try to assign a new unique key value. Caution: if your keys are numbers, do not try to use string representations of those numbers as keys. Conversely, if your keys are strings that happen to have number syntax, do not try to use those number values. Sometimes JavaScript will automatically convert from string to number or vice-versa, but sometimes it won't.

For example, one can define a graph consisting of just two nodes:

 model.nodeDataArray = [
   { key: "Alpha" },
   { key: "Beta" }
 ];

This model cannot detect the modification of the #nodeDataArray array or the modification of any node data object. If you want to add or remove node data from the #nodeDataArray, call the #addNodeData or #removeNodeData methods.

If you want to modify a node data object, it depends on whether the property you want to change is a structural property that the model needs to know about, or whether it is a property that is only used for data binding or other application-specific purposes.

For the former case, call the appropriate method, such as #setKeyForNodeData, #setCategoryForNodeData, GraphLinksModel#setToKeyForLinkData, or GraphLinksModel#setGroupKeyForNodeData. These methods have names that start with "set", "add", "insert", or "remove".

For the latter case, when setting an application-specific property, typically for data binding, and to support undo/redo, call #setDataProperty.

The #copyNodeData method can be called to make a shallow copy of a node data object. However, if some of those property values are Arrays that want not to be shared but to be copied, you can set #copiesArrays to true. This is typically very useful when dealing with data bound item arrays. Furthermore if the items in those copied Arrays are in fact Objects that need to be copied, you can also set #copiesArrayObjects to true, causing a copied Array to refer to newly shallow-copied objects of the original array.

Each model raises ChangedEvents that you can follow by registering a listener via #addChangedListener. Read more at the Introduction page: Changed Events.

Each model comes with its own UndoManager that is initially not enabled. You will need to set UndoManager#isEnabled to true in order for the UndoManager to record model changes and for your users to perform undo and redo.

You can temporarily turn off the recording of changes by setting #skipsUndoManager to true. A number of places within the system do that routinely in order to avoid recording temporary changes, so be sure to remember the original value beforehand and restore it afterwards. Note that in a ChangedEvent listener you may want to ignore events that happen when #skipsUndoManager is true.

One normally saves a diagram by just saving its model. If you can use JSON-formatted text, this is easy to do -- just call #toJson to get the string representation of the model, and save that string. Load the diagram by replacing the Diagram#model with one created by calling the static function Model.fromJson:

  myDiagram.model = go.Model.fromJson(loadedString);

Note that JSON and other textual data formats cannot faithfully store all JavaScript functions. #toJson and Model.fromJson do not try to save and load functional property values. You should arrange that all such functions, including event handlers, are established by your app. #toJson and Model.fromJson also cannot handle circular references; any sharing of references will be lost too. They also skip properties that are not enumerable, those whose names start with an underscore, and those whose values are undefined.

Note that models also do not store the templates used by diagrams, nor any transient or temporary parts such as Adornments, nor any tools, nor any UndoManager state, nor any event listeners. These objects and all other properties of diagrams must be established by your app.

You can add any number of properties to the #modelData object, which is serialized and deserialized into JSON just like any other model data for nodes or links. However #modelData is associated with the model as a whole and does not depend on the existence of any node data or link data.

It is also easy to save the changes that were recorded in the most recent transaction. Call #toIncrementalJson to generate a JSON-format string that holds the current state of modified data plus the keys of inserted or removed data. That method requires as an argument a ChangedEvent that represents a transaction that completed or an undo or a redo that just finished.

It is also possible to use such "incremental" JSON to modify an existing model. Call #applyIncrementalJson, giving it a string generated by #toIncrementalJson, to modify this model by making all of the changes recorded in the JSON text. Note how this method is a regular instance method, whereas Model.fromJson is a static function.

Implementers
Available extensions
Annotations
  • @JS()
  • @staticInterop

Constructors

Model.$1()
factory
Model.$2([dynamic init])
factory
Model.$3([Array<Object>? nodedataarray, dynamic init])
factory

Properties

afterCopyFunction ↔ void Function(Map<Object, Object>, Model, Model)?

Available on Model, provided by the Model$Typings extension

(undocumented) This function (if not null) is called towards the end of Diagram#copyParts in order to support custom data copying operations that depend on references between the parts.
getter/setter pair
copiesArrayObjects bool

Available on Model, provided by the Model$Typings extension

Gets or sets whether the default behavior for #copyNodeData or GraphLinksModel#copyLinkData when copying Arrays also copies array items that are Objects. This only covers copying Objects that are items in Arrays that are copied when #copiesArrays is true. Copying an Object when this property is true also recursively copies any Arrays that are property values. It also assumes that the object's constructor can be called with no arguments.
getter/setter pair
copiesArrays bool

Available on Model, provided by the Model$Typings extension

Gets or sets whether the default behavior for #copyNodeData or GraphLinksModel#copyLinkData makes copies of property values that are Arrays. This only copies Arrays that are top-level property values in data objects, not for Arrays that are in nested objects. Copying Arrays will also copy any array items that are Objects when #copiesArrayObjects is true.
getter/setter pair
copiesKey bool

Available on Model, provided by the Model$Typings extension

Gets or sets whether the default behavior for #copyNodeData or GraphLinksModel#copyLinkData when copying properties of a data object also copies the key property value. Set this to false in order to force a unique key generation for data copied from another Diagram, such as a Palette.
getter/setter pair
copyNodeDataFunction Object Function(Object, Model)?

Available on Model, provided by the Model$Typings extension

Gets or sets a function that makes a copy of a node data object.
getter/setter pair
dataFormat String

Available on Model, provided by the Model$Typings extension

Gets or sets the name of the format of the diagram data. The default value is the empty string. The value must not be null. Use different values to prevent parts from one model to be copy/pasted or drag-and-dropped into another diagram/model.
getter/setter pair
hashCode int
The hash code for this object.
no setterinherited
isReadOnly bool

Available on Model, provided by the Model$Typings extension

Gets or sets whether this model may be modified, such as adding nodes. By default this value is false. Setting the #nodeDataArray to something that is not a true Array of Objects will cause this to be set to true.
getter/setter pair
makeUniqueKeyFunction ↔ dynamic Function(Model, Object)?

Available on Model, provided by the Model$Typings extension

Gets or sets a function that returns a unique id number or string for a node data object. This function is called by #makeNodeDataKeyUnique when a node data object is added to the model, either as part of a new #nodeDataArray or by a call to #addNodeData, to make sure the value of #getKeyForNodeData is unique within the model.
getter/setter pair
modelData Object

Available on Model, provided by the Model$Typings extension

Gets a JavaScript Object that can hold programmer-defined property values for the model as a whole, rather than just for one node or one link.
getter/setter pair
name String

Available on Model, provided by the Model$Typings extension

Gets or sets the name of this model. The initial name is an empty string. The value must not be null.
getter/setter pair
nodeCategoryProperty Object

Available on Model, provided by the Model$Typings extension

Gets or sets the name of the node data property that returns a string naming that data's category. The value may also be a function taking two arguments, where the first argument will be a node data object. If the second argument is not supplied, the function should return the category name; if the second argument is supplied, the function should modify the node data object so that it has that new category name. The default value is the string 'category', meaning that it expects the data to have a property named 'category' if it cares to name a category. This is used by the diagram to distinguish between different kinds of nodes. The name must not be null. If the value is an empty string, #getCategoryForNodeData will return an empty string for all node data objects.
getter/setter pair
nodeDataArray Array<Object>

Available on Model, provided by the Model$Typings extension

Gets or sets the array of node data objects that correspond to Nodes, Groups, or non-Link Parts in the Diagram. The initial value is an empty Array.
getter/setter pair
nodeKeyProperty Object

Available on Model, provided by the Model$Typings extension

Gets or sets the name of the data property that returns a unique id number or string for each node data object. The value may also be a function taking two arguments, where the first argument will be a node data object. If the second argument is not supplied, the function should return the unique key value; if the second argument is supplied, the function should modify the node data object so that it has that new value as its unique key value. The default value is the name 'key', meaning that it expects the data to have a property named 'key' if it has a key value. The name must not be null or the empty string. You must set this property before assigning the #nodeDataArray.
getter/setter pair
runtimeType Type
A representation of the runtime type of the object.
no setterinherited
skipsUndoManager bool

Available on Model, provided by the Model$Typings extension

Gets or sets whether ChangedEvents are not recorded by the UndoManager. The initial and normal value is false. WARNING: while this property is true do not perform any changes that cause any previous transactions to become impossible to undo.
getter/setter pair
undoManager UndoManager

Available on Model, provided by the Model$Typings extension

Gets or sets the UndoManager for this Model.
getter/setter pair

Methods

addArrayItem(Array arr, [dynamic val]) → void

Available on Model, provided by the Model$Typings extension

Add an item at the end of a data array that may be data bound by a Panel as its Panel#itemArray, in a manner that can be undone/redone and that automatically updates any bindings.
addChangedListener(void listener(ChangedEvent)) Model

Available on Model, provided by the Model$Typings extension

Register an event handler that is called when there is a ChangedEvent.
addNodeData(Object nodedata) → void

Available on Model, provided by the Model$Typings extension

When you want to add a node or group to the diagram, call this method with a new data object. This will add that data to the #nodeDataArray and notify all listeners that a new node data object has been inserted into the collection.
addNodeDataCollection(Object coll) → void

Available on Model, provided by the Model$Typings extension

Add to this model all of the node data held in an Array or in an Iterable of node data objects. @param {Iterable.
applyIncrementalJson(Object s) → void

Available on Model, provided by the Model$Typings extension

Modify this model by applying the changes given in an "incremental" model change in JSON format generated by #toIncrementalJson. The expected properties of the argument are described at #toIncrementalJson. Incremental changes must be applied in the same order that the changes occurred in the original model.
assignAllDataProperties(Object data, Object props) → void

Available on Model, provided by the Model$Typings extension

This is similar to Object.assign, but safely calls #setDataProperty for each property other than a key property. This does not delete any properties on the DATA object, although properties may be set to undefined if they are set that way on the PROPS object. @param data a data object @param props an Object holding various properties whose values are to be assigned to the DATA object
changeState(ChangedEvent e, bool undo) → void

Available on Model, provided by the Model$Typings extension

(undocumented) This is called during an undo or redo to modify the model or its objects.
clear() → void

Available on Model, provided by the Model$Typings extension

Clear out all references to any model data. This also clears out the UndoManager, so this operation is not undoable. This method is called by Diagram#clear; it does not notify any Diagrams or other listeners. This method does not unregister any Changed event listeners.
clearUnresolvedReferences([dynamic key]) → void

Available on Model, provided by the Model$Typings extension

(undocumented) @param {string|number=} key
cloneDeep<T>(T obj) → T

Available on Model, provided by the Model$Typings extension

Deeply copy an object or array and return the new object. This is typically called on a #nodeDataArray or GraphLinksModel#linkDataArray or data objects within them.
cloneProtected(Model copy) → void

Available on Model, provided by the Model$Typings extension

Copies properties from this model to the given model, which must be of the same class. This is called by #copy. This method may be overridden. Please read the Introduction page on Extensions for how to override methods and how to call this base method.
commit(void func(Model), [String? tname]) → void

Available on Model, provided by the Model$Typings extension

Starts a new transaction, calls the provided function, and commits the transaction. Code is called within a try-finally loop. If the function does not return normally, this rolls back the transaction rather than committing it. Example usage:
commitTransaction([String? tname]) bool

Available on Model, provided by the Model$Typings extension

Commit the changes of the current transaction. This just calls UndoManager#commitTransaction. @param {string=} tname a descriptive name for the transaction. @return {boolean} the value returned by UndoManager#commitTransaction.
containsNodeData(Object nodedata) bool

Available on Model, provided by the Model$Typings extension

Decide if a given node data object is in this model, using reference equality.
copy() Model

Available on Model, provided by the Model$Typings extension

Creates a shallow copy of this Model and returns it. The data are not copied: #nodeDataArray, #modelData, GraphLinksModel#linkDataArray, GraphLinksModel#archetypeNodeData are left empty. Nor are any Changed listeners or the UndoManager copied. @expose @return {Model} an empty copy of the model with the same properties, other than data @since 1.6
copyNodeData(Object nodedata) Object?

Available on Model, provided by the Model$Typings extension

Make a copy of a node data object. This uses the value of #copyNodeDataFunction to actually perform the copy, unless that property is null. When it is null the default behavior is to just make a shallow copy of the JavaScript Object.
findNodeDataForKey(dynamic key) Object?

Available on Model, provided by the Model$Typings extension

Given a number or string, find the node data object in this model that uses the given value as its unique key. @param {(string|number|undefined)} key a string or a number. @return {Object} null if the key is not present in the model, or if the key is null or undefined or not a string or number. @see #containsNodeData @see #getKeyForNodeData
getCategoryForNodeData(Object nodedata) String

Available on Model, provided by the Model$Typings extension

Find the category of a given node data, a string naming the node template or group template or part template that the Diagram should use to represent the node data. @param {Object} nodedata a JavaScript object represented by a node, group, or non-link. @return {string} @see #nodeCategoryProperty @see #setCategoryForNodeData
getKeyForNodeData(Object nodedata) → dynamic

Available on Model, provided by the Model$Typings extension

Given a node data object return its unique key: a number or a string. This returns undefined if there is no key value.
insertArrayItem(Array arr, num idx, [dynamic val]) → void

Available on Model, provided by the Model$Typings extension

Add an item to a data array that may be data bound by a Panel as its Panel#itemArray, given a new data value and the index at which to insert the new value, in a manner that can be undone/redone and that automatically updates any bindings.
makeNodeDataKeyUnique(Object nodedata) → void

Available on Model, provided by the Model$Typings extension

This method is called when a node data object is added to the model to make sure that #getKeyForNodeData returns a unique key value.
mergeNodeDataArray(Array<Object> arr) → void

Available on Model, provided by the Model$Typings extension

Take an Array of node data objects and update #nodeDataArray without replacing the Array and without replacing any existing node data objects that are identified by key.
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
raiseChangedEvent(EnumValue change, Object propertyname, Object obj, [dynamic oldval, dynamic newval, dynamic oldparam, dynamic newparam]) → void

Available on Model, provided by the Model$Typings extension

Call this method to notify that the model or its objects have changed. This constructs a ChangedEvent and calls all Changed listeners. @param {EnumValue} change specifies the general nature of the change; typically the value is ChangedEvent.Property. @param {string|function(ObjectData,?=):?} propertyname names the property that was modified, or a function that takes an Object and returns the property value. @param {Object} obj the object that was modified, typically a GraphObject, Diagram, or a Model. @param {} oldval the previous or older value. @param {} newval the next or newer value. @param {=} oldparam an optional value that helps describe the older value. @param {=} newparam an optional value that helps describe the newer value.
raiseDataChanged(Object data, Object propertyname, [dynamic oldval, dynamic newval, dynamic oldparam, dynamic newparam]) → void

Available on Model, provided by the Model$Typings extension

Call this method to notify about a data property having changed value. This constructs a ChangedEvent and calls all Changed listeners.
removeArrayItem(Array arr, [num? idx]) → void

Available on Model, provided by the Model$Typings extension

Remove an item from a data array that may be data bound by a Panel as its Panel#itemArray, given the index at which to remove a data value, in a manner that can be undone/redone and that automatically updates any bindings.
removeChangedListener(void listener(ChangedEvent)) → void

Available on Model, provided by the Model$Typings extension

Unregister an event handler listener.
removeNodeData(Object nodedata) → void

Available on Model, provided by the Model$Typings extension

When you want to remove a node or group from the diagram, call this method with an existing data object. This will remove that data from the #nodeDataArray and notify all listeners that a node data object has been removed from the collection.
removeNodeDataCollection(Object coll) → void

Available on Model, provided by the Model$Typings extension

Remove from this model all of the node data held in an Array or in an Iterable of node data objects. @param {Iterable.
rollbackTransaction() bool

Available on Model, provided by the Model$Typings extension

Rollback the current transaction, undoing any recorded changes. This just calls UndoManager#rollbackTransaction. @return {boolean} the value returned by UndoManager#rollbackTransaction.
set(Object data, String propname, [dynamic val]) → void

Available on Model, provided by the Model$Typings extension

A synonym for #setDataProperty @param {Object} data a JavaScript object typically the value of a Panel#data and represented by a Node, Link, Group, simple Part, or item in a Panel#itemArray; or this model's #modelData. @param {string} propname a string that is not null or the empty string. @param {*} val the new value for the property. @see #setDataProperty @since 1.8
setCategoryForNodeData(Object nodedata, String cat) → void

Available on Model, provided by the Model$Typings extension

Change the category of a given node data, a string naming the node template or group template or part template that the Diagram should use to represent the node data.
setDataProperty(Object data, String propname, [dynamic val]) → void

Available on Model, provided by the Model$Typings extension

Change the value of some property of a node data, a link data, an item data, or the Model#modelData, given a string naming the property and the new value, in a manner that can be undone/redone and that automatically updates any bindings.
setKeyForNodeData(Object nodedata, dynamic key) → void

Available on Model, provided by the Model$Typings extension

Change the unique key of a given node data that is already in this model. The new key value must be unique -- i.e. not in use by another node data object. You can call #findNodeDataForKey to check if a proposed new key is already in use.
startTransaction([String? tname]) bool

Available on Model, provided by the Model$Typings extension

Begin a transaction, where the changes are held by a Transaction object in the UndoManager. This just calls UndoManager#startTransaction. @param {string=} tname a descriptive name for the transaction. @return {boolean} the value returned by UndoManager#startTransaction. @see #commit
toIncrementalData(ChangedEvent e) IncrementalData

Available on Model, provided by the Model$Typings extension

Produce an object representing the changes in the most recent Transaction. The structure of the object follows the same format as the JSON output from #toIncrementalJson.
toIncrementalJson(ChangedEvent e, [String? classname]) String

Available on Model, provided by the Model$Typings extension

Produce a JSON-format string representing the changes in the most recent Transaction. This writes out JSON for a model, but recording only changes in the given Transaction, with the addition of the "incremental" property to mark it as different from a complete model. Instead of the "nodeDataArray" property (and "linkDataArray" property for GraphLinksModels), this will have "inserted...", "modified...", and "removed..." properties that are non-empty Arrays.
toJson([String? classname]) String

Available on Model, provided by the Model$Typings extension

Generate a string representation of the persistent data in this model, in JSON format, that can be read in later with a call to Model.fromJson.
toString() String
A string representation of this object.
inherited
updateTargetBindings(Object data, [String? srcpropname]) → void

Available on Model, provided by the Model$Typings extension

Find a Part corresponding to the given data and call its Panel#updateTargetBindings method, in each Diagram that uses this Model.

Operators

operator ==(Object other) bool
The equality operator.
inherited

Static Methods

fromJson(Object s, [Model? model]) Model
This static function parses a string in JSON format that was written by Model#toJson, and then constructs, initializes, and returns a model with that information.