Supported User Interactions
yFiles for HTML offers a wide array of predefined actions, not only for commonly used editor functionality (such as clipboard support, or zooming), but also actions specific to editing graphs. Most kinds of interaction in the following sections are the result of a specific input mode handling input events, usually because they are child input modes of GraphEditorInputMode or GraphViewerInputMode. These child input modes are available on GraphEditorInputMode and GraphViewerInputMode as properties with the same name as the respective input mode. A few interactions are also supported directly by GraphComponent, even without any input mode. Naturally, every interaction that exists to actually change the graph is only supported with GraphEditorInputMode, not GraphViewerInputMode.
Unless otherwise stated, all user interactions which support mouse gestures support touch gestures as well.
One frequent type of customization is to change the gesture for an
interaction. This is usually done with a property whose name ends in
Recognizer
and whose type is a function that takes an Object and an EventArgs instance and returns a boolean value.
event recognizers thus are essentially a predicate that matches on certain events.
You can write them manually, but there are also predefined event recognizers
for many common events, such as mouse button presses and modifier keys.
You can also easily combine event recognizers using appropriate helper methods:
Creating Nodes
Creating nodes is one of the basic user interactions provided by GraphEditorInputMode. By default a new node is created simply when left-clicking or tapping on an empty area in the canvas.
Node creation can be turned off via GraphEditorInputMode’s allowCreateNode property. Further customization options for node creation are discussed in detail in Customizing Creating Nodes.
Nodes can also be created with Drag and Drop.
Creating Edges
Creating edges is another basic interaction provided by GraphEditorInputMode. By default, starting a drag with the left mouse button on an unselected node will start edge creation. Simply releasing the mouse button over another node creates the edge. When using a touch device, the edge creation is started in a similar fashion by a long press on the source node, and then dragging the touch pointer to the target node and releasing it.
Bends can be introduced into the edge during creation by releasing the mouse button or touch pointer at an empty location in the canvas. Subsequent bends can be added by clicking or tapping on empty canvas locations. Right-clicking or long pressing a second touch pointer will undo the most recent bend and, if no bends are left, cancel edge creation altogether.
GraphEditorInputMode’s child input mode CreateEdgeInputMode allows you to customize edge creation in various ways via a number of properties:
- CreateEdgeInputMode.allowCreateBend
- Allows to turn off adding bends during edge creation. Note that to disallow creating bends entirely bend creation for existing edges must be disabled, too.
- CreateEdgeInputMode.edgeDefaults
- The defaults for newly-created edges, most notably their style. This works the same as setting defaults for new edges on a graph.
- CreateEdgeInputMode.allowSelfloops
- Whether self-loops, i.e. an edge that connects a node with itself, can be created.
- CreateEdgeInputMode.validBeginCursor
- The mouse cursor to show when edge creation can start. This is usually when hovering over an unselected node.
- CreateEdgeInputMode.validBendCursor
- The mouse cursor to show when a bend can be added. This is usually when the mouse pointer is over an empty part of the canvas during edge creation.
- CreateEdgeInputMode.validEndCursor
- The mouse cursor to show when edge creation can finish. This is usually when hovering over a possible target node during edge creation.
Creating edges is supported by the following auxiliary interaction concepts:
You can turn off edge creation by disabling the CreateEdgeInputMode via its enabled property or with GraphEditorInputMode’s allowCreateEdge property. Further customization options for edge creation are discussed in detail in Customizing Creating Edges.
Created edges can also be reconnected to other nodes. However, this is not enabled in the default configuration. This is described in detail in Customizing Reconnecting Edges.
Adding and Editing Labels
GraphEditorInputMode supports adding labels to graph items interactively. The default keyboard shortcut is F2, it will open a text area to edit the label for the currently selected item. The newly entered text can then be committed using Enter ↵, in which case it will become the label of the respective item. Changing an existing label can be done with F2 as well. Label editing can be canceled with Esc, in which case either no label is added, or the edited label isn’t changed.
GraphEditorInputMode offers a few simple ways to customize label editing and adding:
- GraphEditorInputMode.labelEditableItems
- The types of items that labels can be edited for. This can be either NODE, EDGE, or both.
- GraphEditorInputMode.allowAddLabel
- Specifies whether labels can be added to graph items by pressing Shift ⇧+F2 (or F2 on items that don’t already have labels).
- GraphEditorInputMode.allowEditLabel
- Specifies whether labels can be edited by pressing F2. When turned off, this also affects adding a label by pressing F2.
- GraphEditorInputMode.autoRemoveEmptyLabels
- Specifies whether labels with an empty text are automatically removed or not. Sometimes labels show more than just their text (e.g. an icon) in which case the empty text may actually be intentional.
Further customization options for label editing are discussed in detail in Customizing Adding and Editing Labels.
Creating Bends
Interactively designing an edge path can be done by creating bends, another of the basic graph structure-related interactions GraphEditorInputMode provides. Bends can be created during edge creation, but if the edge path after creation isn’t satisfactory they can also be added later. By default, the gesture to add a bend is to simply press the left mouse button on an edge path and drag. This will split the edge segment at the drag point and introduce a bend that will be placed where the mouse button is released.
You can be turn off bend creation on GraphEditorInputMode via its allowCreateBend property.
Creating bends is supported by the following auxiliary interaction concepts:
Deleting Items
All items in the graph can not only be created, but also removed again as well. By default selected items can be deleted by pressing Del. Deleting an item will also delete associated other items, such as labels or incident edges when a node is deleted.
GraphEditorInputMode has two properties for easy control of what can be deleted:
- GraphEditorInputMode.deletableItems
- The types of items that can be deleted. Note that dependent items will be deleted regardless of this setting, e.g. incident edges or labels when deleting a node.
- GraphEditorInputMode.deletablePredicate
- A predicate that controls what items can be deleted. This allows finer control than just the item type above.
Further customization options for deleting items are discussed in detail in Customizing Deleting Items.
Moving Items
GraphEditorInputMode offers the ability to reposition items by dragging them. By default this is done by pressing the left mouse button on a selected item and dragging the mouse. Releasing the mouse button again will finalize the new position of the item.
GraphEditorInputMode handles moving items through two child input modes: MoveInputMode which handles moving all items except labels, and MoveLabelInputMode, which handles moving labels. Labels are handled differently since they are only allowed to move to certain positions (as defined by their label model) which are indicated as a visual aid as well. Common adjustments to item moving are as follows:
- GraphEditorInputMode.movableItems
- Specifies the types of items that can be moved.
- MoveInputMode.pressedRecognizer
- Changes the mouse interaction to start a moving gesture.
- MoveInputMode.pressedRecognizerTouch
- Changes the touch interaction to start a moving gesture.
- MoveInputMode.moveCursor
- Changes the mouse cursor to show during the move.
Further customization options for moving items are discussed in detail in Customizing Moving Items.
Moving items is supported by the following auxiliary interaction concepts:
- Grouping: Moving a child node of a group node will resize the surrounding group node accordingly. Nodes can be moved in or out of group nodes by holding the Shift ⇧ key during a move.
- Orthogonal Edge Editing: When moving nodes, incident edges will stay orthogonal.
- Snapping
Resizing Nodes
By default GraphEditorInputMode will show a set of handles for selected items. For nodes these are eight handles on the sides and corners which can be used to resize the node by dragging the handles with the mouse.
Since resizing nodes is done via handles, adjusting the behavior can be done with GraphEditorInputMode’s showHandleItems property. This is also the place where resizing nodes can be turned off completely by setting a value that does not include NODE.
graphEditorInputMode.showHandleItems = GraphItemTypes.ALL & ~GraphItemTypes.NODE
Further customization is possible via GraphEditorInputMode’s child input mode HandleInputMode which is discussed in more detail in Customizing Resizing Nodes.
Resizing nodes is supported by the following auxiliary interaction concepts:
- Grouping: Resizing a child node of a group node will resize the surrounding group node accordingly.
- Orthogonal Edge Editing: When resizing nodes, incident edges will stay orthogonal.
- Snapping
Grouping
Graphs in yFiles for HTML support nesting nodes in so-called group nodes, as described in the introduction to the graph model. GraphEditorInputMode allows to interactively create and handle those as well.
Grouping-related features are disabled by default on GraphEditorInputMode and have to be enabled as the following code snippet shows.
graphEditorInputMode.allowGroupingOperations = true
By default, selected nodes can be grouped in a newly created group node by pressing Ctrl+G. The selected nodes can also be removed from a group by pressing Ctrl+U.
When ungrouping nodes, they will still appear on top of the group node, but are no longer part of that group node. This may not immediately be evident because the group node will still be underneath the nodes, but the difference is apparent when moving the nodes afterwards.
Selected group nodes can also be resized to fit their contents by pressing Ctrl+Shift ⇧+G. Furthermore, nodes can be moved to another group node (or simply out of their current group) by holding the Shift ⇧ key during a move.
GraphEditorInputMode offers a number of properties to configure grouping features and behavior:
- GraphEditorInputMode.allowGroupingOperations
- Enables or disables all grouping-related interaction features. They can be further configured with the other properties below. This property is disabled by default. When disabled, the other properties below have no effect.
- GraphEditorInputMode.allowGroupSelection
- Enables or disables the group selection shortcut Ctrl+G.
- GraphEditorInputMode.allowUngroupSelection
- Enables or disables the ungroup selection shortcut Ctrl+U.
- GraphEditorInputMode.allowAdjustGroupNodeSize
- Enables or disables the adjust group node size shortcut Ctrl+Shift ⇧+G.
In addition to these features, you can collapse and expand groups if folding is enabled.
Keyboard Input
Many interactive features that GraphEditorInputMode provides can be accessed via keyboard shortcuts, some of which are already mentioned shortly in the other sections. Keyboard shortcuts for nearly all predefined operations are part of their respective Commands. Central to handling them is KeyboardInputMode, which both GraphEditorInputMode and GraphViewerInputMode have as a child input mode. KeyboardInputMode allows to add custom actions with custom shortcuts and manages the input and action maps of GraphComponent accordingly which is discussed in Custom Command Bindings.
While tying a keyboard shortcut to a certain command is done in KeyboardInputMode, the actual implementation for that command often resides elsewhere. In this case it is usually GraphEditorInputMode that handles most commands.
Another feature is keyboard navigation and selection, which is handled by the child input mode NavigationInputMode by both GraphEditorInputMode and GraphViewerInputMode. It allows you to navigate between nodes with the arrow keys. Selecting nodes in a certain direction can be done with Shift ⇧+arrow keys and Ctrl+arrow keys moves the focus in a certain direction.
Mouse Clicks
GraphEditorInputMode and GraphViewerInputMode support notifications for left and right mouse clicks and double clicks on items. This is a convenience extension provided on top of the lower-level click events provided by ClickInputMode. ClickInputMode, however, can still be useful if you want to handle clicks regardless of whether they happen on an item or not.
There are no special events on GraphEditorInputMode, GraphViewerInputMode, or ClickInputMode which report middle mouse clicks. Instead you have to use the Clicked or the DoubleClicked event and check by means of its arguments if the middle button has triggered the event.
Both GraphEditorInputMode and GraphViewerInputMode handle clicks on items in the same way. If an item is clicked, it will be focused and selected, in that order. The behavior of clicks can be adjusted with a few properties on either GraphEditorInputMode or GraphViewerInputMode, and their child input mode ClickInputMode:
- GraphViewerInputMode.clickableItems
- GraphEditorInputMode.clickableItems
- The type of items that should be clickable. If an item is not clickable no events will be raised for that item and no default actions (focus and selection) will be taken.
- ClickInputMode.doubleClickPolicy
- How single clicks are reported when they are part of a double click. By default, two single click events followed by a double click event are raised.
Since clicking and selection are closely related, the properties that relate to both clicking and selection are discussed in Selection.
Further customization options for click handling are discussed in detail in Customizing Mouse Clicks.
Touch Gestures
When using touch devices, tapping the screen is processed in a similar fashion as mouse left-click events. The default gestures that are available with tapping are creating nodes and selecting items.
Despite its name, property GraphEditorInputMode.clickableItems will control the item types for which taps are handled as well. Acordingly, the GraphEditorInputMode or GraphViewerInputMode will dispatch an ItemClicked event for tapped items.
A more general handling of tap events is achieved with the low-level events on the TapInputMode which is a sub mode of both GraphEditorInputMode or GraphViewerInputMode.
There are also other more complex gestures with touch input, such as:
- Create edges via long press on node and then drag.
- With the same gesture, you can create bends on an edge.
- Panning und pinch/stretch zooming the viewport.
- Long press and drag on an empty canvas invokes the marquee selection.
Further customization options for touch handling are discussed in detail in Customizing Touch Gestures.
Selection
GraphComponent manages a set of selected items, as described in Selection, Focus, and Highlight. Both GraphEditorInputMode and GraphViewerInputMode offer support for interactively managing this selection. Selected items are used for many commands and interactions, such as clipboard commands, or deleting items.
Items can be selected in both GraphEditorInputMode and GraphViewerInputMode by simply left-clicking them. Selected items are highlighted with an item-specific selection indicator (e.g. a rectangle around a selected node).
When using a touch device, tapping on the device is equal to left-clicking in regards to selection. This means that in the following section, everything that is described as working with clicking will also work with tapping.
Selection in general and click selection in particular can be configured on GraphEditorInputMode and GraphViewerInputMode with a few properties:
- GraphViewerInputMode.selectableItems
- GraphEditorInputMode.selectableItems
- The types of items that can be selected (via any method).
- GraphViewerInputMode.selectablePredicate
- GraphEditorInputMode.selectablePredicate
- A predicate that controls what items can be selected. This allows finer control than just the item type above.
- GraphViewerInputMode.clickSelectableItems
- GraphEditorInputMode.clickSelectableItems
- The types of items that can be selected by clicking them.
clickSelectableItems can only constrain selectableItems further.
Multiple items can easily be selected at once with marquee selection or lasso selection. Both selection modes work by holding the left mouse button on an empty canvas area and dragging the mouse or long press and drag using touch devices. Marquee selection will show a rectangular area in which all items will be selected when the mouse button / touch pointer is released. Lasso selection will show a freehand path within which all items will be selected when the mouse button / touch pointer is released.
There is also a shortcut for selecting all items, Ctrl+A, as well as for deselecting all items again, Ctrl+Shift ⇧+A.
Lasso selection is disabled by default, in favor of marquee selection. However, you can simply enable the lassoSelectionInputMode on GraphViewerInputMode or GraphEditorInputMode. By default lasso selection takes precedence over marquee selection (via the respective priorities of the input modes), so enabling the lassoSelectionInputMode is enough to switch from marquee to lasso selection.
marqueeSelectableItems is an additional property that specifically controls what items can be selected by marquee or lasso selection.
You can customize marquee and lasso selection on GraphViewerInputMode and GraphEditorInputMode and their child input modes MarqueeSelectionInputMode and LassoSelectionInputMode:
- GraphViewerInputMode.marqueeSelectableItems
- GraphEditorInputMode.marqueeSelectableItems
- The types of items that can be selected via marquee or lasso selection.
- MarqueeSelectionInputMode.marqueeCursor
- The mouse cursor to use during the marquee selection gesture.
- MarqueeSelectionInputMode.pressedRecognizer
- MarqueeSelectionInputMode.pressedRecognizerTouch
- Changes the interaction to start marquee selection.
- LassoSelectionInputMode.lassoCursor
- The mouse cursor to use during the lasso selection gesture.
- LassoSelectionInputMode.validEndCursor
- The mouse cursor to use when hovering over the end point for the gesture (by default this is where the gesture started).
- LassoSelectionInputMode.prepareRecognizer
- LassoSelectionInputMode.prepareRecognizerTouch
- Changes the interaction to start lasso selection.
Marquee and lasso selection are available in GraphViewerInputMode, but disabled by default. You can enable either by setting the enabled property on GraphViewerInputMode’s marqueeSelectionInputMode or lassoSelectionInputMode. When enabled, both use Shift ⇧+drag as their default gesture to not clash with panning.
To select multiple items with more than one selection gesture, you can hold down the Ctrl key. Newly selected items will then be added to the selection instead of replacing it. This works with all selection interactions, be it click, marquee, or lasso selection.
Click selection also offers two other features: detail selection and cyclic selection. Detail selection can be used to explicitly select the topmost item under the mouse pointer, regardless of the current hit testing order. For example, by default when clicking a node the node will be selected, even when clicking on its label that is on top of the node. With detail selection, which by default uses Shift ⇧+click you can select the label when clicking it.
The clickHitTestOrder and doubleClickHitTestOrder properties determine by means of the item type which one will be considered when clicked or double-clicked if there are multiple items at a given location.
Cyclic selection on the other hand allows you to cycle through all possible hits at the click location by pressing the Alt key during the click. So, to stay with our example of a single node with a label on top of it, performing cyclic selection will first select the node, Alt-clicking the same location again will select the label. Now, if the node was in a group node, the selection order with cyclic selection would be node, group node, label, because the group node is below its child node and thus also exists at the click location.
Further customization options for click selection, as well as marquee and lasso selection are discussed in Customizing Selection. How the selection indicator’s visualization can be customized is explained in Styling Selection, Focus, and Highlight.
Focus
Similar to selection there is also the concept of a focused item. This item, usually a node, is shown with a dotted border and in many cases is also selected at the same time. Like selection, this focused item is supported by both GraphEditorInputMode and GraphViewerInputMode
The focused item is represented by GraphComponent’s currentItem property and is changed by clicking on a node or creating a new node via clicking on the canvas.
The focus indicator can serve two main purposes. It can be used to highlight a single item, e.g. in applications where the graph can’t be edited, but a single node can be selected for further information. The other purpose is selecting nodes one by one with the keyboard. The focus indicator can be moved by holding the Ctrl key and pressing an arrow key. Pressing Ctrl+Space will then select or de-select the focused node. This works similar to selecting files in many graphical file managers, e.g. Windows Explorer.
You can control what items can be focused interactively by changing the focusableItems property. To disable focusing an item completely, this property can be set to NONE.
How the focus indicator’s visualization can be customized is explained in Styling Selection, Focus, and Highlight.
Tooltips
Tooltips are small snippets of text shown when hovering the mouse pointer over a control. Usually, they explain in more detail what the control does. yFiles for HTML supports tooltips for all graph items with both GraphEditorInputMode and GraphViewerInputMode.
How tooltips can be configured and set up is discussed in detail in Customizing Tooltips.
Drag and Drop
GraphEditorInputMode supports drag and drop gestures as well, or rather, the drop part of the gesture. Drag and drop enables you to conveniently create applications that use a “palette” of items which can be dragged onto the canvas to create graph items.
You can drag elements from within the HTML document into a GraphComponent and drop them there. For nodes, labels, and ports this is handled by GraphEditorInputMode’s child input modes NodeDropInputMode, LabelDropInputMode, and PortDropInputMode, respectively. Since drag and drop functionality is usually different for each application (if needed at all), this mode is disabled by default.
With startDrag arbitrary HTML elements can be registered for a drag operation. By default, when the drag operation ends on a GraphComponent a new node will be created that is a copy of the dragged node.
This feature highly depends on the application implementation and requirements, so any further configuration and customization (including how to drag and drop your own data) is discussed in detail in Customizing Drag and Drop.
Drag and drop is supported by the following auxiliary interaction concepts:
Clipboard
GraphEditorInputMode provides support for the usual clipboard commands: Copy, Cut, and Paste. GraphViewerInputMode on the other hand, only provides support for Copy (as it cannot alter the graph). These commands also have the usual shortcuts:
Command | Shortcuts |
---|---|
The Copy and Cut operations are applied to the selected items. Cut can be thought of as a combined Copy and Delete. This has some implications, e.g. when cutting a node that has incident edges, only the selected node will end up in the clipboard, but since cutting deletes the item from the graph, the connected edges will simply be removed.
There is another command, Duplicate, which can be thought of as a combined Copy-Paste command, except it doesn’t modify the clipboard. You can duplicate the selected items simply by pressing Ctrl+D. Since this is also a clipboard operation, the cases described above apply, e.g. when duplicating an edge with only one connected node.
There are a few easy customizations for the clipboard provided on GraphViewerInputMode and GraphEditorInputMode:
- GraphViewerInputMode.allowClipboardOperations
- Enables or disables copying items.
- GraphEditorInputMode.allowClipboardOperations
- Enables or disables support for Cut, Copy, Paste, and Duplicate.
- GraphEditorInputMode.allowPaste
- Enables or disables pasting items.
- GraphEditorInputMode.pasteSelectableItems
- The types of items that should be selected after pasting.
- GraphEditorInputMode.pasteDelta
- The geometric offset between the mouse location and the location where the items should be pasted.
- GraphEditorInputMode.allowDuplicate
- Enables or disables duplicating items.
The GraphClipboard class offers another option:
- GraphClipboard.copyItems
- The types of items that can be copied and pasted.
The clipboard can be extensively customized in nearly all aspects, which is described in Customizing the Clipboard.
Undo and Redo
yFiles for HTML offers comprehensive support for undoing and redoing graph modifications. Everything that can be changed on a graph can be undone too. Such modifications can be single changes, e.g. adding a node, or composite changes where many items change at once, e.g. moving multiple items. There is no limit to how many operations can be undone, except available memory.
Keyboard shortcuts for Undo and Redo are provided by GraphEditorInputMode. Undo uses Ctrl+Z, and Redo can be invoked with Ctrl+Y.
Undo and Redo support is disabled by default. To turn it on you need to enable it on the
graph setting
undoEngineEnabled
to true
:
graph.undoEngineEnabled = true
Undo and Redo support on GraphEditorInputMode is automatically available when the underlying graph supports it and can be turned off using the allowUndoOperations property.
Changes that can be undone include both interactive and programmatic changes. This is useful when creating custom interactions that modify the graph, which can be undone by the user the same way as interactive changes.
You can extend Undo and Redo support to your own operations or data if needed, and extensively customize it as well. This is described in detail in Customizing Undo and Redo.
Snapping
When creating, moving, or resizing elements, snapping can provide so-called snap lines that capture the mouse pointer when near them. This makes it easy to align items, have nodes share the same size, etc.
Snapping is not turned on by default and consists of two different parts: snapping all items except labels, and snapping labels. To enable snapping, you need to set a GraphSnapContext on GraphEditorInputMode’s snapContext property as well as a LabelSnapContext on GraphEditorInputMode’s labelSnapContext property:
graphEditorInputMode.snapContext = new GraphSnapContext()
graphEditorInputMode.labelSnapContext = new LabelSnapContext()
Snapping is supported by the following interactions:
There are a few different snap lines, some of which are only active with certain interactions:
Border and center snap lines
These snap lines appear at the borders and centers of nodes and make it easy to align centers or a particular border of several nodes when moving or resizing them. Labels will also snap to those snap lines for label models that allow free movement.
Same size snap lines
These snap lines appear during resizing nodes when the width or height of the resized node matches the width or height of another node.
Same distance snap lines
These are snap lines that appear when moving nodes to indicate that the distance between the moved node and an adjacent node matches the distance between two other nodes on the same line. This provides an easy way to create graphs that look regular without having to configure a grid.
Grid snapping
yFiles for HTML also supports a grid, which enables snapping items to points at regular intervals. Grid snapping not only works for moving or resizing nodes, but also for creating edges and adding and moving bends.
Grid snapping has to be enabled explicitly by creating a suitable GridInfo object and activating grid snapping for various items on the GraphSnapContext:
const gridInfo = new GridInfo()
snapContext.nodeGridConstraintProvider = new GridConstraintProvider(gridInfo)
snapContext.bendGridConstraintProvider = new GridConstraintProvider(gridInfo)
snapContext.portGridConstraintProvider = new GridConstraintProvider(gridInfo)
Enabling grid snapping does not mean that the GraphComponent shows any grid visualization. You have to do that in addition:
graphComponent.backgroundGroup.addChild(
new GridVisualCreator(gridInfo),
ICanvasObjectDescriptor.ALWAYS_DIRTY_INSTANCE
)
How to configure and customize snapping is described in detail in Customizing Snapping.
Orthogonal Edge Editing
Orthogonal edge editing is a feature in GraphEditorInputMode that forces edge paths to only have right angles. While snapping gives some help to create and maintain orthogonal edge paths, it’s still time-consuming and unnecessary effort to do so manually when yFiles for HTML offers integrated support for most editing gestures to keep edges orthogonal. (Note that this doesn’t mean that it’s a decision between snapping or orthogonal edge editing — both features work very well together.)
Orthogonal edge editing is disabled by default. To enable it, you have to set an OrthogonalEdgeEditingContext on GraphEditorInputMode’s orthogonalEdgeEditingContext property:
graphEditorInputMode.orthogonalEdgeEditingContext = new OrthogonalEdgeEditingContext()
Orthogonal edge editing is an interactive feature that affects interactive creation and modification of graph elements. If you instead want to programmatically make all edges in a graph orthogonal, the more appropriate approach is an edge routing algorithm. Of course, the two features can both be used in the same application without a problem.
Orthogonal edge editing modifies a number of interactions so that edges stay orthogonal:
Edge creation, naturally, now only creates orthogonal edges. When starting an edge creation gesture, the rough direction in which the mouse is moved first will determine the direction of the first edge segment. If the mouse pointer is not moved exactly orthogonal, a bend will also be shown so that the edge ends at the mouse pointer. Since the first segment direction is not always the correct one on the first try, you can press Space to toggle between the two possible orientations as long as no explicit bend has been created yet.
Adding bends during edge creation is still done with the same gesture, except that implicit bends are also added whenever the current edge segment would not be orthogonal (as can be seen in the figures above).
Creating bends works rather differently when using orthogonal edge editing. Normally when creating a bend the gesture will, well, create a bend. However, with orthogonal edge editing this would always destroy the edge’s orthogonality. The best way to picture bend creation with orthogonal edge editing is actually to see it not as creating bends, but moving edge segments.
In case of the first or last edge segment the segment cannot move. Instead, a part of that segment is split off when dragging:
When dragging a segment so it coincides with another segment (essentially the reverse of the situation shown above), the bends that lie on straight line segments will automatically be removed. This is easier to achieve with snapping.
Deleting bends has special support to keep edges orthogonal by also removing one or two adjacent bends. This can be turned off individually with GraphEditorInputMode’s orthogonalBendRemoval property.
Moving items, most notably nodes, will also keep edges orthogonal. When nodes are moved an incident segment and bend will move with them to keep that segment orthogonal. If there is no adjacent bend, the edge will be broken up in a similar way as when dragging the edge segment itself.
When bends are moved, their incident edge segments will stay orthogonal as well by moving adjacent bends appropriately. If an incident segment is the first or last segment, it will be broken up in a similar manner to moving that segment.
Resizing nodes acts very similar to moving nodes because the end points of incident edges change in a very similar way.