The constructor builds an empty Part.
if not supplied, the default Panel type is Panel.Position.
Gets or sets the category of this part, typically used to distinguish different kinds of nodes or links.
The initial value is an empty string, which is the default category. Any new value must be a string. This should not be set in templates.
When building Parts for node data or link data in a model, the Diagram will call Model.getCategoryForNodeData or GraphLinksModel.getCategoryForLinkData to get the category string for the data object. The diagram uses this value to look up a template in Diagram.nodeTemplateMap, Diagram.linkTemplateMap or Diagram.groupTemplateMap. That template is copied to create the actual Part that is added to the diagram. The diagram will set this property to remember the category it used.
Note that the class of the new Part must be the same as the class of the original Part. For example, a Node cannot be replaced by a simple Part or vice-versa. Nor can a Link be replaced by a subclass of Link or vice-versa.
To change the category for a Part created for model data, call Model.setCategoryForNodeData or GraphLinksModel.setCategoryForLinkData.
This property is also used to distinguish Adornments on a Part. In this scenario you create the Adornment, often indirectly by specifying a template, and set this property explicitly. For example, ResizingTool.updateAdornments creates a resizing Adornment from the Part.resizeAdornmentTemplate and sets its category to be "Resizing". Changing the category of an existing Adornment will update any adorned part's association.
Gets or sets the Group of which this Part or Node is a member. This will be null if this is a top-level part.
You cannot set this property on a Link; it is set for you automatically based on the group memberships of the connected nodes. You cannot set this property on an Adornment at all.
A template should not be a member of any group.
Gets or sets the function that is called after this Part has changed which Group it belongs to, if any. It is typically used to modify the appearance of the part. The first argument will be this Part. The second argument will be the old Group, or null if it had been a top-level part. The third argument will be the new Group, or null if it is now a top-level part.
If the value is a function, that function must not modify the part's containing Group. The containing Group has already been changed -- trying to change it again may produce undefined behavior.
The initial value is null -- no function is called.
Gets or sets whether the user may copy this part. The initial value is true.
Gets or sets whether the user may delete this part. The initial value is true.
Gets or sets the function used to determine the location that this Part can be dragged to. The first argument is a reference to the Part being dragged, the second argument is a Point describing the proposed location, and the third argument is a snapped location, if one was determined during dragging. It should return a Point that is the proposed new location.
By default this function is null and the DraggingTool uses the snapped location, if one was determined and if DraggingTool.isGridSnapEnabled is true, or the proposed location (the second argument) if not snapping to a grid.
In either case the DraggingTool will limit the proposed new location by minLocation and maxLocation.
The function, if supplied, must not have any side-effects.
An example that limits moving a Node to the current viewport:
function stayInViewport(part, pt, gridpt) {
var diagram = part.diagram;
if (diagram === null) return pt;
// compute the area inside the viewport
var v = diagram.viewportBounds.copy();
v.subtractMargin(diagram.padding);
// get the bounds of the part being dragged
var b = part.actualBounds;
var loc = part.location;
// now limit the location appropriately
var x = Math.max(v.x+1, Math.min(pt.x, v.right-b.width-2)) + (loc.x-b.x);
var y = Math.max(v.y+1, Math.min(pt.y, v.bottom-b.height-2)) + (loc.y-b.y);
return new go.Point(x, y);
}
Note that for this functionality you will also probably want to set Diagram.autoScrollRegion to be a zero margin.
myDiagram.nodeTemplate =
$(go.Node, . . .,
{ dragComputation: stayInViewport },
. . .
);
Gets or sets whether the user may group this part to be a member of a new Group. The initial value is true.
The grouping command is implemented by CommandHandler.groupSelection and depends on CommandHandler.archetypeGroupData having been set to a node data object. A Group can be ungrouped by the user if you set Group.ungroupable to true.
Gets or sets the function to execute when this isHighlighted changes. It is typically used to modify the appearance of the part. This function must not highlight or unhighlight any parts.
If this property value is a function, it is called with one argument, this Part that whose isHighlighted value changed. By default this property is null.
Gets or sets whether this part may be animated. The initial value is true.
Gets or sets whether this Part is highlighted. The initial value is false.
Highlighted parts may be shown with a different appearance by changing the brush or visibility of one or more of the GraphObjects within the part. One way of doing that is by using binding. Consider part of the definition of a Node template:
$(go.Shape,
. . .,
// Shape.fill is bound to Node.data.color
new go.Binding("fill", "color"),
// Shape.stroke is red when Node.isHighlighted is true, black otherwise
new go.Binding("stroke", "isHighlighted",
function(h) { return h ? "red" : "black"; }).ofObject()),
Gets or sets whether this Part is part of the document bounds.
The initial value is true. A value of false causes Diagram.computeBounds to ignore this part. If the value is false, it is possible that user will not be able to scroll far enough to see this part, if the part's GraphObject.actualBounds are outside of the Diagram.documentBounds.
Gets or sets whether a Layout positions this Node or routes this Link. This property affects the value of canLayout.
The initial value is true, meaning that this part is laid out by the layout responsible for this Part. If this part is a member of a Group, it is the Group.layout, otherwise it is the Diagram.layout.
A value of false means that this part is not affected by and does not affect any automatic layout, so the layoutConditions property is ignored. You will need to make sure that it has a real location or GraphObject.position value, or else the Part might not be visible anywhere in the diagram.
Another way of controlling when layouts are invalidated is by setting Part.layoutConditions or Layout.isInitial or Layout.isOngoing.
Gets or sets whether this Part is selected. The initial value is false.
Selected parts typically are shown either with an Adornment or with a different appearance by changing the brush or visibility of one or more of the GraphObjects within the part.
Changing this value does not by itself raise any "ChangingSelection" and "ChangedSelection" DiagramEvents. Tools and the CommandHandler and methods such as Diagram.select do raise those DiagramEvents because they want to surround changes to this property with a single "ChangingSelection" DiagramEvent beforehand and a single "ChangedSelection" afterwards.
Gets or sets whether this part will draw shadows. The initial value is false.
By default, setting this property to true will attempt to draw shadows only on the GraphObjects in this Part that appear to act as background objects, and not on GraphObjects that appear to be in front of other GraphObjects in the Part.
To finely control shadows, you may need to set GraphObject.shadowVisible on elements of this Part, so that they explicitly do or do not get shadowed accordingly.
This read-only property returns the Part's Model data key if it is in a Diagram and is backed by Model data. Otherwise this returns undefined.
This read-only property returns the Layer that this Part is in. The value is the Layer that is named with the value of layerName. If you want to change what Layer this Part is in, change the value of layerName to refer to a different Layer.
This will be null if it has not yet been added to a Diagram, or if it has already been removed from a Diagram.
Gets or sets the function to execute when this part changes layers. It is typically used to modify the appearance of the part. This function must not change the layer of this part by setting layerName.
If this property value is a function, it is called with three arguments, this Part, the old Layer (may be null), and the new Layer (may be null). By default this property is null -- no function is called.
Gets or sets the layer name for this part. The initial value is an empty string, which is the name of the default layer. The value of this property determines the value of layer.
If this part is not yet in a Diagram, this value is used by Diagram.add to determine which Layer this part should go in. If no layer can be found with this name, it uses the default layer.
Changing the value of this property while it is already in a layer causes it to change layers if needed.
Gets or sets flags that control when the Layout that is responsible for this Part is invalidated. The initial value is Part.LayoutStandard, which causes the layout for this part to be invalidated when the part is added or removed or changes visibility or size.
Individual layout conditions include: Part.LayoutAdded, Part.LayoutRemoved, Part.LayoutShown, Part.LayoutHidden, and Part.LayoutNodeSized.
This property is ignored when isLayoutPositioned is false -- no operation on this Part will by itself cause the responsible Layout to be invalidated.
You can also control when layouts are invalidated is by setting Layout.isInitial or Layout.isOngoing.
Gets or sets the position of this part in document coordinates, based on the locationSpot in this part's locationObject.
Value must be of type Point. The initial value is Point(NaN, NaN). It is commonplace to data bind this property to some property on your model node data.
The value is related to the GraphObject.position. For Parts, both are in document coordinates; setting one property will set the other property. By default both will have the same value. However, by setting either or both of locationSpot and locationObjectName, the location will be determined by a spot in the locationObject, a GraphObject that is in the visual tree of this Part. The GraphObject.position will always refer to the point at the top-left corner of the whole part.
The minLocation and maxLocation limit the location of a part, not its position. Grid snapping will normally locate the location to be on grid points.
This read-only property returns the GraphObject that determines the location of this Part. The value will be in the visual tree of this Part and is usually named with the value of locationObjectName.
Gets or sets the name of the GraphObject that provides the location of this Part. This name determines the value of locationObject. The actual location also depends on the locationSpot.
The initial value is an empty string, meaning the whole Part itself determines the location. If you want to use a particular GraphObject in the visual tree of this Part, set this property to be the GraphObject.name of the element that you want to be the locationObject.
Gets or sets the location Spot of this Node, the spot on the locationObject that is used in positioning this part in the diagram.
Value must be of the type Spot. The initial value is Spot.TopLeft
. The value must be a specific spot -- i.e. one for which Spot.isSpot is true.
It is commonplace to set this property to Spot.Center
, so that the location has a value corresponding to the point at the center of this Part's locationObject element. But the GraphObject.position of a Part is always at the top-left corner point of the GraphObject.actualBounds.
Gets or sets the maximum location of this Part to which the user may drag using the DraggingTool.
Value must be of type Point. The initial value is (Infinity, Infinity), which imposes no position constraint. A X value of NaN causes Diagram.computeMove to use the part's current location's X value as the maximum, and similarly for NaN as the Y value.
Gets or sets the minimum location of this Part to which the user may drag using the DraggingTool.
Value must be of type Point. The initial value is (-Infinity, -Infinity), which imposes no position constraint. A X value of NaN causes Diagram.computeMove to use the part's current location's X value as the minimum, and similarly for NaN as the Y value.
Gets or sets whether the user may move this part. The initial value is true.
Gets or sets whether the user may reshape this part. The initial value is false.
Gets or sets whether the user may resize this part. The initial value is false.
If you set this to true you may also want to set resizeObjectName to the GraphObject.named element that you want the user to resize. It is also commonplace to add a TwoWay Binding of that named element's GraphObject.desiredSize in order to save to the model data the value that the user set via the ResizingTool.
Gets or sets the adornment template used to create a resize handle Adornment for this part. This is used by the ResizingTool, ToolManager.resizingTool.
If an Adornment is supplied, it is normally a Panel.Spot panel that contains a Placeholder with some number of resize handles at the four corners or at the four side midpoints.
Gets or sets the width and height multiples used when resizing. By default this property is the Size(NaN, NaN).
This read-only property returns the GraphObject that should get resize handles when this part is selected. The value will be in the visual tree of this Part and is usually named with the value of resizeObjectName.
Gets or sets the name of the GraphObject that should get a resize handle when this part is selected. The value of this property affects the value of resizeObject. The initial value is an empty string, meaning the whole Part itself gets any resize handle.
Gets or sets whether the user may rotate this part. The initial value is false.
If you set this to true you may also want to set rotateObjectName to the GraphObject.named element that you want the user to rotate. It is also commonplace to add a TwoWay Binding of that named element's GraphObject.angle in order to save to the model data the value that the user set via the RotatingTool.
Gets or sets the adornment template used to create a rotation handle Adornment for this part. This is used by the RotatingTool, ToolManager.rotatingTool.
This Adornment should not have a Placeholder in it, because the RotatingTool will position it away from the rotateObject at its GraphObject.angle.
This read-only property returns the GraphObject that should get rotate handles when this part is selected. The value will be in the visual tree of this Part and is usually named with the value of rotateObjectName.
Gets or sets the name of the GraphObject that should get a rotate handle when this part is selected. The value of this property affects the value of rotateObject. The initial value is an empty string, meaning the whole Part itself gets any rotate handle.
Gets or sets the spot on the rotateObject that is used in rotating this part with the RotatingTool.
Value must be of the type Spot. The value must be a specific spot -- i.e. one for which Spot.isSpot is true, or else Spot.Default
.
If the value is Spot.Default
, the RotatingTool uses the locationSpot if the rotateObject is equal to the locationObject, otherwise it uses Spot.Center
.
The initial value is Spot.Default
.
Gets or sets whether the user may select this part. The initial value is true.
If you set this to true you may also want to set selectionObjectName to the GraphObject.named element that you want to be adorned when the Part is selected.
Gets or sets whether a selection adornment is shown for this part when it is selected. The initial value is true.
Gets or sets the Adornment template used to create a selection handle for this Part.
If this is null, depending on the class of this Part, the value of Diagram.nodeSelectionAdornmentTemplate, Diagram.groupSelectionAdornmentTemplate, or Diagram.linkSelectionAdornmentTemplate is used instead.
It is commonplace to make use of a Placeholder in an Adornment for a Node, Group, or simple Part. The Placeholder represents the Adornment.adornedObject of the adorned Part. For Links, the Adornment must be of Panel.type Panel.Link.
Gets or sets the function to execute when this part is selected or deselected. It is typically used to modify the appearance of the part. This function must not select or deselect any parts.
If this property value is a function, it is called with one argument, this Part that was selected or that became unselected. When it is called, the value of Diagram.skipsUndoManager is temporarily set to true. By default this property is null.
This function is called with Diagram.skipsUndoManager temporarily set to true, so that any changes to GraphObjects are not recorded in the UndoManager. You do not need to start and commit any transaction in this function.
This read-only property returns the GraphObject that should get a selection handle when this part is selected. The value will be in the visual tree of this Part and is usually named with the value of selectionObjectName. When the selectionObjectName is unspecified, this whole Part is used as the "selection object".
Gets or sets the name of the GraphObject that should get a selection handle when this part is selected. The value of this property affects the value of selectionObject. The initial value is an empty string, meaning the whole Part itself gets any selection handle.
If no GraphObject has a GraphObject.name that is this name, selectionObject returns the whole Part.
Gets or sets the numerical value that describes the shadow's blur. Number must be a non-negative non-infinity float. A value of 0 would mean the shadow does not blur and larger numbers represent increasingly more blur. The total blur area is independent of the Part's area and can become quite large as this number is increased.
This value is not affected by scale. Default value is 4.
Gets or sets the CSS string that describes a shadow color. Default is 'gray'. Brushes cannot be used for this property -- only strings.
Gets or sets the X and Y offset of this part's shadow. This is only relevant if isShadowed is true. The initial value is (6, 6).
Gets or sets a text string that is associated with this part.
The initial value is an empty string. This value is often used for sorting.
Gets or sets whether the user may do in-place text editing on TextBlocks in this part that have TextBlock.editable set to true. The initial value is true.
Gets or sets the Z-ordering position of this Part within its Layer.
Within the same layer, nodes with larger zOrder values are placed in front of nodes with smaller zOrder values. When the value is NaN the ordering is not specified. The default value is NaN.
When a Group has a zOrder value of NaN, it is automatically placed behind its member nodes and links that also have no zOrder. Such automatic ordering is not guaranteed if any nodes including the groups have a numeric zOrder. If you do want to specify the zOrder of nodes, you should also specify the zOrder of their containing groups unless those groups are in different layers.
Associate an Adornment with this Part, perhaps replacing any existing adornment of the same category. Don't forget to set Adornment.adornedObject before calling this method. This adds the Adornment to the Layer named by layerName, normally "Adornment".
Adornments are also data bound to the same data that this Part has, if any. If the Adornment was already associated with a Part, it is unassociated with that old Part.
This method should not be called on templates.
a string identifying the kind or role of the given adornment for this Part.
the new Adornment.
This predicate returns true if copyable is true, if the layer's Layer.allowCopy is true, and if the diagram's Diagram.allowCopy is true.
This does not check Diagram.isReadOnly or Model.isReadOnly, but commands and tools should check those properties.
true if the user may copy this part.
This predicate returns true if deletable is true, if the layer's Layer.allowDelete is true, and if the diagram's Diagram.allowDelete is true.
This does not check Diagram.isReadOnly or Model.isReadOnly, but commands and tools should check those properties.
true if the user may delete this part.
This predicate returns true if textEditable is true, if the layer's Layer.allowTextEdit is true, and if the diagram's Diagram.allowTextEdit is true.
This does not check Diagram.isReadOnly or Model.isReadOnly, but commands and tools should check those properties.
true if the user may edit this part.
This predicate returns true if groupable is true, if the layer's Layer.allowGroup is true, and if the diagram's Diagram.allowGroup is true.
This does not check Diagram.isReadOnly or Model.isReadOnly, but commands and tools should check those properties.
true if the user may group this part.
This predicate is called by Layout implementations to decide whether this Part should be positioned and might affect the positioning of other Parts.
This is false if isLayoutPositioned is false, if isVisible returns false, or if the part is in a temporary Layer.
This does not check Diagram.isReadOnly or Model.isReadOnly, but commands and tools should check those properties.
This predicate returns true if movable is true, if the layer's Layer.allowMove is true, and if the diagram's Diagram.allowMove is true.
This does not check Diagram.isReadOnly or Model.isReadOnly, but commands and tools should check those properties.
true if the user may move this part.
This predicate returns true if reshapable is true, if the layer's Layer.allowReshape is true, and if the diagram's Diagram.allowReshape is true.
This does not check Diagram.isReadOnly or Model.isReadOnly, but commands and tools should check those properties.
true if the user may reshape this part.
This predicate returns true if resizable is true, if the layer's Layer.allowResize is true, and if the diagram's Diagram.allowResize is true.
This does not check Diagram.isReadOnly or Model.isReadOnly, but commands and tools should check those properties.
true if the user may resize this part.
This predicate returns true if rotatable is true, if the layer's Layer.allowRotate is true, and if the diagram's Diagram.allowRotate is true.
This does not check Diagram.isReadOnly or Model.isReadOnly, but commands and tools should check those properties.
true if the user may rotate this part.
This predicate returns true if selectable is true, if the layer's Layer.allowSelect is true, and if the diagram's Diagram.allowSelect is true.
This does not check Diagram.isReadOnly or Model.isReadOnly, but commands and tools should check those properties.
true if the user may select this part.
Remove all adornments associated with this part.
Measures if needed to make sure the GraphObject.measuredBounds and GraphObject.naturalBounds are all real numbers, primarily to get the actual width and height. GraphObject.actualBounds will get a real width and height, but the x and y values may continue to be NaN
if they were that way beforehand.
This is sometimes necessary to call when defining custom layouts or implementing virtualization, so that it can work with the actual size of the nodes.
For efficiency, do not call this method unnecessarily.
Find the Group that perhaps indirectly contains both this part and another one. If this is a Group and it contains the OTHER Part, return this. If the OTHER Part is a Group and it contains this Part, return that OTHER Part.
This returns null if the two parts are unrelated in the hierarchy of part membership. If non-null, the result is a Group.
If you want to find the Node that is the tree parent of two Nodes, call Node.findCommonTreeParent.
may be null
Return how deep this part is in the hierarchy of nested Groups. For parts that have no containingGroup this returns zero.
If you want to know how deep a Node is in a tree structure, call Node.findTreeLevel.
Gets the top-level Part for this part, which is itself when isTopLevel is true. If this Part is a member of a Group, this returns the top-level Part for that Group. If this is a Node that is a label node for a labeled Link, this returns the top-level Part for that Link.
If this is a Node and you are searching for the root of the tree that this node is in, use Node.findTreeRoot.
This will not return null.
Returns the Rect in document coordinates for this object's bounds. If this GraphObject is a Part, the rect will be identical to its actualBounds.
an optional Rect that is modified and returned.
in document coordinates.
Invalidate the Layout that is responsible for positioning this Part. If this part is in a Group, invalidate its Group.layout, if it has one. Otherwise invalidate the Diagram.layout.
But note that if isLayoutPositioned is false, or if it is in a temporary Layer, or if it is not in a diagram or group, no layout is invalidated.
the reason that the layout should be invalidated; if this argument is not supplied, any value of layoutConditions other than Part.LayoutNone will allow the layout to be invalidated.
This predicate is true if this part is a member of the given Part, perhaps indirectly.
If the given part is a Group and this part is a member of the given group, this returns true. If this part is a Node and it is a label node for the given link, this returns true. Otherwise this searches recursively any Part.containingGroup of the given part.
A part cannot be contained by itself. A template should not be a member of any group.
If this is a Node and you want to find whether it is in a subtree whose root is a given Node, use Node.isInTreeOf.
This predicate is true if this Part can be seen. Parts that can be seen can be manipulated by the user, can take space in the document, or can take part in a layout, among many possibilities. Note that the value of this predicate can often be false even while GraphObject.visible is true.
A Part is not seen if it is not GraphObject.visible or if it is in a Layer that is not Layer.visible.
If a Part is a member of a Group and the Group is not Group.isSubGraphExpanded, the part is not seen. (The containing Group might still be visible.)
If a Node is a "tree child" of a Node that is not Node.isTreeExpanded, the node is not seen. (The parent Node might still be visible.)
If a Link is connected to or from a Node that is not isVisible()
and is not a member of a Group that isVisible()
, the link is not seen.
If a Node is a "link label" of a Link and that Link is not isVisible()
, the node is not seen.
This is different from GraphObject.isVisibleObject, which ignores whether the Layer is visible and just checks GraphObject.visible up the chain of containing Panels.
If you want to know whether a Part is in the Diagram's viewport, try:
diagram.viewportBounds.containsRect(part.actualBounds);
or:
diagram.viewportBounds.intersectsRect(part.actualBounds);
true if GraphObject.visible is true and if Layer.visible is true.
Move this part and any parts that are owned by this part to a new position.
If this part is a Group, it also moves all of its members, recursively. If this part is a Link, it also moves all of its label nodes.
a new Point in document coordinates.
true if you want to set the location instead of the position. False by default.
Move this part and any parts that are owned by this part to a new position. This just calls move without the caller having to allocate a new Point.
a new X value in document coordinates.
a new Y value in document coordinates.
true if you want to set the location instead of the position. False by default.
Remove any Adornment of the given category that may be associated with this Part.
a string identifying the kind or role of the given adornment for this Part.
This is responsible for creating any selection Adornment (if this Part isSelected) and any tool adornments for this part.
Update all of the references to nodes in case they had been modified in the model without properly notifying the model by calling GraphLinksModel.setGroupKeyForNodeData or GraphLinksModel.setToKeyForLinkData or other similar methods. This method does not conduct a transaction, so you need to start and commit one yourself.
This only updates the relationships between nodes, to have them reflect what is now declared in the model data. For example, in a GraphLinksModel if code has changed the value of the "to" property of a link data, calling this method on the corresponding Link would cause the link to connect with the Node whose data has the new key.
To update GraphObject properties that are data bound, call updateTargetBindings.
Re-evaluate all data bindings in this Part, in order to assign new property values to the GraphObjects in this visual tree based on this this object's data property values. This method does nothing if data is null.
It is better to call Model.setDataProperty to modify data properties, because that will both record changes for undo/redo and will update all bindings that make depend on that property.
To update relationships between nodes, call updateRelationshipsFromData.
An optional source data property name: when provided, only evaluates those Bindings that use that particular property; when not provided or when it is the empty string, all bindings are evaluated.
This flag may be combined with other "Layout" flags as the value of the Part.layoutConditions property to indicate that when a Part is added to a Diagram or Group, it invalidates the Layout responsible for the Part.
This flag may be combined with other "Layout" flags as the value of the Part.layoutConditions property to indicate that when a Group has been laid out, it invalidates the Layout responsible for that Group; this flag is ignored for Parts that are not Groups.
This flag may be combined with other "Layout" flags as the value of the Part.layoutConditions property to indicate that when a Part's GraphObject.visible becomes false, it invalidates the Layout responsible for the Part.
This flag may be combined with other "Layout" flags as the value of the Part.layoutConditions property to indicate that when a Node or simple Part's category changes, it invalidates the Layout responsible for the Part; this flag is ignored for Parts that are Links.
This flag may be combined with other "Layout" flags as the value of the Part.layoutConditions property to indicate that when a Node or simple Part's GraphObject.actualBounds changes size, it invalidates the Layout responsible for the Part; this flag is ignored for Parts that are Links.
This value may be used as the value of the Part.layoutConditions property to indicate that no operation on this Part causes invalidation of the Layout responsible for this Part.
This flag may be combined with other "Layout" flags as the value of the Part.layoutConditions property to indicate that when a Part is removed from a Diagram or Group, it invalidates the Layout responsible for the Part.
This flag may be combined with other "Layout" flags as the value of the Part.layoutConditions property to indicate that when a Part's GraphObject.visible becomes true, it invalidates the Layout responsible for the Part.
This is the default value for the Part.layoutConditions property, basically a combination of all of the conditions: the Layout responsible for the Part is invalidated when the Part is added or removed or replaced from the Diagram or Group, or when it changes visibility or size, or when a Group's layout has been performed.
This is the base class for all user-manipulated top-level objects. Because it inherits from Panel, it is automatically a visual container of other GraphObjects. Because it thus also inherits from GraphObject, it also has properties such as GraphObject.actualBounds, GraphObject.contextMenu, and GraphObject.visible.
If you just want an object that users can select and manipulate, you can create an instance of this class.
If you want an object that also supports being connected by links to other objects, use the Node class, which inherits from Part. Create those connections by using instances of the Link class.
If you want a node that logically contains a subgraph of nodes and links, use the Group class, which inherits from Node.
If you want an object that decorates another Part, without having to modify that Part, use the Adornment class. Adornments do not support linking or grouping or being selected.
You can construct a Part, add GraphObjects to it programmatically, and then add the part to a diagram by calling Diagram.add. However it is commonplace to add data to a model by setting its Model.nodeDataArray or calling Model.addNodeData, or for Links, setting the GraphLinksModel.linkDataArray or calling GraphLinksModel.addLinkData. Such actions will cause a diagram that is displaying the model to copy a template, which is a Part that may have data Bindings, and add the new part to the diagram. The Panel.data property will refer to that data object in the model.
Some examples of adding Parts to a Diagram:
// A simple Part template myDiagram.nodeTemplate = $(go.Part, "Horizontal", $(go.Shape, "Circle", { width: 20, height: 20 }), $(go.TextBlock, "Hello World") ); // Node templates can be either Nodes, or simple Parts // (But not Groups, Adornments, or Links) // Adds copies of the nodeTemplate bound to the specified node data: myDiagram.model.nodeDataArray = [ { key: "Alpha" }, { key: "Beta" } ]; // Adds one copy of the nodeTemplate bound to the given node data: myDiagram.model.addNodeData( { key: "Gamma" } );
See the Introduction on using Models for examples and more information.
Layers and Z-ordering
Parts added to a Diagram exist in one of the Diagram's Layers. You can specify which layer the part should be in by setting layerName. Parts cannot be nested in the visual tree -- they cannot be added to other Parts of Panels.
Parts can be individually z-ordered within a layer by setting zOrder. Parts within the same layer that have a higher zOrder number will be drawn above parts with a lower number.
Size and Position
The size and position of a part are given by its GraphObject.actualBounds. The size is determined by the GraphObjects that are elements inside this part. You can change the position by setting GraphObject.position or Part.location.
The "location" of a part is commonly the same as its "position". The "position" is always the point that is at the top-left corner of the area occupied by the part. But the "location" may be different from the "position" if you want to think of the part as being "at" a different spot in the part. For example, you might want the "location" to be at the center of a Picture that has a TextBlock title of arbitrary size. In this case you would set the locationSpot to be Spot.Center and the locationObjectName to be the name of the Picture element in your Part.
A part may be selected or de-selected by setting its isSelected property. This may also happen due to a call to Diagram.select or other operations that change the selection. The user may change this property as part of the operation of the ClickSelectingTool, due to the user's mouse click, if the part is selectable.
Ability Properties (Permissions)
There are many properties named "...able", that control what operations the user may perform on this part. These properties correspond to the similarly named properties on Diagram and Layer that govern the behavior for all parts in all layers or for all parts in the given layer. For example, the Part.copyable property corresponds to the properties Diagram.allowCopy and Layer.allowCopy.
For each of these "ability" properties there is a corresponding "can..." predicate. For example, the Part.canCopy predicate is false if any of the three previously named properties is false. Commands and tools will normally call these predicates rather than just looking at Part properties.
For more discussion about permissions, please read: Permissions.
As previously mentioned, each Diagram supports the notion of selected parts. One way of displaying that a part is selected is by modifying the part. You can set the selectionChanged property to be a function that is called when the value of isSelected has changed; it is passed the Part as the first argument. The function can modify the color of one or more GraphObjects in the visual tree of that Part. Or perhaps it could toggle the GraphObject.visible property of an object that is normally hidden when the part is not selected.
The Part class also supports showing separate visual objects for a part when it gets selected. These visuals are typically used to show that the part is selected ("selection handles") or are used to allow the user to manipulate or modify the part with a tool ("tool handles"). These handles are instances of Adornments. The updateAdornments method is responsible for showing or hiding adornments, normally depending on whether the part is selected.
When the selectionAdorned property is true, a selected part automatically gets an Adornment created for it. By default the selection adornment is just a simple blue box around the Part, and a blue shape following the route of a selected Link. However you can set the selectionAdornmentTemplate to an arbitrarily complex Adornment. This way it can show more information or buttons for executing various commands when the user selects a Part.
Tool handles are shown for those mode-less mouse-down tools that need it. The process of updating adornments for a part will call Tool.updateAdornments on each tool in ToolManager.mouseDownTools. Most tools might not need special tool handles. But, for example, ResizingTool naturally will want to create an adornment with eight resize handles positioned at the corners and at the middles of the sides of the selected node's visual element, if the node has its canResize function returning true.
One may not always want the whole Part to get the selection handle or all tool handles. Sometimes one wants to emphasize selection by highlighting a particular element within the part's visual tree. This can be achieved by setting the selectionObjectName property, and making sure the desired element has the same GraphObject.name property value.
For more discussion about selection, see Selection.
Similarly the resizeObjectName and rotateObjectName properties direct the corresponding ResizingTool and RotatingTool to operate on the particular GraphObject in the Part's visual tree with the given name. That includes both providing tool handles and actually modifying properties on that object.
Parts are not resizable or rotatable by default: you need to set resizable and/or rotatable to true.
For more discussion about tools, see Tools.
A Part may be positioned (or a Link may be routed) by a Layout. This will happen automatically if Diagram.layout or Group.layout are set. The default Diagram.layout will position any nodes that were not given explicit positions or location.
If you set isLayoutPositioned to false, this part will not participate in any of the standard layouts, so it will not be moved by a layout or affect other parts in a layout. In order for the part to get a location or position you will need to supply it explicitly.
As parts are added to or removed from a diagram, the Layout responsible for positioning the part is invalidated. This will cause the layout to be performed again in the near future, at the end of the transaction. This automatic layout invalidation also occurs as parts change their visibility (GraphObject.visible) or their size (GraphObject.actualBounds). If you do want there to be a Diagram.layout but you do not want an automatic layout to happen after removing parts (for example), you can set layoutConditions not to include the Part.LayoutRemoved flag. In this particular case, you could set layoutConditions to:
go.Part.LayoutStandard & ~go.Part.LayoutRemoved
. It may also reasonable for your application to set it to Part.LayoutNone. Do not forget to consider applying the same conditions to links as well as to nodes and groups.If you want to save the locations/positions of the parts in a diagram, it is commonplace to data bind the location to a property on your node data with a TwoWay Binding (call Binding.makeTwoWay). For example:
$(go.Part, "Horizontal", new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify), ...
Then as the nodes are moved, whether manually by the user or automatically by a Layout, the model data is automatically updated with the location.
For more discussion about related topics, see Selection, Tools, and Permissions.
Parts that are templates should have no relationships with other Parts. Only real Parts that are in a Diagram can belong to Groups or have any Adornments. Only real Nodes in a Diagram can be connected with Links.