version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
GoJS Class Index
@@ -999,7 +999,7 @@GoJS Class Index
ClickCreatingTool
The ClickCreatingTool lets the user create a node by clicking where they want the new node to be. More... By default a double-click is required to start this tool; set #isDoubleClick to false if you want a single-click to create a node.This tool is a standard mouse-up tool, the ToolManager.clickCreatingTool. However, it will not be able to start running unless you have set the #archetypeNodeData property to an object that can be copied and added to the diagram's model.
This tool does not utilize any Adornments or tool handles. This tool does conduct a transaction when inserting the new node.
ClickSelectingTool
The ClickSelectingTool selects and deselects Parts when there is a click. More... It does this by calling Tool.standardMouseSelect. It is also responsible for handling and dispatching click events on GraphObjects by calling Tool.standardMouseClick.This tool is a standard mouse-up tool, the ToolManager.clickSelectingTool.
This tool does not utilize any Adornments or tool handles. This tool does not modify the model or conduct any transaction.
An example customization of this tool is shown in the Tree Map sample, where the Tool.standardMouseSelect method is overridden to permit the user to cycle through the chain of containing groups, changing the selection on each click to the next containing group.
ClickSelectingTool
The ClickSelectingTool selects and deselects Parts when there is a click. More... It does this by calling Tool.standardMouseSelect. It is also responsible for handling and dispatching click events on GraphObjects by calling Tool.standardMouseClick.Note that this tool avoids raising click events on objects that are in temporary layers. This is to prevent parts such as selection adornments from interfering with clicking on selected nodes or links. (Adornments are in the "Adornment" Layer, which Layer.isTemporary.) However this means that if you add a GraphObject.click event handler on a GraphObject in an Adornment, it will not be called. You can get it to be called by setting GraphObject.isActionable to true on that object in the adornment.
This tool is a standard mouse-up tool, the ToolManager.clickSelectingTool.
This tool does not utilize any Adornments or tool handles. This tool does not modify the model or conduct any transaction.
An example customization of this tool is shown in the Tree Map sample, where the Tool.standardMouseSelect method is overridden to permit the user to cycle through the chain of containing groups, changing the selection on each click to the next containing group.
CommandHandler
The Diagram.commandHandler implements various commands such as CommandHandler.deleteSelection or CommandHandler.redo. More... The CommandHandler includes keyboard event handling to interpret key presses as commands.CommandHandlers cannot be shared amongst multiple Diagrams.
You may define a CommandHandler subclass and override methods. However you must seriously consider calling the base method in order to gets its default behavior. There may be situations where not calling the base method may cause subtle bugs, but that depends on the method. Please read the Introduction page on Extensions for how to override methods and how to call a base method.
There is an example custom CommandHandler in the extensions directory: DrawCommandHandler.js, which provides alignment commands and additional behaviors for the arrow keys.
For additional discussion, please read the Introduction page on Commands.
Keyboard Shortcuts
The CommandHandler implements the following command bindings for keyboard input in #doKeyDown:Ctrl-X
&Shift-Del
invoke #cutSelectionCtrl-C
&Ctrl-Insert
invoke #copySelectionCtrl-V
&Shift-Insert
invoke #pasteSelectionDel
invokes #deleteSelectionCtrl-A
invokes #selectAllCtrl-Z
&Alt-Backspace
invoke undoCtrl-Y
&Alt-Shift-Backspace
invoke redoUp
&Down
&Left
&Right
(arrow keys) invoke Diagram.scrollPageUp
&PageDown
invoke Diagram.scrollHome
&End
set Diagram.positionCtrl-- & Keypad--
(minus) invoke #decreaseZoomCtrl-+ & Keypad-+
(plus) invoke #increaseZoomCtrl-0
invokes #resetZoomShift-Z
invokes #zoomToFit; repeat to return to the original scale and positionCtrl-G
invokes #groupSelectionCtrl-Shift-G
invokes #ungroupSelectionF2
invokes #editTextBlockMenu Key
invokes #showContextMenuEsc
invokes #stopCommand
On a Macintosh the Command key is used as the modifier instead of the Control key.
On touch devices there is a default context menu that shows many commonly-used commands when you hold a finger down on the diagram.
GoJS Class Index
DraggingTool
The DraggingTool is used to move or copy selected parts with the mouse. More... This sets the Part.location property; you may want to save the location to the model by using a TwoWay Binding on the "location" property in your Parts/Nodes/Groups templates.Dragging the selection moves parts for which Part.canMove is true. If the user holds down the Control key (Option key on Mac), this tool will make a copy of the parts being dragged, for those parts for which Part.canCopy is true.
When the drag starts it calls #computeEffectiveCollection to find the actual collection of Parts to be dragged. Normally this collection includes not only the Diagram.selection, but also parts that belong to those selected parts, such as members of groups. If #dragsTree is true, the effective collection also includes all of the nodes and links that constitute the subtree starting from selected nodes. The result of #computeEffectiveCollection is not a Set but a Map which remembers the original Part.location for all of the dragged parts. This map is saved as the value of #draggedParts.
During the drag if the user holds down the Control/Option key this tool makes a copy of the #draggedParts and proceeds to drag it around. (It only copies the Diagram.selection, not the whole effective collection, if #copiesEffectiveCollection is false.) The collection of copied parts is held by #copiedParts. It too is a Map remembering the original locations of the parts. #copiedParts will be null when this tool is moving (not copying) at the moment.
Each Part's movement is limited by the #computeMove method. By default it limits the Part.location to be within the bounds given by Part.minLocation and Part.maxLocation. (Those default to minus Infinity to plus Infinity.) As a further convenience, the value of NaN in minLocation and maxLocation cause #computeMove to use the part's current location. So, for example, an easy way to declare that the user may only drag a node horizontally is to just set:
$(go.Node, . . . { minLocation: new go.Point(-Infinity, NaN), maxLocation: new go.Point(Infinity, NaN) }, . . . )
If you set #isGridSnapEnabled to true, dragged or copied parts will be snapped to points on a grid. The snapping occurs continuously during a drag unless you set #isGridSnapRealtime to false. Normally the grid points come from the Diagram.grid, even if that grid is not GraphObject.visible. However you can override those grid's properties for the snapping grid cell size and offset by setting the properties here: #gridSnapCellSize and #gridSnapOrigin. This computes the point to snap to for each dragged part. The resulting point is used as the new Part.location.
For the most general control over where a part may be dragged, either set the Part.dragComputation property or override #computeMove. For the common case of wanting to keep member nodes within the Group that they are members of, you can do something like:
// this is a Part.dragComputation function for limiting where a Node may be dragged function stayInGroup(part, pt, gridpt) { // don't constrain top-level nodes var grp = part.containingGroup; if (grp === null) return pt; // try to stay within the background Shape of the Group var back = grp.findObject("SHAPE"); if (back === null) return pt; // allow dragging a Node out of a Group if the Shift key is down //if (part.diagram.lastInput.shift) return pt; var p1 = back.getDocumentPoint(go.Spot.TopLeft); var p2 = back.getDocumentPoint(go.Spot.BottomRight); var b = part.actualBounds; var loc = part.location; // find the padding inside the group's placeholder that is around the member parts var m = (grp.placeholder !== null ? grp.placeholder.padding : new go.Margin(0)); // now limit the location appropriately var x = Math.max(p1.x + m.left, Math.min(pt.x, p2.x - m.right - b.width - 1)) + (loc.x-b.x); var y = Math.max(p1.y + m.top, Math.min(pt.y, p2.y - m.bottom - b.height - 1)) + (loc.y-b.y); return new go.Point(x, y); }Note that this expects there to be a "SHAPE" object within the Group's visual tree that delimits where the part may be dragged within the group. This also expects that Group.computesBoundsIncludingLinks is false. Then in your node template(s), just set:
$(go.Node, . . ., { dragComputation: stayInGroup }, . . . )
This tool does not utilize any Adornments or tool handles. If the drag is successful, it raises the "SelectionMoved" or "SelectionCopied" DiagramEvent and produces a "Move" or a "Copy" transaction.
DragSelectingTool
The DragSelectingTool lets the user select multiple parts within a rectangular area drawn by the user. More... There is a temporary part, the #box, that shows the current area encompassed between the mouse-down point and the current mouse point. The default drag selection box is a magenta rectangle. You can change the #box to customize its appearance -- see its documentation for an example.This tool is a standard mouse-move tool, the ToolManager.dragSelectingTool. However this cannot start running unless there has been a motionless delay after the mouse-down event of at least #delay milliseconds.
This tool does not utilize any Adornments or tool handles, but it does temporarily add the #box part to the diagram. This tool does not modify the model or conduct any transaction.
Selection occurs on a mouse-up when it calls #selectInRect with the value of #computeBoxBounds. Selectable parts are selected when their bounds fall entirely within the rectangle, unless #isPartialInclusion is set to true.
If you implement your own drag-in-the-background-to-do-something tool, you may need to disable this tool or insert your new tool in the ToolManager.mouseMoveTools list before this tool, in order for your tool to run. There are two examples of such tools defined in the extensions directory: Drag Creating Tool and Drag Zooming Tool.
DragSelectingTool
The DragSelectingTool lets the user select multiple parts within a rectangular area drawn by the user. More... There is a temporary part, the #box, that shows the current area encompassed between the mouse-down point and the current mouse point. The default drag selection box is a magenta rectangle. You can change the #box to customize its appearance -- see its documentation for an example.This tool is a standard mouse-move tool, the ToolManager.dragSelectingTool. However this cannot start running unless there has been a motionless delay after the mouse-down event of at least #delay milliseconds.
This tool does not utilize any Adornments or tool handles, but it does temporarily add the #box part to the diagram. This tool does not modify the model or conduct any transaction.
Selection occurs on a mouse-up when it calls #selectInRect with the value of #computeBoxBounds. Selectable parts are selected when their bounds fall entirely within the rectangle, unless #isPartialInclusion is set to true.
If you implement your own drag-in-the-background-to-do-something tool, you may need to disable this tool or insert your new tool in the ToolManager.mouseMoveTools list before this tool, in order for your tool to run. There are examples of such tools defined in the extensions directory: Realtime Drag Selecting Tool, Drag Creating Tool, and Drag Zooming Tool.
ForceDirectedEdge
This holds ForceDirectedLayout-specific information about Links. More...This class inherits from LayoutEdge.
GoJS Class Index
Geometry
The Geometry class is used to define the "shape" of a Shape. More... A Geometry can be simple straight lines, rectangles, or ellipses. A Geometry can also be an arbitrarily complex path, consisting of a list of PathFigures.A Geometry must not be modified once it has been used by a Shape. However, a Geometry may be shared by multiple Shapes.
GraphLinksModel
GraphLinksModels support links between nodes and grouping nodes and links into subgraphs. More... GraphLinksModels hold node data and link data in separate arrays. Node data is normally represented in a Diagram by instances of Node, but they could be represented by simple Parts or by Groups. Link data should be represented by instances of Link.Each link data object is assumed to have two values, one referring to the node that the link is coming from and one that the link is going to. The #linkFromKeyProperty property names the property on the link data whose value is the key of the "from" node. The #linkToKeyProperty property names the property on the link data whose value is the key of the "to" node. The default values for these properties are "from" and "to" respectively.
For example, one can define a graph consisting of two nodes with one link connecting them:
model.nodeDataArray = [ { key: "Alpha" }, { key: "Beta" } ]; model.linkDataArray = [ { from: "Alpha", to: "Beta" } ];
If you want to have subgraphs in your diagram, where a group node contains some number of nodes and links, you need to declare that some node data actually represent groups, and you need to provide a reference from a member node data to its containing group node data. The #nodeIsGroupProperty property names the property on a node data that is true if that node data represents a group. The #nodeGroupKeyProperty property names the property on a node data whose value is the key of the containing group's node data. The default values for these properties are "isGroup" and "group" respectively.
For example, one can define a graph consisting of one group containing a subgraph of two nodes connected by a link, with a second link from that group to a third node that is not a member of that group:
model.nodeDataArray = [ { key: "Group1", isGroup: true}, { key: "Alpha", group: "Group1" }, { key: "Beta", group: "Group1" }, { key: "Gamma" } ]; model.linkDataArray = [ { from: "Alpha", to: "Beta" }, { from: "Group1", to: "Gamma" } ];
GraphLinksModels also support distinguishing the "port" element of a node to which a link can connect, at either end of the link. This identification is a string that names the "port" element in the node. However, you need to set the #linkFromPortIdProperty and/or #linkToPortIdProperty properties before the model is able to get the "port id" information from the link data.
For example, one can define a graph consisting of a "subtraction" node and two inputs and one output. The "subtraction" node has two distinct inputs called "subtrahend" and "minuend"; the output is called "difference".
model.linkFromPortIdProperty = "fromPort"; // necessary to remember portIds model.linkToPortIdProperty = "toPort"; model.nodeDataArray = [ { key: 1, constant: 5 }, // a constant input node { key: 2, constant: 2 }, // another constant node { key: 3, operation: "subtract" }, { key: 4, value: 3 } // the output node ]; model.linkDataArray = [ { from: 1, to: 3, toPort: "subtrahend" }, { from: 2, to: 3, toPort: "minuend" }, { from: 3, to: 4, fromPort: "difference" } ];In this case links connected to node 3 (which is the subtraction operation) are distinguished by port id. The connections to the other nodes do not have any port identification, presumably because there is only one port on those nodes, representing the node value.
This model does not support the modification of whether a node data object is a group.
This model cannot detect the modification of the #linkDataArray array or the modification of any link data object. If you want to add or remove link data from the #linkDataArray, call the #addLinkData or #removeLinkData methods. If you want to modify the node a link connects to, call the #setFromKeyForLinkData and/or #setToKeyForLinkData methods. If you want to change the membership of a node data in a group, call the #setGroupKeyForNodeData method.
GraphLinksModel
GraphLinksModels support links between nodes and grouping nodes and links into subgraphs. More... GraphLinksModels hold node data and link data in separate arrays. Node data is normally represented in a Diagram by instances of Node, but they could be represented by simple Parts or by Groups. Link data should be represented by instances of Link.Each link data object is assumed to have two values, one referring to the node that the link is coming from and one that the link is going to. The #linkFromKeyProperty property names the property on the link data whose value is the key of the "from" node. The #linkToKeyProperty property names the property on the link data whose value is the key of the "to" node. The default values for these properties are "from" and "to" respectively.
For example, one can define a graph consisting of two nodes with one link connecting them:
model.nodeDataArray = [ { key: "Alpha" }, { key: "Beta" } ]; model.linkDataArray = [ { from: "Alpha", to: "Beta" } ];
If you want to have subgraphs in your diagram, where a group node contains some number of nodes and links, you need to declare that some node data actually represent groups, and you need to provide a reference from a member node data to its containing group node data. The #nodeIsGroupProperty property names the property on a node data that is true if that node data represents a group. The #nodeGroupKeyProperty property names the property on a node data whose value is the key of the containing group's node data. The default values for these properties are "isGroup" and "group" respectively.
For example, one can define a graph consisting of one group containing a subgraph of two nodes connected by a link, with a second link from that group to a third node that is not a member of that group:
model.nodeDataArray = [ { key: "Group1", isGroup: true}, { key: "Alpha", group: "Group1" }, { key: "Beta", group: "Group1" }, { key: "Gamma" } ]; model.linkDataArray = [ { from: "Alpha", to: "Beta" }, { from: "Group1", to: "Gamma" } ];
GraphLinksModels also support distinguishing the "port" element of a node to which a link can connect, at either end of the link. This identification is a string that names the "port" element in the node. However, you need to set the #linkFromPortIdProperty and/or #linkToPortIdProperty properties before the model is able to get the "port id" information from the link data.
For example, one can define a graph consisting of a "subtraction" node and two inputs and one output. The "subtraction" node has two distinct inputs called "subtrahend" and "minuend"; the output is called "difference".
model.linkFromPortIdProperty = "fromPort"; // necessary to remember portIds model.linkToPortIdProperty = "toPort"; model.nodeDataArray = [ { key: 1, constant: 5 }, // a constant input node { key: 2, constant: 2 }, // another constant node { key: 3, operation: "subtract" }, { key: 4, value: 3 } // the output node ]; model.linkDataArray = [ { from: 1, to: 3, toPort: "subtrahend" }, { from: 2, to: 3, toPort: "minuend" }, { from: 3, to: 4, fromPort: "difference" } ];In this case links connected to node 3 (which is the subtraction operation) are distinguished by port id. The connections to the other nodes do not have any port identification, presumably because there is only one port on those nodes, representing the node value.
Note that there is no requirement that the link data objects have any kind of unique identifier, unlike for node data. There is no expectation that there be references to link data in the model, so there is no need for such an identifier. When there are multiple links connecting two ports, the only way to distinguish the links in the model is by reference to the particular link data object. This is why there are two methods on the Diagram class for Nodes, Diagram.findNodeForKey and Diagram.findNodeForData, but there is only the one method for Links, Diagram.findLinkForData.
However you may wish to add your own unique identifiers on the link data. One way to implement this is by setting a property on the link data each time one is added to the model:
model.addChangedListener(function(e) { if (e.change === go.ChangedEvent.Insert && e.modelChange === "linkDataArray") { var id = e.model.modelData.linkCounter; // keep the counter on the Model.modelData object if (typeof id !== 'number') id = 0; e.model.modelData.linkCounter = id + 1; e.newValue.id = id; // e.newValue is the link data object that was added } });Note how the counter is kept on the Model.modelData object, so that it can be saved and loaded automatically. Remember to re-establish the listener on a newly constructed model, including those constructed by Model.fromJson.
This model does not support the modification of whether a node data object is a group.
This model cannot detect the modification of the #linkDataArray array or the modification of any link data object. If you want to add or remove link data from the #linkDataArray, call the #addLinkData or #removeLinkData methods. If you want to modify the node a link connects to, call the #setFromKeyForLinkData and/or #setToKeyForLinkData methods. If you want to change the membership of a node data in a group, call the #setGroupKeyForNodeData method.
GraphObject
This is the abstract base class for all graphical objects. More... Classes inheriting from GraphObject include: Shape, TextBlock, Picture, and Panel. From the Panel class the Part class is derived, from which the Node and Link classes derive.It is very common to make use of the static function GraphObject.make in order to build up a visual tree of GraphObjects. You can see many examples of this throughout the Introduction, starting at Building Objects, and the Samples, starting with Minimal Sample.
Since GraphObject is an abstract class, programmers do not create GraphObjects themselves, but this class defines many properties used by all kinds of GraphObjects.
The only visual properties on GraphObject are #background and #areaBackground. However one can control whether the GraphObject is drawn at all by setting #visible, or by setting #opacity to zero if you still want the GraphObject to occupy space. Also, if you want to control whether any mouse or touch events "see" the GraphObject, you can set #pickable to false.
For more information about specifying how things get drawn, see the properties on the Shape, TextBlock, and Picture classes.
GraphObject Sizing
GraphObject defines most of the properties that cause objects to size themselves differently. The most prominent ones include:
- The #desiredSize, #minSize, and #maxSize properties are used to explicitly set or limit the size of visual elements. #width and #height are convenience properties that set the #desiredSize width and height, respectively.
- The #angle and #scale properties are used to transform visual elements.
- The #stretch property determines how a GraphObject will fill its visual space, contextually granted to it by its containing Panel. Top-level (Part) GraphObjects are not affected by this property because they are always granted infinite space.
All GraphObjects in a Diagram are measured and then arranged by their containing Panels in a tree-like fashion. After measuring and arranging, a GraphObject will have valid values for the read-only properties #naturalBounds, #measuredBounds, and #actualBounds.
- The #naturalBounds of a GraphObject describe its local size, without any transformations (#scale, #angle) affecting it.
- The #measuredBounds of a GraphObject describe its size relative to its containing Panel.
- The #actualBounds of a GraphObject describe its position and given size inside of its panel. This size may be smaller than #measuredBounds, for instance if a GraphObject with a large #desiredSize is placed in a Panel of a smaller #desiredSize. Smaller #actualBounds than #measuredBounds typically means an object will be cropped.
See the Introduction page on sizing for usage information and examples.
GraphObject Size and Position within Panel
Several GraphObject properties guide the containing Panel for how to size and position the object within the panel.- The #alignment specifies where the object should be relative to some area of the panel. For example, an alignment value of Spot.BottomRight means that the GraphObject should be at the bottom-right corner of the panel.
- The #alignmentFocus specifies precisely which point of the GraphObject should be aligned at the #alignment spot.
- The #column and #row properties are only used by Panel.Table panels, to indicate where the GraphObject should be.
- The #columnSpan and #rowSpan properties tell the Panel.Table panel how large the GraphObject should be.
- The #isPanelMain property indicates to some kinds of Panels that the GraphObject is the "primary" object that other panel children should be measured with or positioned in.
- The #margin property tells the containing Panel how much extra space to put around this GraphObject.
- The #position property is used to determine the relative position of GraphObjects when they are elements of a Panel.Position panel.
See the Introduction page on Panels and Table Panels for an overview of the capabilities.
Top-level GraphObjects are Parts
A Part is a derived class of GraphObject representing a top-level object. All top-level GraphObjects must be Parts, and Node, Link, Group, and Adornment derive from Part. The position of a Part determines the point of the Part's top-left corner in document coordinates. See also Part.location, which supports an way to specify the position based on a different spot of a different element within the Part.
There are several read-only properties that help navigate up the visual tree.
- #panel returns the Panel that directly contains this GraphObject
- #part returns the Part that this GraphObject is in, perhaps via intervening Panels; this is frequently used in order to get to the model data, Panel.data
- #layer returns the Layer that this GraphObject's Part is in
- #diagram returns the Diagram that this GraphObject's Part's Layer is in
See the Visual Tree sample for a diagram displaying the visual tree of a simple diagram.
User Interaction
GraphObjects have several properties enabling dynamic customizable interaction. There are several definable functions that execute on input events: #mouseDragEnter, #mouseDragLeave, #mouseDrop, #mouseEnter, #mouseHold, #mouseHover, #mouseLeave, and #mouseOver. For example, you could define mouse enter-and-leave event handlers to modify the appearance of a link as the mouse passes over it:
myDiagram.linkTemplate = $(go.Link, $(go.Shape, { strokeWidth: 2, stroke: "gray" }, // default color is "gray" { // here E is the InputEvent and OBJ is this Shape mouseEnter: function(e, obj) { obj.strokeWidth = 4; obj.stroke = "dodgerblue"; }, mouseLeave: function(e, obj) { obj.strokeWidth = 2; obj.stroke = "gray"; } }));
There are #click, #doubleClick, and #contextClick functions that execute when a user appropriately clicks the GraphObject. These click functions are called with the InputEvent as the first argument and this GraphObject as the second argument. For example, you could define a click event handler on a Node that goes to another page:
myDiagram.nodeTemplate = $(go.Node, "Auto", $(go.Shape, "RoundedRectangle", new go.Binding("fill", "color")), $(go.TextBlock, { name: "TB", margin: 3 }, new go.Binding("text", "key")), { // second arg will be this GraphObject, which in this case is the Node itself: click: function(e, node) { window.open("http://en.wikipedia.org/Wiki/" + node.data.key); } });
Note: you may prefer defining DiagramEvent listeners on the Diagram rather than on individual GraphObjects. DiagramEvents also include more general events that do not necessarily correspond to input events.
The properties #actionCancel, #actionDown, #actionMove, and #actionUp define functions to execute when the GraphObject's #isActionable property is set to true (default false). See the ActionTool for more detail.
See the Introduction page on Events for a more general discussion.
GraphObjects as Ports
In GoJS, Links can only connect to elements within a Node that are specified as "ports", and by default the only port is the Node itself. Setting the #portId of a GraphObject inside a Node allows that object to act as a port. Note: the only kind of model that can save which port a link is connected with, i.e. portIds that are not an empty string, is a GraphLinksModel whose GraphLinksModel.linkFromPortIdProperty and GraphLinksModel.linkToPortIdProperty have been set to name properties on the link data objects.
GraphObjects have several properties that are only relevant when they are acting as ports. These port-related properties are:
- #portId, which must be set to a string that is unique within the Node, in order for this GraphObject to be treated as a "port", rather than the whole node
- #fromSpot and #toSpot, where a link should connect with this port
- #fromEndSegmentLength and #toEndSegmentLength, the length of the link segment adjacent to this port
- #fromEndSegmentDirection and #toEndSegmentDirection, the orientation of the link when connecting to this port
- #fromShortLength and #toShortLength, the distance the link should terminate before touching this port
- #fromLinkable and #toLinkable, whether the user may draw links connecting with this port
- #fromLinkableDuplicates and #toLinkableDuplicates, whether the user may draw multiple links between the same pair of ports
- #fromLinkableSelfNode and #toLinkableSelfNode, whether the user may draw a link between ports on the same node
- #fromMaxLinks and #toMaxLinks, to limit the number of links connecting with this port in a particular direction
See the Introduction page on ports and link connection points for port usage information and examples.
GraphObjects as labels on a Link
GraphObjects can also be used as "labels" on a Link. In addition to the #alignmentFocus property, these properties direct a Link Panel to position a "label" at a particular point along the route of the link, in a particular manner:
- #segmentIndex, which segment the label should be on
- #segmentFraction, how far along the segment the label should be
- #segmentOffset, where the label should be positioned relative to the segment
- #segmentOrientation, how the label should be rotated relative to the angle of the segment
See the Introduction page on link labels for examples of how to make use of labels on Links.
Interactive Behavior
There are several properties that specify fairly high-level interactive behavior:
For more information, please read the Introduction page about Context Menus and the page about ToolTips.
Also see the Basic sample for examples of how to show context menus and tooltips.
GoJS Class Index
Margin
A Margin represents a band of space outside or inside a rectangular area, with possibly different values on each of the four sides. More...Example uses include GraphObject.margin, Panel.padding, and Diagram.padding.
Use the static functions Margin.parse and Margin.stringify to convert to and from a standard string representation that is independent of the current locale.
When an instance of this class is the value of a property of a GraphObject class or Diagram or CommandHandler or a Tool class, you should treat the object as if it were frozen or read-only -- you cannot modify its properties. This allows the property to return a value without allocating a new instance. If you need to do your own calculations with the value, call #copy to make a new instance with the same values that you can modify.
Many methods modify the object's properties and then return a reference to "this" object. The only instance method to allocate a new object is the #copy method. The static Margin.parse method also allocates a new object.
The "Debug" implementation of this class is significantly slower than the "Release" implementation, mostly due to additional error checking.
You cannot inherit from this class.
Model
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. More... 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 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.
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.
Model
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. More... 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 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.
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.
Node
A Node is a Part that may connect to other nodes with Links, or that may be a member of a Group. More...Group inherits from Node, enabling nodes to logically contain other nodes and links.
For a more general discussion of how to define nodes, see Introduction to Nodes.
Although you can create a Node and Diagram.add it to a Diagram, this does not update the Model. It is more common to create a node by adding a node data object to the model by calling Model.addNodeData. For example:
myDiagram.startTransaction("make new node"); myDiagram.model.addNodeData({ key: "Omega" }); myDiagram.commitTransaction("make new node");
This will cause a Node or simple Part to be created (copying the template found in Diagram.nodeTemplateMap), added to the Diagram in some Layer (based on Part.layerName), and bound to the node data (resulting in Panel.data referring to that node data object). If you do not keep a reference to that JavaScript object, as the above code does not, you can retrieve it later by calling Model.findNodeDataForKey.
It is very common to initialize a Diagram by setting Model.nodeDataArray to a JavaScript Array of JavaScript objects holding the properties that you need in your model. Nearly all of the samples do this kind of initialization.
You can delete a Node by either calling Diagram.remove or by calling Model.removeNodeData. The latter obviously will modify the Model; the former does so if the Node was created from model data. Commands such as CommandHandler.deleteSelection call these methods within a transaction.
You can find all of the Links that are connected with a Node by calling #findLinksConnected. Because links normally have a direction, you can find all of the links that have their Link.toNode be a given Node by calling #findLinksInto. Similarly, you can call #findLinksOutOf to find all of the links coming out from a node; such links have their Link.fromNode be that node. For tree-structured graphs, use #findTreeChildrenLinks or #findTreeParentLink.
If you are not so interested in the links but are interested in the nodes at the other end of the links connecting with a node, there are other methods that you can call. #findNodesConnected returns all of the nodes that are at the other end of the links that connect with a given node. #findNodesInto and #findNodesOutOf return the subsets of those nodes considering only those links that go into or come out of the given node. For tree-structured graphs, use #findTreeChildrenNodes or #findTreeParentNode.
For example, to operate on the data of all of the destination nodes:
var it = somenode.findNodesOutOf(); while (it.next()) { var child = it.value; if (child.data.text.indexOf("special") >= 0) { ... } }
You can link two nodes by creating a new Link, setting its Link.toNode and Link.fromNode (in either order), and Diagram.adding it to the diagram. But it is more common to add a link data object to the Diagram.model by calling GraphLinksModel.addLinkData. Just creating and adding a Link will not update the model.
Thus to add a link when using a GraphLinksModel you should do something like:
myDiagram.startTransaction("make new link"); myDiagram.model.addLinkData({ from: "Alpha", to: "Beta" }); myDiagram.commitTransaction("make new link");
Where you would substitute the keys of the actual nodes that you want to connect with a link. If you are using a TreeModel, there are no link data objects, so you just need to call TreeModel.setParentKeyForNodeData to specify the "parent" node's key for a "child" node data.
To find a Link given a link data object in the GraphLinksModel, call Diagram.findLinkForData. When using a TreeModel, call either Diagram.findNodeForData or Diagram.findNodeForKey to get a Node, and then call #findTreeParentLink to get the Link, if any exists.
To find a link that connects two nodes, call #findLinksTo or #findLinksBetween. With the former method, the direction matters; with the latter method it returns links in either direction.
As links connect with a node or are disconnected, you may want to update the appearance of the node. You can set the #linkConnected and #linkDisconnected properties to be functions that are called. These functions must not modify any link relationships -- the properties just exist to update the appearance of the node. A typical usage would be to change the color or figure of a shape.
You can control whether the user may draw a new link or reconnect a link between a pair of Nodes by affecting the result of LinkingBaseTool.isValidLink. You can override that predicate on LinkingTool and RelinkingTool, but it is easier to set the #linkValidation or LinkingBaseTool.linkValidation functional property.
For a more general discussion of validation, see Introduction to Validation.
Nodes also support the ability to provide logical and physical distinctions in the connection points that links use at a node. These connection objects are called "ports". By default the port object will be the whole Node. However, you can set the GraphObject.portId property on any GraphObject in the visual tree of a node to cause that element to be treated as a "port". The "port id" is just a string that ought to be unique amongst all of the port elements in the node.
In the case of a node only having a single port, you should set the GraphObject.portId as an empty string. When there is no such element declared as the default port, it uses the whole node. You can use the #port property to get the only port element.
When a node should have multiple ports, i.e. multiple GraphObjects acting as separate connection points for links, you should set each port's GraphObject.portId to a string value that is unique for the node. When there may be multiple ports on a node, you can get a collection of elements representing ports by using the #ports property. Use the #findPort method to find a particular port element by name.
Note: the only kind of model that can save port information, i.e. portIds that are not an empty string, for links is a GraphLinksModel whose GraphLinksModel.linkFromPortIdProperty and GraphLinksModel.linkToPortIdProperty have been set to name properties on the link data objects.
For a more general discussion of ports, see Introduction to Ports.
All of the "findLinks..." and "findNodes..." methods mentioned above take an optional port id argument. When no argument is passed, these methods consider all links connecting with the node. When a port id argument is provided, these methods only consider links that connect with that port in the given node. Thus when navigating through the diagram, you can easily look at all of the nodes that links coming out of a given node go to. Or you can just look at those nodes at the ends of links coming out of a particular port.
You can also control the default connecting behavior of Links at each port. Because a port can be any GraphObject, they are all properties on GraphObject. The properties are duplicated so that you can guide the "from" ends of links differently from the "to" ends of links. The properties include:
- GraphObject.fromSpot, GraphObject.toSpot
- GraphObject.fromEndSegmentLength, GraphObject.toEndSegmentLength
- GraphObject.fromEndSegmentDirection, GraphObject.toEndSegmentDirection
- GraphObject.fromShortLength, GraphObject.toShortLength
- GraphObject.fromLinkable, GraphObject.toLinkable
- GraphObject.fromLinkableDuplicates, GraphObject.toLinkableDuplicates
- GraphObject.fromLinkableSelfNode, GraphObject.toLinkableSelfNode
- GraphObject.fromMaxLinks, GraphObject.toMaxLinks
The "...Spot" and "...Length" and "...Direction" properties control the position and routing of links at a port. The "...Linkable..." and "...MaxLinks" properties control whether or not users can draw a new link or reconnect an existing link from or to a port. (The "...Spot" and "...Length" and "...Direction" properties also exist on Link, to override for a particular link the default values that come from a port element.)
For a more general discussion of link points, see Introduction to Link Connection Points.
When the graph is tree-structured, you can use several functions for traversing the tree:
- #findTreeParentNode
- #findTreeChildrenNodes
- #findTreeParentLink
- #findTreeChildrenLinks
- #findTreeRoot
- #findTreeParts
- #findCommonTreeParent
- #isInTreeOf
- #findTreeLevel
Determining whether a tree grows from the root via links that go out to the children or vice-versa is controlled for the whole diagram by the Diagram.isTreePathToChildren property. However an individual link will be ignored by the above functions if Link.isTreeLink is false.
The Node class also supports the notion of expanding and collapsing a subtree of nodes and links, causing those nodes and links to be shown or hidden. Principally this is a matter of setting Node.isTreeExpanded. Of course if the diagram's graph is not tree-structured, these concepts and properties might not apply.
If you want to change the appearance of the node you can do so in a function that you assign to the #treeExpandedChanged property. This function must not modify any link relationships or expand or collapse any subtrees -- the property just exists to update the appearance of the node.
There is an option for link routing to try to avoid crossing over nodes: Link.routing = Link.AvoidsNodes. You can control whether such links should avoid or ignore a node by setting #avoidable. Set #avoidableMargin to control the area beyond the GraphObject.actualBounds where AvoidsNodes links should not go.
For more discussion and examples, see Nodes, Ports, and Link Points.
For more about trees, see Trees, and SubTrees.
Only Nodes that are in Diagrams can have connections via Links. Templates should not be connected with Links, be labels of Links, be members of Groups, or have any Adornments.
GoJS Class Index
TextEditingTool
The TextEditingTool is used to let the user interactively edit text in place. More... This sets the TextBlock.text property; you may want to save the changed text to the model by using a TwoWay Binding on the "text" property of editable TextBlocks.
Typically this is used by setting the TextBlock.editable property to true
on a particular
The TextBlock is accessible as the TextEditingTool.textBlock property.
The text editor is accessible as the TextEditingTool.currentTextEditor property.
From the text editor control one can access the
You can disable mouse clicking from starting this text editing tool by setting Tool.isEnabled to false. You can disable the F2 key from starting this text editing tool by making sure Part.canEdit returns false, by either setting Diagram.allowTextEdit to false or by setting Part.textEditable to false.
Tool
Tools handle mouse events and keyboard events. More... The currently running tool, Diagram.currentTool, receives all input events from the Diagram.Most tools are "mode-less" tools that are managed by the ToolManager, which chooses the current tool based on the kind and position of the mouse event and the parts in the diagram. The ToolManager has properties holding instances of most of the pre-defined Tool classes. These classes include:
- In the ToolManager.mouseDownTools List:
- In the ToolManager.mouseMoveTools List:
- In the ToolManager.mouseUpTools List:
A tool is in the "running" state when it is the value of Diagram.currentTool. The Diagram.currentTool property setter will call #doStop on the old tool and then call #doStart on the new tool.
A tool can then go into the "active" state once it decides it can actually do something. This happens with a call to #doActivate, normally called by the ToolManager. Later it is deactivated (#doDeactivate) and then stopped. #isActive should be true when the tool is "active". Often tools should ignore certain common events, such as calls to #doMouseMove, unless the tool is "active".
You can prevent a "mode-less" tool (i.e. one managed by the ToolManager) from being started by the ToolManager by setting isEnabled to false.
You can also go into a particular "mode" by setting Diagram.currentTool explicitly, thereby circumventing the normal operation of the ToolManager. This ignores the isEnabled property and does not call the #canStart predicate. The behavior will depend on the tool -- not all of the predefined tools support operating as a "modal" tool.
Tools cannot be shared amongst multiple Diagrams.
If you define a Tool subclass, you may override any of the methods whose names start with "do" and any other methods that are documented to be overridable, such as #canStart. However you must seriously consider calling the base method in order to gets its default behavior. There may be situations where not calling the base method may cause subtle bugs. But that depends on the method and the tool. Please read the Introduction page on Extensions for how to override methods and how to call this base method.
Tool
Tools handle mouse, keyboard, and touch events. More... The currently running tool, Diagram.currentTool, receives all input events from the Diagram via canonicalized InputEvents.Most tools are "mode-less" tools that are managed by the ToolManager, which chooses the current tool based on the kind and position of the mouse event and the parts in the diagram. The ToolManager has properties holding instances of most of the pre-defined Tool classes. These classes include:
- In the ToolManager.mouseDownTools List:
- In the ToolManager.mouseMoveTools List:
- In the ToolManager.mouseUpTools List:
A tool is in the "running" state when it is the value of Diagram.currentTool. The Diagram.currentTool property setter will call #doStop on the old tool and then call #doStart on the new tool.
A tool can then go into the "active" state once it decides it can actually do something. This happens with a call to #doActivate, normally called by the ToolManager. Later it is deactivated (#doDeactivate) and then stopped. #isActive should be true when the tool is "active". Often tools should ignore certain common events, such as calls to #doMouseMove, unless the tool #isActive.
You can prevent a "mode-less" tool (i.e. one managed by the ToolManager) from being started by the ToolManager by setting isEnabled to false.
You can also go into a particular "mode" by setting Diagram.currentTool explicitly, thereby circumventing the normal operation of the ToolManager. This ignores the isEnabled property and does not call the #canStart predicate. The behavior will depend on the tool -- not all of the predefined tools support operating as a "modal" tool.
Tools cannot be shared amongst multiple Diagrams.
If you define a Tool subclass, you may override any of the methods whose names start with "do" and any other methods that are documented to be overridable, such as #canStart. However you must seriously consider calling the base method in order to gets its default behavior. There may be situations where not calling the base method may cause subtle bugs. But that depends on the method and the tool. Please read the Introduction page on Extensions for how to override methods and how to call the base method.
ToolManager
This special Tool is responsible for managing all of the Diagram's mode-less tools, which you can access as the Diagram.toolManager. More...Mode-less tools are tools that are present in one of the following lists: #mouseDownTools, #mouseMoveTools, or #mouseUpTools. This ToolManager tool is normally the Diagram.defaultTool, so it is also usually the Diagram.currentTool when the user is doing "nothing".
When this tool is running as the current tool, it handles mouse-down, mouse-move, and mouse-up events and the corresponding touch events. For each event it iterates over each of the tools in the corresponding list, calling the tool's Tool.canStart predicate. If that predicate returns true, it starts that tool by making it the diagram's current tool. It then activates the tool and passes on the event to the tool by calling the corresponding method (either Tool.doMouseDown, Tool.doMouseMove, or Tool.doMouseUp).
Because this tool is typically the one running as the diagram's current tool when the user isn't "doing" anything, this tool can also handle other events, such as mouse wheel events and keyboard commands.
Keyboard events are just passed on to the Diagram.commandHandler's CommandHandler.doKeyDown or CommandHandler.doKeyUp method.
This tool also is responsible for showing tooltips. Tooltip Adornments may be declared as any GraphObject.toolTip, or as the Diagram.toolTip if the mouse or finger remains motionless in the background of the diagram.
This tool does not utilize any tool handles. This tool does not conduct any transactions. But of course some of the tools that the ToolManager starts can show tool handles and/or conduct their own transactions.
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Constructor
- You do not normally need to create an instance of this tool
because one already exists as the ToolManager.actionTool.
+ You do not normally need to create an instance of this tool
because one already exists as the ToolManager.actionTool. More...
The Tool.name of this tool is "Action".
diff --git a/api/symbols/Adornment.html b/api/symbols/Adornment.html
index 35a542ce2..e67dc03ab 100644
--- a/api/symbols/Adornment.html
+++ b/api/symbols/Adornment.html
@@ -974,7 +974,7 @@
Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
diff --git a/api/symbols/AnimationManager.html b/api/symbols/AnimationManager.html
index 5704123ea..f1e879c99 100644
--- a/api/symbols/AnimationManager.html
+++ b/api/symbols/AnimationManager.html
@@ -974,7 +974,7 @@ Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
diff --git a/api/symbols/Binding.html b/api/symbols/Binding.html
index 599668677..00a9c28d4 100644
--- a/api/symbols/Binding.html
+++ b/api/symbols/Binding.html
@@ -974,7 +974,7 @@ Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
diff --git a/api/symbols/Brush.html b/api/symbols/Brush.html
index 4930ed7a6..f62c7dd75 100644
--- a/api/symbols/Brush.html
+++ b/api/symbols/Brush.html
@@ -974,7 +974,7 @@ Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
diff --git a/api/symbols/ChangedEvent.html b/api/symbols/ChangedEvent.html
index c0d54c5a2..2761cfa87 100644
--- a/api/symbols/ChangedEvent.html
+++ b/api/symbols/ChangedEvent.html
@@ -974,7 +974,7 @@ Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
diff --git a/api/symbols/CircularEdge.html b/api/symbols/CircularEdge.html
index 488b3dcc0..1f1b83236 100644
--- a/api/symbols/CircularEdge.html
+++ b/api/symbols/CircularEdge.html
@@ -974,7 +974,7 @@ Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
diff --git a/api/symbols/CircularLayout.html b/api/symbols/CircularLayout.html
index f140dbce8..d18fb313b 100644
--- a/api/symbols/CircularLayout.html
+++ b/api/symbols/CircularLayout.html
@@ -974,7 +974,7 @@ Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
diff --git a/api/symbols/CircularVertex.html b/api/symbols/CircularVertex.html
index b1b39cd74..fdd634774 100644
--- a/api/symbols/CircularVertex.html
+++ b/api/symbols/CircularVertex.html
@@ -974,7 +974,7 @@ Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
diff --git a/api/symbols/ClickCreatingTool.html b/api/symbols/ClickCreatingTool.html
index e750a5e7d..e59885082 100644
--- a/api/symbols/ClickCreatingTool.html
+++ b/api/symbols/ClickCreatingTool.html
@@ -974,7 +974,7 @@ Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
@@ -1014,7 +1014,7 @@ Constructor
- You do not normally need to create an instance of this tool
because one already exists as the ToolManager.clickCreatingTool, which you can modify.
+ You do not normally need to create an instance of this tool
because one already exists as the ToolManager.clickCreatingTool, which you can modify. More...
The Tool.name of this tool is "ClickCreating".
diff --git a/api/symbols/ClickSelectingTool.html b/api/symbols/ClickSelectingTool.html
index d8e0eb551..84e2583a8 100644
--- a/api/symbols/ClickSelectingTool.html
+++ b/api/symbols/ClickSelectingTool.html
@@ -974,7 +974,7 @@
Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
@@ -991,7 +991,7 @@
Tool.
- The ClickSelectingTool selects and deselects Parts when there is a click.
It does this by calling Tool.standardMouseSelect.
It is also responsible for handling and dispatching click events on GraphObjects
by calling Tool.standardMouseClick.
This tool is a standard mouse-up tool, the ToolManager.clickSelectingTool.
This tool does not utilize any Adornments or tool handles.
This tool does not modify the model or conduct any transaction.
An example customization of this tool is shown in the Tree Map sample,
where the Tool.standardMouseSelect method is overridden to permit the user to cycle through
the chain of containing groups, changing the selection on each click to the next containing group.
+ The ClickSelectingTool selects and deselects Parts when there is a click.
It does this by calling Tool.standardMouseSelect.
It is also responsible for handling and dispatching click events on GraphObjects
by calling Tool.standardMouseClick.
Note that this tool avoids raising click events on objects that are in temporary layers.
This is to prevent parts such as selection adornments from interfering with clicking on selected nodes or links.
(Adornments are in the "Adornment" Layer, which Layer.isTemporary.)
However this means that if you add a GraphObject.click event handler on a GraphObject in an Adornment,
it will not be called.
You can get it to be called by setting GraphObject.isActionable to true on that object in the adornment.
This tool is a standard mouse-up tool, the ToolManager.clickSelectingTool.
This tool does not utilize any Adornments or tool handles.
This tool does not modify the model or conduct any transaction.
An example customization of this tool is shown in the Tree Map sample,
where the Tool.standardMouseSelect method is overridden to permit the user to cycle through
the chain of containing groups, changing the selection on each click to the next containing group.
@@ -1014,7 +1014,7 @@ Constructor
- You do not normally need to create an instance of this tool
because one already exists as the ToolManager.clickSelectingTool.
+ You do not normally need to create an instance of this tool
because one already exists as the ToolManager.clickSelectingTool. More...
The Tool.name of this tool is "ClickSelecting".
diff --git a/api/symbols/CommandHandler.html b/api/symbols/CommandHandler.html
index 37723caaf..a60b8345c 100644
--- a/api/symbols/CommandHandler.html
+++ b/api/symbols/CommandHandler.html
@@ -974,7 +974,7 @@
Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
diff --git a/api/symbols/ContextMenuTool.html b/api/symbols/ContextMenuTool.html
index eb89e04b9..3ace9f197 100644
--- a/api/symbols/ContextMenuTool.html
+++ b/api/symbols/ContextMenuTool.html
@@ -974,7 +974,7 @@ Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
@@ -1014,7 +1014,7 @@ Constructor
- You do not normally need to create an instance of this tool
because one already exists as the ToolManager.contextMenuTool, which you can modify.
+ You do not normally need to create an instance of this tool
because one already exists as the ToolManager.contextMenuTool, which you can modify. More...
The Tool.name of this tool is "ContextMenu".
@@ -1205,7 +1205,7 @@
Method Summary
- If there is something found by findObjectWithContextMenu,
call showContextMenu with that object's GraphObject.contextMenu
or Diagram.contextMenu. More...
Once a context menu is being shown,
if a click occurs on a part of the context menu, call Tool.standardMouseClick.
Otherwise if the click occurs elsewhere, just stop this tool.
Unlike some tools, a mouse-up should not stop this tool.
+ If there is something found by findObjectWithContextMenu,
call showContextMenu with that object's GraphObject.contextMenu
or the Diagram.contextMenu. More...
If nothing is found or there is no context menu, call showDefaultContextMenu.
Once a context menu is being shown,
if a click occurs on a part of the context menu, call Tool.standardMouseClick.
Otherwise if the click occurs elsewhere, just stop this tool.
Unlike most tools, the first mouse-up should not stop this tool.
diff --git a/api/symbols/Diagram.html b/api/symbols/Diagram.html
index 6352da961..0eeb688fe 100644
--- a/api/symbols/Diagram.html
+++ b/api/symbols/Diagram.html
@@ -974,7 +974,7 @@
Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
diff --git a/api/symbols/DiagramEvent.html b/api/symbols/DiagramEvent.html
index fde337a0d..dede7a4b1 100644
--- a/api/symbols/DiagramEvent.html
+++ b/api/symbols/DiagramEvent.html
@@ -974,7 +974,7 @@ Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
diff --git a/api/symbols/DragSelectingTool.html b/api/symbols/DragSelectingTool.html
index a125cdc0e..e96891637 100644
--- a/api/symbols/DragSelectingTool.html
+++ b/api/symbols/DragSelectingTool.html
@@ -974,7 +974,7 @@ Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
@@ -991,7 +991,7 @@
Tool.
- The DragSelectingTool lets the user select multiple parts within a rectangular area drawn by the user.
There is a temporary part, the box,
that shows the current area encompassed between the mouse-down
point and the current mouse point.
The default drag selection box is a magenta rectangle.
You can change the box to customize its appearance -- see its documentation for an example.
This tool is a standard mouse-move tool, the ToolManager.dragSelectingTool.
However this cannot start running unless there has been a motionless delay
after the mouse-down event of at least delay milliseconds.
This tool does not utilize any Adornments or tool handles,
but it does temporarily add the box part to the diagram.
This tool does not modify the model or conduct any transaction.
Selection occurs on a mouse-up when it calls selectInRect
with the value of computeBoxBounds.
Selectable parts are selected when their bounds fall entirely within the rectangle,
unless isPartialInclusion is set to true.
If you implement your own drag-in-the-background-to-do-something tool, you may need to disable
this tool or insert your new tool in the ToolManager.mouseMoveTools list before this tool,
in order for your tool to run. There are two examples of such tools defined in the extensions directory:
Drag Creating Tool and
Drag Zooming Tool.
+ The DragSelectingTool lets the user select multiple parts within a rectangular area drawn by the user.
There is a temporary part, the box,
that shows the current area encompassed between the mouse-down
point and the current mouse point.
The default drag selection box is a magenta rectangle.
You can change the box to customize its appearance -- see its documentation for an example.
This tool is a standard mouse-move tool, the ToolManager.dragSelectingTool.
However this cannot start running unless there has been a motionless delay
after the mouse-down event of at least delay milliseconds.
This tool does not utilize any Adornments or tool handles,
but it does temporarily add the box part to the diagram.
This tool does not modify the model or conduct any transaction.
Selection occurs on a mouse-up when it calls selectInRect
with the value of computeBoxBounds.
Selectable parts are selected when their bounds fall entirely within the rectangle,
unless isPartialInclusion is set to true.
If you implement your own drag-in-the-background-to-do-something tool, you may need to disable
this tool or insert your new tool in the ToolManager.mouseMoveTools list before this tool,
in order for your tool to run. There are examples of such tools defined in the extensions directory:
Realtime Drag Selecting Tool,
Drag Creating Tool, and
Drag Zooming Tool.
@@ -1014,7 +1014,7 @@ Constructor
- You do not normally need to create an instance of this tool
because one already exists as the ToolManager.dragSelectingTool, which you can modify.
+ You do not normally need to create an instance of this tool
because one already exists as the ToolManager.dragSelectingTool, which you can modify. More...
The Tool.name of this tool is "DragSelecting".
@@ -1052,7 +1052,7 @@
Properties Summary
- Gets or sets the Part used as the "rubber-band selection box"
that is stretched to follow the mouse, as feedback for what area will
be passed to selectInRect upon a mouse-up. More...
Initially this is a Part containing only a simple magenta rectangular Shape.
The object to be resized during dragging should be named "SHAPE".
Setting this property does not raise any events.
Here is an example of changing the selection box to be a thicker bright green rectangle:
myDiagram.toolManager.dragSelectingTool.box =
$(go.Part,
{ layerName: "Tool" },
$(go.Shape,
{ name: "SHAPE", fill: null, stroke: "chartreuse", strokeWidth: 3 }));
Note that the Part should be put into a Layer that Layer.isTemporary.
Modifying this property while this tool Tool.isActive might have no effect.
+
Gets or sets the Part used as the "rubber-band selection box"
that is stretched to follow the mouse, as feedback for what area will
be passed to selectInRect upon a mouse-up. More...
Initially this is a Part containing only a simple magenta rectangular Shape.
The object to be resized during dragging should be named "SHAPE".
Setting this property does not raise any events.
Here is an example of changing the selection box to be a thicker bright green rectangle:
myDiagram.toolManager.dragSelectingTool.box =
$(go.Part,
{ layerName: "Tool", selectable: false },
$(go.Shape,
{ name: "SHAPE", fill: null, stroke: "chartreuse", strokeWidth: 3 }));
Note that the Part should be put into a Layer that Layer.isTemporary.
Modifying this property while this tool Tool.isActive might have no effect.
diff --git a/api/symbols/DraggingTool.html b/api/symbols/DraggingTool.html
index 6945db51b..da025656b 100644
--- a/api/symbols/DraggingTool.html
+++ b/api/symbols/DraggingTool.html
@@ -974,7 +974,7 @@ Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
@@ -1014,7 +1014,7 @@ Constructor
- You do not normally need to create an instance of this tool
because one already exists as the ToolManager.draggingTool, which you can modify.
+ You do not normally need to create an instance of this tool
because one already exists as the ToolManager.draggingTool, which you can modify. More...
The Tool.name of this tool is "Dragging".
diff --git a/api/symbols/ForceDirectedEdge.html b/api/symbols/ForceDirectedEdge.html
index c462aef2f..b6835e25e 100644
--- a/api/symbols/ForceDirectedEdge.html
+++ b/api/symbols/ForceDirectedEdge.html
@@ -974,7 +974,7 @@
Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
diff --git a/api/symbols/ForceDirectedLayout.html b/api/symbols/ForceDirectedLayout.html
index 16ea209a0..1037910a6 100644
--- a/api/symbols/ForceDirectedLayout.html
+++ b/api/symbols/ForceDirectedLayout.html
@@ -974,7 +974,7 @@ Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
diff --git a/api/symbols/ForceDirectedVertex.html b/api/symbols/ForceDirectedVertex.html
index 5b69a97c8..e51bb0c88 100644
--- a/api/symbols/ForceDirectedVertex.html
+++ b/api/symbols/ForceDirectedVertex.html
@@ -974,7 +974,7 @@ Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
diff --git a/api/symbols/Geometry.html b/api/symbols/Geometry.html
index bc4463eff..fdf2b265d 100644
--- a/api/symbols/Geometry.html
+++ b/api/symbols/Geometry.html
@@ -974,7 +974,7 @@ Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
diff --git a/api/symbols/GraphLinksModel.html b/api/symbols/GraphLinksModel.html
index c602464bb..62ca6f2ec 100644
--- a/api/symbols/GraphLinksModel.html
+++ b/api/symbols/GraphLinksModel.html
@@ -974,7 +974,7 @@ Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
@@ -991,7 +991,7 @@
Model.
- GraphLinksModels support links between nodes and grouping nodes and links into subgraphs.
GraphLinksModels hold node data and link data in separate arrays.
Node data is normally represented in a Diagram by instances of Node,
but they could be represented by simple Parts or by Groups.
Link data should be represented by instances of Link.
Each link data object is assumed to have two values, one referring to the node that the
link is coming from and one that the link is going to.
The linkFromKeyProperty property names the property on the link data whose value
is the key of the "from" node.
The linkToKeyProperty property names the property on the link data whose value
is the key of the "to" node.
The default values for these properties are "from" and "to" respectively.
For example, one can define a graph consisting of two nodes with one link connecting them:
model.nodeDataArray = [
{ key: "Alpha" },
{ key: "Beta" }
];
model.linkDataArray = [
{ from: "Alpha", to: "Beta" }
];
If you want to have subgraphs in your diagram, where a group node contains some number of nodes and links,
you need to declare that some node data actually represent groups,
and you need to provide a reference from a member node data to its containing group node data.
The nodeIsGroupProperty property names the property on a node data that is true
if that node data represents a group.
The nodeGroupKeyProperty property names the property on a node data whose value
is the key of the containing group's node data.
The default values for these properties are "isGroup" and "group" respectively.
For example, one can define a graph consisting of one group containing a subgraph of
two nodes connected by a link, with a second link from that group to a third node
that is not a member of that group:
model.nodeDataArray = [
{ key: "Group1", isGroup: true},
{ key: "Alpha", group: "Group1" },
{ key: "Beta", group: "Group1" },
{ key: "Gamma" }
];
model.linkDataArray = [
{ from: "Alpha", to: "Beta" },
{ from: "Group1", to: "Gamma" }
];
GraphLinksModels also support distinguishing the "port" element of a node to which
a link can connect, at either end of the link.
This identification is a string that names the "port" element in the node.
However, you need to set the linkFromPortIdProperty and/or
linkToPortIdProperty properties before the model is able to
get the "port id" information from the link data.
For example, one can define a graph consisting of a "subtraction" node and two inputs and one output.
The "subtraction" node has two distinct inputs called "subtrahend" and "minuend";
the output is called "difference".
model.linkFromPortIdProperty = "fromPort"; // necessary to remember portIds
model.linkToPortIdProperty = "toPort";
model.nodeDataArray = [
{ key: 1, constant: 5 }, // a constant input node
{ key: 2, constant: 2 }, // another constant node
{ key: 3, operation: "subtract" },
{ key: 4, value: 3 } // the output node
];
model.linkDataArray = [
{ from: 1, to: 3, toPort: "subtrahend" },
{ from: 2, to: 3, toPort: "minuend" },
{ from: 3, to: 4, fromPort: "difference" }
];
In this case links connected to node 3 (which is the subtraction operation)
are distinguished by port id.
The connections to the other nodes do not have any port identification,
presumably because there is only one port on those nodes, representing the node value.
This model does not support the modification of whether a node data object is a group.
This model cannot detect the modification of the linkDataArray array
or the modification of any link data object.
If you want to add or remove link data from the linkDataArray,
call the addLinkData or removeLinkData methods.
If you want to modify the node a link connects to, call the
setFromKeyForLinkData and/or setToKeyForLinkData methods.
If you want to change the membership of a node data in a group,
call the setGroupKeyForNodeData method.
+ GraphLinksModels support links between nodes and grouping nodes and links into subgraphs.
GraphLinksModels hold node data and link data in separate arrays.
Node data is normally represented in a Diagram by instances of Node,
but they could be represented by simple Parts or by Groups.
Link data should be represented by instances of Link.
Each link data object is assumed to have two values, one referring to the node that the
link is coming from and one that the link is going to.
The linkFromKeyProperty property names the property on the link data whose value
is the key of the "from" node.
The linkToKeyProperty property names the property on the link data whose value
is the key of the "to" node.
The default values for these properties are "from" and "to" respectively.
For example, one can define a graph consisting of two nodes with one link connecting them:
model.nodeDataArray = [
{ key: "Alpha" },
{ key: "Beta" }
];
model.linkDataArray = [
{ from: "Alpha", to: "Beta" }
];
If you want to have subgraphs in your diagram, where a group node contains some number of nodes and links,
you need to declare that some node data actually represent groups,
and you need to provide a reference from a member node data to its containing group node data.
The nodeIsGroupProperty property names the property on a node data that is true
if that node data represents a group.
The nodeGroupKeyProperty property names the property on a node data whose value
is the key of the containing group's node data.
The default values for these properties are "isGroup" and "group" respectively.
For example, one can define a graph consisting of one group containing a subgraph of
two nodes connected by a link, with a second link from that group to a third node
that is not a member of that group:
model.nodeDataArray = [
{ key: "Group1", isGroup: true},
{ key: "Alpha", group: "Group1" },
{ key: "Beta", group: "Group1" },
{ key: "Gamma" }
];
model.linkDataArray = [
{ from: "Alpha", to: "Beta" },
{ from: "Group1", to: "Gamma" }
];
GraphLinksModels also support distinguishing the "port" element of a node to which
a link can connect, at either end of the link.
This identification is a string that names the "port" element in the node.
However, you need to set the linkFromPortIdProperty and/or
linkToPortIdProperty properties before the model is able to
get the "port id" information from the link data.
For example, one can define a graph consisting of a "subtraction" node and two inputs and one output.
The "subtraction" node has two distinct inputs called "subtrahend" and "minuend";
the output is called "difference".
model.linkFromPortIdProperty = "fromPort"; // necessary to remember portIds
model.linkToPortIdProperty = "toPort";
model.nodeDataArray = [
{ key: 1, constant: 5 }, // a constant input node
{ key: 2, constant: 2 }, // another constant node
{ key: 3, operation: "subtract" },
{ key: 4, value: 3 } // the output node
];
model.linkDataArray = [
{ from: 1, to: 3, toPort: "subtrahend" },
{ from: 2, to: 3, toPort: "minuend" },
{ from: 3, to: 4, fromPort: "difference" }
];
In this case links connected to node 3 (which is the subtraction operation)
are distinguished by port id.
The connections to the other nodes do not have any port identification,
presumably because there is only one port on those nodes, representing the node value.
Note that there is no requirement that the link data objects have any kind of unique identifier, unlike for node data.
There is no expectation that there be references to link data in the model, so there is no need for such an identifier.
When there are multiple links connecting two ports, the only way to distinguish the links in the model
is by reference to the particular link data object.
This is why there are two methods on the Diagram class for Nodes, Diagram.findNodeForKey and Diagram.findNodeForData,
but there is only the one method for Links, Diagram.findLinkForData.
However you may wish to add your own unique identifiers on the link data.
One way to implement this is by setting a property on the link data each time one is added to the model:
model.addChangedListener(function(e) {
if (e.change === go.ChangedEvent.Insert && e.modelChange === "linkDataArray") {
var id = e.model.modelData.linkCounter; // keep the counter on the Model.modelData object
if (typeof id !== 'number') id = 0;
e.model.modelData.linkCounter = id + 1;
e.newValue.id = id; // e.newValue is the link data object that was added
}
});
Note how the counter is kept on the Model.modelData object, so that it can be saved and loaded automatically.
Remember to re-establish the listener on a newly constructed model, including those constructed by Model.fromJson.
This model does not support the modification of whether a node data object is a group.
This model cannot detect the modification of the linkDataArray array
or the modification of any link data object.
If you want to add or remove link data from the linkDataArray,
call the addLinkData or removeLinkData methods.
If you want to modify the node a link connects to, call the
setFromKeyForLinkData and/or setToKeyForLinkData methods.
If you want to change the membership of a node data in a group,
call the setGroupKeyForNodeData method.
diff --git a/api/symbols/GraphObject.html b/api/symbols/GraphObject.html
index a36b99d04..69da15fed 100644
--- a/api/symbols/GraphObject.html
+++ b/api/symbols/GraphObject.html
@@ -974,7 +974,7 @@ Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
@@ -2060,7 +2060,7 @@ Properties Summary
- Gets or sets the function to execute when the user moves the mouse
into this object without holding down any buttons. More...
This property is used by the ToolManager.
If this property value is a function, it is called with an InputEvent,
this GraphObject, and any previous GraphObject that the mouse was in.
The InputEvent.targetObject provides the GraphObject that was found
at the mouse point before looking up the visual tree of GraphObject.panels
to get to this object.
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.
After calling this function the diagram will be updated immediately.
For example, consider the situation where one wants to display buttons that the user can click
whenever the user passes the mouse over a node, and the buttons automatically disappear when the
mouse leaves the node. This can be implemented by showing an Adornment holding the buttons.
var nodeContextMenu =
$(go.Adornment, "Spot",
{ background: "transparent" }, // to help detect when the mouse leaves the area
$(go.Placeholder),
$(go.Panel, "Vertical",
{ alignment: go.Spot.Right, alignmentFocus: go.Spot.Left },
$("Button",
$(go.TextBlock, "Command 1"),
{
click: function(e, obj) {
var node = obj.part.adornedPart;
alert("Command 1 on " + node.data.text);
node.removeAdornment("ContextMenuOver");
}
}),
$("Button",
$(go.TextBlock, "Command 2"),
{
click: function(e, obj) {
var node = obj.part.adornedPart;
alert("Command 2 on " + node.data.text);
node.removeAdornment("ContextMenuOver");
}
})
));
Then in the definition of the Node we can implement a mouseEnter event handler:
myDiagram.nodeTemplate =
$(go.Node,
. . .
{
mouseEnter: function(e, node) {
nodeContextMenu.adornedObject = node;
nodeContextMenu.mouseLeave = function(ev, cm) {
node.removeAdornment("ContextMenuOver");
};
node.addAdornment("ContextMenuOver", nodeContextMenu);
}
});
Note how it automatically defines a mouseLeave event handler too.
The context menu Adornment is removed either when the mouse leaves the area of the Adornment
or when the user executes a button click event handler.
+ Gets or sets the function to execute when the user moves the mouse
into this object without holding down any buttons. More...
This property is used by the ToolManager.
If this property value is a function, it is called with an InputEvent,
this GraphObject that the mouse is now in,
and any previous GraphObject that the mouse was in.
The InputEvent.targetObject provides the GraphObject that was found
at the mouse point before looking up the visual tree of GraphObject.panels
to get to this object.
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.
After calling this function the diagram will be updated immediately.
For example, consider the situation where one wants to display buttons that the user can click
whenever the user passes the mouse over a node, and the buttons automatically disappear when the
mouse leaves the node. This can be implemented by showing an Adornment holding the buttons.
var nodeContextMenu =
$(go.Adornment, "Spot",
{ background: "transparent" }, // to help detect when the mouse leaves the area
$(go.Placeholder),
$(go.Panel, "Vertical",
{ alignment: go.Spot.Right, alignmentFocus: go.Spot.Left },
$("Button",
$(go.TextBlock, "Command 1"),
{
click: function(e, obj) {
var node = obj.part.adornedPart;
alert("Command 1 on " + node.data.text);
node.removeAdornment("ContextMenuOver");
}
}),
$("Button",
$(go.TextBlock, "Command 2"),
{
click: function(e, obj) {
var node = obj.part.adornedPart;
alert("Command 2 on " + node.data.text);
node.removeAdornment("ContextMenuOver");
}
})
));
Then in the definition of the Node we can implement a mouseEnter event handler:
myDiagram.nodeTemplate =
$(go.Node,
. . .
{
mouseEnter: function(e, node) {
nodeContextMenu.adornedObject = node;
nodeContextMenu.mouseLeave = function(ev, cm) {
node.removeAdornment("ContextMenuOver");
};
node.addAdornment("ContextMenuOver", nodeContextMenu);
}
});
Note how it automatically defines a mouseLeave event handler too.
The context menu Adornment is removed either when the mouse leaves the area of the Adornment
or when the user executes a button click event handler.
See also:
@@ -2149,7 +2149,7 @@ Properties Summary
- Gets or sets the function to execute when the user moves the mouse
into this object without holding down any buttons. More...
This property is used by the ToolManager.
If this property value is a function, it is called with an InputEvent,
this GraphObject, and any previous GraphObject that the mouse had been in.
The InputEvent.targetObject provides the GraphObject that was found
at the mouse point before looking up the visual tree of GraphObject.panels
to get to this object.
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.
After calling this function the diagram will be updated immediately.
For example, the Flow Chart sample
automatically shows and hides the ports as the mouse passes over a node.
The node template includes the following settings:
myDiagram.nodeTemplate =
$(go.Node,
. . .
{
. . .
// handle mouse enter/leave events to show/hide the ports
mouseEnter: function (e, obj) { showPorts(obj.part, true); },
mouseLeave: function (e, obj) { showPorts(obj.part, false); }
. . .
});
where the showPorts
function is defined to set the visible
property of each of the port elements of the node.
+ Gets or sets the function to execute when the user moves the mouse
into this object without holding down any buttons. More...
This property is used by the ToolManager.
If this property value is a function, it is called with an InputEvent,
this GraphObject that the mouse has left,
and any next GraphObject that the mouse is now in.
The InputEvent.targetObject provides the GraphObject that was found
at the mouse point before looking up the visual tree of GraphObject.panels
to get to this object.
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.
After calling this function the diagram will be updated immediately.
For example, the Flow Chart sample
automatically shows and hides the ports as the mouse passes over a node.
The node template includes the following settings:
myDiagram.nodeTemplate =
$(go.Node,
. . .
{
. . .
// handle mouse enter/leave events to show/hide the ports
mouseEnter: function (e, obj) { showPorts(obj.part, true); },
mouseLeave: function (e, obj) { showPorts(obj.part, false); }
. . .
});
where the showPorts
function is defined to set the visible
property of each of the port elements of the node.
See also:
diff --git a/api/symbols/GridLayout.html b/api/symbols/GridLayout.html
index 215086f54..3cec6c288 100644
--- a/api/symbols/GridLayout.html
+++ b/api/symbols/GridLayout.html
@@ -974,7 +974,7 @@ Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
diff --git a/api/symbols/Group.html b/api/symbols/Group.html
index b05370881..c68961f05 100644
--- a/api/symbols/Group.html
+++ b/api/symbols/Group.html
@@ -974,7 +974,7 @@ Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
diff --git a/api/symbols/InputEvent.html b/api/symbols/InputEvent.html
index c7443bfd6..aaf01ce8d 100644
--- a/api/symbols/InputEvent.html
+++ b/api/symbols/InputEvent.html
@@ -974,7 +974,7 @@ Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
diff --git a/api/symbols/Iterable.html b/api/symbols/Iterable.html
index 05a6506af..fe75273c4 100644
--- a/api/symbols/Iterable.html
+++ b/api/symbols/Iterable.html
@@ -974,7 +974,7 @@ Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
diff --git a/api/symbols/Iterator.html b/api/symbols/Iterator.html
index ee0db0e49..3a475e4bf 100644
--- a/api/symbols/Iterator.html
+++ b/api/symbols/Iterator.html
@@ -974,7 +974,7 @@ Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
diff --git a/api/symbols/Layer.html b/api/symbols/Layer.html
index 5467f4bd4..fcd8a37c6 100644
--- a/api/symbols/Layer.html
+++ b/api/symbols/Layer.html
@@ -974,7 +974,7 @@ Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
diff --git a/api/symbols/LayeredDigraphEdge.html b/api/symbols/LayeredDigraphEdge.html
index ac4a15815..169e2c564 100644
--- a/api/symbols/LayeredDigraphEdge.html
+++ b/api/symbols/LayeredDigraphEdge.html
@@ -974,7 +974,7 @@ Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
diff --git a/api/symbols/LayeredDigraphLayout.html b/api/symbols/LayeredDigraphLayout.html
index 0e5c5cebb..4f0ac963e 100644
--- a/api/symbols/LayeredDigraphLayout.html
+++ b/api/symbols/LayeredDigraphLayout.html
@@ -974,7 +974,7 @@ Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
diff --git a/api/symbols/LayeredDigraphVertex.html b/api/symbols/LayeredDigraphVertex.html
index e1f0d0b31..b6b6537c0 100644
--- a/api/symbols/LayeredDigraphVertex.html
+++ b/api/symbols/LayeredDigraphVertex.html
@@ -974,7 +974,7 @@ Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
diff --git a/api/symbols/Layout.html b/api/symbols/Layout.html
index d481a0224..fda5f8113 100644
--- a/api/symbols/Layout.html
+++ b/api/symbols/Layout.html
@@ -974,7 +974,7 @@ Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
diff --git a/api/symbols/LayoutEdge.html b/api/symbols/LayoutEdge.html
index 79fedbeda..4c427461e 100644
--- a/api/symbols/LayoutEdge.html
+++ b/api/symbols/LayoutEdge.html
@@ -974,7 +974,7 @@ Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
diff --git a/api/symbols/LayoutNetwork.html b/api/symbols/LayoutNetwork.html
index c703a1831..6602e916e 100644
--- a/api/symbols/LayoutNetwork.html
+++ b/api/symbols/LayoutNetwork.html
@@ -974,7 +974,7 @@ Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
diff --git a/api/symbols/LayoutVertex.html b/api/symbols/LayoutVertex.html
index 9040d05b8..69b9d5d27 100644
--- a/api/symbols/LayoutVertex.html
+++ b/api/symbols/LayoutVertex.html
@@ -974,7 +974,7 @@ Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
diff --git a/api/symbols/Link.html b/api/symbols/Link.html
index 1e0b4cee3..14d39c351 100644
--- a/api/symbols/Link.html
+++ b/api/symbols/Link.html
@@ -974,7 +974,7 @@ Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
diff --git a/api/symbols/LinkReshapingTool.html b/api/symbols/LinkReshapingTool.html
index 403d6ceeb..a470ba300 100644
--- a/api/symbols/LinkReshapingTool.html
+++ b/api/symbols/LinkReshapingTool.html
@@ -974,7 +974,7 @@ Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
@@ -1014,7 +1014,7 @@ Constructor
- You do not normally need to create an instance of this tool
because one already exists as the ToolManager.linkReshapingTool, which you can modify.
+ You do not normally need to create an instance of this tool
because one already exists as the ToolManager.linkReshapingTool, which you can modify. More...
The Tool.name of this tool is "LinkReshaping".
diff --git a/api/symbols/LinkingBaseTool.html b/api/symbols/LinkingBaseTool.html
index 35f82d2f8..05c5c404b 100644
--- a/api/symbols/LinkingBaseTool.html
+++ b/api/symbols/LinkingBaseTool.html
@@ -974,7 +974,7 @@
Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
diff --git a/api/symbols/LinkingTool.html b/api/symbols/LinkingTool.html
index f2e484c47..d538151a6 100644
--- a/api/symbols/LinkingTool.html
+++ b/api/symbols/LinkingTool.html
@@ -974,7 +974,7 @@ Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
@@ -1014,7 +1014,7 @@ Constructor
- You do not normally need to create an instance of this tool
because one already exists as the ToolManager.linkingTool, which you can modify.
+ You do not normally need to create an instance of this tool
because one already exists as the ToolManager.linkingTool, which you can modify. More...
The Tool.name of this tool is "Linking".
diff --git a/api/symbols/List.html b/api/symbols/List.html
index 560c282ab..232a72327 100644
--- a/api/symbols/List.html
+++ b/api/symbols/List.html
@@ -974,7 +974,7 @@
Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
diff --git a/api/symbols/Map.html b/api/symbols/Map.html
index f361c3518..bcf818c90 100644
--- a/api/symbols/Map.html
+++ b/api/symbols/Map.html
@@ -974,7 +974,7 @@ Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
diff --git a/api/symbols/Margin.html b/api/symbols/Margin.html
index 4a8c7c262..b57510ea5 100644
--- a/api/symbols/Margin.html
+++ b/api/symbols/Margin.html
@@ -974,7 +974,7 @@ Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
diff --git a/api/symbols/Model.html b/api/symbols/Model.html
index 7dbc6806e..a31e97248 100644
--- a/api/symbols/Model.html
+++ b/api/symbols/Model.html
@@ -974,7 +974,7 @@ Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
@@ -989,7 +989,7 @@
- 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 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.
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.
+ 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 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.
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.
diff --git a/api/symbols/Node.html b/api/symbols/Node.html
index 73198f6e8..c28016920 100644
--- a/api/symbols/Node.html
+++ b/api/symbols/Node.html
@@ -974,7 +974,7 @@ Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
diff --git a/api/symbols/Overview.html b/api/symbols/Overview.html
index 73d688baf..585badd40 100644
--- a/api/symbols/Overview.html
+++ b/api/symbols/Overview.html
@@ -974,7 +974,7 @@ Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
diff --git a/api/symbols/Palette.html b/api/symbols/Palette.html
index a856a4857..d9a745fc0 100644
--- a/api/symbols/Palette.html
+++ b/api/symbols/Palette.html
@@ -974,7 +974,7 @@ Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
diff --git a/api/symbols/Panel.html b/api/symbols/Panel.html
index 85ee79ede..36310337b 100644
--- a/api/symbols/Panel.html
+++ b/api/symbols/Panel.html
@@ -974,7 +974,7 @@ Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
diff --git a/api/symbols/PanningTool.html b/api/symbols/PanningTool.html
index abca5c4b1..3b3591347 100644
--- a/api/symbols/PanningTool.html
+++ b/api/symbols/PanningTool.html
@@ -974,7 +974,7 @@ Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
@@ -1014,7 +1014,7 @@ Constructor
- You do not normally need to create an instance of this tool
because one already exists as the ToolManager.panningTool.
+ You do not normally need to create an instance of this tool
because one already exists as the ToolManager.panningTool. More...
The Tool.name of this tool is "Panning".
diff --git a/api/symbols/Part.html b/api/symbols/Part.html
index ae877b175..b080e13f0 100644
--- a/api/symbols/Part.html
+++ b/api/symbols/Part.html
@@ -974,7 +974,7 @@
Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
diff --git a/api/symbols/PathFigure.html b/api/symbols/PathFigure.html
index 080f9c94b..37b5a64d6 100644
--- a/api/symbols/PathFigure.html
+++ b/api/symbols/PathFigure.html
@@ -974,7 +974,7 @@ Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
diff --git a/api/symbols/PathSegment.html b/api/symbols/PathSegment.html
index 35c61e475..efa79609a 100644
--- a/api/symbols/PathSegment.html
+++ b/api/symbols/PathSegment.html
@@ -974,7 +974,7 @@ Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
diff --git a/api/symbols/Picture.html b/api/symbols/Picture.html
index e1a47331e..ced14194b 100644
--- a/api/symbols/Picture.html
+++ b/api/symbols/Picture.html
@@ -974,7 +974,7 @@ Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
diff --git a/api/symbols/Placeholder.html b/api/symbols/Placeholder.html
index bca477ce5..1b0b8f63e 100644
--- a/api/symbols/Placeholder.html
+++ b/api/symbols/Placeholder.html
@@ -974,7 +974,7 @@ Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
diff --git a/api/symbols/Point.html b/api/symbols/Point.html
index b5864ba9a..df2b6f847 100644
--- a/api/symbols/Point.html
+++ b/api/symbols/Point.html
@@ -974,7 +974,7 @@ Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
@@ -1012,7 +1012,7 @@ Constructor
- The default constructor produces the Point(0,0). More...
+ The default constructor produces the Point(0,0). More...
This constructor may take either zero arguments or two arguments.
- Parameters:
diff --git a/api/symbols/Rect.html b/api/symbols/Rect.html
index e41883234..770fa8e95 100644
--- a/api/symbols/Rect.html
+++ b/api/symbols/Rect.html
@@ -974,7 +974,7 @@ Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
diff --git a/api/symbols/RelinkingTool.html b/api/symbols/RelinkingTool.html
index cbe5e4bfc..db643c84a 100644
--- a/api/symbols/RelinkingTool.html
+++ b/api/symbols/RelinkingTool.html
@@ -974,7 +974,7 @@ Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
@@ -1014,7 +1014,7 @@ Constructor
- You do not normally need to create an instance of this tool
because one already exists as the ToolManager.relinkingTool, which you can modify.
+ You do not normally need to create an instance of this tool
because one already exists as the ToolManager.relinkingTool, which you can modify. More...
The Tool.name of this tool is "Relinking".
diff --git a/api/symbols/ResizingTool.html b/api/symbols/ResizingTool.html
index f64c0a737..1c1beacc2 100644
--- a/api/symbols/ResizingTool.html
+++ b/api/symbols/ResizingTool.html
@@ -974,7 +974,7 @@
Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
@@ -1014,7 +1014,7 @@ Constructor
- You do not normally need to create an instance of this tool
because one already exists as the ToolManager.resizingTool, which you can modify.
+ You do not normally need to create an instance of this tool
because one already exists as the ToolManager.resizingTool, which you can modify. More...
The Tool.name of this tool is "Resizing".
diff --git a/api/symbols/RotatingTool.html b/api/symbols/RotatingTool.html
index 7c96ba4c9..4650817fc 100644
--- a/api/symbols/RotatingTool.html
+++ b/api/symbols/RotatingTool.html
@@ -974,7 +974,7 @@
Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
@@ -1014,7 +1014,7 @@ Constructor
- You do not normally need to create an instance of this tool
because one already exists as the ToolManager.rotatingTool, which you can modify.
+ You do not normally need to create an instance of this tool
because one already exists as the ToolManager.rotatingTool, which you can modify. More...
The Tool.name of this tool is "Rotating".
diff --git a/api/symbols/RowColumnDefinition.html b/api/symbols/RowColumnDefinition.html
index ede9dd152..536fb450f 100644
--- a/api/symbols/RowColumnDefinition.html
+++ b/api/symbols/RowColumnDefinition.html
@@ -974,7 +974,7 @@
Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
diff --git a/api/symbols/Set.html b/api/symbols/Set.html
index cd578b57e..eed8c8934 100644
--- a/api/symbols/Set.html
+++ b/api/symbols/Set.html
@@ -974,7 +974,7 @@ Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
diff --git a/api/symbols/Shape.html b/api/symbols/Shape.html
index 76977e7aa..777e65ff1 100644
--- a/api/symbols/Shape.html
+++ b/api/symbols/Shape.html
@@ -974,7 +974,7 @@ Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
diff --git a/api/symbols/Size.html b/api/symbols/Size.html
index a72e35aa5..7ba9fc1b7 100644
--- a/api/symbols/Size.html
+++ b/api/symbols/Size.html
@@ -974,7 +974,7 @@ Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
@@ -1012,7 +1012,7 @@ Constructor
- The default constructor produces the Size(0,0). More...
+ The default constructor produces the Size(0,0). More...
This constructor may take either zero arguments or two arguments.
- Parameters:
diff --git a/api/symbols/Spot.html b/api/symbols/Spot.html
index aeb97e722..a9e3540ef 100644
--- a/api/symbols/Spot.html
+++ b/api/symbols/Spot.html
@@ -974,7 +974,7 @@ Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
diff --git a/api/symbols/TextBlock.html b/api/symbols/TextBlock.html
index ec3ddc4e4..963c0404a 100644
--- a/api/symbols/TextBlock.html
+++ b/api/symbols/TextBlock.html
@@ -974,7 +974,7 @@ Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
diff --git a/api/symbols/TextEditingTool.html b/api/symbols/TextEditingTool.html
index cb2b9ce35..b8246f3b5 100644
--- a/api/symbols/TextEditingTool.html
+++ b/api/symbols/TextEditingTool.html
@@ -974,7 +974,7 @@ Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
@@ -1014,7 +1014,7 @@ Constructor
- You do not normally need to create an instance of this tool
because one already exists as the ToolManager.textEditingTool, which you can modify.
+ You do not normally need to create an instance of this tool
because one already exists as the ToolManager.textEditingTool, which you can modify. More...
The Tool.name of this tool is "TextEditing".
diff --git a/api/symbols/Tool.html b/api/symbols/Tool.html
index 316cc36a1..95920c517 100644
--- a/api/symbols/Tool.html
+++ b/api/symbols/Tool.html
@@ -974,7 +974,7 @@
Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
@@ -989,7 +989,7 @@
- Tools handle mouse events and keyboard events.
The currently running tool, Diagram.currentTool, receives all input events from the Diagram.
Most tools are "mode-less" tools that are managed by the ToolManager,
which chooses the current tool based on the kind and position of the mouse event and the parts in the diagram.
The ToolManager has properties holding instances of most of the pre-defined Tool classes.
These classes include:
- In the ToolManager.mouseDownTools List:
- In the ToolManager.mouseMoveTools List:
- In the ToolManager.mouseUpTools List:
The ToolManager chooses a tool to make current by finding in its lists of tools the first tool
whose canStart method returns true.
A tool is in the "running" state when it is the value of Diagram.currentTool.
The Diagram.currentTool property setter will call doStop on the old tool
and then call doStart on the new tool.
A tool can then go into the "active" state once it decides it can actually do something.
This happens with a call to doActivate, normally called by the ToolManager.
Later it is deactivated (doDeactivate) and then stopped.
isActive should be true when the tool is "active".
Often tools should ignore certain common events, such as calls to doMouseMove,
unless the tool is "active".
You can prevent a "mode-less" tool (i.e. one managed by the ToolManager)
from being started by the ToolManager by setting isEnabled to false.
You can also go into a particular "mode" by setting Diagram.currentTool explicitly,
thereby circumventing the normal operation of the ToolManager.
This ignores the isEnabled property and does not call the canStart predicate.
The behavior will depend on the tool -- not all of the predefined tools support operating as a "modal" tool.
Tools cannot be shared amongst multiple Diagrams.
If you define a Tool subclass, you may override any of the methods whose names start with "do"
and any other methods that are documented to be overridable, such as canStart.
However you must seriously consider calling the base method in order to gets its default behavior.
There may be situations where not calling the base method may cause subtle bugs.
But that depends on the method and the tool.
Please read the Introduction page on Extensions for how to override methods and how to call this base method.
+ Tools handle mouse, keyboard, and touch events.
The currently running tool, Diagram.currentTool, receives all input events from the Diagram
via canonicalized InputEvents.
Most tools are "mode-less" tools that are managed by the ToolManager,
which chooses the current tool based on the kind and position of the mouse event and the parts in the diagram.
The ToolManager has properties holding instances of most of the pre-defined Tool classes.
These classes include:
- In the ToolManager.mouseDownTools List:
- In the ToolManager.mouseMoveTools List:
- In the ToolManager.mouseUpTools List:
The ToolManager chooses a tool to run as the diagram's current tool by finding in its lists of tools the first tool
whose canStart method returns true. The ToolManager then sets Diagram.currentTool to be that tool.
A tool is in the "running" state when it is the value of Diagram.currentTool.
The Diagram.currentTool property setter will call doStop on the old tool
and then call doStart on the new tool.
A tool can then go into the "active" state once it decides it can actually do something.
This happens with a call to doActivate, normally called by the ToolManager.
Later it is deactivated (doDeactivate) and then stopped.
isActive should be true when the tool is "active".
Often tools should ignore certain common events, such as calls to doMouseMove,
unless the tool isActive.
You can prevent a "mode-less" tool (i.e. one managed by the ToolManager)
from being started by the ToolManager by setting isEnabled to false.
You can also go into a particular "mode" by setting Diagram.currentTool explicitly,
thereby circumventing the normal operation of the ToolManager.
This ignores the isEnabled property and does not call the canStart predicate.
The behavior will depend on the tool -- not all of the predefined tools support operating as a "modal" tool.
Tools cannot be shared amongst multiple Diagrams.
If you define a Tool subclass, you may override any of the methods whose names start with "do"
and any other methods that are documented to be overridable, such as canStart.
However you must seriously consider calling the base method in order to gets its default behavior.
There may be situations where not calling the base method may cause subtle bugs.
But that depends on the method and the tool.
Please read the Introduction page on Extensions for how to override methods and how to call the base method.
@@ -1068,7 +1068,7 @@ Properties Summary
- Gets or sets whether this tool is started and is actively doing something. More...
You can set this to true after your tool is started (i.e. when it is the
Diagram.currentTool and doStart
had been called), but when it is not yet in a state
that it is actually "doing" something, because it is waiting for the right
circumstances. This is typically only important when the tool is used in
a modal fashion.
The default value is false.
+
Gets or sets whether this tool is started and is actively doing something. More...
You can set this to true after your tool is started (i.e. when it is the
Diagram.currentTool and doStart
had been called), but when it is not yet in a state
that it is actually "doing" something, because it is waiting for the right
circumstances. This is typically only important when the tool is used in
a modal fashion.
The default value is false.
This is normally set by doActivate and doDeactivate.
@@ -1104,7 +1104,7 @@ Properties Summary
- Gets or sets the name of this tool. More...
The initial name is an empty string.
This name is sometimes used by tools that use Adornments as the Part.category for their Adornments.
It is also sometimes used by tools that conduct transactions as the transaction name.
+
Gets or sets the name of this tool. More...
The default name is an empty string,
but the constructor for each instance of a subclass of Tool will initialize it appropriately.
For example, the name of the DragSelectingTool is "DragSelecting".
This name is sometimes used by tools that use Adornments as the Part.category for their Adornments.
It is also sometimes used by tools that conduct transactions as the transaction name.
@@ -1122,7 +1122,7 @@ Properties Summary
- Gets or sets the name of the transaction to be committed by stopTransaction;
if null, the transaction will be rolled back. More...
If this is non-null at the time of a call to stopTransaction,
it calls Diagram.commitTransaction with this transaction name;
if this is null at that time, it calls Diagram.rollbackTransaction.
The default value is null; startTransaction will also set this to null.
This property exists so that no matter what execution path occurs to end the usage of a tool,
any ongoing transaction can be properly committed or rolled-back.
+
Gets or sets the name of the transaction to be committed by stopTransaction;
if null, the transaction will be rolled back. More...
If this is non-null at the time of a call to stopTransaction,
it calls Diagram.commitTransaction with this transaction name;
if this is null at that time, it calls Diagram.rollbackTransaction.
The default value is null; startTransaction will also set this to null.
Because a value of null when stopTransaction is called will rollback the transaction,
it is important that your code sets this property to a non-null value when it thinks it has succeeded.
This property exists so that no matter what execution path occurs to end the usage of a tool,
any ongoing transaction can be properly committed or rolled-back.
@@ -1191,7 +1191,7 @@ Method Summary
Returns:
- {boolean} true if isEnabled is true and
if the Diagram.toolManager can make this tool the current one and
then call the doStart method.
+ {boolean} true if isEnabled is true and
if the Diagram.toolManager can make this tool the Diagram.currentTool and
then call the doStart method.
@@ -1214,7 +1214,7 @@ Method Summary
- Called by ToolManager#domousedown and ToolManager#domousemove,
this method determines whether or not to allow pinch zooming from a multi-touch event. More...
By default this predicate just returns true.
This method may be overridden.
Please read the Introduction page on Extensions for how to override methods and how to call this base method.
+ Called by ToolManager.doMouseDown and ToolManager.doMouseMove,
this method determines whether or not to allow pinch zooming from a multi-touch event. More...
By default this predicate just returns true.
This method may be overridden.
Please read the Introduction page on Extensions for how to override methods and how to call this base method.
See also:
@@ -1272,7 +1272,7 @@ Method Summary
- The diagram will call this method when the user wishes to cancel the
current tool's operation. More...
Typically this is called when the user hits the ESCAPE key.
This should restore the original state and then call stopTool.
By default this method just calls stopTool.
This method may be overridden.
Please read the Introduction page on Extensions for how to override methods and how to call this base method.
+
The diagram will call this method when the user wishes to cancel the
current tool's operation. More...
Typically this is called when the user hits the ESCAPE key.
This should restore the original state of what was modified by this tool, and then it should call stopTool.
This method is not responsible for cleaning up any side-effects that should be performed
by doDeactivate and/or doStop, which will always be called whether the tool stops normally or abnormally.
By default this method just calls stopTool.
You will want to override this method even in tools that call startTransaction and stopTransaction,
because the UndoManager might not be enabled.
This method may be overridden.
Please read the Introduction page on Extensions for how to override methods and how to call this base method.
@@ -1593,7 +1593,7 @@
Method Summary
- Implement the standard behavior for mouse clicks,
searching for and calling click handler functions on GraphObjects
or on Diagram,
and raising the corresponding DiagramEvent. More...
A click on a GraphObject of the diagram will raise one of the following DiagramEvents:
"ObjectSingleClicked", "ObjectDoubleClicked", or "ObjectContextClicked".
This will also look at the corresponding click property:
GraphObject.click, GraphObject.doubleClick, or GraphObject.contextClick.
If the value is a function, this will call it, passing the current InputEvent
and the GraphObject.
If the value is null, it tries looking at the parent GraphObject.panel,
and so on, walking up the visual tree until it finds the appropriate function to call.
After calling the click function, if the value of InputEvent.handled is false,
this method will continue walking up the visual tree looking for more click functions
to call.
Once it has looked at the top-level object (a Part)
for a click function, this method stops.
A click in the background of the diagram will raise one of the following DiagramEvents:
"BackgroundSingleClicked", "BackgroundDoubleClicked", or "BackgroundContextClicked".
This will also look at the corresponding click property:
Diagram.click, Diagram.doubleClick, or Diagram.contextClick.
If the value is a function, this will call it, passing the current InputEvent.
This method is not responsible for selecting or deselecting any parts.
Call standardMouseSelect for that functionality.
This method may be overridden, but you should consider calling this base method in order to get all of its functionality.
Please read the Introduction page on Extensions for how to override methods and how to call this base method.
+
Implement the standard behavior for mouse clicks,
searching for and calling click handler functions on GraphObjects
or on Diagram,
and raising the corresponding DiagramEvent. More...
A click on a GraphObject of the diagram will raise one of the following DiagramEvents:
"ObjectSingleClicked", "ObjectDoubleClicked", or "ObjectContextClicked".
This will also look at the corresponding click property:
GraphObject.click, GraphObject.doubleClick, or GraphObject.contextClick.
If the value is a function, this will call it, passing the current InputEvent
and the GraphObject.
If the value is null, it tries looking at the parent GraphObject.panel,
and so on, walking up the visual tree until it finds the appropriate function to call.
After calling the click function, if the value of InputEvent.handled is false,
this method will continue walking up the visual tree looking for more click functions
to call.
Once it has looked at the top-level object (a Part)
for a click function, this method stops.
A click in the background of the diagram will raise one of the following DiagramEvents:
"BackgroundSingleClicked", "BackgroundDoubleClicked", or "BackgroundContextClicked".
This will also look at the corresponding click property:
Diagram.click, Diagram.doubleClick, or Diagram.contextClick.
If the value is a function, this will call it, passing the current InputEvent.
This method is not responsible for selecting or deselecting any parts.
Call standardMouseSelect for that functionality.
The ClickSelectingTool calls this method in its override of doMouseUp in order to raise "click" events.
Note that by default GraphObjects in Layers that are Layer.isTemporary will not be "clicked".
To change that behavior it is easiest to set GraphObject.isActionable to true on those objects for which you wish to handle "click" events.
Then the ActionTool's doMouseUp override will raise the standard "click" events.
This method may be overridden, but you should consider calling this base method in order to get all of its functionality.
Please read the Introduction page on Extensions for how to override methods and how to call this base method.
@@ -1652,7 +1652,7 @@ Method Summary
- Implement the standard behavior for selecting parts with the mouse,
depending on the control and shift modifier keys. More...
Control-clicking on a part will select it if it wasn't already,
and will deselect if it had been selected.
Shift-clicking on a part will add it to the selection (if it wasn't already).
Otherwise, clicking on a part will select it (if it wasn't already).
Note that there are restrictions on selection.
For example, a part cannot be selected in this manner if Part.selectable is false,
or if Diagram.maxSelectionCount would be exceeded.
A left click in the background of the diagram with no modifier keys clears the selection.
This method does not implement any click event behavior -- that is implemented by standardMouseClick.
This method may be overridden, but you should consider calling this base method in order to get all of its functionality.
Please read the Introduction page on Extensions for how to override methods and how to call this base method.
+
Implement the standard behavior for selecting parts with the mouse,
depending on the control and shift modifier keys. More...
Control-clicking on a part will select it if it wasn't already,
and will deselect if it had been selected.
Shift-clicking on a part will add it to the selection (if it wasn't already).
Otherwise, clicking on a part will select it (if it wasn't already).
Note that there are restrictions on selection.
For example, a part cannot be selected in this manner if Part.selectable is false,
or if Diagram.maxSelectionCount would be exceeded.
A left click in the background of the diagram with no modifier keys clears the selection.
This method does not implement any click event behavior -- that is implemented by standardMouseClick.
The ClickSelectingTool calls this method in its override of doMouseUp in order to change the selection.
This method may be overridden, but you should consider calling this base method in order to get all of its functionality.
Please read the Introduction page on Extensions for how to override methods and how to call this base method.
diff --git a/api/symbols/ToolManager.html b/api/symbols/ToolManager.html
index e7983dd0b..802f299f9 100644
--- a/api/symbols/ToolManager.html
+++ b/api/symbols/ToolManager.html
@@ -974,7 +974,7 @@
Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
@@ -1014,7 +1014,7 @@ Constructor
- You do not normally need to create an instance of this tool
because one already exists as the Diagram.toolManager, which you can modify. More...
The constructor produces a ToolManager that manages no tools.
Call initializeStandardTools to create various tools,
initialize the tool properties such as draggingTool,
and initialize the three mouse tool lists with those newly created tools.
+
You do not normally need to create an instance of this tool
because one already exists as the Diagram.toolManager, which you can modify. More...
The Tool.name of this tool is "ToolManager".
The constructor produces a ToolManager that manages no tools.
Call initializeStandardTools to create various tools,
initialize the tool properties such as draggingTool,
and initialize the three mouse tool lists with those newly created tools.
@@ -1195,6 +1195,8 @@
Properties Summary
gestureBehavior
+ 1.5
+
@@ -1726,7 +1728,7 @@ Method Summary
- Initialize the three mouse tool lists with instances of the standard tools. More...
This adds tools to the following three mouse tool lists:
mouseDownTools, mouseMoveTools, or mouseUpTools.
This also sets the various tool properties of this ToolManager
to those newly created tools.
Please read the Introduction page on Extensions for how to override methods and how to call this base method.
+ Initialize the three mouse tool lists with instances of the standard tools. More...
This adds new instances of tools to the following three mouse tool lists:
mouseDownTools, mouseMoveTools, or mouseUpTools.
This also sets the various tool properties of this ToolManager
to those newly created tools.
Please read the Introduction page on Extensions for how to override methods and how to call this base method.
diff --git a/api/symbols/Transaction.html b/api/symbols/Transaction.html
index 262badb48..1983863fd 100644
--- a/api/symbols/Transaction.html
+++ b/api/symbols/Transaction.html
@@ -974,7 +974,7 @@ Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
diff --git a/api/symbols/TreeEdge.html b/api/symbols/TreeEdge.html
index e7433b4da..6daeef054 100644
--- a/api/symbols/TreeEdge.html
+++ b/api/symbols/TreeEdge.html
@@ -974,7 +974,7 @@ Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
diff --git a/api/symbols/TreeLayout.html b/api/symbols/TreeLayout.html
index 0dd6b43ea..5a7d0c386 100644
--- a/api/symbols/TreeLayout.html
+++ b/api/symbols/TreeLayout.html
@@ -974,7 +974,7 @@ Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
diff --git a/api/symbols/TreeModel.html b/api/symbols/TreeModel.html
index fe13d7996..a0fe241bd 100644
--- a/api/symbols/TreeModel.html
+++ b/api/symbols/TreeModel.html
@@ -974,7 +974,7 @@ Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
diff --git a/api/symbols/TreeVertex.html b/api/symbols/TreeVertex.html
index 93cdafc75..0057d2715 100644
--- a/api/symbols/TreeVertex.html
+++ b/api/symbols/TreeVertex.html
@@ -974,7 +974,7 @@ Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
diff --git a/api/symbols/UndoManager.html b/api/symbols/UndoManager.html
index 368059444..61c42f505 100644
--- a/api/symbols/UndoManager.html
+++ b/api/symbols/UndoManager.html
@@ -974,7 +974,7 @@ Collection Classes
- GoJS® Diagramming Components
version 1.5.3 for JavaScript/HTML
by Northwoods Software®
+ GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
diff --git a/assets/images/screenshots/Spiral.png b/assets/images/screenshots/Spiral.png
new file mode 100644
index 000000000..7b5344317
Binary files /dev/null and b/assets/images/screenshots/Spiral.png differ
diff --git a/doc/changelog.html b/doc/changelog.html
index 7d728b8fb..8c666c848 100644
--- a/doc/changelog.html
+++ b/doc/changelog.html
@@ -53,6 +53,26 @@ GoJS® Change Log
}
+ Changes for 1.5.4
+
+ -
+ Added the Realtime Drag Selecting Tool sample,
+ with the RealtimeDragSelectingTool defined in the RealtimeDragSelectingTool.js
+ in the Extensions directory.
+
+ -
+ Added the Hover Buttons sample,
+ demonstrating how an Adornment can be used to show buttons for a node when the mouse is briefly motionless over the node.
+
+ -
+ Added the Spiral Layout sample,
+ with the SpiralLayout defined in the SpiralLayout.js file in the Extensions directory.
+
+ -
+ Fixed ContextMenuTool so that any click events (Tool.standardMouseClick) in the ContextMenuTool.currentContextMenuoccur on mouse-up, not mouse-down.
+
+
+
Changes for 1.5.3
- The transaction name argument to UndoManager.commitTransaction (or Model.commitTransaction or Diagram.commitTransaction) is now optional,
diff --git a/extensions/RealtimeDragSelecting.html b/extensions/RealtimeDragSelecting.html
new file mode 100644
index 000000000..1fc650fec
--- /dev/null
+++ b/extensions/RealtimeDragSelecting.html
@@ -0,0 +1,97 @@
+
+
+
+
Realtime Drag Selecting Tool
+
+
+
+
+
+
+
+
+
+
+
+
+
+ This sample demonstrates the RealtimeDragSelectingTool, which replaces the standard DragSelectingTool.
+ Press in the background, wait briefly, and then drag to start selecting Nodes or Links that intersect with the box.
+ You can press or release Control (Command on Mac) or Shift while dragging to see how the selection changes.
+
+
+ Load it in your own app by including RealtimeDragSelectingTool.js.
+ Initialize your Diagram by setting ToolManager.dragSelectingTool to a new instance of this tool.
+ For example:
+
+
+ myDiagram.toolManager.dragSelectingTool = new go.RealtimeDragSelectingTool();
+
+ or
+
+ $(go.Diagram, { . . .,
+ toolManager: $(RealtimeDragSelectingTool, { isPartialInclusion: true }),
+ . . . })
+
+
+
+
diff --git a/extensions/RealtimeDragSelectingTool.js b/extensions/RealtimeDragSelectingTool.js
new file mode 100644
index 000000000..3a9f95850
--- /dev/null
+++ b/extensions/RealtimeDragSelectingTool.js
@@ -0,0 +1,127 @@
+"use strict";
+/*
+* Copyright (C) 1998-2015 by Northwoods Software Corporation. All Rights Reserved.
+*/
+
+// A custom DragSelectingTool for selecting and deselecting Parts during a drag.
+
+/**
+* @constructor
+* @extends DragSelectingTool
+* @class
+* The RealtimeDragSelectingTool selects and deselects Parts within the {@link DragSelectingTool#box}
+* during a drag, not just at the end of the drag.
+*/
+function RealtimeDragSelectingTool() {
+ go.DragSelectingTool.call(this);
+ this._originalSelection = null;
+ this._temporarySelection = null;
+}
+
+go.Diagram.inherit(RealtimeDragSelectingTool, go.DragSelectingTool);
+
+/**
+* Remember the original collection of selected Parts.
+* @this {RealtimeDragSelectingTool}
+*/
+RealtimeDragSelectingTool.prototype.doActivate = function() {
+ go.DragSelectingTool.prototype.doActivate.call(this);
+ // keep a copy of the original Set of selected Parts
+ this._originalSelection = this.diagram.selection.copy();
+ // these Part.isSelected may have been temporarily modified
+ this._temporarySelection = new go.Set(go.Part);
+};
+
+/**
+* Release any references to selected Parts.
+* @this {RealtimeDragSelectingTool}
+*/
+RealtimeDragSelectingTool.prototype.doDeactivate = function() {
+ this._originalSelection = null;
+ this._temporarySelection = null;
+ go.DragSelectingTool.prototype.doDeactivate.call(this);
+};
+
+/**
+* Restore the selection which may have been modified during a drag.
+* @this {RealtimeDragSelectingTool}
+*/
+RealtimeDragSelectingTool.prototype.doCancel = function() {
+ var orig = this._originalSelection;
+ if (orig !== null) {
+ orig.each(function(p) { p.isSelected = true; });
+ this._temporarySelection.each(function(p) { if (!orig.contains(p)) p.isSelected = false; });
+ }
+ go.DragSelectingTool.prototype.doCancel.call(this);
+};
+
+/**
+* @this {RealtimeDragSelectingTool}
+*/
+RealtimeDragSelectingTool.prototype.doMouseMove = function() {
+ if (this.isActive) {
+ go.DragSelectingTool.prototype.doMouseMove.call(this);
+ this.selectInRect(this.computeBoxBounds());
+ }
+};
+
+/**
+* @this {RealtimeDragSelectingTool}
+*/
+RealtimeDragSelectingTool.prototype.doKeyDown = function() {
+ if (this.isActive) {
+ go.DragSelectingTool.prototype.doKeyDown.call(this);
+ this.selectInRect(this.computeBoxBounds());
+ }
+};
+
+/**
+* @this {RealtimeDragSelectingTool}
+*/
+RealtimeDragSelectingTool.prototype.doKeyUp = function() {
+ if (this.isActive) {
+ go.DragSelectingTool.prototype.doKeyUp.call(this);
+ this.selectInRect(this.computeBoxBounds());
+ }
+};
+
+/**
+* @ignore
+* Platform detection to use Meta (Command) key on Mac keyboard
+*/
+RealtimeDragSelectingTool.isMac = navigator.platform.toUpperCase().indexOf("MAC") >= 0;
+
+/**
+* @expose
+* @this {RealtimeDragSelectingTool}
+* @param {Rect} r a rectangular bounds in document coordinates.
+*/
+RealtimeDragSelectingTool.prototype.selectInRect = function(r) {
+ var diagram = this.diagram;
+ var orig = this._originalSelection;
+ var temp = this._temporarySelection;
+ if (diagram === null || orig === null) return;
+ var e = diagram.lastInput;
+ diagram.raiseDiagramEvent("ChangingSelection");
+ var found = diagram.findObjectsIn(r, null,
+ function(p) { return (p instanceof go.Part) && p.canSelect(); },
+ this.isPartialInclusion,
+ new go.Set(go.Part));
+ if (RealtimeDragSelectingTool.isMac ? e.meta : e.control) { // toggle or deselect
+ if (e.shift) { // deselect only
+ temp.each(function(p) { if (!found.contains(p)) p.isSelected = orig.contains(p); });
+ found.each(function(p) { p.isSelected = false; temp.add(p); });
+ } else { // toggle selectedness of parts based on _originalSelection
+ temp.each(function(p) { if (!found.contains(p)) p.isSelected = orig.contains(p); });
+ found.each(function(p) { p.isSelected = !orig.contains(p); temp.add(p); });
+ }
+ } else if (e.shift) { // extend selection only
+ temp.each(function(p) { if (!found.contains(p)) p.isSelected = orig.contains(p); });
+ found.each(function(p) { p.isSelected = true; temp.add(p); });
+ } else { // select found parts, and unselect all other previously selected parts
+ temp.each(function(p) { if (!found.contains(p)) p.isSelected = false; });
+ orig.each(function(p) { if (!found.contains(p)) p.isSelected = false; });
+ found.each(function(p) { p.isSelected = true; temp.add(p); });
+ }
+ diagram.raiseDiagramEvent("ChangedSelection");
+};
diff --git a/extensions/Spiral.html b/extensions/Spiral.html
new file mode 100644
index 000000000..5327cd906
--- /dev/null
+++ b/extensions/Spiral.html
@@ -0,0 +1,104 @@
+
+
+
+Spiral Layout
+
+
+
+
+
+
+
+
+
+
+
+
+
+ This sample demonstrates a custom Layout, SpiralLayout, which assumes the graph consists of a chain of nodes.
+ The layout is defined in its own file, as SpiralLayout.js.
+
+
+
+
diff --git a/extensions/SpiralLayout.js b/extensions/SpiralLayout.js
new file mode 100644
index 000000000..d31c2749b
--- /dev/null
+++ b/extensions/SpiralLayout.js
@@ -0,0 +1,138 @@
+"use strict";
+/*
+* Copyright (C) 1998-2015 by Northwoods Software Corporation. All Rights Reserved.
+*/
+
+// A custom Layout that lays out a chain of nodes in a spiral
+
+/**
+* @constructor
+* @extends Layout
+* @class
+* This layout assumes the graph is a chain of Nodes,
+* {@link #spacing} controls the spacing between nodes.
+*/
+function SpiralLayout() {
+ go.Layout.call(this);
+ this._spacing = 100;
+ this._clockwise = true;
+}
+go.Diagram.inherit(SpiralLayout, go.Layout);
+
+/**
+* This method actually positions all of the Nodes, assuming that the ordering of the nodes
+* is given by a single link from one node to the next.
+* This respects the {@link #spacing} property to affect the layout.
+* @this {SpiralLayout}
+* @param {Diagram|Group|Iterable} coll the collection of Parts to layout.
+*/
+SpiralLayout.prototype.doLayout = function(coll) {
+ var diagram = this.diagram;
+ if (coll instanceof go.Diagram) {
+ diagram = coll;
+ coll = coll.nodes; // use all links connecting with these nodes
+ } else if (coll instanceof go.Group) {
+ diagram = coll.diagram;
+ coll = coll.memberParts;
+ }
+
+ var root = null;
+ // find a root node -- one without any incoming links
+ var it = coll.iterator;
+ while (it.next()) {
+ var n = it.value;
+ if (!(n instanceof go.Node)) continue;
+ if (root === null) root = n;
+ if (n.findLinksInto().count === 0) {
+ root = n;
+ break;
+ }
+ }
+ // couldn't find a root node
+ if (root === null) return;
+
+ var space = this.spacing;
+
+ // implementations of doLayout that do not make use of a LayoutNetwork
+ // need to perform their own transactions
+ if (diagram !== null) diagram.startTransaction("Spiral Layout");
+
+ // treat the root node specially: it goes in the center
+ var r = this.diameter(root)/4;
+ var c = (this.clockwise ? 1 : -1);
+ var angle = c * Math.PI;
+ root.location = new go.Point(0, 0);
+ var rootlink = root.findLinksOutOf().first();
+ if (rootlink !== null) rootlink.curviness = c * r;
+
+ // now locate each of the following nodes, in order, along a spiral
+ var node = (rootlink !== null ? rootlink.toNode : null);
+ while (node !== null) {
+ var nextlink = node.findLinksOutOf().first();
+ var nextnode = (nextlink !== null ? nextlink.toNode : null);
+
+ // involute spiral
+ var cos = Math.cos(angle);
+ var sin = Math.sin(angle);
+ var x = r * (cos + angle * sin);
+ var y = r * (sin - angle * cos);
+ node.location = new go.Point(x, y);
+
+ var dia = this.diameter(node)/2 + this.diameter(nextnode)/2;
+ angle += c * Math.atan((dia + space) / Math.sqrt(x * x + y * y));
+ node = nextnode;
+ }
+
+ if (diagram !== null) diagram.commitTransaction("Spiral Layout");
+};
+
+/**
+* @ignore
+* Compute the effective diameter of a Node.
+* @this {SpiralLayout}
+* @param {Node} node
+* @return {number}
+*/
+SpiralLayout.prototype.diameter = function(node) {
+ if (!node) return 0;
+ var b = node.actualBounds;
+ return Math.sqrt(b.width*b.width + b.height*b.height);
+};
+
+// Public properties
+
+/**
+* Gets or sets the spacing between nodes.
+* The default value is 100.
+* @name SpiralLayout#spacing
+* @function.
+* @return {number}
+*/
+Object.defineProperty(SpiralLayout.prototype, "spacing", {
+ get: function() { return this._spacing; },
+ set: function(val) {
+ if (typeof val !== "number") throw new Error("new value for SpiralLayout.spacing must be a number, not: " + val);
+ if (this._spacing !== val) {
+ this._spacing = val;
+ this.invalidateLayout();
+ }
+ }
+});
+
+/**
+* Gets or sets whether the spiral should go clockwise or counter-clockwise.
+* The default value is true.
+* @name SpiralLayout#clockwise
+* @function.
+* @return {boolean}
+*/
+Object.defineProperty(SpiralLayout.prototype, "clockwise", {
+ get: function() { return this._clockwise; },
+ set: function(val) {
+ if (typeof val !== "boolean") throw new Error("new value for SpiralLayout.clockwise must be a boolean, not: " + val);
+ if (this._clockwise !== val) {
+ this._clockwise = val;
+ this.invalidateLayout();
+ }
+ }
+});
diff --git a/extensions/goSamples.js b/extensions/goSamples.js
index 15d56e0ef..8f0079072 100644
--- a/extensions/goSamples.js
+++ b/extensions/goSamples.js
@@ -139,9 +139,11 @@ var myMenu = '\
- Fishbone Layout
\
- Parallel Layout
\
- Serpentine Layout
\
+ - Spiral Layout
\
- Tree Map Layout
\
- Table Layout
\
\
+ - Realtime Selecting
\
- Drag Creating
\
- Drag Zooming
\
- Freehand Drawing
\
diff --git a/index.html b/index.html
index f099a2673..aa8e13a69 100644
--- a/index.html
+++ b/index.html
@@ -201,15 +201,15 @@ Interactive Diagrams for the Web
- GoJS is a feature-rich JavaScript library for implementing interactive diagrams across modern browsers and platforms.
- GoJS makes constructing diagrams of complex Nodes, Links, and Groups easy with customizable templates and layouts.
+
GoJS is a feature-rich JavaScript library for implementing interactive diagrams across modern web browsers and platforms.
+ GoJS makes constructing diagrams of complex nodes, links, and groups easy with customizable templates and layouts.
GoJS offers many advanced features for user interactivity such as drag-and-drop, copy-and-paste,
in-place text editing, templates, data binding and models, transactional state and undo management,
palettes, overviews, event handlers, commands, and an extensible tool system for custom operations.
GoJS is pure JavaScript, so users get interactivity without requiring round-trips to servers and without plugins such as Flash or Silverlight.
- GoJS normally runs completely in the browser, without any server-side requirements.
+ GoJS normally runs completely in the browser, rendering to a Canvas element or SVG without any server-side requirements.
GoJS does not depend on any JavaScript libraries or frameworks, so it should work with any HTML5 or JavaScript framework or with no framework at all.
diff --git a/intro/goIntro.js b/intro/goIntro.js
index 6d79407ab..92b872644 100644
--- a/intro/goIntro.js
+++ b/intro/goIntro.js
@@ -159,10 +159,7 @@ var myMenu = '\
- Diagram SVG
\
- Printing
\
- Server-side Images
\
- - Deployment
\
- \
+ - Deployment
\
';
//]]>
\ No newline at end of file
diff --git a/intro/performance.html b/intro/performance.html
index 8f2eac4f6..49ac10a09 100644
--- a/intro/performance.html
+++ b/intro/performance.html
@@ -13,28 +13,87 @@
Performance Considerations
- This page contains design suggestions to increase the performance of your diagrams.
- The optimizations available depend on the nature of your diagrams, and we encourage you to experiment.
+ Getting good performance for your diagrams does not require any effort on your part when
+ the diagrams are limited to a few hundreds of nodes and links, especially on the desktop.
+ However when your app might deal with thousands or tens of thousands of nodes and links,
+ you may need to adapt your implementation to avoid expensive features.
-Give as many GraphObjects as possible static sizes
-
- In general, setting GraphObject.desiredSize (ones that may be dynamically sized like Pictures, TextBlocks, etc) in your templates will speed up the measure and arrange portion of diagram initialization.
+ The perceived performance of your diagram depends on many different factors.
+
+ - JavaScript code is normally several to many times slower than Java or .NET code
+ on the same hardware platform.
+ - JavaScript code performance varies between different browsers and versions of browsers.
+ - Memory limitations, particularly on mobile devices, affect performance.
+ - There can be a wide variation of drawing performance on different platforms.
+ - Drawing and animation effects take resources.
+ - Complicated nodes or links are slower to build and update and draw than simple ones.
+ - Some layouts are inherently slower than others.
+
+Effects and Appearances
+
+ Shadows are relatively expensive to draw, so consider not setting Part.isShadowed to true.
+ Gradient Brushes are slower to draw than solid colors.
+ Complex Shape Geometrys are slower to draw than simpler ones, and they require more
+ computation when computing intersections.
+
- If you have Pictures and you know their size beforehand, its best to set a desiredSize so that each of them does not have to re-measure once the image is loaded. This may also avoid re-layouts due to images loading.
+ Animation takes up resources; consider setting AnimationManager.isEnabled to false.
-Virtualization
+Constructing and Sizing Nodes
+
+ Keep your Nodes and Links as simple as you can make it.
+ Limit how many GraphObjects that you use in your templates.
+ Use simpler Panel types when feasible -- the "Table" Panel is the most featureful,
+ but maybe you can just use a "Horizontal" or a "Vertical" or a "Spot" or an "Auto" Panel.
+ A Panel should have two or more elements in them (although there can be exceptions).
+ If you have no elements in a Panel, delete the panel.
+ If you have only one element in a Panel, consider removing the panel and merging the element
+ into the panel's containing panel.
+
+
+ Do not include objects that not visible.
+ Limit how much data binding that you use, and avoid Bindings with no source property name
+ or that are Binding.ofObject.
+
+
+ If you have a Picture and you know its intended size beforehand,
+ it's best to set its GraphObject.desiredSize
+ (or GraphObject.width and GraphObject.height)
+ so that it does not have to re-measured once the image loads.
+ When nodes change size a Layout might need to be performed again,
+ so having fixed size nodes helps reduce diagram layouts.
+ In general, setting GraphObject.desiredSize on the elements of your nodes,
+ especially Pictures, will speed up how quickly GoJS can measure and arrange
+ the Panels that form your Nodes or Links.
+
+Layouts
- For Diagrams with many nodes and links that only display a fraction of these at a time, you could implement some form of virtualization to optimize your Diagram.
+ GridLayout and TreeLayout are fast. LayeredDigraphLayout is slow.
+Virtualization
- The Virtualized Tree sample contains 123,456 total nodes, yet is fairly quick to render, because it only constructs nodes that are visible.
+ For diagrams with many nodes and links that only display a fraction of them at a time,
+ you could implement some form of virtualization to optimize your diagram.
+ The Virtualized Tree sample contains 123,456
+ total nodes, yet is fairly quick to load and render, because it only constructs nodes
+ and links that intersect with the viewport.
+
+
+ But this does complicate the implementation of the diagram, because you need to use a
+ separate model from the Diagram.model and manage adding and removing Nodes and
+ Links when the viewport changes.
+ Furthermore layout is more complicated because it needs to work on LayoutVertexes
+ and LayoutEdges, not on Nodes and Links.
+
+
+ Other virtualization samples are listed at Unlisted Samples.
Other considerations
@@ -44,19 +103,18 @@ Other considerations
set Diagram.div to null in order for the page to garbage collect the memory.
- Shadows and animation slow down rendering and can be turned off. LayeredDigraphLayout is the slowest of the layouts. Templates can be simplified to reduce rendering and re-measuring. The number of TextBlocks, the complexity of shapes, gradient Brushes all impact performance slightly, and reducing their use in aggregate may result in a performance gain.
-
-
-
- Depening on your app, it may be worthwhile to selectively toggle off some features (like shadows and animation) or to use simpler templates altogether, when slower environments are present, such as on mobile devices.
+ Depending on your app, it may be worthwhile to selectively toggle off some features
+ (like shadows and animation) or to use simpler templates altogether,
+ when slower environments are present, such as on mobile devices.
-
- You can use multiple templates depending on your zoom level. If you are zoomed out far enough (and therefore have a lot of nodes on the screen) you can switch to a simplified template so that rendering (when panning, dragging, etc) is faster. The process of switching templates has a performance cost, though, since Parts have to rebuild themselves.
+ You can use multiple templates depending on your zoom level.
+ If you are zoomed out far enough (and therefore have a lot of nodes on the screen)
+ you can switch to a simplified template so that rendering (when panning, dragging, etc) is faster.
+ The process of switching templates has a performance cost, though,
+ since Parts have to rebuild themselves.
-
-
The Tool.name of this tool is "Action". diff --git a/api/symbols/Adornment.html b/api/symbols/Adornment.html index 35a542ce2..e67dc03ab 100644 --- a/api/symbols/Adornment.html +++ b/api/symbols/Adornment.html @@ -974,7 +974,7 @@
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Constructor
The Tool.name of this tool is "ClickCreating". diff --git a/api/symbols/ClickSelectingTool.html b/api/symbols/ClickSelectingTool.html index d8e0eb551..84e2583a8 100644 --- a/api/symbols/ClickSelectingTool.html +++ b/api/symbols/ClickSelectingTool.html @@ -974,7 +974,7 @@
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Tool. - The ClickSelectingTool selects and deselects Parts when there is a click. It does this by calling Tool.standardMouseSelect. It is also responsible for handling and dispatching click events on GraphObjects by calling Tool.standardMouseClick.
This tool is a standard mouse-up tool, the ToolManager.clickSelectingTool.
This tool does not utilize any Adornments or tool handles. This tool does not modify the model or conduct any transaction.
An example customization of this tool is shown in the Tree Map sample, where the Tool.standardMouseSelect method is overridden to permit the user to cycle through the chain of containing groups, changing the selection on each click to the next containing group. + The ClickSelectingTool selects and deselects Parts when there is a click. It does this by calling Tool.standardMouseSelect. It is also responsible for handling and dispatching click events on GraphObjects by calling Tool.standardMouseClick.
Note that this tool avoids raising click events on objects that are in temporary layers. This is to prevent parts such as selection adornments from interfering with clicking on selected nodes or links. (Adornments are in the "Adornment" Layer, which Layer.isTemporary.) However this means that if you add a GraphObject.click event handler on a GraphObject in an Adornment, it will not be called. You can get it to be called by setting GraphObject.isActionable to true on that object in the adornment.
This tool is a standard mouse-up tool, the ToolManager.clickSelectingTool.
This tool does not utilize any Adornments or tool handles. This tool does not modify the model or conduct any transaction.
An example customization of this tool is shown in the Tree Map sample, where the Tool.standardMouseSelect method is overridden to permit the user to cycle through the chain of containing groups, changing the selection on each click to the next containing group.
@@ -1014,7 +1014,7 @@Constructor
The Tool.name of this tool is "ClickSelecting". diff --git a/api/symbols/CommandHandler.html b/api/symbols/CommandHandler.html index 37723caaf..a60b8345c 100644 --- a/api/symbols/CommandHandler.html +++ b/api/symbols/CommandHandler.html @@ -974,7 +974,7 @@
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Constructor
The Tool.name of this tool is "ContextMenu". @@ -1205,7 +1205,7 @@
Method Summary
Once a context menu is being shown, if a click occurs on a part of the context menu, call Tool.standardMouseClick. Otherwise if the click occurs elsewhere, just stop this tool. Unlike most tools, the first mouse-up should not stop this tool. diff --git a/api/symbols/Diagram.html b/api/symbols/Diagram.html index 6352da961..0eeb688fe 100644 --- a/api/symbols/Diagram.html +++ b/api/symbols/Diagram.html @@ -974,7 +974,7 @@
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Tool. - The DragSelectingTool lets the user select multiple parts within a rectangular area drawn by the user. There is a temporary part, the box, that shows the current area encompassed between the mouse-down point and the current mouse point. The default drag selection box is a magenta rectangle. You can change the box to customize its appearance -- see its documentation for an example.
This tool is a standard mouse-move tool, the ToolManager.dragSelectingTool. However this cannot start running unless there has been a motionless delay after the mouse-down event of at least delay milliseconds.
This tool does not utilize any Adornments or tool handles, but it does temporarily add the box part to the diagram. This tool does not modify the model or conduct any transaction.
Selection occurs on a mouse-up when it calls selectInRect with the value of computeBoxBounds. Selectable parts are selected when their bounds fall entirely within the rectangle, unless isPartialInclusion is set to true.
If you implement your own drag-in-the-background-to-do-something tool, you may need to disable this tool or insert your new tool in the ToolManager.mouseMoveTools list before this tool, in order for your tool to run. There are two examples of such tools defined in the extensions directory: Drag Creating Tool and Drag Zooming Tool. + The DragSelectingTool lets the user select multiple parts within a rectangular area drawn by the user. There is a temporary part, the box, that shows the current area encompassed between the mouse-down point and the current mouse point. The default drag selection box is a magenta rectangle. You can change the box to customize its appearance -- see its documentation for an example.
This tool is a standard mouse-move tool, the ToolManager.dragSelectingTool. However this cannot start running unless there has been a motionless delay after the mouse-down event of at least delay milliseconds.
This tool does not utilize any Adornments or tool handles, but it does temporarily add the box part to the diagram. This tool does not modify the model or conduct any transaction.
Selection occurs on a mouse-up when it calls selectInRect with the value of computeBoxBounds. Selectable parts are selected when their bounds fall entirely within the rectangle, unless isPartialInclusion is set to true.
If you implement your own drag-in-the-background-to-do-something tool, you may need to disable this tool or insert your new tool in the ToolManager.mouseMoveTools list before this tool, in order for your tool to run. There are examples of such tools defined in the extensions directory: Realtime Drag Selecting Tool, Drag Creating Tool, and Drag Zooming Tool.
@@ -1014,7 +1014,7 @@Constructor
The Tool.name of this tool is "DragSelecting". @@ -1052,7 +1052,7 @@
Properties Summary
Initially this is a Part containing only a simple magenta rectangular Shape. The object to be resized during dragging should be named "SHAPE". Setting this property does not raise any events.
Here is an example of changing the selection box to be a thicker bright green rectangle:
Note that the Part should be put into a Layer that Layer.isTemporary.
myDiagram.toolManager.dragSelectingTool.box =
$(go.Part,
{ layerName: "Tool" },
$(go.Shape,
{ name: "SHAPE", fill: null, stroke: "chartreuse", strokeWidth: 3 }));
Modifying this property while this tool Tool.isActive might have no effect. +
Initially this is a Part containing only a simple magenta rectangular Shape. The object to be resized during dragging should be named "SHAPE". Setting this property does not raise any events.
Here is an example of changing the selection box to be a thicker bright green rectangle:
Note that the Part should be put into a Layer that Layer.isTemporary.
myDiagram.toolManager.dragSelectingTool.box =
$(go.Part,
{ layerName: "Tool", selectable: false },
$(go.Shape,
{ name: "SHAPE", fill: null, stroke: "chartreuse", strokeWidth: 3 }));
Modifying this property while this tool Tool.isActive might have no effect.
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Constructor
The Tool.name of this tool is "Dragging". diff --git a/api/symbols/ForceDirectedEdge.html b/api/symbols/ForceDirectedEdge.html index c462aef2f..b6835e25e 100644 --- a/api/symbols/ForceDirectedEdge.html +++ b/api/symbols/ForceDirectedEdge.html @@ -974,7 +974,7 @@
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Model. - GraphLinksModels support links between nodes and grouping nodes and links into subgraphs. GraphLinksModels hold node data and link data in separate arrays. Node data is normally represented in a Diagram by instances of Node, but they could be represented by simple Parts or by Groups. Link data should be represented by instances of Link.
Each link data object is assumed to have two values, one referring to the node that the link is coming from and one that the link is going to. The linkFromKeyProperty property names the property on the link data whose value is the key of the "from" node. The linkToKeyProperty property names the property on the link data whose value is the key of the "to" node. The default values for these properties are "from" and "to" respectively.
For example, one can define a graph consisting of two nodes with one link connecting them:
model.nodeDataArray = [ { key: "Alpha" }, { key: "Beta" } ]; model.linkDataArray = [ { from: "Alpha", to: "Beta" } ];
If you want to have subgraphs in your diagram, where a group node contains some number of nodes and links, you need to declare that some node data actually represent groups, and you need to provide a reference from a member node data to its containing group node data. The nodeIsGroupProperty property names the property on a node data that is true if that node data represents a group. The nodeGroupKeyProperty property names the property on a node data whose value is the key of the containing group's node data. The default values for these properties are "isGroup" and "group" respectively.
For example, one can define a graph consisting of one group containing a subgraph of two nodes connected by a link, with a second link from that group to a third node that is not a member of that group:
model.nodeDataArray = [ { key: "Group1", isGroup: true}, { key: "Alpha", group: "Group1" }, { key: "Beta", group: "Group1" }, { key: "Gamma" } ]; model.linkDataArray = [ { from: "Alpha", to: "Beta" }, { from: "Group1", to: "Gamma" } ];
GraphLinksModels also support distinguishing the "port" element of a node to which a link can connect, at either end of the link. This identification is a string that names the "port" element in the node. However, you need to set the linkFromPortIdProperty and/or linkToPortIdProperty properties before the model is able to get the "port id" information from the link data.
For example, one can define a graph consisting of a "subtraction" node and two inputs and one output. The "subtraction" node has two distinct inputs called "subtrahend" and "minuend"; the output is called "difference".
model.linkFromPortIdProperty = "fromPort"; // necessary to remember portIds model.linkToPortIdProperty = "toPort"; model.nodeDataArray = [ { key: 1, constant: 5 }, // a constant input node { key: 2, constant: 2 }, // another constant node { key: 3, operation: "subtract" }, { key: 4, value: 3 } // the output node ]; model.linkDataArray = [ { from: 1, to: 3, toPort: "subtrahend" }, { from: 2, to: 3, toPort: "minuend" }, { from: 3, to: 4, fromPort: "difference" } ];In this case links connected to node 3 (which is the subtraction operation) are distinguished by port id. The connections to the other nodes do not have any port identification, presumably because there is only one port on those nodes, representing the node value.
This model does not support the modification of whether a node data object is a group.
This model cannot detect the modification of the linkDataArray array or the modification of any link data object. If you want to add or remove link data from the linkDataArray, call the addLinkData or removeLinkData methods. If you want to modify the node a link connects to, call the setFromKeyForLinkData and/or setToKeyForLinkData methods. If you want to change the membership of a node data in a group, call the setGroupKeyForNodeData method. + GraphLinksModels support links between nodes and grouping nodes and links into subgraphs. GraphLinksModels hold node data and link data in separate arrays. Node data is normally represented in a Diagram by instances of Node, but they could be represented by simple Parts or by Groups. Link data should be represented by instances of Link.
Each link data object is assumed to have two values, one referring to the node that the link is coming from and one that the link is going to. The linkFromKeyProperty property names the property on the link data whose value is the key of the "from" node. The linkToKeyProperty property names the property on the link data whose value is the key of the "to" node. The default values for these properties are "from" and "to" respectively.
For example, one can define a graph consisting of two nodes with one link connecting them:
model.nodeDataArray = [ { key: "Alpha" }, { key: "Beta" } ]; model.linkDataArray = [ { from: "Alpha", to: "Beta" } ];
If you want to have subgraphs in your diagram, where a group node contains some number of nodes and links, you need to declare that some node data actually represent groups, and you need to provide a reference from a member node data to its containing group node data. The nodeIsGroupProperty property names the property on a node data that is true if that node data represents a group. The nodeGroupKeyProperty property names the property on a node data whose value is the key of the containing group's node data. The default values for these properties are "isGroup" and "group" respectively.
For example, one can define a graph consisting of one group containing a subgraph of two nodes connected by a link, with a second link from that group to a third node that is not a member of that group:
model.nodeDataArray = [ { key: "Group1", isGroup: true}, { key: "Alpha", group: "Group1" }, { key: "Beta", group: "Group1" }, { key: "Gamma" } ]; model.linkDataArray = [ { from: "Alpha", to: "Beta" }, { from: "Group1", to: "Gamma" } ];
GraphLinksModels also support distinguishing the "port" element of a node to which a link can connect, at either end of the link. This identification is a string that names the "port" element in the node. However, you need to set the linkFromPortIdProperty and/or linkToPortIdProperty properties before the model is able to get the "port id" information from the link data.
For example, one can define a graph consisting of a "subtraction" node and two inputs and one output. The "subtraction" node has two distinct inputs called "subtrahend" and "minuend"; the output is called "difference".
model.linkFromPortIdProperty = "fromPort"; // necessary to remember portIds model.linkToPortIdProperty = "toPort"; model.nodeDataArray = [ { key: 1, constant: 5 }, // a constant input node { key: 2, constant: 2 }, // another constant node { key: 3, operation: "subtract" }, { key: 4, value: 3 } // the output node ]; model.linkDataArray = [ { from: 1, to: 3, toPort: "subtrahend" }, { from: 2, to: 3, toPort: "minuend" }, { from: 3, to: 4, fromPort: "difference" } ];In this case links connected to node 3 (which is the subtraction operation) are distinguished by port id. The connections to the other nodes do not have any port identification, presumably because there is only one port on those nodes, representing the node value.
Note that there is no requirement that the link data objects have any kind of unique identifier, unlike for node data. There is no expectation that there be references to link data in the model, so there is no need for such an identifier. When there are multiple links connecting two ports, the only way to distinguish the links in the model is by reference to the particular link data object. This is why there are two methods on the Diagram class for Nodes, Diagram.findNodeForKey and Diagram.findNodeForData, but there is only the one method for Links, Diagram.findLinkForData.
However you may wish to add your own unique identifiers on the link data. One way to implement this is by setting a property on the link data each time one is added to the model:
model.addChangedListener(function(e) { if (e.change === go.ChangedEvent.Insert && e.modelChange === "linkDataArray") { var id = e.model.modelData.linkCounter; // keep the counter on the Model.modelData object if (typeof id !== 'number') id = 0; e.model.modelData.linkCounter = id + 1; e.newValue.id = id; // e.newValue is the link data object that was added } });Note how the counter is kept on the Model.modelData object, so that it can be saved and loaded automatically. Remember to re-establish the listener on a newly constructed model, including those constructed by Model.fromJson.
This model does not support the modification of whether a node data object is a group.
This model cannot detect the modification of the linkDataArray array or the modification of any link data object. If you want to add or remove link data from the linkDataArray, call the addLinkData or removeLinkData methods. If you want to modify the node a link connects to, call the setFromKeyForLinkData and/or setToKeyForLinkData methods. If you want to change the membership of a node data in a group, call the setGroupKeyForNodeData method.
diff --git a/api/symbols/GraphObject.html b/api/symbols/GraphObject.html index a36b99d04..69da15fed 100644 --- a/api/symbols/GraphObject.html +++ b/api/symbols/GraphObject.html @@ -974,7 +974,7 @@Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Properties Summary
If this property value is a function, it is called with an InputEvent, this GraphObject, and any previous GraphObject that the mouse was in. The InputEvent.targetObject provides the GraphObject that was found at the mouse point before looking up the visual tree of GraphObject.panels to get to this object. 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. After calling this function the diagram will be updated immediately.
For example, consider the situation where one wants to display buttons that the user can click whenever the user passes the mouse over a node, and the buttons automatically disappear when the mouse leaves the node. This can be implemented by showing an Adornment holding the buttons.
var nodeContextMenu = $(go.Adornment, "Spot", { background: "transparent" }, // to help detect when the mouse leaves the area $(go.Placeholder), $(go.Panel, "Vertical", { alignment: go.Spot.Right, alignmentFocus: go.Spot.Left }, $("Button", $(go.TextBlock, "Command 1"), { click: function(e, obj) { var node = obj.part.adornedPart; alert("Command 1 on " + node.data.text); node.removeAdornment("ContextMenuOver"); } }), $("Button", $(go.TextBlock, "Command 2"), { click: function(e, obj) { var node = obj.part.adornedPart; alert("Command 2 on " + node.data.text); node.removeAdornment("ContextMenuOver"); } }) ));Then in the definition of the Node we can implement a mouseEnter event handler:
myDiagram.nodeTemplate = $(go.Node, . . . { mouseEnter: function(e, node) { nodeContextMenu.adornedObject = node; nodeContextMenu.mouseLeave = function(ev, cm) { node.removeAdornment("ContextMenuOver"); }; node.addAdornment("ContextMenuOver", nodeContextMenu); } });Note how it automatically defines a mouseLeave event handler too. The context menu Adornment is removed either when the mouse leaves the area of the Adornment or when the user executes a button click event handler. +
If this property value is a function, it is called with an InputEvent, this GraphObject that the mouse is now in, and any previous GraphObject that the mouse was in. The InputEvent.targetObject provides the GraphObject that was found at the mouse point before looking up the visual tree of GraphObject.panels to get to this object. 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. After calling this function the diagram will be updated immediately.
For example, consider the situation where one wants to display buttons that the user can click whenever the user passes the mouse over a node, and the buttons automatically disappear when the mouse leaves the node. This can be implemented by showing an Adornment holding the buttons.
var nodeContextMenu = $(go.Adornment, "Spot", { background: "transparent" }, // to help detect when the mouse leaves the area $(go.Placeholder), $(go.Panel, "Vertical", { alignment: go.Spot.Right, alignmentFocus: go.Spot.Left }, $("Button", $(go.TextBlock, "Command 1"), { click: function(e, obj) { var node = obj.part.adornedPart; alert("Command 1 on " + node.data.text); node.removeAdornment("ContextMenuOver"); } }), $("Button", $(go.TextBlock, "Command 2"), { click: function(e, obj) { var node = obj.part.adornedPart; alert("Command 2 on " + node.data.text); node.removeAdornment("ContextMenuOver"); } }) ));Then in the definition of the Node we can implement a mouseEnter event handler:
myDiagram.nodeTemplate = $(go.Node, . . . { mouseEnter: function(e, node) { nodeContextMenu.adornedObject = node; nodeContextMenu.mouseLeave = function(ev, cm) { node.removeAdornment("ContextMenuOver"); }; node.addAdornment("ContextMenuOver", nodeContextMenu); } });Note how it automatically defines a mouseLeave event handler too. The context menu Adornment is removed either when the mouse leaves the area of the Adornment or when the user executes a button click event handler. See also:
-
@@ -2149,7 +2149,7 @@
Properties Summary
If this property value is a function, it is called with an InputEvent, this GraphObject, and any previous GraphObject that the mouse had been in. The InputEvent.targetObject provides the GraphObject that was found at the mouse point before looking up the visual tree of GraphObject.panels to get to this object. 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. After calling this function the diagram will be updated immediately.
For example, the Flow Chart sample automatically shows and hides the ports as the mouse passes over a node. The node template includes the following settings:
myDiagram.nodeTemplate = $(go.Node, . . . { . . . // handle mouse enter/leave events to show/hide the ports mouseEnter: function (e, obj) { showPorts(obj.part, true); }, mouseLeave: function (e, obj) { showPorts(obj.part, false); } . . . });where the
showPorts
function is defined to set the visible
property of each of the port elements of the node.
+ If this property value is a function, it is called with an InputEvent, this GraphObject that the mouse has left, and any next GraphObject that the mouse is now in. The InputEvent.targetObject provides the GraphObject that was found at the mouse point before looking up the visual tree of GraphObject.panels to get to this object. 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. After calling this function the diagram will be updated immediately.
For example, the Flow Chart sample automatically shows and hides the ports as the mouse passes over a node. The node template includes the following settings:
myDiagram.nodeTemplate = $(go.Node, . . . { . . . // handle mouse enter/leave events to show/hide the ports mouseEnter: function (e, obj) { showPorts(obj.part, true); }, mouseLeave: function (e, obj) { showPorts(obj.part, false); } . . . });where the
showPorts
function is defined to set the visible
property of each of the port elements of the node.
See also:
-
diff --git a/api/symbols/GridLayout.html b/api/symbols/GridLayout.html
index 215086f54..3cec6c288 100644
--- a/api/symbols/GridLayout.html
+++ b/api/symbols/GridLayout.html
@@ -974,7 +974,7 @@
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Constructor
The Tool.name of this tool is "LinkReshaping". diff --git a/api/symbols/LinkingBaseTool.html b/api/symbols/LinkingBaseTool.html index 35f82d2f8..05c5c404b 100644 --- a/api/symbols/LinkingBaseTool.html +++ b/api/symbols/LinkingBaseTool.html @@ -974,7 +974,7 @@
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Constructor
The Tool.name of this tool is "Linking". diff --git a/api/symbols/List.html b/api/symbols/List.html index 560c282ab..232a72327 100644 --- a/api/symbols/List.html +++ b/api/symbols/List.html @@ -974,7 +974,7 @@
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
- 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 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.
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. + 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 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.
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.
diff --git a/api/symbols/Node.html b/api/symbols/Node.html index 73198f6e8..c28016920 100644 --- a/api/symbols/Node.html +++ b/api/symbols/Node.html @@ -974,7 +974,7 @@Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Constructor
The Tool.name of this tool is "Panning". diff --git a/api/symbols/Part.html b/api/symbols/Part.html index ae877b175..b080e13f0 100644 --- a/api/symbols/Part.html +++ b/api/symbols/Part.html @@ -974,7 +974,7 @@
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Constructor
- Parameters: diff --git a/api/symbols/Rect.html b/api/symbols/Rect.html index e41883234..770fa8e95 100644 --- a/api/symbols/Rect.html +++ b/api/symbols/Rect.html @@ -974,7 +974,7 @@
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Constructor
The Tool.name of this tool is "Relinking". diff --git a/api/symbols/ResizingTool.html b/api/symbols/ResizingTool.html index f64c0a737..1c1beacc2 100644 --- a/api/symbols/ResizingTool.html +++ b/api/symbols/ResizingTool.html @@ -974,7 +974,7 @@
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Constructor
The Tool.name of this tool is "Resizing". diff --git a/api/symbols/RotatingTool.html b/api/symbols/RotatingTool.html index 7c96ba4c9..4650817fc 100644 --- a/api/symbols/RotatingTool.html +++ b/api/symbols/RotatingTool.html @@ -974,7 +974,7 @@
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Constructor
The Tool.name of this tool is "Rotating". diff --git a/api/symbols/RowColumnDefinition.html b/api/symbols/RowColumnDefinition.html index ede9dd152..536fb450f 100644 --- a/api/symbols/RowColumnDefinition.html +++ b/api/symbols/RowColumnDefinition.html @@ -974,7 +974,7 @@
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Constructor
- Parameters: diff --git a/api/symbols/Spot.html b/api/symbols/Spot.html index aeb97e722..a9e3540ef 100644 --- a/api/symbols/Spot.html +++ b/api/symbols/Spot.html @@ -974,7 +974,7 @@
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Constructor
The Tool.name of this tool is "TextEditing". diff --git a/api/symbols/Tool.html b/api/symbols/Tool.html index 316cc36a1..95920c517 100644 --- a/api/symbols/Tool.html +++ b/api/symbols/Tool.html @@ -974,7 +974,7 @@
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
- Tools handle mouse events and keyboard events. The currently running tool, Diagram.currentTool, receives all input events from the Diagram.
Most tools are "mode-less" tools that are managed by the ToolManager, which chooses the current tool based on the kind and position of the mouse event and the parts in the diagram. The ToolManager has properties holding instances of most of the pre-defined Tool classes. These classes include:
- In the ToolManager.mouseDownTools List:
- In the ToolManager.mouseMoveTools List:
- In the ToolManager.mouseUpTools List:
A tool is in the "running" state when it is the value of Diagram.currentTool. The Diagram.currentTool property setter will call doStop on the old tool and then call doStart on the new tool.
A tool can then go into the "active" state once it decides it can actually do something. This happens with a call to doActivate, normally called by the ToolManager. Later it is deactivated (doDeactivate) and then stopped. isActive should be true when the tool is "active". Often tools should ignore certain common events, such as calls to doMouseMove, unless the tool is "active".
You can prevent a "mode-less" tool (i.e. one managed by the ToolManager) from being started by the ToolManager by setting isEnabled to false.
You can also go into a particular "mode" by setting Diagram.currentTool explicitly, thereby circumventing the normal operation of the ToolManager. This ignores the isEnabled property and does not call the canStart predicate. The behavior will depend on the tool -- not all of the predefined tools support operating as a "modal" tool.
Tools cannot be shared amongst multiple Diagrams.
If you define a Tool subclass, you may override any of the methods whose names start with "do" and any other methods that are documented to be overridable, such as canStart. However you must seriously consider calling the base method in order to gets its default behavior. There may be situations where not calling the base method may cause subtle bugs. But that depends on the method and the tool. Please read the Introduction page on Extensions for how to override methods and how to call this base method. + Tools handle mouse, keyboard, and touch events. The currently running tool, Diagram.currentTool, receives all input events from the Diagram via canonicalized InputEvents.
Most tools are "mode-less" tools that are managed by the ToolManager, which chooses the current tool based on the kind and position of the mouse event and the parts in the diagram. The ToolManager has properties holding instances of most of the pre-defined Tool classes. These classes include:
- In the ToolManager.mouseDownTools List:
- In the ToolManager.mouseMoveTools List:
- In the ToolManager.mouseUpTools List:
A tool is in the "running" state when it is the value of Diagram.currentTool. The Diagram.currentTool property setter will call doStop on the old tool and then call doStart on the new tool.
A tool can then go into the "active" state once it decides it can actually do something. This happens with a call to doActivate, normally called by the ToolManager. Later it is deactivated (doDeactivate) and then stopped. isActive should be true when the tool is "active". Often tools should ignore certain common events, such as calls to doMouseMove, unless the tool isActive.
You can prevent a "mode-less" tool (i.e. one managed by the ToolManager) from being started by the ToolManager by setting isEnabled to false.
You can also go into a particular "mode" by setting Diagram.currentTool explicitly, thereby circumventing the normal operation of the ToolManager. This ignores the isEnabled property and does not call the canStart predicate. The behavior will depend on the tool -- not all of the predefined tools support operating as a "modal" tool.
Tools cannot be shared amongst multiple Diagrams.
If you define a Tool subclass, you may override any of the methods whose names start with "do" and any other methods that are documented to be overridable, such as canStart. However you must seriously consider calling the base method in order to gets its default behavior. There may be situations where not calling the base method may cause subtle bugs. But that depends on the method and the tool. Please read the Introduction page on Extensions for how to override methods and how to call the base method.
@@ -1068,7 +1068,7 @@Properties Summary
You can set this to true after your tool is started (i.e. when it is the Diagram.currentTool and doStart had been called), but when it is not yet in a state that it is actually "doing" something, because it is waiting for the right circumstances. This is typically only important when the tool is used in a modal fashion.
The default value is false. +
You can set this to true after your tool is started (i.e. when it is the Diagram.currentTool and doStart had been called), but when it is not yet in a state that it is actually "doing" something, because it is waiting for the right circumstances. This is typically only important when the tool is used in a modal fashion.
The default value is false. This is normally set by doActivate and doDeactivate.
Properties Summary
This name is sometimes used by tools that use Adornments as the Part.category for their Adornments. It is also sometimes used by tools that conduct transactions as the transaction name. +
This name is sometimes used by tools that use Adornments as the Part.category for their Adornments. It is also sometimes used by tools that conduct transactions as the transaction name.
Properties Summary
If this is non-null at the time of a call to stopTransaction, it calls Diagram.commitTransaction with this transaction name; if this is null at that time, it calls Diagram.rollbackTransaction.
The default value is null; startTransaction will also set this to null.
This property exists so that no matter what execution path occurs to end the usage of a tool, any ongoing transaction can be properly committed or rolled-back. +
If this is non-null at the time of a call to stopTransaction, it calls Diagram.commitTransaction with this transaction name; if this is null at that time, it calls Diagram.rollbackTransaction.
The default value is null; startTransaction will also set this to null. Because a value of null when stopTransaction is called will rollback the transaction, it is important that your code sets this property to a non-null value when it thinks it has succeeded.
This property exists so that no matter what execution path occurs to end the usage of a tool, any ongoing transaction can be properly committed or rolled-back.
Method Summary
Returns:
- {boolean} true if isEnabled is true and
if the Diagram.toolManager can make this tool the current one and
then call the doStart method.
+ {boolean} true if isEnabled is true and
if the Diagram.toolManager can make this tool the Diagram.currentTool and
then call the doStart method.
@@ -1214,7 +1214,7 @@ Method Summary
-
@@ -1272,7 +1272,7 @@
Method Summary
By default this method just calls stopTool. This method may be overridden. Please read the Introduction page on Extensions for how to override methods and how to call this base method. +
By default this method just calls stopTool. You will want to override this method even in tools that call startTransaction and stopTransaction, because the UndoManager might not be enabled. This method may be overridden. Please read the Introduction page on Extensions for how to override methods and how to call this base method. @@ -1593,7 +1593,7 @@
Method Summary
A click on a GraphObject of the diagram will raise one of the following DiagramEvents: "ObjectSingleClicked", "ObjectDoubleClicked", or "ObjectContextClicked". This will also look at the corresponding click property: GraphObject.click, GraphObject.doubleClick, or GraphObject.contextClick. If the value is a function, this will call it, passing the current InputEvent and the GraphObject. If the value is null, it tries looking at the parent GraphObject.panel, and so on, walking up the visual tree until it finds the appropriate function to call. After calling the click function, if the value of InputEvent.handled is false, this method will continue walking up the visual tree looking for more click functions to call. Once it has looked at the top-level object (a Part) for a click function, this method stops.
A click in the background of the diagram will raise one of the following DiagramEvents: "BackgroundSingleClicked", "BackgroundDoubleClicked", or "BackgroundContextClicked". This will also look at the corresponding click property: Diagram.click, Diagram.doubleClick, or Diagram.contextClick. If the value is a function, this will call it, passing the current InputEvent.
This method is not responsible for selecting or deselecting any parts. Call standardMouseSelect for that functionality.
This method may be overridden, but you should consider calling this base method in order to get all of its functionality. Please read the Introduction page on Extensions for how to override methods and how to call this base method. +
A click on a GraphObject of the diagram will raise one of the following DiagramEvents: "ObjectSingleClicked", "ObjectDoubleClicked", or "ObjectContextClicked". This will also look at the corresponding click property: GraphObject.click, GraphObject.doubleClick, or GraphObject.contextClick. If the value is a function, this will call it, passing the current InputEvent and the GraphObject. If the value is null, it tries looking at the parent GraphObject.panel, and so on, walking up the visual tree until it finds the appropriate function to call. After calling the click function, if the value of InputEvent.handled is false, this method will continue walking up the visual tree looking for more click functions to call. Once it has looked at the top-level object (a Part) for a click function, this method stops.
A click in the background of the diagram will raise one of the following DiagramEvents: "BackgroundSingleClicked", "BackgroundDoubleClicked", or "BackgroundContextClicked". This will also look at the corresponding click property: Diagram.click, Diagram.doubleClick, or Diagram.contextClick. If the value is a function, this will call it, passing the current InputEvent.
This method is not responsible for selecting or deselecting any parts. Call standardMouseSelect for that functionality.
The ClickSelectingTool calls this method in its override of doMouseUp in order to raise "click" events. Note that by default GraphObjects in Layers that are Layer.isTemporary will not be "clicked". To change that behavior it is easiest to set GraphObject.isActionable to true on those objects for which you wish to handle "click" events. Then the ActionTool's doMouseUp override will raise the standard "click" events.
This method may be overridden, but you should consider calling this base method in order to get all of its functionality. Please read the Introduction page on Extensions for how to override methods and how to call this base method.
-
@@ -1652,7 +1652,7 @@
Method Summary
Control-clicking on a part will select it if it wasn't already, and will deselect if it had been selected. Shift-clicking on a part will add it to the selection (if it wasn't already). Otherwise, clicking on a part will select it (if it wasn't already).
Note that there are restrictions on selection. For example, a part cannot be selected in this manner if Part.selectable is false, or if Diagram.maxSelectionCount would be exceeded.
A left click in the background of the diagram with no modifier keys clears the selection.
This method does not implement any click event behavior -- that is implemented by standardMouseClick.
This method may be overridden, but you should consider calling this base method in order to get all of its functionality. Please read the Introduction page on Extensions for how to override methods and how to call this base method. +
Control-clicking on a part will select it if it wasn't already, and will deselect if it had been selected. Shift-clicking on a part will add it to the selection (if it wasn't already). Otherwise, clicking on a part will select it (if it wasn't already).
Note that there are restrictions on selection. For example, a part cannot be selected in this manner if Part.selectable is false, or if Diagram.maxSelectionCount would be exceeded.
A left click in the background of the diagram with no modifier keys clears the selection.
This method does not implement any click event behavior -- that is implemented by standardMouseClick.
The ClickSelectingTool calls this method in its override of doMouseUp in order to change the selection.
This method may be overridden, but you should consider calling this base method in order to get all of its functionality. Please read the Introduction page on Extensions for how to override methods and how to call this base method. diff --git a/api/symbols/ToolManager.html b/api/symbols/ToolManager.html index e7983dd0b..802f299f9 100644 --- a/api/symbols/ToolManager.html +++ b/api/symbols/ToolManager.html @@ -974,7 +974,7 @@
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Constructor
The constructor produces a ToolManager that manages no tools. Call initializeStandardTools to create various tools, initialize the tool properties such as draggingTool, and initialize the three mouse tool lists with those newly created tools. +
The Tool.name of this tool is "ToolManager".
The constructor produces a ToolManager that manages no tools. Call initializeStandardTools to create various tools, initialize the tool properties such as draggingTool, and initialize the three mouse tool lists with those newly created tools. @@ -1195,6 +1195,8 @@
Properties Summary
gestureBehavior
+ 1.5
+
Method Summary
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
Collection Classes
version 1.5.3 for JavaScript/HTML
by Northwoods Software® + GoJS® Diagramming Components
version 1.5.4 for JavaScript/HTML
by Northwoods Software®
GoJS® Change Log
} +Changes for 1.5.4
+-
+
- + Added the Realtime Drag Selecting Tool sample, + with the RealtimeDragSelectingTool defined in the RealtimeDragSelectingTool.js + in the Extensions directory. + +
- + Added the Hover Buttons sample, + demonstrating how an Adornment can be used to show buttons for a node when the mouse is briefly motionless over the node. + +
- + Added the Spiral Layout sample, + with the SpiralLayout defined in the SpiralLayout.js file in the Extensions directory. + +
- + Fixed ContextMenuTool so that any click events (Tool.standardMouseClick) in the ContextMenuTool.currentContextMenuoccur on mouse-up, not mouse-down. + +
Changes for 1.5.3
- The transaction name argument to UndoManager.commitTransaction (or Model.commitTransaction or Diagram.commitTransaction) is now optional,
diff --git a/extensions/RealtimeDragSelecting.html b/extensions/RealtimeDragSelecting.html
new file mode 100644
index 000000000..1fc650fec
--- /dev/null
+++ b/extensions/RealtimeDragSelecting.html
@@ -0,0 +1,97 @@
+
+
+
+
Realtime Drag Selecting Tool + + + + + + + + + + ++ ++ + diff --git a/extensions/RealtimeDragSelectingTool.js b/extensions/RealtimeDragSelectingTool.js new file mode 100644 index 000000000..3a9f95850 --- /dev/null +++ b/extensions/RealtimeDragSelectingTool.js @@ -0,0 +1,127 @@ +"use strict"; +/* +* Copyright (C) 1998-2015 by Northwoods Software Corporation. All Rights Reserved. +*/ + +// A custom DragSelectingTool for selecting and deselecting Parts during a drag. + +/** +* @constructor +* @extends DragSelectingTool +* @class +* The RealtimeDragSelectingTool selects and deselects Parts within the {@link DragSelectingTool#box} +* during a drag, not just at the end of the drag. +*/ +function RealtimeDragSelectingTool() { + go.DragSelectingTool.call(this); + this._originalSelection = null; + this._temporarySelection = null; +} + +go.Diagram.inherit(RealtimeDragSelectingTool, go.DragSelectingTool); + +/** +* Remember the original collection of selected Parts. +* @this {RealtimeDragSelectingTool} +*/ +RealtimeDragSelectingTool.prototype.doActivate = function() { + go.DragSelectingTool.prototype.doActivate.call(this); + // keep a copy of the original Set of selected Parts + this._originalSelection = this.diagram.selection.copy(); + // these Part.isSelected may have been temporarily modified + this._temporarySelection = new go.Set(go.Part); +}; + +/** +* Release any references to selected Parts. +* @this {RealtimeDragSelectingTool} +*/ +RealtimeDragSelectingTool.prototype.doDeactivate = function() { + this._originalSelection = null; + this._temporarySelection = null; + go.DragSelectingTool.prototype.doDeactivate.call(this); +}; + +/** +* Restore the selection which may have been modified during a drag. +* @this {RealtimeDragSelectingTool} +*/ +RealtimeDragSelectingTool.prototype.doCancel = function() { + var orig = this._originalSelection; + if (orig !== null) { + orig.each(function(p) { p.isSelected = true; }); + this._temporarySelection.each(function(p) { if (!orig.contains(p)) p.isSelected = false; }); + } + go.DragSelectingTool.prototype.doCancel.call(this); +}; + +/** +* @this {RealtimeDragSelectingTool} +*/ +RealtimeDragSelectingTool.prototype.doMouseMove = function() { + if (this.isActive) { + go.DragSelectingTool.prototype.doMouseMove.call(this); + this.selectInRect(this.computeBoxBounds()); + } +}; + +/** +* @this {RealtimeDragSelectingTool} +*/ +RealtimeDragSelectingTool.prototype.doKeyDown = function() { + if (this.isActive) { + go.DragSelectingTool.prototype.doKeyDown.call(this); + this.selectInRect(this.computeBoxBounds()); + } +}; + +/** +* @this {RealtimeDragSelectingTool} +*/ +RealtimeDragSelectingTool.prototype.doKeyUp = function() { + if (this.isActive) { + go.DragSelectingTool.prototype.doKeyUp.call(this); + this.selectInRect(this.computeBoxBounds()); + } +}; + +/** +* @ignore +* Platform detection to use Meta (Command) key on Mac keyboard +*/ +RealtimeDragSelectingTool.isMac = navigator.platform.toUpperCase().indexOf("MAC") >= 0; + +/** +* @expose +* @this {RealtimeDragSelectingTool} +* @param {Rect} r a rectangular bounds in document coordinates. +*/ +RealtimeDragSelectingTool.prototype.selectInRect = function(r) { + var diagram = this.diagram; + var orig = this._originalSelection; + var temp = this._temporarySelection; + if (diagram === null || orig === null) return; + var e = diagram.lastInput; + diagram.raiseDiagramEvent("ChangingSelection"); + var found = diagram.findObjectsIn(r, null, + function(p) { return (p instanceof go.Part) && p.canSelect(); }, + this.isPartialInclusion, + new go.Set(go.Part)); + if (RealtimeDragSelectingTool.isMac ? e.meta : e.control) { // toggle or deselect + if (e.shift) { // deselect only + temp.each(function(p) { if (!found.contains(p)) p.isSelected = orig.contains(p); }); + found.each(function(p) { p.isSelected = false; temp.add(p); }); + } else { // toggle selectedness of parts based on _originalSelection + temp.each(function(p) { if (!found.contains(p)) p.isSelected = orig.contains(p); }); + found.each(function(p) { p.isSelected = !orig.contains(p); temp.add(p); }); + } + } else if (e.shift) { // extend selection only + temp.each(function(p) { if (!found.contains(p)) p.isSelected = orig.contains(p); }); + found.each(function(p) { p.isSelected = true; temp.add(p); }); + } else { // select found parts, and unselect all other previously selected parts + temp.each(function(p) { if (!found.contains(p)) p.isSelected = false; }); + orig.each(function(p) { if (!found.contains(p)) p.isSelected = false; }); + found.each(function(p) { p.isSelected = true; temp.add(p); }); + } + diagram.raiseDiagramEvent("ChangedSelection"); +}; diff --git a/extensions/Spiral.html b/extensions/Spiral.html new file mode 100644 index 000000000..5327cd906 --- /dev/null +++ b/extensions/Spiral.html @@ -0,0 +1,104 @@ + + + ++ This sample demonstrates the RealtimeDragSelectingTool, which replaces the standard DragSelectingTool. + Press in the background, wait briefly, and then drag to start selecting Nodes or Links that intersect with the box. + You can press or release Control (Command on Mac) or Shift while dragging to see how the selection changes. +
++ Load it in your own app by including RealtimeDragSelectingTool.js. + Initialize your Diagram by setting ToolManager.dragSelectingTool to a new instance of this tool. + For example: +
++ myDiagram.toolManager.dragSelectingTool = new go.RealtimeDragSelectingTool(); +
+ or ++ $(go.Diagram, { . . ., + toolManager: $(RealtimeDragSelectingTool, { isPartialInclusion: true }), + . . . }) +
+Spiral Layout + + + + + + + + + + ++ ++ + diff --git a/extensions/SpiralLayout.js b/extensions/SpiralLayout.js new file mode 100644 index 000000000..d31c2749b --- /dev/null +++ b/extensions/SpiralLayout.js @@ -0,0 +1,138 @@ +"use strict"; +/* +* Copyright (C) 1998-2015 by Northwoods Software Corporation. All Rights Reserved. +*/ + +// A custom Layout that lays out a chain of nodes in a spiral + +/** +* @constructor +* @extends Layout +* @class +* This layout assumes the graph is a chain of Nodes, +* {@link #spacing} controls the spacing between nodes. +*/ +function SpiralLayout() { + go.Layout.call(this); + this._spacing = 100; + this._clockwise = true; +} +go.Diagram.inherit(SpiralLayout, go.Layout); + +/** +* This method actually positions all of the Nodes, assuming that the ordering of the nodes +* is given by a single link from one node to the next. +* This respects the {@link #spacing} property to affect the layout. +* @this {SpiralLayout} +* @param {Diagram|Group|Iterable} coll the collection of Parts to layout. +*/ +SpiralLayout.prototype.doLayout = function(coll) { + var diagram = this.diagram; + if (coll instanceof go.Diagram) { + diagram = coll; + coll = coll.nodes; // use all links connecting with these nodes + } else if (coll instanceof go.Group) { + diagram = coll.diagram; + coll = coll.memberParts; + } + + var root = null; + // find a root node -- one without any incoming links + var it = coll.iterator; + while (it.next()) { + var n = it.value; + if (!(n instanceof go.Node)) continue; + if (root === null) root = n; + if (n.findLinksInto().count === 0) { + root = n; + break; + } + } + // couldn't find a root node + if (root === null) return; + + var space = this.spacing; + + // implementations of doLayout that do not make use of a LayoutNetwork + // need to perform their own transactions + if (diagram !== null) diagram.startTransaction("Spiral Layout"); + + // treat the root node specially: it goes in the center + var r = this.diameter(root)/4; + var c = (this.clockwise ? 1 : -1); + var angle = c * Math.PI; + root.location = new go.Point(0, 0); + var rootlink = root.findLinksOutOf().first(); + if (rootlink !== null) rootlink.curviness = c * r; + + // now locate each of the following nodes, in order, along a spiral + var node = (rootlink !== null ? rootlink.toNode : null); + while (node !== null) { + var nextlink = node.findLinksOutOf().first(); + var nextnode = (nextlink !== null ? nextlink.toNode : null); + + // involute spiral + var cos = Math.cos(angle); + var sin = Math.sin(angle); + var x = r * (cos + angle * sin); + var y = r * (sin - angle * cos); + node.location = new go.Point(x, y); + + var dia = this.diameter(node)/2 + this.diameter(nextnode)/2; + angle += c * Math.atan((dia + space) / Math.sqrt(x * x + y * y)); + node = nextnode; + } + + if (diagram !== null) diagram.commitTransaction("Spiral Layout"); +}; + +/** +* @ignore +* Compute the effective diameter of a Node. +* @this {SpiralLayout} +* @param {Node} node +* @return {number} +*/ +SpiralLayout.prototype.diameter = function(node) { + if (!node) return 0; + var b = node.actualBounds; + return Math.sqrt(b.width*b.width + b.height*b.height); +}; + +// Public properties + +/** +* Gets or sets the spacing between nodes. +* The default value is 100. +* @name SpiralLayout#spacing +* @function. +* @return {number} +*/ +Object.defineProperty(SpiralLayout.prototype, "spacing", { + get: function() { return this._spacing; }, + set: function(val) { + if (typeof val !== "number") throw new Error("new value for SpiralLayout.spacing must be a number, not: " + val); + if (this._spacing !== val) { + this._spacing = val; + this.invalidateLayout(); + } + } +}); + +/** +* Gets or sets whether the spiral should go clockwise or counter-clockwise. +* The default value is true. +* @name SpiralLayout#clockwise +* @function. +* @return {boolean} +*/ +Object.defineProperty(SpiralLayout.prototype, "clockwise", { + get: function() { return this._clockwise; }, + set: function(val) { + if (typeof val !== "boolean") throw new Error("new value for SpiralLayout.clockwise must be a boolean, not: " + val); + if (this._clockwise !== val) { + this._clockwise = val; + this.invalidateLayout(); + } + } +}); diff --git a/extensions/goSamples.js b/extensions/goSamples.js index 15d56e0ef..8f0079072 100644 --- a/extensions/goSamples.js +++ b/extensions/goSamples.js @@ -139,9 +139,11 @@ var myMenu = '\+ This sample demonstrates a custom Layout, SpiralLayout, which assumes the graph consists of a chain of nodes. + The layout is defined in its own file, as SpiralLayout.js. +
+- Fishbone Layout
\- Parallel Layout
\- Serpentine Layout
\ +- Spiral Layout
\- Tree Map Layout
\- Table Layout
\
\ +- Realtime Selecting
\- Drag Creating
\- Drag Zooming
\- Freehand Drawing
\ diff --git a/index.html b/index.html index f099a2673..aa8e13a69 100644 --- a/index.html +++ b/index.html @@ -201,15 +201,15 @@Interactive Diagrams for the Web
-diff --git a/intro/goIntro.js b/intro/goIntro.js index 6d79407ab..92b872644 100644 --- a/intro/goIntro.js +++ b/intro/goIntro.js @@ -159,10 +159,7 @@ var myMenu = '\GoJS is a feature-rich JavaScript library for implementing interactive diagrams across modern browsers and platforms. - GoJS makes constructing diagrams of complex Nodes, Links, and Groups easy with customizable templates and layouts. +
GoJS is a feature-rich JavaScript library for implementing interactive diagrams across modern web browsers and platforms. + GoJS makes constructing diagrams of complex nodes, links, and groups easy with customizable templates and layouts.
GoJS offers many advanced features for user interactivity such as drag-and-drop, copy-and-paste, in-place text editing, templates, data binding and models, transactional state and undo management, palettes, overviews, event handlers, commands, and an extensible tool system for custom operations.
GoJS is pure JavaScript, so users get interactivity without requiring round-trips to servers and without plugins such as Flash or Silverlight. - GoJS normally runs completely in the browser, without any server-side requirements. + GoJS normally runs completely in the browser, rendering to a Canvas element or SVG without any server-side requirements. GoJS does not depend on any JavaScript libraries or frameworks, so it should work with any HTML5 or JavaScript framework or with no framework at all.
- Diagram SVG
\- Printing
\- Server-side Images
\ -- Deployment
\ - \ +- Deployment
\ '; //]]> \ No newline at end of file diff --git a/intro/performance.html b/intro/performance.html index 8f2eac4f6..49ac10a09 100644 --- a/intro/performance.html +++ b/intro/performance.html @@ -13,28 +13,87 @@Performance Considerations
- This page contains design suggestions to increase the performance of your diagrams. - The optimizations available depend on the nature of your diagrams, and we encourage you to experiment. + Getting good performance for your diagrams does not require any effort on your part when + the diagrams are limited to a few hundreds of nodes and links, especially on the desktop. + However when your app might deal with thousands or tens of thousands of nodes and links, + you may need to adapt your implementation to avoid expensive features.
-Give as many GraphObjects as possible static sizes
-- In general, setting GraphObject.desiredSize (ones that may be dynamically sized like Pictures, TextBlocks, etc) in your templates will speed up the measure and arrange portion of diagram initialization. + The perceived performance of your diagram depends on many different factors.
+-
+
- JavaScript code is normally several to many times slower than Java or .NET code + on the same hardware platform. +
- JavaScript code performance varies between different browsers and versions of browsers. +
- Memory limitations, particularly on mobile devices, affect performance. +
- There can be a wide variation of drawing performance on different platforms. +
- Drawing and animation effects take resources. +
- Complicated nodes or links are slower to build and update and draw than simple ones. +
- Some layouts are inherently slower than others. +
Effects and Appearances
++ Shadows are relatively expensive to draw, so consider not setting Part.isShadowed to true. + Gradient Brushes are slower to draw than solid colors. + Complex Shape Geometrys are slower to draw than simpler ones, and they require more + computation when computing intersections. +
- If you have Pictures and you know their size beforehand, its best to set a desiredSize so that each of them does not have to re-measure once the image is loaded. This may also avoid re-layouts due to images loading. + Animation takes up resources; consider setting AnimationManager.isEnabled to false.
-Virtualization
+Constructing and Sizing Nodes
++ Keep your Nodes and Links as simple as you can make it. + Limit how many GraphObjects that you use in your templates. + Use simpler Panel types when feasible -- the "Table" Panel is the most featureful, + but maybe you can just use a "Horizontal" or a "Vertical" or a "Spot" or an "Auto" Panel. + A Panel should have two or more elements in them (although there can be exceptions). + If you have no elements in a Panel, delete the panel. + If you have only one element in a Panel, consider removing the panel and merging the element + into the panel's containing panel. +
++ Do not include objects that not visible. + Limit how much data binding that you use, and avoid Bindings with no source property name + or that are Binding.ofObject. +
++ If you have a Picture and you know its intended size beforehand, + it's best to set its GraphObject.desiredSize + (or GraphObject.width and GraphObject.height) + so that it does not have to re-measured once the image loads. + When nodes change size a Layout might need to be performed again, + so having fixed size nodes helps reduce diagram layouts. + In general, setting GraphObject.desiredSize on the elements of your nodes, + especially Pictures, will speed up how quickly GoJS can measure and arrange + the Panels that form your Nodes or Links. +
+Layouts
- For Diagrams with many nodes and links that only display a fraction of these at a time, you could implement some form of virtualization to optimize your Diagram. + GridLayout and TreeLayout are fast. LayeredDigraphLayout is slow.
+Virtualization
- The Virtualized Tree sample contains 123,456 total nodes, yet is fairly quick to render, because it only constructs nodes that are visible. + For diagrams with many nodes and links that only display a fraction of them at a time, + you could implement some form of virtualization to optimize your diagram. + The Virtualized Tree sample contains 123,456 + total nodes, yet is fairly quick to load and render, because it only constructs nodes + and links that intersect with the viewport. +
++ But this does complicate the implementation of the diagram, because you need to use a + separate model from the Diagram.model and manage adding and removing Nodes and + Links when the viewport changes. + Furthermore layout is more complicated because it needs to work on LayoutVertexes + and LayoutEdges, not on Nodes and Links. +
++ Other virtualization samples are listed at Unlisted Samples.
Other considerations
@@ -44,19 +103,18 @@Other considerations
set Diagram.div to null in order for the page to garbage collect the memory.- Shadows and animation slow down rendering and can be turned off. LayeredDigraphLayout is the slowest of the layouts. Templates can be simplified to reduce rendering and re-measuring. The number of TextBlocks, the complexity of shapes, gradient Brushes all impact performance slightly, and reducing their use in aggregate may result in a performance gain. -
- -- Depening on your app, it may be worthwhile to selectively toggle off some features (like shadows and animation) or to use simpler templates altogether, when slower environments are present, such as on mobile devices. + Depending on your app, it may be worthwhile to selectively toggle off some features + (like shadows and animation) or to use simpler templates altogether, + when slower environments are present, such as on mobile devices.
-- You can use multiple templates depending on your zoom level. If you are zoomed out far enough (and therefore have a lot of nodes on the screen) you can switch to a simplified template so that rendering (when panning, dragging, etc) is faster. The process of switching templates has a performance cost, though, since Parts have to rebuild themselves. + You can use multiple templates depending on your zoom level. + If you are zoomed out far enough (and therefore have a lot of nodes on the screen) + you can switch to a simplified template so that rendering (when panning, dragging, etc) is faster. + The process of switching templates has a performance cost, though, + since Parts have to rebuild themselves.
- -