UNPKG

38.2 kBHTMLView Raw
1<!DOCTYPE html>
2<html lang="en">
3 <head>
4<meta charset="utf-8"/>
5<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no, viewport-fit=cover"/>
6
7<link rel="stylesheet" href="../assets/css/style.css"/>
8<!-- Copyright 1998-2021 by Northwoods Software Corporation. --> <title> GoJS Events -- Northwoods Software </title>
9 <link rel="stylesheet" href="../assets/css/prism.css" />
10 </head>
11 <script>
12
13 window.diagrams = [];
14 window.goCode = function(pre, w, h, parentid, animation) {
15 window.diagrams.push([pre, w, h, parentid, animation]);
16 }
17 </script>
18 <body>
19 <nav id="navTop" class="w-full z-30 top-0 text-white bg-nwoods-primary">
20 <div class="w-full container max-w-screen-lg mx-auto flex flex-wrap sm:flex-nowrap items-center justify-between mt-0 py-2">
21 <div class="md:pl-4">
22 <a class="text-white hover:text-white no-underline hover:no-underline
23 font-bold text-2xl lg:text-4xl rounded-lg hover:bg-nwoods-secondary " href="../">
24 <h1 class="mb-0 p-1 ">GoJS</h1>
25 </a>
26 </div>
27 <button id="topnavButton" class="rounded-lg sm:hidden focus:outline-none focus:ring" aria-label="Navigation">
28 <svg fill="currentColor" viewBox="0 0 20 20" class="w-6 h-6">
29 <path id="topnavOpen" fill-rule="evenodd" d="M3 5a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zM3 10a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zM9 15a1 1 0 011-1h6a1 1 0 110 2h-6a1 1 0 01-1-1z" clip-rule="evenodd"></path>
30 <path id="topnavClosed" class="hidden" fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd"></path>
31 </svg>
32 </button>
33 <div id="topnavList" class="hidden sm:block items-center w-auto mt-0 text-white p-0 z-20">
34 <ul class="list-reset list-none font-semibold flex justify-end flex-wrap sm:flex-nowrap items-center px-0 pb-0">
35 <li class="p-1 sm:p-0"><a class="topnav-link" href="../learn/">Learn</a></li>
36 <li class="p-1 sm:p-0"><a class="topnav-link" href="../samples/">Samples</a></li>
37 <li class="p-1 sm:p-0"><a class="topnav-link" href="../intro/">Intro</a></li>
38 <li class="p-1 sm:p-0"><a class="topnav-link" href="../api/">API</a></li>
39 <li class="p-1 sm:p-0"><a class="topnav-link" href="https://www.nwoods.com/products/register.html">Register</a></li>
40 <li class="p-1 sm:p-0"><a class="topnav-link" href="../download.html">Download</a></li>
41 <li class="p-1 sm:p-0"><a class="topnav-link" href="https://forum.nwoods.com/c/gojs/11">Forum</a></li>
42 <li class="p-1 sm:p-0"><a class="topnav-link" href="https://www.nwoods.com/contact.html"
43 target="_blank" rel="noopener" onclick="getOutboundLink('https://www.nwoods.com/contact.html', 'contact');">Contact</a></li>
44 <li class="p-1 sm:p-0"><a class="topnav-link" href="https://www.nwoods.com/sales/index.html"
45 target="_blank" rel="noopener" onclick="getOutboundLink('https://www.nwoods.com/sales/index.html', 'buy');">Buy</a></li>
46 </ul>
47 </div>
48 </div>
49 <hr class="border-b border-gray-600 opacity-50 my-0 py-0" />
50 </nav>
51
52 <div class="md:flex flex-col md:flex-row md:min-h-screen w-full max-w-screen-xl mx-auto">
53
54 <div id="navSide" class="flex flex-col w-full md:w-40 lg:w-48 text-gray-700 bg-white flex-shrink-0">
55 <div class="flex-shrink-0 px-8 py-4">
56 <button id="navButton" class="rounded-lg md:hidden focus:outline-none focus:ring" aria-label="Navigation">
57 <svg fill="currentColor" viewBox="0 0 20 20" class="w-6 h-6">
58 <path id="navOpen" fill-rule="evenodd" d="M3 5a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zM3 10a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zM9 15a1 1 0 011-1h6a1 1 0 110 2h-6a1 1 0 01-1-1z" clip-rule="evenodd"></path>
59 <path id="navClosed" class="hidden" fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd"></path>
60 </svg>
61 </button>
62 </div>
63 <nav id="navList" class="min-h-screen hidden md:block sidebar-nav flex-grow px-1 lg:px-4 pb-4 md:pb-0 md:overflow-y-auto break-words">
64 <a href="index.html">Basics</a>
65 <a href="buildingObjects.html">Building Parts</a>
66 <a href="usingModels.html">Using Models</a>
67 <a href="dataBinding.html">Data Binding</a>
68 <a href="react.html">GoJS with React</a>
69 <a href="angular.html">GoJS with Angular</a>
70 <a href="textBlocks.html">TextBlocks</a>
71 <a href="shapes.html">Shapes</a>
72 <a href="pictures.html">Pictures</a>
73 <a href="panels.html">Panels</a>
74 <a href="tablePanels.html">Table Panels</a>
75 <a href="brush.html">Brushes</a>
76 <a href="sizing.html">Sizing Objects</a>
77 <a href="itemArrays.html">Item Arrays</a>
78 <a href="changedEvents.html">Changed Events</a>
79 <a href="transactions.html">Transactions</a>
80 <a href="viewport.html">Coordinates</a>
81 <a href="initialView.html">Initial View</a>
82 <a href="collections.html">Collections</a>
83 <a href="links.html">Links</a>
84 <a href="linkLabels.html">Link Labels</a>
85 <a href="connectionPoints.html">Link Points</a>
86 <a href="ports.html">Ports</a>
87 <a href="nodes.html">Nodes</a>
88 <a href="debugging.html">Debugging</a>
89 <a href="layouts.html">Layouts</a>
90 <a href="trees.html">Trees</a>
91 <a href="subtrees.html">SubTrees</a>
92 <a href="groups.html">Groups</a>
93 <a href="subgraphs.html">SubGraphs</a>
94 <a href="sizedGroups.html">Sized Groups</a>
95 <a href="selection.html">Selection</a>
96 <a href="highlighting.html">Highlighting</a>
97 <a href="animation.html">Animation</a>
98 <a href="toolTips.html">ToolTips</a>
99 <a href="contextmenus.html">Context Menus</a>
100 <a href="events.html">Diagram Events</a>
101 <a href="tools.html">Tools</a>
102 <a href="commands.html">Commands</a>
103 <a href="permissions.html">Permissions</a>
104 <a href="validation.html">Validation</a>
105 <a href="HTMLInteraction.html">HTML Interaction</a>
106 <a href="layers.html">Layers &amp; Z-ordering</a>
107 <a href="palette.html">Palette</a>
108 <a href="overview.html">Overview</a>
109 <a href="resizing.html">Resizing Diagrams</a>
110 <a href="replacingDeleting.html">Replacing and Deleting</a>
111 <a href="buttons.html">Buttons</a>
112 <a href="templateMaps.html">Template Maps</a>
113 <a href="legends.html">Legends and Titles</a>
114 <a href="extensions.html">Extensions</a>
115 <a href="geometry.html">Geometry Strings</a>
116 <a href="grids.html">Grid Patterns</a>
117 <a href="graduatedPanels.html">Graduated Panels</a>
118 <a href="makingImages.html">Diagram Images</a>
119 <a href="makingSVG.html">Diagram SVG</a>
120 <a href="printing.html">Printing</a>
121 <a href="serverSideImages.html">Server-side Images</a>
122 <a href="nodeScript.html">GoJS in Node.js</a>
123 <a href="testing.html">Testing</a>
124 <a href="storage.html">Storage</a>
125 <a href="performance.html">Performance</a>
126 <a href="source.html">Building from Source</a>
127 <a href="platforms.html">Platforms</a>
128 <a href="deployment.html">Deployment</a>
129 </nav>
130 </div>
131 <div class="pt-4 px-2 md:px-0 lg:px-4 pb-16 w-full overflow-hidden">
132
133
134
135
136<h1>Events</h1>
137<p>
138There are three basic kinds of events that <b>GoJS</b> deals with:
139<a>DiagramEvent</a>s, <a>InputEvent</a>s, and <a>ChangedEvent</a>s.
140This page discusses the first two; see <a href="changedEvents.html">Changed Events</a> for the last kind of event.
141</p>
142
143<h2 id="DiagramEvents">Diagram Events</h2>
144<p>
145<a>DiagramEvent</a>s represent general user-initiated changes to a diagram.
146You can register one or more diagram event handlers by calling <a>Diagram.addDiagramListener</a>.
147You can also register a diagram event handler in <a>Diagram</a> initialization when calling <a>GraphObject,make</a>.
148Each kind of diagram event is distinguished by its name.
149</p>
150<p>
151Currently defined diagram event names include:
152</p>
153<ul>
154 <li id="InitialAnimationStarting" onclick="window.location.hash = '#AnimationStarting'">
155 "<b>InitialAnimationStarting</b>", the initial default animation is about to start;
156 do not modify the diagram or its model in the event listener.
157 This can be useful for modifying the <a>AnimationManager.defaultAnimation</a> to make a custom initial animation.
158 See <a>AnimationManager.initialAnimationStyle</a> for details.
159 </li>
160 <li id="AnimationStarting" onclick="window.location.hash = '#AnimationStarting'">
161 "<b>AnimationStarting</b>", a default animation (<a>AnimationManager.defaultAnimation</a>) is about to start;
162 do not modify the diagram or its model in the event listener.
163 </li>
164 <li id="AnimationFinished" onclick="window.location.hash = '#AnimationFinished'">
165 "<b>AnimationFinished</b>", a default animation (<a>AnimationManager.defaultAnimation</a>) just completed;
166 do not modify the diagram or its model in the event listener.
167 </li>
168 <li id="BackgroundSingleClicked" onclick="window.location.hash = '#BackgroundSingleClicked'">
169 "<b>BackgroundSingleClicked</b>", when a mouse left-button single-click happened in the background of the Diagram, not on a Part;
170 if you make any changes, start and commit your own transaction.
171 </li>
172 <li id="BackgroundDoubleClicked" onclick="window.location.hash = '#BackgroundDoubleClicked'">
173 "<b>BackgroundDoubleClicked</b>", when a mouse left-button double-click happened in the background of the Diagram, not on a Part;
174 if you make any changes, start and commit your own transaction.
175 </li>
176 <li id="BackgroundContextClicked" onclick="window.location.hash = '#BackgroundContextClicked'">
177 "<b>BackgroundContextClicked</b>", when a mouse right-button single-click happened in the background of the Diagram, not on a Part;
178 if you make any changes, start and commit your own transaction.
179 </li>
180 <li id="ChangingSelection" onclick="window.location.hash = '#ChangingSelection'">
181 "<b>ChangingSelection</b>", an operation is about to change the <a>Diagram.selection</a> collection,
182 which is also the value of the <a>DiagramEvent.subject</a>;
183 do not make any changes to the selection or the diagram or the model in the event listener;
184 note that just setting <a>Part.isSelected</a> will not raise this event, but tools and commands will.
185 </li>
186 <li id="ChangedSelection" onclick="window.location.hash = '#ChangedSelection'">
187 "<b>ChangedSelection</b>", an operation has just changed the <a>Diagram.selection</a> collection,
188 which is also the value of the <a>DiagramEvent.subject</a>;
189 do not make any changes to the selection or the diagram or the model in the event listener;
190 note that just setting <a>Part.isSelected</a> will not raise this event, but tools and commands will.
191 </li>
192 <li id="ClipboardChanged" onclick="window.location.hash = '#ClipboardChanged'">
193 "<b>ClipboardChanged</b>", Parts have been copied to the clipboard by <a>CommandHandler.copySelection</a>;
194 the <a>DiagramEvent.subject</a> is the collection of Parts;
195 if you make any changes, start and commit your own transaction.
196 </li>
197 <li id="ClipboardPasted" onclick="window.location.hash = '#ClipboardPasted'">
198 "<b>ClipboardPasted</b>", Parts have been copied from the clipboard into the Diagram by <a>CommandHandler.pasteSelection</a>;
199 the <a>DiagramEvent.subject</a> is the <a>Diagram.selection</a>,
200 and this is called within a transaction, so that you do not have to start and commit your own transaction.
201 </li>
202 <li id="DocumentBoundsChanged" onclick="window.location.hash = '#DocumentBoundsChanged'">
203 "<b>DocumentBoundsChanged</b>", the area of the diagram's Parts, <a>Diagram.documentBounds</a>, has changed;
204 the <a>DiagramEvent.parameter</a> is the old Rect.
205 </li>
206 <li id="ExternalObjectsDropped" onclick="window.location.hash = '#ExternalObjectsDropped'">
207 "<b>ExternalObjectsDropped</b>", Parts have been copied into the Diagram by drag-and-drop from outside of the Diagram;
208 the <a>DiagramEvent.subject</a> is the set of Parts that were dropped (which is also the <a>Diagram.selection</a>),
209 the <a>DiagramEvent.parameter</a> is the source Diagram,
210 and this is called within a transaction, so that you do not have to start and commit your own transaction.
211 </li>
212 <li id="GainedFocus" onclick="window.location.hash = '#GainedFocus'">
213 "<b>GainedFocus</b>", the diagram has gained keyboard focus, such as after a call to <a>Diagram.focus</a>.
214 </li>
215 <li id="InitialLayoutCompleted" onclick="window.location.hash = '#InitialLayoutCompleted'">
216 "<b>InitialLayoutCompleted</b>", the whole diagram layout has updated for the first time since a major change to the Diagram,
217 such as replacing the Model;
218 if you make any changes, you do not need to perform a transaction.
219 </li>
220 <li id="LayoutCompleted" onclick="window.location.hash = '#LayoutCompleted'">
221 "<b>LayoutCompleted</b>", the whole diagram layout has just been updated;
222 if you make any changes, you do not need to perform a transaction.
223 </li>
224 <li id="LinkDrawn" onclick="window.location.hash = '#LinkDrawn'">
225 "<b>LinkDrawn</b>", the user has just created a new Link using <a>LinkingTool</a>;
226 the <a>DiagramEvent.subject</a> is the new Link,
227 and this is called within a transaction, so that you do not have to start and commit your own transaction..
228 </li>
229 <li id="LinkRelinked" onclick="window.location.hash = '#LinkRelinked'">
230 "<b>LinkRelinked</b>", the user has just reconnected an existing Link using <a>RelinkingTool</a> or <a>DraggingTool</a>;
231 the <a>DiagramEvent.subject</a> is the modified Link,
232 the <a>DiagramEvent.parameter</a> is the GraphObject port that the link was disconnected from,
233 and this is called within a transaction, so that you do not have to start and commit your own transaction..
234 </li>
235 <li id="LinkReshaped" onclick="window.location.hash = '#LinkReshaped'">
236 "<b>LinkReshaped</b>", the user has just rerouted an existing Link using <a>LinkReshapingTool</a>;
237 the <a>DiagramEvent.subject</a> is the modified Link,
238 the <a>DiagramEvent.parameter</a> is the List of Points of the link's original route,
239 and this is called within a transaction, so that you do not have to start and commit your own transaction..
240 </li>
241 <li id="LostFocus" onclick="window.location.hash = '#LostFocus'">
242 "<b>LostFocus</b>", the diagram has lost keyboard focus ("blur").
243 </li>
244 <li id="Modified" onclick="window.location.hash = '#Modified'">
245 "<b>Modified</b>", the <a>Diagram.isModified</a> property has been set to a new value --
246 useful for marking a window as having been modified since the last save;
247 do not modify the Diagram or its Model in the event listener.
248 </li>
249 <li id="ObjectSingleClicked" onclick="window.location.hash = '#ObjectSingleClicked'">
250 "<b>ObjectSingleClicked</b>", a click that occurred on a GraphObject;
251 the <a>DiagramEvent.subject</a> is the GraphObject;
252 if you make any changes, start and commit your own transaction.
253 </li>
254 <li id="ObjectDoubleClicked" onclick="window.location.hash = '#ObjectDoubleClicked'">
255 "<b>ObjectDoubleClicked</b>", a double-click that occurred on a GraphObject;
256 the <a>DiagramEvent.subject</a> is the GraphObject;
257 if you make any changes, start and commit your own transaction.
258 </li>
259 <li id="ObjectContextClicked" onclick="window.location.hash = '#ObjectContextClicked'">
260 "<b>ObjectContextClicked</b>", a context-click that occurred on a GraphObject;
261 the <a>DiagramEvent.subject</a> is the GraphObject;
262 if you make any changes, start and commit your own transaction.
263 </li>
264 <li id="PartCreated" onclick="window.location.hash = '#PartCreated'">
265 "<b>PartCreated</b>", the user inserted a new Part by <a>ClickCreatingTool</a>;
266 the <a>DiagramEvent.subject</a> is the new Part,
267 and this is called within a transaction, so that you do not have to start and commit your own transaction.
268 </li>
269 <li id="PartResized" onclick="window.location.hash = '#PartResized'">
270 "<b>PartResized</b>", the user has changed the size of a GraphObject by <a>ResizingTool</a>;
271 the <a>DiagramEvent.subject</a> is the GraphObject,
272 the <a>DiagramEvent.parameter</a> is the original Size,
273 and this is called within a transaction, so that you do not have to start and commit your own transaction.
274 </li>
275 <li id="PartRotated" onclick="window.location.hash = '#PartRotated'">
276 "<b>PartRotated</b>", the user has changed the angle of a GraphObject by <a>RotatingTool</a>;
277 the <a>DiagramEvent.subject</a> is the GraphObject,
278 the <a>DiagramEvent.parameter</a> is the original angle in degrees,
279 and this is called within a transaction, so that you do not have to start and commit your own transaction.
280 </li>
281 <li id="SelectionMoved" onclick="window.location.hash = '#SelectionMoved'">
282 "<b>SelectionMoved</b>", the user has moved selected Parts by <a>DraggingTool</a>;
283 the <a>DiagramEvent.subject</a> is a Set of the moved Parts,
284 and this is called within a transaction, so that you do not have to start and commit your own transaction.
285 </li>
286 <li id="SelectionCopied" onclick="window.location.hash = '#SelectionCopied'">
287 "<b>SelectionCopied</b>", the user has copied selected Parts by <a>DraggingTool</a>;
288 the <a>DiagramEvent.subject</a> is Set of the newly copied Parts,
289 and this is called within a transaction, so that you do not have to start and commit your own transaction.
290 </li>
291 <li id="SelectionDeleting" onclick="window.location.hash = '#SelectionDeleting'">
292 "<b>SelectionDeleting</b>", the user is about to delete selected Parts by <a>CommandHandler.deleteSelection</a>;
293 the <a>DiagramEvent.subject</a> is the <a>Diagram.selection</a> collection of Parts to be deleted,
294 and this is called within a transaction, so that you do not have to start and commit your own transaction.
295 </li>
296 <li id="SelectionDeleted" onclick="window.location.hash = '#SelectionDeleted'">
297 "<b>SelectionDeleted</b>", the user has deleted selected Parts by <a>CommandHandler.deleteSelection</a>;
298 the <a>DiagramEvent.subject</a> is the collection of Parts that were deleted,
299 and this is called within a transaction, so that you do not have to start and commit your own transaction.
300 </li>
301 <li id="SelectionGrouped" onclick="window.location.hash = '#SelectionGrouped'">
302 "<b>SelectionGrouped</b>", the user has made a new Group out of the selected Parts by <a>CommandHandler.groupSelection</a>;
303 the <a>DiagramEvent.subject</a> is the new Group,
304 and this is called within a transaction, so that you do not have to start and commit your own transaction.
305 </li>
306 <li id="SelectionUngrouped" onclick="window.location.hash = '#SelectionUngrouped'">
307 "<b>SelectionUngrouped</b>", the user has removed a selected Group but kept its members by <a>CommandHandler.ungroupSelection</a>;
308 the <a>DiagramEvent.subject</a> is the collection of Groups that were ungrouped,
309 the <a>DiagramEvent.parameter</a> is the collection of former member Parts that were ungrouped,
310 and this is called within a transaction, so that you do not have to start and commit your own transaction.
311 </li>
312 <li id="SubGraphCollapsed" onclick="window.location.hash = '#SubGraphCollapsed'">
313 "<b>SubGraphCollapsed</b>", the user has collapsed selected Groups by <a>CommandHandler.collapseSubGraph</a>;
314 the <a>DiagramEvent.subject</a> is the collection of Groups that were collapsed,
315 and this is called within a transaction, so that you do not have to start and commit your own transaction.
316 </li>
317 <li id="SubGraphExpanded" onclick="window.location.hash = '#SubGraphExpanded'">
318 "<b>SubGraphExpanded</b>", the user has expanded selected Groups by <a>CommandHandler.expandSubGraph</a>;
319 the <a>DiagramEvent.subject</a> is the collection of Groups that were expanded,
320 and this is called within a transaction, so that you do not have to start and commit your own transaction.
321 </li>
322 <li id="TextEdited" onclick="window.location.hash = '#TextEdited'">
323 "<b>TextEdited</b>", the user has changed the string value of a TextBlock by <a>TextEditingTool</a>;
324 the <a>DiagramEvent.subject</a> is the edited TextBlock,
325 the <a>DiagramEvent.parameter</a> is the original string,
326 and this is called within a transaction, so that you do not have to start and commit your own transaction.
327 </li>
328 <li id="TreeCollapsed" onclick="window.location.hash = '#TreeCollapsed'">
329 "<b>TreeCollapsed</b>", the user has collapsed selected Nodes with subtrees by <a>CommandHandler.collapseTree</a>;
330 the <a>DiagramEvent.subject</a> is the collection of Nodes that were collapsed,
331 and this is called within a transaction, so that you do not have to start and commit your own transaction.
332 </li>
333 <li id="TreeExpanded" onclick="window.location.hash = '#TreeExpanded'">
334 "<b>TreeExpanded</b>", the user has expanded selected Nodes with subtrees by <a>CommandHandler.expandTree</a>;
335 the <a>DiagramEvent.subject</a> is the collection of Nodes that were expanded,
336 and this is called within a transaction, so that you do not have to start and commit your own transaction.
337 </li>
338 <li id="ViewportBoundsChanged" onclick="window.location.hash = '#ViewportBoundsChanged'">
339 "<b>ViewportBoundsChanged</b>", the visible area of the Diagram, <a>Diagram.viewportBounds</a>, has changed;
340 the <a>DiagramEvent.subject</a> is an object whose "scale" property is the old <a>Diagram.scale</a> value,
341 whose "position" property is the old <a>Diagram.position</a> value,
342 and whose "bounds" property is the old <a>Diagram.viewportBounds</a> value;
343 the <a>DiagramEvent.parameter</a> is also the old viewportBounds Rect.
344 Do not modify the Diagram position or scale (i.e. the viewport bounds) in the listener.
345 </li>
346</ul>
347
348<p>
349DiagramEvents do not necessarily correspond to mouse events or keyboard events or touch events.
350Nor do they necessarily correspond to changes to the diagram's model --
351for tracking such changes, use <a>Model.addChangedListener</a> or <a>Diagram.addModelChangedListener</a>.
352DiagramEvents only occur because the user did something, perhaps indirectly.
353</p>
354<p>
355<p>
356In addition to the DiagramEvent listeners there are also circumstances where detecting such changes is common
357enough to warrant having properties that are event handlers.
358Because these events do not necessarily correspond to any particular input or diagram event,
359these event handlers have custom arguments that are specific to the situation.
360</p>
361<p>
362One very common such event property is <a>GraphObject.click</a>, which if non-null is a function that is called
363whenever the user clicks on that object.
364This is most commonly used to specify behavior for "Button"s, but it and the other "click" event properties,
365"doubleClick" and "contextClick", can be useful on any GraphObject.
366</p>
367<p>
368Another common event property is <a>Part.selectionChanged</a>,
369which (if non-null) is called whenever <a>Part.isSelected</a> changes.
370In this case the event hander function is passed a single argument, the Part.
371There is no need for additional arguments because the function can check the current value of <a>Part.isSelected</a> to decide what to do.
372</p>
373</p>
374<p>
375Model <a>ChangedEvent</a>s are more complete and reliable than depending on <a>DiagramEvent</a>s.
376For example, the "LinkDrawn" DiagramEvent is not raised when code adds a link to a diagram.
377That DiagramEvent is only raised when the user draws a new link using the <a>LinkingTool</a>.
378Furthermore the link has not yet been routed, so <a>Link.points</a> will not have been computed.
379In fact, creating a new link may invalidate a <a>Layout</a>, so all of the nodes may be moved in the near future.
380</p>
381
382<p class="box bg-danger">
383Sometimes you want to update a database as the user makes changes to a diagram.
384Usually you will want to implement a <a>Model</a> <a>ChangedEvent</a> listener,
385by calling <a>Model.addChangedListener</a> or <a>Diagram.addModelChangedListener</a>,
386that notices the changes to the model and decides what to record in the database.
387See the discussion of <a href="changedEvents.html">Changed Events</a> and the <a href="../samples/UpdateDemo.html">Update Demo</a>.
388</p>
389
390<p>
391This example demonstrates handling several diagram events: <b>"ObjectSingleClicked"</b>,
392<b>"BackgroundDoubleClicked"</b>, and <b>"ClipboardPasted"</b>.
393</p>
394<pre class="lang-js" id="diagramEvents"><code>
395 function showMessage(s) {
396 document.getElementById("diagramEventsMsg").textContent = s;
397 }
398
399 diagram.addDiagramListener("ObjectSingleClicked",
400 function(e) {
401 var part = e.subject.part;
402 if (!(part instanceof go.Link)) showMessage("Clicked on " + part.data.key);
403 });
404
405 diagram.addDiagramListener("BackgroundDoubleClicked",
406 function(e) { showMessage("Double-clicked at " + e.diagram.lastInput.documentPoint); });
407
408 diagram.addDiagramListener("ClipboardPasted",
409 function(e) { showMessage("Pasted " + e.diagram.selection.count + " parts"); });
410
411 var nodeDataArray = [
412 { key: "Alpha" },
413 { key: "Beta", group: "Omega" },
414 { key: "Gamma", group: "Omega" },
415 { key: "Omega", isGroup: true },
416 { key: "Delta" }
417 ];
418 var linkDataArray = [
419 { from: "Alpha", to: "Beta" }, // from outside the Group to inside it
420 { from: "Beta", to: "Gamma" }, // this link is a member of the Group
421 { from: "Omega", to: "Delta" } // from the Group to a Node
422 ];
423 diagram.model = new go.GraphLinksModel(nodeDataArray, linkDataArray);
424</code></pre>
425<script>goCode("diagramEvents", 600, 200)</script>
426<span id="diagramEventsMsg" style="color: red">(message)</span>
427
428
429<h2 id="InputEvents">Input Events</h2>
430<p>
431When a low-level HTML DOM event occurs, <b>GoJS</b> canonicalizes the keyboard/mouse/touch event information
432into a new <a>InputEvent</a> that can be passed to various event-handling methods and saved for later examination.
433</p>
434<p>
435An InputEvent keeps the <a>InputEvent.key</a> for keyboard events,
436the <a>InputEvent.button</a> for mouse events,
437the <a>InputEvent.viewPoint</a> for mouse and touch events,
438and <a>InputEvent.modifiers</a> for keyboard and mouse events.
439</p>
440<p>
441The diagram's event handlers also record the <a>InputEvent.documentPoint</a>,
442which is the <a>InputEvent.viewPoint</a> in document coordinates at the time of the mouse event,
443and the <a>InputEvent.timestamp</a>, which records the time that the event occurred in milliseconds.
444</p>
445<p>
446The InputEvent class also provides many handy properties for particular kinds of events.
447Examples include <a>InputEvent.control</a> (if the control key had been pressed) and
448<a>InputEvent.left</a> (if the left/primary mouse button was pressed).
449</p>
450<p>
451Some tools find the "current" <a>GraphObject</a> at the mouse point.
452This is remembered as the <a>InputEvent.targetObject</a>.
453</p>
454
455<h2 id="HigherLevelInputEvents">Higher-level input events</h2>
456<p>
457Some tools detect a sequence of input events to compose somewhat more abstract user events.
458Examples include "click" (mouse-down-and-up very close to each other) and "hover" (motionless mouse for some time).
459The tools will call an event handler (if there is any) for the current <a>GraphObject</a> at the mouse point.
460The event handler is held as the value of a property on the object.
461It then also "bubbles" the event up the chain of <a>GraphObject.panel</a>s until it ends with a <a>Part</a>.
462This allows a "click" event handler to be declared on a <a>Panel</a> and have it apply even if the click actually happens on an element deep inside the panel.
463If there is no object at the mouse point, the event occurs on the diagram.
464</p>
465<p>
466Click-like event properties include <a>GraphObject.click</a>, <a>GraphObject.doubleClick</a>, and <a>GraphObject.contextClick</a>.
467They also occur when there is no GraphObject -- the event happened in the diagram's background:
468<a>Diagram.click</a>, <a>Diagram.doubleClick</a>, and <a>Diagram.contextClick</a>.
469These are all properties that you can set to a function that is the event handler.
470These events are caused by both mouse events and touch events.
471</p>
472<p>
473Mouse-over-like event properties include <a>GraphObject.mouseEnter</a>, <a>GraphObject.mouseOver</a>, and <a>GraphObject.mouseLeave</a>.
474But only <a>Diagram.mouseOver</a> applies to the diagram.
475</p>
476<p>
477Hover-like event properties include <a>GraphObject.mouseHover</a> and <a>GraphObject.mouseHold</a>.
478The equivalent diagram properties are <a>Diagram.mouseHover</a> and <a>Diagram.mouseHold</a>.
479</p>
480<p>
481There are also event properties for dragging operations: <a>GraphObject.mouseDragEnter</a>, <a>GraphObject.mouseDragLeave</a>, and <a>GraphObject.mouseDrop</a>.
482These apply to stationary objects, not the objects being dragged.
483And they also occur when dragging by touch events, not just mouse events.
484</p>
485
486<p>
487This example demonstrates handling three higher-level input events:
488clicking on nodes and entering/leaving groups.
489</p>
490<pre class="lang-js" id="inputEvents"><code>
491 function showMessage(s) {
492 document.getElementById("inputEventsMsg").textContent = s;
493 }
494
495 diagram.nodeTemplate =
496 $(go.Node, "Auto",
497 $(go.Shape, "Ellipse", { fill: "white" }),
498 $(go.TextBlock,
499 new go.Binding("text", "key")),
500 { click: function(e, obj) { showMessage("Clicked on " + obj.part.data.key); } }
501 );
502
503 diagram.groupTemplate =
504 $(go.Group, "Vertical",
505 $(go.TextBlock,
506 { alignment: go.Spot.Left, font: "Bold 12pt Sans-Serif" },
507 new go.Binding("text", "key")),
508 $(go.Panel, "Auto",
509 $(go.Shape, "RoundedRectangle",
510 { name: "SHAPE",
511 parameter1: 14,
512 fill: "rgba(128,128,128,0.33)" }),
513 $(go.Placeholder, { padding: 5 })
514 ),
515 { mouseEnter: function(e, obj, prev) { // change group's background brush
516 var shape = obj.part.findObject("SHAPE");
517 if (shape) shape.fill = "red";
518 },
519 mouseLeave: function(e, obj, next) { // restore to original brush
520 var shape = obj.part.findObject("SHAPE");
521 if (shape) shape.fill = "rgba(128,128,128,0.33)";
522 } });
523
524 var nodeDataArray = [
525 { key: "Alpha" },
526 { key: "Beta", group: "Omega" },
527 { key: "Gamma", group: "Omega" },
528 { key: "Omega", isGroup: true },
529 { key: "Delta" }
530 ];
531 var linkDataArray = [
532 { from: "Alpha", to: "Beta" }, // from outside the Group to inside it
533 { from: "Beta", to: "Gamma" }, // this link is a member of the Group
534 { from: "Omega", to: "Delta" } // from the Group to a Node
535 ];
536 diagram.model = new go.GraphLinksModel(nodeDataArray, linkDataArray);
537</code></pre>
538<script>goCode("inputEvents", 600, 200)</script>
539<span id="inputEventsMsg" style="color: red">(message)</span>
540
541
542<h2 id="ClickingAndSelecting">Clicking and Selecting</h2>
543<p>
544This example demonstrates both the "click" and the "selectionChanged" events:
545</p>
546<pre class="lang-js" id="changeMethods"><code>
547 function showMessage(s) {
548 document.getElementById("changeMethodsMsg").textContent = s;
549 }
550
551 diagram.nodeTemplate =
552 $(go.Node, "Auto",
553 { selectionAdorned: false },
554 $(go.Shape, "Ellipse", { fill: "white" }),
555 $(go.TextBlock,
556 new go.Binding("text", "key")),
557 {
558 click: function(e, obj) { showMessage("Clicked on " + obj.part.data.key); },
559 selectionChanged: function(part) {
560 var shape = part.elt(0);
561 shape.fill = part.isSelected ? "red" : "white";
562 }
563 }
564 );
565
566 var nodeDataArray = [
567 { key: "Alpha" }, { key: "Beta" }, { key: "Gamma" }
568 ];
569 var linkDataArray = [
570 { from: "Alpha", to: "Beta" },
571 { from: "Beta", to: "Gamma" }
572 ];
573 diagram.model = new go.GraphLinksModel(nodeDataArray, linkDataArray);
574</code></pre>
575<script>goCode("changeMethods", 600, 200)</script>
576<span id="changeMethodsMsg" style="color: red">(message)</span>
577<p>
578Try Ctrl-A to select everything.
579Note the distinction between the <a>GraphObject.click</a> event property and the <a>Part.selectionChanged</a> event property.
580Both are methods that get called when something has happened to the node.
581The <a>GraphObject.click</a> occurs when the user clicks on the node, which happens to select the node.
582But the <a>Part.selectionChanged</a> occurs even when there is no click event or even any mouse event --
583it was due to a property change to the node.
584</p>
585
586 </div>
587 </div>
588
589 <div class="bg-nwoods-primary">
590 <section class="max-w-screen-lg text-white container mx-auto py-2 px-12">
591 <p id="version" class="leading-none mb-2 my-4">GoJS</p>
592 </section>
593 </div><footer class="bg-nwoods-primary text-white">
594 <div class="container max-w-screen-lg mx-auto px-8">
595 <div class="w-full py-6">
596
597 <div class="max-w-screen-lg xl:max-w-screen-xl mx-auto px-4 sm:px-6 md:px-8">
598 <ul class="text-sm font-medium pb-14 sm:pb-20 grid grid-cols-1 sm:grid-cols-3 gap-y-10">
599 <li class="list-none row-span-2">
600 <h2 class="text-base font-semibold tracking-wide">GoJS</h2>
601 <ul class="list-none space-y-4 md:space-y-1 px-0">
602 <li>
603 <a href="../samples/index.html">Samples</a>
604 </li>
605 <li>
606 <a href="../learn/index.html">Learn</a>
607 </li>
608 <li>
609 <a href="../intro/index.html">Intro</a>
610 </li>
611 <li>
612 <a href="../api/index.html">API</a>
613 </li>
614 <li>
615 <a href="../changelog.html">Changelog</a>
616 </li>
617 <li>
618 <a href="https://github.com/NorthwoodsSoftware/GoJS">GitHub</a>
619 </li>
620 </ul>
621 </li>
622 <li class="list-none row-span-2">
623 <h2 class="text-base font-semibold tracking-wide">Support</h2>
624 <ul class="list-none space-y-4 md:space-y-1 px-0">
625 <li>
626 <a href="https://www.nwoods.com/contact.html"
627 target="_blank" rel="noopener" onclick="getOutboundLink('https://www.nwoods.com/contact.html', 'contact');">Contact</a>
628 </li>
629 <li>
630 <a href="https://forum.nwoods.com/c/gojs">Forum</a>
631 </li>
632 <li>
633 <a href="https://www.nwoods.com/app/activate.aspx?sku=gojs">Activate</a>
634 </li>
635 <li>
636 <a href="https://www.nwoods.com/sales/index.html"
637 target="_blank" rel="noopener" onclick="getOutboundLink('https://www.nwoods.com/sales/index.html', 'buy');">Buy</a>
638 </li>
639 <li>
640 <a href="https://www.youtube.com/channel/UC9We8EoX596-6XFjJDtZIDg">Videos</a>
641 </li>
642 </ul>
643 </li>
644 <li class="list-none row-span-2">
645 <h2 class="text-base font-semibold tracking-wide">Company</h2>
646 <ul class="list-none space-y-4 md:space-y-1 px-0">
647 <li>
648 <a href="https://www.nwoods.com">Northwoods</a>
649 </li>
650 <li>
651 <a href="https://www.nwoods.com/about.html">About Us</a>
652 </li>
653 <li>
654 <a href="https://www.nwoods.com/contact.html">Contact Us</a>
655 </li>
656 <li>
657 <a href="https://twitter.com/northwoodsgo">Twitter</a>
658 </li>
659
660 </ul>
661 </li>
662 </ul>
663
664
665 <p class="text-sm text-gray-100 md:mb-6">
666 Copyright 1998-2021 <a class="text-white" href="https://www.nwoods.com">Northwoods Software</a>
667 </p>
668 </div>
669 </div>
670</footer> </body>
671
672<script async src="https://www.googletagmanager.com/gtag/js?id=UA-1506307-5"></script>
673<script>
674 window.dataLayer = window.dataLayer || [];
675 function gtag(){dataLayer.push(arguments);}
676 gtag('js', new Date()); gtag('config', 'UA-1506307-5');
677 var getOutboundLink = function(url, label) {
678 gtag('event', 'click', {
679 'event_category': 'outbound',
680 'event_label': label,
681 'transport_type': 'beacon'
682 });
683 }
684
685 // topnav
686 var topButton = document.getElementById("topnavButton");
687 var topnavList = document.getElementById("topnavList");
688 topButton.addEventListener("click", function() {
689 this.classList.toggle("active");
690 topnavList.classList.toggle("hidden");
691 document.getElementById("topnavOpen").classList.toggle("hidden");
692 document.getElementById("topnavClosed").classList.toggle("hidden");
693 });
694</script>
695 <script src="../assets/js/prism.js"></script>
696 <script src="../release/go.js"></script>
697 <script src="../assets/js/goDoc.js"></script>
698 <script>
699 document.addEventListener("DOMContentLoaded", function() {
700 if (window.go) document.getElementById('version').textContent = "GoJS version " + go.version;
701 if (window.goDoc) window.goDoc();
702 var d = window.diagrams;
703 for (var i = 0; i < d.length; i++) {
704 var dargs = d[i];
705 goCodeExecute(dargs[0], dargs[1], dargs[2], dargs[3], dargs[4]);
706 }
707 if (window.extra) window.extra();
708 });
709 </script>
710</html>