graph.addNodeCreatedListener(callback)
Migrating to 3.0 from 2.6
yFiles for HTML 3.0 introduces a comprehensive revision of many parts of the API. Unlike previous major releases, where we prioritized backward compatibility, this version removes technical debt to provide a more intuitive, consistent, and streamlined experience. The result is a more modern and efficient API that simplifies development.
However, this also results in many incompatible changes for existing projects. This chapter describes of the most significant changes in more detail and helps with the migration. For a complete list of changes, refer to the changelog.
Many changes can be found in the layout part of the library. These changes include major renamings, changed default values, and removed API. In addition, there have been major changes to basic layout concepts including, among others, the graph model, the handling of ports, the maximum duration/abort handling, the scope of affected elements, and the handling of grouped graph structures.
This chapter also contains layout-algorithm-centric sections that summarize the main changes to individual algorithms, such as the Hierarchic Layout, Organic Layout, Tree Layout, Orthogonal Layout, Edge Router, and Generic Labeling.
New RenderTree and IObjectRenderer API
The new renderTree property on the CanvasComponent now encapsulates all low-level render object related API. Previously, these APIs were directly available on the CanvasComponent. This affects the following members on CanvasComponent:
-
Property backgroundGroup
-
Property contentGroup
-
Property focusGroup
-
Property highlightGroup
-
Property inputModeGroup
-
Property rootGroup
-
Property selectionGroup
-
Property renderOrderComparator
-
Method getElements
In addition, the ICanvasObject
interface and related types have been renamed and slightly adjusted.
In particular:
yFiles for HTML 2.6 | yFiles for HTML 3.0 |
---|---|
|
|
|
|
|
|
|
Additional Changes
-
The new foregroundGroup on the RenderTree handles the rendering of foreground elements.
-
The new
createElement
methods on RenderTree add elements to the CanvasComponent for rendering. -
The
ICanvasObjectInstaller
has been removed in favor of the simpler IObjectRenderer<TRenderTag>. -
Removed the "changed" events for the render groups.
-
Removed previously protected creation methods for the render groups.
-
Removed constant
ICanvasObjectDescriptor
instances onICanvasObjectDescriptor
in favor of new RenderTreecreateElement
methods-
Constant
ICanvasObjectDescriptor.ALWAYS_DIRTY_INSTANCE
-
Constant
ICanvasObjectDescriptor.ALWAYS_DIRTY_LOOKUP
-
Constant
ICanvasObjectDescriptor.ALWAYS_DIRTY_VISUAL
-
Constant
ICanvasObjectDescriptor.DYNAMIC_DIRTY_INSTANCE
-
Constant
ICanvasObjectDescriptor.DYNAMIC_DIRTY_LOOKUP
-
Constant
ICanvasObjectDescriptor.VISUAL
-
Constant
ICanvasObjectDescriptor.VOID
-
-
Removed class
VoidVisualCreator
from the public API. An instance can be obtained from VOID_VISUAL_CREATOR. -
The more versatile IObjectRenderer<TRenderTag> replaces the previous
IVisualTemplate
such thatVisualTemplate
was removed from the API. Related resource keys are removed, and usages should be replaced with arenderer
property on the related type.
Events and Event Registration
Note
|
This migration can be performed automatically using the migration tool. |
The event registration system for event listeners has been updated to align with the DOM model, transitioning to a standardized approach.
New Event Registration Methods
Component |
Description |
Method Name |
|
Syntax |
|
Component |
Description |
Method Name |
|
Syntax |
|
Method Parameters
- eventName
-
String specifying the event type
- callback
-
Function to be called when the event triggers
- options
-
Optional object with configuration settings
The
options
object can have the following properties: *once
- When true, the listener is automatically removed after the first time it is triggered. *signal
- AnAbortController
signal
that can be used to manage the listener’s lifecycle.
Benefits
-
Simplification: A single method handles all events.
-
Flexibility: Supports single-use listeners.
-
Control: Offers enhanced listener management through the AbortController.
Migration Example
graph.addEventListener('node-created', callback)
Migration Steps
-
Replace specific listener methods with
addEventListener
. -
Convert event names to lowercase and use dashes as separators.
-
Add an options object when needed.
Callback Signature Changes
Old Signature |
New Signature |
|
|
graph.addNodeCreatedListener((sender, eventArgs) => {
// handle node creation
})
graph.addEventListener('node-created', (eventArgs) => {
// handle node creation
})
Important Notes
-
The
sender
argument has been moved to after theevent
argument in callbacks. -
Event handling now focuses directly on
event
arguments, which can conveniently be destructured, and thesender
can be omitted. Typically, thesender
is in the closure of the method definition anyway. -
This follows standard DOM event model conventions.
-
An automatic migration is available via the migration tool.
-
You can find more information about events in the Events section.
Mouse and Touch Events
yFiles for HTML 3.0 introduces a unified input event handling system using PointerEventArgs.
This replaces the separate MouseEventArgs
and TouchEventArgs
classes.
This new class handles mouse, touch, and pen inputs, simplifying event handling and reducing code duplication.
PointerEventArgs provides properties to identify the source of the event (mouse, touch, or pen) and access the specific input data for each.
Pointer Type
The PointerEventArgs class provides the pointerType property, which allows you to identify the type of device that triggered the event. The pointerType property is of type PointerType enum, which has the following possible values:
You can use this property to tailor your event handling logic based on the input device. For example:
graphComponent.addEventListener('pointer-move', (evt: PointerEventArgs) => {
if (evt.pointerType === PointerType.MOUSE) {
// Handle mouse-specific logic
console.log('Mouse move event')
} else if (evt.pointerType === PointerType.TOUCH) {
// Handle touch-specific logic
console.log('Touch move event')
} else if (evt.pointerType === PointerType.PEN) {
// Handle pen-specific logic
console.log('Pen move event')
}
})
The eventType property (of type PointerEventArgs) provides even more specific information about the event:
-
ENTER: The pointer has entered the component’s bounds.
-
MOVE: The pointer has been moved.
-
DOWN: A pointer becomes active.
-
DRAG: The pointer has been dragged, which means it has been moved while at least one button has been pressed.
-
UP: A pointer button/state is no longer down.
-
CLICK: A pointer click or touch/pen tap has been recognized.
-
WHEEL: The mouse wheel has been turned.
-
LEAVE: The pointer has exited the component’s bounds.
-
DRAG_CAPTURE_LOST: Input capture has been lost while the pointer was dragging.
-
LONG_PRESS: A long press has been recognized.
-
LONG_REST: A long rest has been recognized.
-
NONE: Not a pointer event.
Direct Property Access
PointerEventArgs provides direct access to properties specific to different input types. This includes:
-
pointerSize: A Size object representing the width and height of the pointer’s contact area (for touch events).
-
pressure: A number between 0 and 1 representing the normalized pressure of the pointer input (for pen events).
-
pointerId: A unique identifier assigned to the pointer causing the event, replacing the
TouchDevice
object from the oldTouchEventArgs
. -
isPrimary: Indicates if the pointer represents the primary pointer of this type.
Enhanced Gesture Handling
The PointerEventArgs simplifies gesture handling by providing a unified event stream for all input types. You can use the pointerType and eventType properties to create flexible gesture recognizers that work with mouse, touch, and pen input.
Mapping Previous API to New
The following table shows how to map properties from the old MouseEventArgs
and TouchEventArgs
classes to the new PointerEventArgs class:
Old Class | Property | New Class | Property | Notes |
---|---|---|---|---|
|
|
Use the |
||
|
|
Use the |
||
|
|
|||
|
|
|
||
|
|
|||
|
|
originalEvent. |
Check if originalEvent is a WheelEvent first. |
|
|
|
Use the PointerEventType enum. Note the different values. |
||
|
|
|||
|
|
Use the ModifierKeys enum. |
||
|
|
May be |
||
|
|
Not available |
Removed. Use |
|
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
pointerId, |
||
|
|
Use the PointerEventType enum. Note the different values. |
||
|
|
|||
|
|
|||
|
|
May be |
||
|
|
clickCount works for mouse clicks, touch taps, pen taps, and any other possible "button" interaction. |
PointerButtons Enum Mapping
The PointerButtons enum now encompasses states for mouse, pen, and touch inputs. Here’s how the old values map to the new enum:
Old Value | Description | New Enum (PointerButtons) | Notes |
---|---|---|---|
|
The left mouse button. |
Remains the same. |
|
|
The middle mouse button. |
Remains the same. |
|
|
The right mouse button. |
Remains the same. |
|
|
Extra mouse button 1. |
Remains the same. |
|
|
Extra mouse button 2. |
Remains the same. |
|
|
No button or state is active. |
Remains the same. |
|
n/a |
The touch device (finger) has contact with the input device. |
Indicates that a finger is touching the surface. |
|
n/a |
Pen has the barrel button pressed. |
Use this to detect the barrel button press on a pan. |
|
n/a |
The PEN device has contact with the input device. |
Indicates that the pen is touching the surface. |
|
n/a |
Pen has the eraser button pressed, or it is used upside-down. |
Use this to detect eraser functionality. |
Example: Migrating a Mouse Move Handler
graphComponent.addMouseMoveListener((sender, evt: MouseEventArgs) => {
const worldLocation = evt.location
console.log(`Mouse moved to: ${worldLocation.x}, ${worldLocation.y}`)
})
graphComponent.addEventListener('pointer-move', (evt: PointerEventArgs) => {
if (evt.pointerType === PointerType.MOUSE) {
const location = evt.location
console.log(`Mouse moved to: ${location.x}, ${location.y}`)
}
})
Example: Migrating a Touch Tap Handler
graphComponent.addTouchTapListener((sender, evt: TouchEventArgs) => {
const worldLocation = evt.location
console.log(`Touch tapped at: ${worldLocation.x}, ${worldLocation.y}`)
})
graphComponent.addEventListener('pointer-click', (evt: PointerEventArgs) => {
if (evt.pointerType === PointerType.TOUCH) {
const worldLocation = evt.location
console.log(`Touch tapped at: ${worldLocation.x}, ${worldLocation.y}`)
}
})
Pressure-sensitive Drawing
You can use the pressure property to change thickness or opacity of the created element based on the pressure applied by a pen:
graphComponent.addEventListener('pointer-drag', (evt: PointerEventArgs) => {
if (evt.pointerType === PointerType.PEN) {
const strokeThickness = evt.pressure * 5 // Scale pressure to a thickness value
// ... use strokeThickness to draw the line ...
}
})
Enhanced Touch Interactions
The pointerSize property can be used to create more realistic touch interactions. For example, you could adjust the size of an element based on the size of the touch contact area.
graphComponent.addEventListener('pointer-drag', (evt: PointerEventArgs) => {
if (evt.pointerType === PointerType.TOUCH) {
const touchWidth = evt.pointerSize.width
const touchHeight = evt.pointerSize.height
// ... adjust element size based on touchWidth and touchHeight ...
}
})
Compatibility Considerations
-
scrollAmount
: ThescrollAmount
property fromMouseEventArgs
is no longer directly available. If needed, you can access the originalEvent (the native DOM event) to get this information. -
Event Registration: Event registration has changed to DOM-style event registration using lowercase-dashed names for the event type. See the event registration section and the example below:
graphComponent.addMouseDownListener((sender, mouseEventArgs) => {
// handle mouse down
})
graphComponent.addEventListener('pointer-down', (evt: PointerEventArgs) => {
// handle node creation
if (evt.pointerType === PointerType.MOUSE) {
}
})
-
Event Listeners: Make sure that you replace all
addMouseMoveListener
,addMouseUpListener
,addMouseDownListener
,addTouchMoveListener
,addTouchTapListener
, etc., calls with theiraddEventListener
equivalents. Adapt the event registration as shown above. The "type" parameter is the lowercase-dashed name of the event type. You can do this automatically using the migration tool.
User Interaction Changes
The default user interactions have been updated. We have carefully updated keyboard shortcuts and default gestures to align with the standards found in many popular drawing and design applications like PowerPoint and Photoshop. If you have made only few customizations, the changes will be incompatible but likely beneficial.
Depending on your application, you may want or need to migrate your existing behavior to the new release. Reverting the behavior to match the old defaults is possible but requires different steps depending on the type of change.
Reverting Default Gestures in GraphEditorInputMode
The most noticeable change in GraphEditorInputMode is how elements are moved interactively. In version 2.6, you had to explicitly enable the option that allowed users to move elements without selecting them first. This is now the default behavior and can be disabled or controlled using the movableUnselectedItems property.
To continue supporting edge creation, the way edge creations are initiated has changed. Users now hover over a node to display the port candidates. Then, they can start dragging a new edge from a candidate, even if the node is selected. You can revert to the old behavior by setting startOverCandidateOnly to false
, disabling moveUnselectedItemsInputMode, and assigning a higher priority to moveSelectedItemsInputMode.
const geim = new GraphEditorInputMode({
createEdgeInputMode: { priority: 110, startOverCandidateOnly: false,
showPortCandidates: 'end' },
moveSelectedItemsInputMode: { priority: 100 },
moveUnselectedItemsInputMode: { enabled: false }
})
In version 2.6, it was not intuitive for users on touch devices to cancel an edge creation gesture that was
started by accident. By default, moving back to the start node without creating enough bends now cancels edge creation
instead of creating a self-loop. You can revert to the old behavior by setting
minimumSelfLoopBendCount to 0
.
In version 2.6, this property is set to 2
by default.
Changed Keyboard Shortcuts
Most keyboard shortcuts in yFiles for HTML are configured via the yfiles.resources
object, as explained in Customizing String Resources.
With yFiles for HTML 2.6, a number of changes were implemented:
-
Keyboard Shortcut Changes: There were significant changes in keyboard shortcuts, especially for navigation and group manipulation (
CollapseGroupKey
,EnterGroupKey
,ExitGroupKey
,ExpandGroupKey
,ToggleExpansionStateKey
).Ctrl
was changed toControl
where appropriate. -
Arrow Keys Constant Names: The simple direction keys (
Up
,Down
,Left
,Right
) have been replaced withArrowUp
,ArrowDown
,ArrowLeft
, andArrowRight
. -
Hierarchy Navigation: New keys have been added for extending selection and moving focus through a hierarchical structure.
-
UpdateContentRect Key Renamed: The key
UpdateContentRect
has been renamed toUpdateContentBounds
. -
Stripe Insets Key Renamed: The keys
SetStripeInsets.RedoName
andSetStripeInsets.UndoName
have been renamed toSetStripePadding.RedoName
andSetStripePadding.UndoName
.
The names of the shortcut modifiers have been adjusted. If you have customized them, replace Ctrl
with Control
.
Key | Old Value | New Value |
---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
To revert to the original shortcut, set the property to the "old value."
yfiles.resources["invariant"]["ExtendSelectionUpKey"] = "Control+ArrowUp"
Key | Value |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
delete yfiles.resources["invariant"]["IncreaseZoomKey"]
Theming
The Theme
class and ThemeVariant
enum have been removed. You can now change the theming through CSS classes.
Old Theme property |
New yfiles-canvascomponent CSS class |
Default | Notes |
---|---|---|---|
|
|
#000000 |
|
|
|
#3399ff |
|
|
|
#ffffff |
|
|
|
round-hatched |
Possible values: |
|
|
1 |
|
|
n/a |
Removed. Set |
|
|
n/a |
Removed. Set |
|
n/a |
|
2 |
New. This offset prevents handles from overlapping ports. |
n/a |
|
2 |
New |
ThemeVariant.CLASSIC
has been removed and has no CSS replacement.
Migration Example
graphComponent.theme = new Theme({ scale: 2 })
<div id="graphComponent" style="--yfiles-theme-scale: 2"></div>
graphComponent.style.setProperty('--yfiles-theme-scale', '2')
For more about theming, refer to the Themes section.
Migrating WebGL2 Styles
Note
|
The renamings shown below can be done automatically with the help of the migration tool. |
In this release, WebGL2 styles now implement the standard interfaces:
This integration enables seamless usage with standard IGraph API methods and infrastructure.
The following features now work directly with WebGL styles and no longer require special handling:
-
Building Graphs
-
Defaults configuration
-
Undo functionality
-
Clipboard operations
-
Serialization
-
Folding support
Note
|
These changes will simplify your codebase by eliminating the need for special handling of WebGL styles. |
-
Remove any special handling for WebGL styles.
-
Use standard style interfaces when specifying styles during:
-
Node creation
-
Edge creation
-
Label creation
-
-
Apply WebGL style instances directly in or during:
-
Element creation
-
Factories
-
Defaults
-
-
Instead of obtaining the WebGL style from WebGLGraphModelManager, obtain the style directly from the
.style
property of the elements.
Tip
|
Treat WebGL styles just like any other style in your application. No special considerations are required. |
const node = graph.createNode({
style: new WebGLShapeNodeStyle({
fill: '#242265',
effect: 'ambient-stroke-color',
stroke: '3px dashed orangered',
shape: 'hexagon',
})
})
graph.nodeDefaults.style = new WebGLImageNodeStyle(someImageData)
graphComponent.inputMode = new GraphEditorInputMode({
createEdgeInputMode: {
edgeDefaults: {
style: new WebGLArcEdgeStyle(
{ stroke: "3px solid darkblue", height: 20, fixedHeight: true }
)
}
}
})
Level of Detail Rendering with WebGL and Non-WebGL styles
For applications that dynamically switch between WebGL mode and SVG/HTML/Canvas rendering, the WebGL styles are automatically mapped to visually similar SVG-based styles. When using level of detail rendering and custom styles are desired in SVG mode, a convenience implementation is available. This implementation implements the corresponding style interface, allowing you to specify both the WebGL and the non-WebGL style instance.
const node = graph.createNode({
style:
new WebGLNodeStyleDecorator(
myCustomNodeStyle,
new WebGLImageNodeStyle(someImageData)
)
})
WebGL API Changes in yFiles for HTML 3.0
Most types that had a WebGL2
prefix now have the 2
removed from their name.
Note
|
WebGL2Visual still has the WebGL2 prefix, as there already is a WebGLVisual, that is used for working with WebGL 1.
|
2.6 API | 3.0 API |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Clipboard API
Note
|
The renaming aspects of the migration below can be performed automatically using the migration tool. |
GraphEditorInputMode Event Changes
The following events now use ItemsEventArgs and have their names adjusted. See Events and Event Registration for details on how events are handled in 3.0.
-
elementsCut
→items-cut
-
elementsCopied
→items-copied
-
elementsPasted
→items-pasted
-
elementsDuplicated
→items-duplicated
-
deletedSelection
→deleted-selection
Changes of IClipboardHelper
-
Added methods to support
duplicate
:-
shouldDuplicate: Determines whether duplication is supported.
-
onDuplicated: Handles the duplication of items.
-
-
Renamed methods:
-
Changes to method signatures:
-
cut
andcopy
no longer return an object. If you need to pass information between cut/copy and paste, store that information in your implementing class (onthis
). -
Removed object parameter from
paste
and shouldPaste. Get the information from the instance (this
).
-
GraphClipboard
-
Now uses the specialized ClipboardGraphCopier instead of the general GraphCopier
-
Added the static member DEFAULT_GRAPH_CLIPBOARD, which is the clipboard shared by all GraphComponent instances if no other instance is specified.
-
paste now accepts an optional
pasteLocation
parameter specifying the center of the bounds of the pasted items. -
Members of GraphClipboard with "Element" in their name that referred to model items were renamed to use "Item" instead.
-
The following properties have been changed:
-
empty
has been renamed to isEmpty -
pasteDelta
has been renamed to pasteOffset -
isDummy
has been renamed to isHelper -
clipboardGraph is now read-only
-
-
The following methods have been removed; use the property setters instead:
-
createClipboardGraph
-
createToClipboardCopier
-
createFromClipboardCopier
-
createDuplicateCopier
-
createDefaultClipboardIdProvider
-
getMemento
-
getClipboardHelper
-
Folding API
Note
|
These renaming aspects of the migration below can be performed automatically using the migration tool. |
Core Changes
-
Simplified configuration of edges at folder nodes.
-
Allow propagation of property changes of elements in the folding state back to the master configurations.
-
Enhanced default implementation for folder nodes and folding edge converters.
-
Collapsed group nodes can now have different tags from their expanded form.
Interface Updates
IFolderNodeConverter
-
Added a new updateGroupNodeState method to propagate changes from the folder node back to the corresponding group node.
-
The
DefaultFolderNodeConverter
(renamed to FolderNodeConverter) now uses FolderNodeDefaults to manage state configuration. The FolderNodeDefaults API has a structure similar to the INodeDefaults interface. For each node aspect (ports, labels, port labels), you can configure whether changes are synchronized in either direction.
IFoldingEdgeConverter
-
Added a new updateMasterEdges method to propagate changes from the folding edge back to the edges it represents.
-
Both
DefaultFoldingEdgeConverter
(renamed to FoldingEdgeConverter) and MergingFoldingEdgeConverter now use FoldingEdgeDefaults to manage state configuration. The FoldingEdgeDefaults API has a structure similar to the IEdgeDefaults interface. For each edge aspect (ports, labels), you can configure whether changes are synchronized in either direction.
Behavior Changes
-
In folding view graphs,
createGroupNode
always creates a group, regardless of the isExpanded predicate. -
Changes to view states can be reflected back to master items using:
-
updateGroupNodeState for folder nodes
-
updateMasterEdges for folding edges
-
Note
|
To respect the isExpanded predicate, create the group node in the master graph instead of the folding view graph. |
GraphML
Core Changes
-
Reflection metadata for types and properties has been completely reworked. Instead of using
$meta
annotations in a class declaration, you should now provide type metadata through external annotations. This also affects how markup extensions are registered. The attribute classesGraphMLAttribute
andTypeAttribute
have been removed as well. -
Other configuration and customization of GraphML I/O has been simplified. All configuration should now be done through the GraphMLIOHandler class.
API changes
Changes to class GraphMLIOHandler
The following classes, methods, and properties have been removed. Their functionality has been replaced by reasonable default values or moved to application logic:
-
Properties
writeSharedReferences
andwriteXMLSchema
: These are now always enabled. -
Method
addInputHandlerFactory
and the interfaceIGenericInputHandlerFactory
: This functionality should now be implemented as part of the application logic. -
Method
addInputMapperFuture
and the classFuture
: This functionality should now be implemented as part of the application logic. -
Methods
addRegistryInputMapper
andaddRegistryOutputMapper
: You need to manage the association between attribute names and IMapper<K,V> instances as part of the application logic.
The following classes, methods, and properties have been removed. Their functionality is now provided by the listed alternatives:
-
Protected methods
configureDeserializationHandlers
,configureSerializationHandlers
,configureInputHandlers
, andconfigureOutputHandlers
have been removed. All protectedhandle*Serialization
,handle*Deserialization
,register*InputHandler
, andregister*OutputHandler
methods have been removed as well. Use the correspondinghandle-deserialization
,handle-serialization
,query-input-handlers
, andquery-output-handlers
events instead to configure additional input or output features or enable or disable predefined features. -
All other protected
configure*
methods have been removed. Use the new methods configureParseContext and configureWriteContext or the providedSerializationProperties
instead. -
All protected
on*
methods that raised an event have been removed. Subscribe to the corresponding event instead.
Changes to support classes and interfaces
-
Classes
GraphMLParser
andGraphMLWriter
and their creation and configuration methods on GraphMLIOHandler have been removed. All I/O configuration should now happen through class GraphMLIOHandler. -
Enums
GraphMLSharingPolicy
andSharingState
and the interfacesIReferenceHandle
andIReferenceHandler
have been removed. All reference handling is now performed by the framework. -
Interfaces
IGraphElementIdAcceptor
andIGraphElementIdProvider
have been removed. Use GRAPH_ELEMENT_IDS and GRAPH_IDS instead. -
Class
XmlWriter
has been removed. Use the instance of IXmlWriter that is provided by the write context instead. -
Helper class
GraphMLSupport
and enumStorageLocation
have been removed. This functionality should now be implemented as part of the application logic.
Changes to the file format
-
The default XML namespaces have changed:
-
Most types that were in the
http://www.yworks.com/xml/yfiles-common/3.0
XML namespace have been moved to thehttp://www.yworks.com/xml/yfiles-common/4.0
XML namespace. A few types that are needed for basic compatibility with other platforms remain in the old namespace. -
All types that were in the
http://www.yworks.com/xml/yfiles-for-html/2.0/xaml
XML namespace have been moved to thehttp://www.yworks.com/xml/yfiles-for-html/3.0/xaml
XML namespace
-
-
Changes to the object representation:
-
Most changes to types and properties are reflected in the corresponding GraphML representation. A few types and properties that are needed for basic compatibility with other platforms retain their old GraphML representation.
-
Note
|
The
|
Noteworthy Layout Changes
Changed Names
Many API members have been renamed to achieve better consistency and uniformity throughout the entire API. The following tables list major renamings of algorithm/stage classes and other important classes. Warning: It is not a complete listing of name changes!
Note
|
This chapter presents renamings of more general concepts with respect to layout algorithms. For migration help with specific algorithms, please refer to the respective chapters (e.g., Hierarchical Layout). |
yFiles for HTML 2.6 | yFiles for HTML 3.0 |
---|---|
BalloonLayout |
|
BendConverter |
|
CactusGroupLayout |
|
EdgeBundlingStage |
|
FixNodeLayoutStage |
|
GivenCoordinatesStage |
|
GraphLayoutLineWrapper |
|
HideGroupsStage |
|
HierarchicLayout |
|
OrientationLayout |
|
PolylineLayoutStage |
|
SubgraphLayout |
|
TemporaryGroupNodeInsertionStage |
yFiles for HTML 2.6 | yFiles for HTML 3.0 |
---|---|
AbortHandler |
|
*EdgeLayoutDescriptor classes |
|
maximumDuration properties |
Properties are now named stopDuration, e.g., stopDuration |
*NodeLayoutDescriptor classes |
|
NodeAggregationAlgorithm |
|
NodeHalo |
Class removed. Properties are now named NodeMargins and are of type Insets |
PartitionGrid |
|
ColumnDescriptor |
|
RowDescriptor |
|
PartitionCellId |
Changed Default Values
The following table lists the most important changes to default values.
Feature | Default in yFiles for HTML 2.6 | Default in yFiles for HTML 3.0 | Notes |
---|---|---|---|
Routing style of Hierarchical Layout |
Polyline |
Orthogonal |
Can be changed via property routingStyleDescriptor |
ComponentLayout style in classes CircularLayout, OrganicLayout, RadialLayout, RadialTreeLayout (Balloon), RadialGroupLayout |
Can be changed via property style |
||
Placement of edge labels |
Often ignored |
Labels are always handled |
Settings are controlled via properties of enum type, for example, edgeLabelPlacement |
Consideration of node labels |
Often ignored |
Labels are always considered |
Settings are controlled via properties of enum type, for example, nodeLabelPlacement |
|
|
Now, empty group nodes are not resized. |
Removed API
Important API members that are no longer part of yFiles for HTML 3.0 are listed in table Removed layout API members. Warning: this is not a complete list of removed API members!
Member | Replacement in yFiles for HTML 3.0 |
---|---|
Algorithm classes with static methods (e.g. Centrality, ShortestPaths) |
All algorithms available to be run directly on the LayoutGraph are now collected in class LayoutGraphAlgorithms. |
AspectRatioTreeLayout |
TreeLayout with subtree placer AspectRatioSubtreePlacer. |
BufferedLayout |
|
BusRouter |
Bus routing feature of EdgeRouter via property EdgeRouterData<TNode, TEdge, TNodeLabel, TEdgeLabel>.buses. |
ChannelEdgeRouter (including OrthogonalSegmentDistributionStage and OrthogonalPatternEdgeRouter) |
To configure the EdgeRouter to generate a similar style, set the stopDuration property to zero and use the predefined cost configuration LOW_QUALITY. |
ClassicOrganicLayout |
It is superseded by the more powerful OrganicLayout. |
ClassicTreeLayout |
|
CompactOrthogonalLayout |
Use OrthogonalLayout or, for more compact results, consider using HierarchicalLayout with low distance settings. |
FamilyTreeLayout |
None |
FixPortLocationStage |
To correct the port locations after applying a layout, use the class PortPlacementStage. |
GraphTransformer |
Factory methods on class LayoutTransformations provide stages with the same functionality. |
HandleNaNCoordinatesStage |
None |
IDataProvider |
The generic IMapper<K,V> interface. |
LayoutMultiplexer |
The features of ComponentLayout or RecursiveGroupLayout |
MultiStageLayout |
Stages are now configured on layout algorithms via the property |
NodeHalo |
Halos are now specified as insets in the corresponding layout data (e.g. nodeMargins). |
NormalizeGraphElementOrderStage |
|
SingleCycleLayout |
The CircularLayout with partitioning policy SINGLE_CYCLE can be used instead. |
SnapOuterPortsToNodeBorderStage |
Layout Data
The LayoutData<TNode,TEdge,TNodeLabel,TEdgeLabel> used to specify custom data input for layout algorithms has become generic. It can no longer only be applied in conjunction with IGraph but also with LayoutGraph. This change means that the classes now have several generic type arguments that describe the type of items in the graph. See for example HierarchicalLayoutData.
Migrate existing usages
Instead of directly instantiating the data, you can now use the new factory methods on the algorithm instance, for example, createLayoutData.
const iGraph = new Graph()
const hierarchicalLayout = new HierarchicalLayout()
// create layout data for IGraph using factory method
const data = hierarchicalLayout.createLayoutData()
// ... and example usage of the created data
data.incrementalNodes.predicate = (iNode: INode) =>
iNode.labels.size > 0
iGraph.applyLayout(hierarchicalLayout, data)
Using the creation methods is often more convenient. However, creating the layout data via the constructor is still possible.
// create layout data for IGraph using constructor
const data = new HierarchicalLayoutData<
INode,
IEdge,
IModelItem,
ILabel,
ILabel
>()
You can now use the layout data when working with LayoutGraph in the same way.
const layoutGraph = new LayoutGraph()
const hierarchicalLayout = new HierarchicalLayout()
// create layout data for layoutGraph using factory method
const data = hierarchicalLayout.createLayoutData(layoutGraph)
// ... and example usage of the created data
data.incrementalNodes.predicate = (node: LayoutNode) =>
node.labels.size > 0
layoutGraph.applyLayout(hierarchicalLayout, data)
Further changes
-
Settings related to ports are now all grouped within a sub-data structure. This structure is a top-level property on the respective layout data. For example, see HierarchicalLayoutData<TNode, TEdge, TNodeEdge, TNodeLabel, TEdgeLabel>.ports.
-
Layout data properties that are not intended for user input but provide an output or result now include "Result" as a suffix. For example, see layerIndicesResult.
Layout Scope and Affected Items
The scope of a layout algorithm defines which graph elements are affected by the algorithm. yFiles for HTML 3.0 offers a more uniform scope API, designed to simplify the configuration of common use cases.
Restricting the Scope
The properties for restricting the scope of layout algorithms have been unified and, where possible, moved to the layout data. These layout data classes now offer a scope property, e.g., EdgeRouterData.scope, that supports any convenience that was previously offered on the layout algorithms, such as restricting affected edges by specifying incident nodes.
const edgeRouter = new EdgeRouter()
const edgeRouterData = edgeRouter.createLayoutData()
edgeRouterData.scope.incidentNodes.source = graphControl.selection.nodes
Convenience features that depend on an intermediate state of the layout, such as the EdgeRouter only handling broken paths, can now be assigned for individual elements through the Scope property.
edgeRouterData.scope.edgeMapping.mapperFunction = (edge: IEdge) =>
edge.tag === 'Route if necessary'
? EdgeRouterScope.PATH_AS_NEEDED
: EdgeRouterScope.IGNORE
The GenericLabeling algorithm is a notable exception to this general rule. While it supports the same ways of specifying the affected labels, it also retains functionality to restrict the algorithm to EdgeLabels or NodeLabels only on the labeling algorithm itself, since this use case was common enough to warrant a deviation from the norm. This convenience can theoretically be combined with a custom selection specified via the labeling data’s scope property to further restrict the affected labels. However, in such cases, it would be simpler and more maintainable to fully specify the scope on the layout data.
const genericLabeling = new GenericLabeling()
genericLabeling.scope = 'edge-labels'
Shared Scopes
In a layout pipeline that consists of multiple layout stages, it is often necessary for all algorithms to operate on the same subset of graph elements. Consequently, yFiles for HTML 3.0 introduces a single scope that only has to be set once for all layout algorithms. This replaces the individual scope-related data keys on the layout algorithms and affects all simple boolean states configurable through the layout data’s Scope properties, as well as values registered directly with the layout graph using the LayoutKeys:
As a result, writeable DataKeys such as RecursiveGroupLayout.InterEdgesDpKey
and EdgeRouter.AffectedEdgesDataKey
,
that previously had to be manually synchronized to enable communication between the algorithms, are no longer necessary and were
removed in yFiles for HTML 3.0. The communication between algorithms is now established automatically, using the
new shared scope information.
However, scope information that relies on conditions more complex than a boolean value, such as OrganicScope, is still associated specifically with the corresponding layout algorithm.
For use cases where layout stages of the same layout pipeline must operate on different scopes, the ContextModificationStage can be used to temporarily change the data associated with any of the layout keys mentioned above, or even to temporarily apply an alternative layout data.
Ports in Layout
General
In yFiles for HTML 3.0, the former concepts of PortConstraints
and PortCandidates
have been combined into a single,
more powerful concept. A possible port (that is, the side or even the exact location where an edge connects to its source or target) is now represented by the class LayoutPortCandidate.
Additionally, the valid sides of ports are now specified using the property side.
The previous basic side values North
, South
, West
, and East
, provided by the enum PortSide
have been renamed to TOP, BOTTOM, LEFT, and
RIGHT, and are now defined in the enum PortSides.
The LayoutPortCandidate instances are typically not created directly but are instead part of NodePortCandidates (which are related to the former concept of PortCandidateSets
) and EdgePortCandidates (which are related to the former concept of lists of PortCandidates
).
Most LayoutData classes for the major layout algorithm now have a ports property (for example,
HierarchicalLayoutData.ports) that offer access to a new sub-data of type BasicPortData or PortData.
These classes enable easy specification of port-related data for edges and nodes.
Using class EdgePortCandidates demonstrates how to achieve this for different edges, and
Using class NodePortCandidates shows how to specify the valid ports provided by a node.
// create the layout algorithm and the corresponding layout data instance
const layout = new HierarchicalLayout()
const data = layout.createLayoutData(graph)
// the 'ports' sub-data provides all port-related data;
// we want to specify the ports of edges on both endpoints (source and target)
const spcMapper = data.ports.sourcePortCandidates.mapper
const tpcMapper = data.ports.targetPortCandidates.mapper
// the source port of edge e1 should be at the center on the right side
// and the target port on the top or bottom side
spcMapper.set(
e1,
new EdgePortCandidates().addFixedCandidate('right', new Point(15, 0))
)
tpcMapper.set(
e1,
new EdgePortCandidates()
.addFreeCandidate('top')
.addFreeCandidate('bottom')
)
// the source port of edge e2 should be on the left side
// and on the target we want to keep the current port which is on the bottom side
spcMapper.set(e2, new EdgePortCandidates().addFreeCandidate('left'))
tpcMapper.set(e2, new EdgePortCandidates().addFixedCandidate('bottom'))
// specify some ports at the top side of node n1 ...
data.ports.nodePortCandidates.mapper.set(
n1,
new NodePortCandidates()
.addFixedCandidate('top', new Point(-5, -15))
.addFixedCandidate('top', new Point(5, -15), 3.0, 2)
)
// ... and a left and right port for node n2
data.ports.nodePortCandidates.mapper.set(
n2,
new NodePortCandidates()
.addFreeCandidate('left', 2.0)
.addFixedCandidate('right', new Point(15, 0))
)
Note that the former strong port constraints (enforcing that the layout algorithm keeps the current port location) can now be modeled with the method addFixedCandidate, that is, by creating a fixed candidate without specifying an offset.
The former class PortConstraintKeys
has been removed. In most cases, the port data can simply be specified with the new port-related sub-data
as mentioned above. If this is not possible, the data can still be specified and registered
directly with the layout graph using the following data keys:
With yFiles for HTML 3.0, most layout algorithms provide at least generic support for ports. More precisely, for algorithms that do not directly support port candidates with an integrated approach, the ports are fixed as a post-processing step by automatically applying the class PortPlacementStage. Therefore, most of the algorithms’ LayoutData classes provide a port-related sub-data via the property ports (see BasicPortData and its usages).
Matching between node and edge port candidates
The layout algorithms automatically attempt to match appropriate node and edge port candidates. In yFiles for HTML 3.0, the matching process also
considers the new matchingId
parameter as shown in Creating matching port candidates. Two candidates can only be matched if their matching-ids are equal, or if at least one of the matching-ids is null (a `null`matching-id - which is the default - matches any other matching-id).
const layout = new HierarchicalLayout()
const data = layout.createLayoutData(graph)
// all nodes should provide two fixed ports at the top and bottom side;
// the available ports are subdivided into "red" and "blue" ports
data.ports.nodePortCandidates.constant = new NodePortCandidates()
.addFixedCandidate({
side: PortSides.TOP,
offset: new Point(-5, -15),
matchingId: 'red'
})
.addFixedCandidate({
side: PortSides.TOP,
offset: new Point(5, -15),
matchingId: 'blue'
})
.addFixedCandidate({
side: PortSides.BOTTOM,
offset: new Point(-5, 15),
matchingId: 'red'
})
.addFixedCandidate({
side: PortSides.BOTTOM,
offset: new Point(5, 15),
matchingId: 'blue'
})
const spcMapper = data.ports.sourcePortCandidates.mapper
const tpcMapper = data.ports.targetPortCandidates.mapper
// the source port of edge e1 can be any "red" port provided by the source node on its top side
spcMapper.set(
e1,
new EdgePortCandidates().addFreeCandidate({
side: PortSides.TOP,
matchingId: 'red'
})
)
// the target port of edge e1 can be any port provided by the target node (matches each matchingId)
tpcMapper.set(
e1,
new EdgePortCandidates().addFreeCandidate({ side: PortSides.ANY })
)
// the source port of edge e2 can be any "blue" port provided by the source node
spcMapper.set(
e2,
new EdgePortCandidates().addFreeCandidate({
side: PortSides.ANY,
matchingId: 'blue'
})
)
// the target port of edge e2 can be any port provided by the target node on its bottom side
tpcMapper.set(
e2,
new EdgePortCandidates().addFreeCandidate({ side: PortSides.BOTTOM })
)
Layout Duration and Aborting
While the two basic approaches to aborting the calculation of a graph layout have not changed, both approaches have received updated names to more accurately represent their usage and offer convenience improvements.
AbortHandler
The AbortHandler has been renamed to LayoutAbortController. The static methods to add or remove an abort controller to or from a graph have been removed. If necessary, a created abort controller can be registered directly with the LayoutGraph using the LayoutGraphContext property layoutAbortController. When starting a layout run via the LayoutExecutor, the run can be controlled via the properties cancelDuration and stopDuration.
Maximum Duration
The MaximumDuration property of layout algorithms that support early termination has been renamed to StopDuration to emphasize that it marks the time at which the layout algorithm begins the termination process. The termination itself can take additional time, as the algorithm still has to produce a consistent result. The type of the StopDuration property has been changed from a simple numeric value in a fixed unit (milliseconds) to TimeSpan, which supports specifying the duration in most common units of time.
Behavior Change
The ComponentLayout will no longer apply an abort controller’s stopDuration and cancelDuration to each component in full. Instead, the duration is now automatically split among the components based on their size.
Layout Stages and Multi-Stage Layouts
Some of yFiles’ more complex layout algorithms benefit from applying generalized pre- and post-processing stages. In yFiles for HTML 2.6, these algorithms implemented MultiStageLayout, which offered a framework to configure and execute the necessary stages. However, the inheritance introduced some conveniences for stages that were not helpful for a specific MultiStageLayout implementation. yFiles for HTML 3.0 replaces this inheritance-based approach by making a LayoutStageStack, as well as tailored convenience properties for accessing relevant stages, available on the respective algorithms. In addition, each ILayoutStage now offers an enabled property to conveniently enable or disable stages on the stack.
For more details also check the API documentation of the respective algorithm:
-
HierarchicalLayout (formerly: HierarchicLayout)
-
RadialTreeLayout (formerly: BalloonLayout)
-
RadialGroupLayout (formerly: CactusGroupLayout)
New Layout Graph API
Important
|
The changes described in this chapter are relevant for developers who directly use the LayoutGraph API, for example, when writing custom layout algorithms. |
With yFiles for HTML 3.0, the LayoutGraph API has been streamlined. Instead of using the Graph
and
LayoutGraph
base classes with specific implementations, the LayoutGraph is now the sole graph model class. Concepts like the
CopiedLayoutGraph
are now implemented by methods such as createCopy.
Importantly, the API is now more similar to IGraph, making it easier for developers
familiar with that part of yFiles. This primarily affects how you Accessing Graph Elements and
Modifying the Graph Structure, but also includes the use of generic collections for graph elements instead
of low-level datatypes like NodeList
and EdgeList
. As a result, you can query graph properties like the number of nodes and edges
as properties of the nodes and edges collections.
Accessing Graph Elements
A goal of the layout graph rework in yFiles for HTML 3.0 was to make accessing graph elements more uniform, regardless of whether they are elements of a LayoutGraph or an IGraph. This results in the following changes:
Nodes
-
LayoutGraph.GetLayout(Node)
has been replaced by a layout property accessible on the LayoutNode. -
Convenience properties like
LayoutGraph.FirstNode
have been replaced by native convenience on the nodes collection. -
Convenience properties like
Node.Neighbors
have been removed. Instead, LayoutNode.edges can be used to access them.
Edges
-
The ports and bends of edges can be accessed directly on the LayoutEdge, using properties such as sourcePortLocation, targetPortLocation, and bends.
-
LayoutGraph.ContainsEdge(Node, Node)
has been removed in favor of LayoutGraph.getEdgesBetween. -
Node.GetEdgeTo
andGetEdgeFrom
have been removed. Instead, the collection returned by LayoutGraph.getEdgesBetween can be used.
Labels
Labels have become fully-fledged layout graph elements of type LayoutNodeLabel and LayoutEdgeLabel with bounds, indices, customizable tags and a reference to their owner. Instead of accessing them from the layout graph, they can be retrieved directly via their owners’ LayoutNode.labels and LayoutEdge.labels properties.
More information on how to migrate to the new labeling API can be found in Labeling.
Examples
const graph = getMyGraph()
// Iterating the nodes and their labels
for (const node of graph.nodes) {
// Do something with each node...
for (const nodeLabel of node.labels) {
// Do something with each label...
}
}
// Iterating the edges of the graph
for (const edge of graph.edges) {
// Do something with each edge...
}
// Get the first and last node of the node set from the graph.
const firstNode = graph.nodes.first
const lastNode = graph.nodes.last
// Check if some given node belongs to this graph.
const containsNode = graph.contains(node)
// Check if there is an edge between first and last node of the graph.
const containsEdge = graph
.getEdgesBetween(graph.nodes.first()!, graph.nodes.last()!)
.some()
Modifying the Graph Structure
-
LayoutGraph.RemoveNode
andLayoutGraph.RemoveEdge
have been combined into the overloaded LayoutGraph.remove method, which also covers labels and bends.
// get the first edge and node let firstEdge = graph.edges.first()! let firstNode = graph.nodes.first()! // remove the first edge and node graph.remove(firstEdge) graph.remove(firstNode) // get the new first edge and node firstEdge = graph.edges.first()! firstNode = graph.nodes.first()! // remove the first label of the node graph.remove(firstNode.labels.first()!) // remove the first bend of the edge's path graph.remove(firstEdge.bends.first()!)
-
Hiding graph elements directly on the LayoutGraph is no longer possible. Instead, this functionality is provided by LayoutGraphHider.
// Hide all edges which are part of some set/collection const graphHider = new LayoutGraphHider(graph) const edgesToHide = getEdgesToHideList() graphHider.hideEdges(edgesToHide) // now do something with the graph layoutAlgorithm.applyLayout(graph) // cleanup graphHider.unhideAll()
-
The LayoutGraph now offers convenience for modifying its grouping hierarchy. For more information, see Grouping in the LayoutGraph.
Copying the Graph
The yFiles for HTML 3.0 API no longer offers CopiedLayoutGraph
as a LayoutGraph implementation specifically for
copying an existing layout graph. Instead, LayoutGraph.createCopy
can be used. This approach also replaces the removed BufferedLayout
, though it should be noted that running a buffered
layout is generally only necessary when applying custom layout code that relies on, for example, indices of nodes and edges staying
consistent. Whenever a layout is applied to an IGraph instance, the layout is calculated on a layout graph that
is created as a copy of the original graph. This provides the same conceptual benefits as a buffered layout run.
// copy the graph
const copiedGraph = LayoutGraph.createCopy(graph)
// apply a layout to the copied graph
layout.applyLayout(copiedGraph)
// write the calculated layout back to the original graph
copiedGraph.context.graphCopyData!.commitLayoutToOriginalGraph()
Structure Graph
For use cases where the graph structure must be analyzed, performance is often crucial. With yFiles for HTML 3.0, it’s possible to create a structure-only LayoutGraph designed to model only the graph structure and to ignore properties like positions or sizes of the elements. Such a graph can be created using the static createStructureGraph method of the LayoutGraph. Graphs created by this method can be used by all methods offered as LayoutGraphAlgorithms with the exception of findIntersections, which relies on coordinates.
The behavior of any method to query or change layout properties of a structure graph’s elements, as well as the behavior of any layout algorithm applied to a structure graph is undefined.
Labeling
With yFiles for HTML 3.0, the labeling API for graph layouts has received a major overhaul. Labels are now fully-fledged elements of the layout graph. They have defined bounds, indices, customizable tags and a reference to their owner, while configuring how labels are handled by the layout algorithms has been streamlined.
Configuration of Layouts
Going forward, all layout algorithms offer a
nodeLabelPlacement
and edgeLabelPlacement property to specify how the algorithm should handle node labels and edge labels. This replaces
properties like ConsiderNodeLabels
, ConsiderEdgeLabels
, IntegratedNodeLabeling
, IntegratedEdgeLabeling
, and
NodeLabelingPolicy
by offering all supported policies out of the following:
Property |
Possible Policies |
||||||
NodeLabelPlacement |
IGNORE |
IGNORE_GROUP_LABELS |
CONSIDER |
GENERIC |
HORIZONTAL |
RAY_LIKE |
RAY_LIKE_LEAVES |
EdgeLabelPlacement |
IGNORE |
CONSIDER |
GENERIC |
INTEGRATED |
The two properties can also be used to conveniently add a GenericLabeling step as a post-processing for all node labels, edge labels or both.
const organicLayout = new OrganicLayout({
// node labels are considered, i.e., overlaps with them avoided
nodeLabelPlacement: 'consider',
// edge labels will be placed by generic labeling algorithm
edgeLabelPlacement: 'generic'
})
// configure the GenericLabeling step
const genericLabeling = organicLayout.genericLabeling
genericLabeling.reduceLabelOverlaps = false
The PreferredPlacementDescriptor
class has been renamed to EdgeLabelPreferredPlacement. Preferred
placements can be specified for each edge label using the corresponding property on the layout data classes of
algorithms that support edge label placement, such as the HierarchicalLayoutData’s
edgeLabelPreferredPlacements.
const layout = new HierarchicalLayout()
const layoutData = layout.createLayoutData(graph) // works for both IGraph and LayoutGraph
layoutData.edgeLabelPreferredPlacements.constant =
new EdgeLabelPreferredPlacement({
placementAlongEdge: 'at-center'
})
Generic Labeling Algorithm
Along with the updated labeling API, the generic labeling algorithm has been improved with respect to:
-
specifying valid candidate positions for labels
-
selecting labels that should be handled by the algorithm
-
prioritizing desirable qualities of the resulting labeling
These improvements are described in detail in Generic Labeling.
Labels in Custom Layouts
Important
|
The changes described in this section only affect users who directly interact with the LayoutGraph API, for example, when writing custom layout algorithms. |
The previous representation of labels as INodeLabelLayouts
and IEdgeLabelLayouts
has been replaced by the new
LayoutNodeLabel and LayoutEdgeLabel types.
Additionally, working with labels of the LayoutGraph is now more similar to the workflow
in the IGraph.
Labels can be added and removed directly on the graph for any of its nodes and edges, using methods like
addLabel or
remove. This replaces the functionality of the
ILabelLayoutFactory
, which was removed as a result.
Nodes and edges now offer a live view of their labels through their labels
properties. This replaces the GetLabelLayout
method on the layout graph, which used to create a list of the labels
associated with the graph element at the time it was called.
Labels of the layout graph no longer have any models or model parameters. Layout algorithms (other than GenericLabeling) do not support placing labels on a subset of valid positions during the layout calculation. Despite the removal of label models, the labels are still repositioned with their owner if the owner is moved.
Binding Data to a LayoutGraph
Important
|
The changes described in this chapter only affect users who work directly with the LayoutGraph API of yFiles. This is necessary only if you implement your own ILayoutAlgorithm, ILayoutStage, or another customization of the layout part. Therefore, this migration guide is not relevant for users who just apply a layout on an IGraph. To learn about how to bind custom input data in that case, please see the corresponding migration chapter. |
The new class LayoutGraphContext now manages all supplementary data for the graph and its
elements, which can be used by layout algorithms during computation.
Therefore, it replaces methods LayoutGraph.AddDataProvider
and LayoutGraph.RemoveDataProvider
of yFiles for HTML 2.6.
The interface IDataProvider
has been removed. In yFiles for HTML 3.0, its replacement is the
generic interface IMapper<K,V>.
Data Keys
Like before, data is stored on the graph using unique lookup key instances, typically defined by layout algorithms. Client code or LayoutData can supply additional data associated with a particular key. Layout algorithms can then retrieve this data using these keys and use it as input.
Keys are now called data keys. The base class for data keys is DataKey<TValue>. This class replaces the
former DpKeyBase<TValue>
. For items, like nodes and edges, there are specific keys, namely
NodeDataKey<TValue> and EdgeDataKey<TValue>.
Note
|
All the static keys on the layout algorithms have been renamed accordingly; for example, xyzDpKey is now xyzDataKey .
The data storage and retrieval methods in the layout API are now generic and type safe.
|
Data for Specific Items
// Create a mapper and set values for two specific edges
const edgeMapper = new Map<LayoutEdge, number>()
edgeMapper.set(edge1, 4.5)
edgeMapper.set(edge2, 1.0)
// Register the mapper using an existing DataKey
// Note: corresponds to old code graph.addDataProvider(EdgeThicknessDataKey)
graph.context.addItemData(
HierarchicalLayout.EDGE_THICKNESS_DATA_KEY,
edgeMapper
)
// ... Somewhere else: get the mapper from the graph
// Note: corresponds to old code graph.getDataProvider(EdgeThicknessDataKey)
const mapper = graph.context.getItemData(
HierarchicalLayout.EDGE_THICKNESS_DATA_KEY
)
It is not required to always provide an IMapper<K,V>. Providing a getter/callback
can be more convenient. This is a good replacement for code where in yFiles for HTML 2.6 a custom
DataProviderAdapter
was added.
// Add item data for nodes by using a getter/callback function
graph.context.addItemData(
LayoutKeys.NODE_MARGIN_DATA_KEY,
(node: LayoutNode) =>
node.degree === 0 ? Insets.EMPTY : new Insets(10)
)
Global Data for the Graph
Previously, registering a single value with the LayoutGraph required using the IDataProvider
interface,
which has been removed. The DataProviders.CreateConstantDataProvider
factory method was useful in that scenario.
The replacement is the addData<TValue> method.
// Add a single rectangle as data using the key provided as first argument
graph.context.addData(
ClearAreaLayout.EXPANDED_NODE_ORIGINAL_BOUNDS_DATA_KEY,
new Rect(0, -20, 100, 200)
)
Amending and Removing Data
In previous versions of yFiles for HTML 2.6, temporarily changing, replacing, or removing data required
manually removing an IDataProvider
, addding a different one, and finally, once done, re-adding the original instance.
While this approach is still possible, the new LayoutGraphContext
now uses layers. Layers can be pushed onto and popped from the context. Pushing a layer creates a new layer,
and any item data registered with a key on this new layer makes previously registered data invisible.
This approach makes temporary changes much clearer.
// Push a new layer onto the context
graph.context.pushLayer()
// Register margins data, in this case defining a margin of 40 pixels for each node
graph.context.addItemData(
LayoutKeys.NODE_MARGIN_DATA_KEY,
(_) => new Insets(40)
)
// ... Do something, e.g., apply an algorithm. At this moment the 40 pixels margin is visible
new OrganicLayout().applyLayout(graph)
// Remove one context layer. This way the state will be equal to the original one. Margins are now as
// reset to whatever they were. It does not matter if margins were even registered or not.
graph.context.popLayer()
Grouping in the LayoutGraph
Important
|
The changes described in this chapter only affect users who work directly with the LayoutGraph API, such as when writing custom layout algorithms. |
The grouping on the LayoutGraph is no longer defined by using data keys (GroupingKeys
class
in yFiles for HTML 2.6). Grouping information is now directly accessible by using methods on the
graph instance itself:
Basic changes to the grouping can also be implemented using the graph and the following methods:
LayoutGraphGrouping
The LayoutGraphGrouping class replaces the (Layout)GroupingSupport
class
from yFiles for HTML 2.6 and offers more advanced grouping operations. You can create it using
different factory methods, depending on whether you need a read-only or a writable instance.
Additionally, it provides convenient methods such as checking if a graph is grouped at all
(isGrouped).
When you need to query a lot of grouping information in performance-critical code, this approach is more efficient than accessing it through the graph instance.
In previous yFiles versions, you had to manually modify the data registered with the keys of
GroupingKeys
. Now, LayoutGraphGrouping offers methods to replace or hide
the grouping structure. These operations can (and usually should) be undone later.
// given three nodes n1, n2, n3; n1 should be a group node that contains n2 and n3
// with this code we completely replace any previously defined grouping and define new relations
const grouping = LayoutGraphGrouping.replaceGrouping(graph)
grouping.setIsGroupNode(n1, true)
grouping.setParent(n2, n1)
grouping.setParent(n3, n1)
// ... other code
// finally, the replacement can be undone again
grouping.restore()
// hide the grouping so that the graph appears to contain no grouping at all
const hiddenGrouping = LayoutGraphGrouping.hideGrouping(graph)
// ... other code
// now, make it visible again
hiddenGrouping.restore()
Analysis Algorithms on the LayoutGraph
Important
|
The changes described in this chapter only affect users who work directly with the LayoutGraph API, such as when writing custom layout algorithms. To run analysis algorithms on IGraph, please see chapter Graph Analysis. |
To execute analysis algorithms (e.g. shortest path, centrality measures) directly on a LayoutGraph,
static methods are provided. In yFiles for HTML 2.6, the methods were thematically distributed among
different types, for example, ShortestPaths
, Centrality
, Trees
etc. Now, all algorithms are collected
in the new class:
- LayoutGraphAlgorithms
-
Provides all analysis algorithms offered for the LayoutGraph. For example, shortestPath, isTree, graphCentrality, and many more.
Note
|
Methods to check for specific graph features that were previously on class
GraphCecker have also been moved to LayoutGraphAlgorithms.
|
Furthermore, the signatures of the algorithm methods have been streamlined and simplified in many cases. When using an overload/signature that is not available anymore in yFiles for HTML 3.0, it will usually be possible to achieve the same again, but there is no generic recipe on how to migrate.
Tip
|
In yFiles for HTML 3.0, a structure graph can be used for most analysis algorithms to improve the algorithm’s performance. |
Hierarchical Layout
This section describes the major changes to the HierarchicalLayout (formerly HierarchicLayout).
As with all major layout algorithms, the HierarchicalLayout no longer inherits from MultiStageLayout, but directly implements ILayoutAlgorithm. The layout stages are now managed by a LayoutStageStack, which can be obtained via the layoutStages property; see the migration chapter Layout Stages and Multi-Stage Layouts for more details.
Renamed, Moved, and Removed Classes and Members
The following table lists the renamed, moved, and removed classes and members of the major classes of HierarchicalLayout. In addition to the changes listed here, the expert API was streamlined as well; see Major Changes to Expert API.
yFiles for HTML 2.6 | yFiles for HTML 3.0 | Remarks |
---|---|---|
HierarchicLayout |
||
Members of class HierarchicalLayout |
||
backLoopRouting |
The two settings have been combined. To set different values for self-loops and other edges, set individual HierarchicalLayoutEdgeDescriptors using the edgeDescriptors property of HierarchicalLayoutData. |
|
backLoopRoutingForSelfLoops |
||
compactGroups |
The setting has been combined with RecursiveGroupLayering. |
|
componentLayoutEnabled |
removed |
The ComponentLayout can be accessed using property componentLayout, and enabled if required. |
considerNodeLabels |
The enum now allows you to choose between considering the node labels and the GenericLabeling algorithm. |
|
createIncrementalHintsFactory |
removed |
The factory is no longer necessary, see Incremental Hints. |
createLayerConstraintFactory |
removed |
The factory is no longer necessary, see Layer and Sequence Constraints. |
createSequenceConstraintFactory |
removed |
The factory is no longer necessary, see Layer and Sequence Constraints. |
edgeLayoutDescriptor |
Settings for individual edges can be specified via the edgeDescriptors property of HierarchicalLayoutData. |
|
edgeToEdgeDistance |
||
fixedElementsLayerer |
Moved to HierarchicalLayoutCore. |
|
fixedElementsSequencer |
Moved to HierarchicalLayoutCore. |
|
fromScratchLayerer |
Moved to HierarchicalLayoutCore. |
|
fromScratchSequencer |
core.fromScratchSequencer |
Moved to HierarchicalLayoutCore. |
hideGroupsStage |
removed |
The HierarchicalLayout is able to handle groups itself, so the stage was not necessary. |
hideGroupsStageEnabled |
||
hierarchicLayoutCore |
The core class no longer implements ILayoutAlgorithm. |
|
integratedEdgeLabeling |
The enum now allows you to choose between integrated labeling and the GenericLabeling algorithm. |
|
labeling |
removed |
To influence the labeling, use the nodeLabelPlacement and edgeLabelPlacement properties. |
labelingEnabled |
||
layoutMode |
The type of the property has been changed to boolean. The incremental mode is now called the from-sketch mode. |
|
maximumDuration |
The HierarchicalLayout tries to stop within the given time, but it is not guaranteed to do so. The property was renamed to better signal this intent. |
|
nodeLayoutDescriptor |
Settings for individual edges can be specified via nodeDescriptors on HierarchicalLayoutData. |
|
nodePlacer |
||
nodeToNodeDistance |
||
orientationLayout |
removed |
Use layoutOrientation to set the desired layout orientation. |
orientationLayoutEnabled |
||
orthogonalRouting |
removed |
The routing style can be specified via the routingStyleDescriptor property on HierarchicalLayoutEdgeDescriptor. |
parallelEdgeRouter |
removed |
The HierarchicalLayout handles parallel edges itself. Thus, this stage is not necessary. |
parallelEdgeRouterEnabled |
||
recursiveGroupLayering |
The setting was combined with CompactGroups. |
|
selfLoopRouter |
removed |
The HierarchicalLayout handles self-loops itself. Thus, this stage is not necessary. |
selfLoopRouterEnabled |
||
separateLayers |
core.coordinateAssigner.separateLayers |
Moved to class CoordinateAssigner, which can be accessed via the coordinateAssigner property of HierarchicalLayoutCore. |
stopAfterLayering |
Moved to HierarchicalLayoutCore. |
|
stopAfterSequencing |
Moved to HierarchicalLayoutCore. |
|
subgraphLayout |
removed |
If necessary, the SubgraphLayoutStage can be accessed and enabled via method get<T> of property layoutStages, but this may lead to overlaps. |
subgraphLayoutEnabled |
||
HierarchicLayoutData |
HierarchicalLayoutData<TNode,TEdge,TNodeEdge,TNodeLabel,TEdgeLabel> |
|
Properties in class HierarchicalLayoutData |
||
abortHandler |
removed |
A LayoutAbortController is exposed by the LayoutExecutor; see Section Layout Duration and Aborting for more details. |
bfsLayererCoreNodes |
||
busRootOffsets |
||
buses |
||
constraintIncrementalLayererAdditionalEdgeWeights |
removed |
Use the ADDITIONAL_EDGE_WEIGHT_DATA_KEY with the GenericLayoutData<TNode,TEdge,TNodeLabel,TEdgeLabel>. |
edgeLabelPreferredPlacement |
||
edgeLayoutDescriptors |
||
givenLayersLayererIds |
||
incrementalHints |
All nodes specified with this property are layered incrementally. To specify more specific hints, see Section Incremental Hints. |
|
All edges specified with this property are considered incremental during all phases of the algorithm. |
||
layerConstraintFactory |
removed |
Define layer constraints via the layerConstraints property. |
layerIndices |
In addition, the resulting indices are now nullable to indicate that no index was defined, e.g., in the case of group nodes. |
|
nodeHalos |
The type of the values was changed to Insets. |
|
nodeLayoutDescriptors |
||
nodePortCandidatesSet |
ports.nodePortCandidates |
Moved to sub-data ports. See also Ports in Layout. |
partitionGridData |
||
selfLoopCalculatorData |
removed |
Settings like minimum lengths for self-loop edges are now specified via the HierarchicalLayoutEdgeDescriptor class like for normal edges. |
sequenceConstraintFactory |
removed |
Define sequence constraints via the sequenceConstraints property. |
sourcePortCandidates |
ports.sourcePortCandidates |
Moved to sub-data ports. PortCandidates and PortConstraints are now combined in one concept; see migration chapter about Ports in Layout. |
sourcePortConstraints |
||
sourcePortGroupIds |
ports.sourcePortGroupIds |
Moved to sub-data ports. |
targetPortCandidates |
ports.targetPortCandidates |
Moved to sub-data ports. PortCandidates and PortConstraints are now combined in one concept; see migration chapter about Ports in Layout. |
targetPortConstraints |
||
targetPortGroupIds |
ports.targetPortGroupIds |
Moved to sub-data ports. |
LayerConstraintData |
Available via the layerConstraints property. |
|
Properties in class LayerConstraintData<TNode> |
||
placeAbove |
||
placeBelow |
||
SequenceConstraintData |
Available via the sequenceConstraints property. |
|
Properties in class SequenceConstraintData<TNode,TEdge,TItem> |
||
placeAfter |
||
placeBefore |
||
HierarchicLayoutNodeLayoutDescriptor |
||
Properties in class HierarchicalLayoutNodeDescriptor |
||
nodeLabelMode |
removed |
If node labels shall be considered by the layout algorithm (see HierarchicalLayout.nodeLabelPlacement), they are now considered during all phases. |
portBorderGapRatios |
The ratio is now the same on all four sides of the node and cannot be defined individually. |
|
HierarchicLayoutEdgeLayoutDescriptor |
||
Properties in class HierarchicalLayoutEdgeDescriptor |
||
recursiveEdgeStyle |
||
routingStyle |
||
sourcePortOptimization |
removed |
To influence the port placement, use NodePortCandidates or EdgePortCandidates; see also Ports in Layout. |
targetPortOptimization |
||
HierarchicLayoutEdgeRoutingStrategy |
||
HierarchicLayoutRoutingStyle |
||
IHierarchicLayoutNodePlacer |
||
SimplexNodePlacer |
||
Properties in class CoordinateAssigner |
||
barycenterMode |
The type has been changed to SymmetryOptimizationStrategy. A previous value of |
|
groupCompactionPolicy |
The type has been changed to boolean. |
|
maximumDuration |
The CoordinateAssigner tries to stop within the given time, but it is not guaranteed to do so. The property was renamed to better signal this intent. |
|
swimLaneCrossingWeight |
||
ILayerer |
||
AsIsLayerer |
||
BFSLayerer |
||
ConstraintIncrementalLayerer |
||
GivenLayersLayerer |
||
MultiComponentLayerer |
||
TopologicalLayerer |
||
WeightedLayerer |
||
AsIsSequencer |
||
DefaultLayerSequencer |
||
IPortAllocator |
||
DefaultPortAllocator |
Changed Default Values and Behavior Changes
The default routing style of the HierarchicalLayout has changed from POLYLINE to ORTHOGONAL. The routing style can be specified via the routingStyleDescriptor property on HierarchicalLayoutEdgeDescriptor. In case that one HierarchicalLayoutEdgeDescriptor suffices for all edges, it can be set via the defaultEdgeDescriptor property on HierarchicalLayout.
Node labels are now considered by default. To change this behavior, set the nodeLabelPlacement property to the desired value. It is now also easier to place node labels with GenericLabeling by setting the value to GENERIC.
Edge labels are now placed by an integrated labeling algorithm by default. To change this behavior, set the edgeLabelPlacement property to the desired value. It is now also easier to place edge labels with GenericLabeling by setting the value to GENERIC.
By default, the HierarchicalLayout now prefers more symmetric layouts at the expense of other layout qualities such as compactness. The influence of symmetry on the layout can be configured via the CoordinateAssigner.symmetryOptimizationStrategy property. The CoordinateAssigner that is used by the HierarchicalLayout is available via the HierarchicalLayout.coordinateAssigner property.
The gridSpacing property of HierarchicalLayout now requires the argument to be non-negative. To specify that no grid should be used, set the value to 0.
Incremental Hints
Specifying incremental hints has been simplified. In the simple case where some nodes or edges should be marked as incremental for all parts of the layout algorithm, the incrementalNodes and incrementalEdges properties on the HierarchicalLayoutData can be used.
// create a HierarchicalLayout which rearranges only the incremental graph elements
const hl = new HierarchicalLayout({ fromSketchMode: true })
// provide additional data to configure the HierarchicalLayout
const hlData = hl.createLayoutData(graph)
// specify the nodes to rearrange
hlData.incrementalNodes.source = incrementalNodes
// specify the edges to rearrange
hlData.incrementalEdges.source = incrementalEdges
graph.applyLayout(hl, hlData)
To specify more specific hints, it is no longer necessary to use an IIncrementalHintsFactory. Instead, the enum values of IncrementalNodeHint and IncrementalEdgeHint can be used directly. The interface IIncrementalHintsFactory has been removed.
// create a HierarchicalLayout which rearranges only the incremental graph elements
const hl = new HierarchicalLayout({ fromSketchMode: true })
// provide additional data to configure the HierarchicalLayout for incremental edges
const hlData = hl.createLayoutData()
// sequence hint for incremental edges
hlData.incrementalEdges.source = incrementalEdges
// provide additional GenericLayoutData to configure incremental nodes
const glData = new GenericLayoutData<INode, IEdge, ILabel, ILabel>()
glData.addItemMapping(
HierarchicalLayout.INCREMENTAL_NODE_HINTS_DATA_KEY
).mapperFunction = (node: INode) => {
if (incrementalNodes.includes(node)) {
// create a hint for incremental nodes
if (graph.isGroupNode(node)) {
// special hint for groups
return IncrementalNodeHint.INCREMENTAL_GROUP
}
if (fixedNodes.includes(node)) {
// exact layer for the fixedNodes
return IncrementalNodeHint.USE_EXACT_COORDINATES
}
// simple layer hint for all other nodes
return IncrementalNodeHint.LAYER_INCREMENTALLY
}
return IncrementalNodeHint.NONE
}
// combine both layout data instances
const layoutData = hlData.combineWith(glData)
graph.applyLayout(hl, layoutData)
GridComponents (Formerly Buses)
The bus structure concept of the HierarchicalLayout has been renamed to GridComponent to prevent confusion with the buses (bus-style edge routing) of the EdgeRouter. GridComponents can be configured with GridComponentDescriptor instances, which can be set via the gridComponents property of the HierarchicalLayoutData.
Layer and Sequence Constraints
Important
|
The changes described in this section only affect users who directly used the LayoutGraph API, for example, when writing custom layout algorithms. |
In yFiles for HTML 2.6, defining layer or sequence constraints when working directly on the LayoutGraph factories required using the ILayerConstraintFactory and ISequenceConstraintFactory interfaces. These interfaces have been removed and replaced by the LayoutGraphLayerConstraints and LayoutGraphSequenceConstraints classes.
However, it is now highly recommended that you define layer and sequence constraints using the HierarchicalLayoutData, which is also available for the LayoutGraph.
const layout = new HierarchicalLayout()
// Layout data is now also available for LayoutGraphs
const layoutData = layout.createLayoutData(graph)
// Ensure that node2 is placed after node1
layoutData.sequenceConstraints.placeNodeBeforeNode(node1, node2)
// Also place another node at the very start
layoutData.sequenceConstraints.placeNodeAtHead(firstNodeInLayer)
Major Changes to Expert API
Important
|
The changes described in this section only affect users who directly worked with the LayoutGraph API, such as when writing custom layout algorithms. |
This section aims to provide a broad overview of the changes to the classes that define the low-level details governing the inner workings of the HierarchicalLayout. It is not meant to be a comprehensive list of all changes.
Several interfaces were removed or replaced by their concrete implementations, as shown in the following table.
yFiles for HTML 2.6 | yFiles for HTML 3.0 | Remarks |
---|---|---|
IItemFactory |
||
IEdgeData |
||
ILayer |
||
ILayers |
Methods to insert and remove layers are available on HierarchicalLayoutContext. |
|
ILayoutDataProvider |
||
INodeData |
Several protected methods have also been removed.
Organic Layout
This section describes the major changes to the OrganicLayout.
Like all major layout algorithms, the OrganicLayout no longer inherits from MultiStageLayout but instead implements ILayoutAlgorithm directly. The layout stages are now managed by a LayoutStageStack, which can be obtained via the layoutStages property. See Layout Stages and Multi-Stage Layouts for more details.
Renamed, Moved, and Removed Classes and Members
The following table lists the renamed, moved, and removed classes and members of the major classes of the OrganicLayout. In addition to the changes listed here, the expert API was streamlined as well by removing some protected methods of OrganicLayout.
yFiles for HTML 2.6 | yFiles for HTML 3.0 | Remarks |
---|---|---|
OrganicLayout |
class name unchanged |
|
Members of class OrganicLayout |
||
clusterAsGroupSubstructureAllowed |
||
clusterNodes |
removed |
To disable clustering, set the clusteringPolicy property to NONE. |
clusteringQuality |
removed |
The clustering quality is now automatically determined based on the qualityTimeRatio. |
componentLayoutEnabled |
componentLayout.enabled |
|
considerNodeLabels |
The enum now allows you to choose between considering the node labels and the GenericLabeling algorithm. |
|
considerNodeSizes |
removed |
The OrganicLayout now always considers the node sizes. |
createConstraintFactory |
removed |
The factory is no longer necessary, see Constraints. |
hideGroupsStage |
removed |
The OrganicLayout is able to handle group nodes itself. |
hideGroupsStageEnabled |
||
integratedEdgeLabeling |
The enum now allows you to choose between integrated labeling and the GenericLabeling algorithm. |
|
L labeling |
removed |
To influence the labeling, use the nodeLabelPlacement and edgeLabelPlacement properties. |
labelingEnabled |
||
maximumDuration |
The OrganicLayout tries to stop within the given time, but it is not guaranteed to do so. The property was renamed to better reflect this. |
|
minimumNodeDistance |
Settings for individual edges can be specified via the OrganicLayoutData.minimumNodeDistances property. |
|
nodeEdgeOverlapAvoided |
||
nodeOverlapsAllowed |
||
orientationLayout |
removed |
Use layoutOrientation to set the desired layout orientation. |
orientationLayoutEnabled |
||
outputRestriction |
||
parallelEdgeRouterEnabled |
parallelEdgeRouter.enabled |
|
preferredEdgeLength |
Settings for individual edges can be specified via the OrganicLayoutData.preferredEdgeLengths property. |
|
scope |
OrganicLayoutData.scope.scopeModes |
All settings related to the scope have been moved to the layout data. The scope mode can now be set individually per node. See also the section Scope. |
selfLoopRouterEnabled |
selfLoopRouter.enabled |
|
smartComponentLayout |
removed |
The OrganicLayout now configures the ComponentLayout. To disable this configuration, remove or replace the instance of the ComponentLayout in the LayoutStageStack accessible via the layoutStages property. |
subgraphLayout |
removed |
If necessary, the OrganicLayout can be wrapped by a SubgraphLayoutStage, but this may lead to overlaps. It is usually advisable to set an appropriate scope. |
SubgraphLayoutEnabled |
||
OrganicLayoutData |
||
Properties in class OrganicLayoutData |
||
abortHandler |
removed |
A LayoutAbortController is exposed by the LayoutExecutor; see Section Layout Duration and Aborting for more details. |
affectedNodes |
scope.nodes |
All settings related to the scope have been combined into the sub-data scope. See also section Scope. |
edgeLabelPreferredPlacement |
||
edgeOrientations |
||
groupNodeModes |
All settings related to the scope have been combined into the sub-data scope. See also section Scope. |
|
nodeHalos |
The type of the values was changed to Insets. |
|
partitionGridData |
||
sourceGroupIds |
||
targetGroupIds |
||
zCoordinates |
||
OrganicLayoutScope |
removed |
Now a scope mode is set per node; see section Scope. |
GroupNodeMode |
||
Constants in enum GroupNodeHandlingPolicy |
||
NORMAL |
||
OutputRestriction |
||
Methods in class ShapeConstraint |
||
createAspectRatioRestriction |
||
createCircularCageRestriction |
||
createEllipticalCageRestriction |
||
createRectangularCageRestriction |
||
OrganicLayoutTreeSubstructureStyle |
enum name unchanged |
|
Constants in enum OrthogonalLayoutTreeSubstructureStyle |
||
BALLOON |
The layout algorithm was renamed to RadialTreeLayout as well. |
|
OrganicLayoutClusteringPolicy |
enum name unchanged |
|
Constants in enum OrganicLayoutClusteringPolicy |
||
USER_DEFINED |
removed |
Cluster IDs defined via OrganicLayoutData.clusterIds are now always considered. |
ClassicOrganicLayout |
removed |
Use the OrganicLayout instead; see section ClassicOrganicLayout. |
OrganicPartitionGridLayoutStage |
removed |
The OrganicLayout handles layout grids itself. |
OrganicRemoveOverlapsStage |
removed |
Use the RemoveOverlapsStage with property overlapRemovalPolicy set to PRESERVE_RELATIVE_LOCATIONS. |
Changed Default Values and Behavior Changes
Node sizes are now always considered. Consequently, the property OrganicLayout.ConsiderNodeSizes has been removed.
Node labels are now considered by default. To change this behavior, set the nodeLabelPlacement property to the desired value. It is now also easier to place node labels with GenericLabeling by setting the value to GENERIC.
Edge labels are now placed by the GenericLabeling algorithm by default. To change this behavior, set the edgeLabelPlacement property to the desired value.
The default component arrangement style has been changed from ROWS to PACKED_CIRCLE. The style can be specified via the ComponentLayout.style property. The ComponentLayout that is used by the OrganicLayout is available via the componentLayout property.
The OrganicLayout now always configures the ComponentLayout to respect the location of fixed nodes that lie in different components. The property SmartComponentLayout has been removed. To disable this configuration, replace the instance of the ComponentLayout in the LayoutStageStack accessible via the layoutStages property.
Port placement now takes the specified port candidates into account. The ports are placed in a post-processing step by the PortPlacementStage. Port candidates can be specified via the properties on the sub-data OrganicLayoutData.ports. See also the section Ports in Layout.
If custom clusters are defined via the OrganicLayoutData.clusterIds, these are
considered automatically, and the value of OrganicLayout.clusteringPolicy is ignored.
It is no longer necessary to set it to ClusteringPolicy.USER_DEFINED
, which consequently has been removed.
ClassicOrganicLayout
The ClassicOrganicLayout has been superseded by the OrganicLayout, which supports all use cases of the ClassicOrganicLayout. Consequently, the ClassicOrganicLayout has been removed.
Scope
In yFiles for HTML 3.0, defining the scope has been made uniform for all major layout algorithms. For the OrganicLayout, this means that all settings related to the scope have been combined into the sub-data scope of the OrganicLayoutData.
Additionally, the scope mode can now be set per node, which makes it more flexible than before.
To emulate the previous settings of the scope
property of the OrganicLayout, the following settings can be used.
-
ALL: The default behavior. It can be explicitly set by adding all nodes to nodes.
-
SUBSET: Add the desired subset of nodes to nodes.
-
MAINLY_SUBSET: Set scopeModes to INCLUDE_EXTENDED_NEIGHBORHOOD for the nodes in the subset and to FIXED for the other nodes.
-
MAINLY_SUBSET_GEOMETRIC: Set scopeModes to INCLUDE_CLOSE_NODES for the nodes in the subset and to FIXED for the other nodes.
Constraints
Important
|
The changes described in this chapter only affect users who work directly with the LayoutGraph API, for example, when writing custom layout algorithms. |
The class ConstraintFactory has been removed. Node placement constraints should now be specified directly via the constraints property on the OrganicLayoutData, as when working with an IGraph.
const organicLayout = new OrganicLayout()
const layoutData = organicLayout.createLayoutData(graph)
// Align all nodes in the list on a horizontal line
layoutData.constraints.addAlignmentConstraint('horizontal').source =
nodesToAlign
Interactive Organic Layout
The interactive organic layout has been significantly reworked. It is recommended to also consult the source code demo for the Interactive Organic Layout.
There is now a corresponding InteractiveOrganicLayoutData. This class is responsible for setting the value of the properties of the edges and nodes both before and during the layout calculations.
To set the initial values of these properties, it offers properties like preferredEdgeLengths. To update these values while the layout algorithm is running and to query the values that the algorithm used after completion, use handles (InteractiveOrganicNodeHandle and InteractiveOrganicEdgeHandle). For example, the method InteractiveOrganicLayout.SetPreferredEdgeLength has been replaced with the property InteractiveOrganicEdgeHandle.preferredEdgeLength. Mappings from the nodes to these handles are maintained by the InteractiveOrganicLayoutData using the properties nodeHandles and edgeHandles.
yFiles for HTML 2.6 | yFiles for HTML 3.0 | Remarks |
---|---|---|
addStructureUpdate |
removed |
|
getCenter |
The handles are available via InteractiveOrganicLayoutData.nodeHandles. |
|
getCenterX |
||
getCenterY |
||
setCenter |
||
setCenterX |
||
setCenterY |
||
commitPositions |
||
commitPositionsSmoothly |
||
disableAllStages |
removed |
|
getInertia |
The handles are available via InteractiveOrganicLayoutData.nodeHandles. |
|
setInertia |
||
maximumDuration |
The InteractiveOrganicLayout tries to stop within the given time, but it is not guaranteed to do so. The property was renamed to signal this intent better. |
|
outputRestriction |
||
preferredEdgeLength |
Settings for individual edges can be specified via the InteractiveOrganicLayoutData.preferredEdgeLengths property. |
|
setPreferredEdgeLength |
The handles are available via InteractiveOrganicLayoutData.edgeHandles. |
|
setRadius |
The handles are available via InteractiveOrganicLayoutData.nodeHandles. |
|
setStress |
The handles are available via InteractiveOrganicLayoutData.nodeHandles. |
|
syncStructure |
removed |
Orthogonal Layout
This chapter describes the major API changes to the OrthogonalLayout introduced with yFiles for HTML 3.0 and how to migrate from the older version.
As with all major layout algorithms, the OrthogonalLayout no longer inherits from MultiStageLayout, but implements ILayoutAlgorithm directly. The layout stages are now managed by a LayoutStageStack, which can be obtained via the layoutStages property; see Layout Stages and Multi-Stage Layouts for more details.
Renamed, Moved, and Removed Classes and Members
The following table lists the renamed, moved, and removed classes and members of the major classes of the OrthogonalLayout. In addition to the changes listed here, the expert API was also streamlined by removing some protected methods of OrthogonalLayout.
yFiles for HTML 2.6 | yFiles for HTML 3.0 | Remarks |
---|---|---|
OrthogonalLayout |
class name unchanged |
|
Properties in class OrthogonalLayout |
||
chainSize |
||
chainStyle |
||
componentLayoutEnabled |
componentLayout.enabled |
|
crossingReduction |
removed |
Crossing reduction is implicitly controlled by the property qualityTimeRatio. |
cycleStyle |
||
cycleSize |
||
defaultEdgeLayoutDescriptor |
||
edgeLengthReduction |
removed |
Edge length reduction is implicitly controlled by the property qualityTimeRatio. |
faceMaximization |
removed |
Face maximization is implicitly controlled by the property qualityTimeRatio. |
hideGroupsStage |
removed |
The OrthogonalLayout is able to handle group nodes itself. |
hideGroupsStageEnabled |
||
layoutStyle |
||
maximumDuration |
The algorithm tries to stop within the given time, but it is not guaranteed to do so. The property was renamed to better reflect this. |
|
optimizePerceivedBends |
removed |
Perceived bends are implicitly controlled by the property qualityTimeRatio. |
orientationLayout |
removed |
Use layoutOrientation to set the desired layout orientation. |
orientationLayoutEnabled |
||
parallelEdgeRouter |
removed |
The OrthogonalLayout handles parallel edges itself. |
parallelEdgeRouterEnabled |
||
selfLoopRouter |
removed |
The OrthogonalLayout handles self-loops itself. |
selfLoopRouterEnabled |
||
randomization |
removed |
Randomization is implicitly controlled by the property qualityTimeRatio. |
subgraphLayout |
removed |
If necessary, the SubgraphLayoutStage can be accessed and enabled via method get<T> of property layoutStages, but this may lead to overlaps. |
subgraphLayoutEnabled |
||
treeOrientation |
||
treeSize |
||
treeStyle |
||
OrthogonalLayoutData |
||
Properties in class OrthogonalLayoutData |
||
nodeHalos |
||
directedEdges |
ItemMapping that assigns to each edge a value from [-1,0,1]. |
|
edgeLayoutDescriptors |
||
edgeLabelPreferredPlacement |
||
ChainLayoutStyle |
||
CompactOrthogonalLayout |
removed |
|
CycleLayoutStyle |
||
OrthogonalLayoutEdgeLayoutDescriptor |
||
OrthogonalLayoutStyle |
||
TreeLayoutStyle |
Changed Default Values and Behavior Changes
Node labels are now considered by default. To revert to the previous behavior, set the nodeLabelPlacement property to the desired value. It is now also easier to place node labels using GenericLabeling by setting the value to GENERIC.
Edge labels are now considered by default. To revert to the previous behavior, set the edgeLabelPlacement property to the desired value. It is now also easier to place edge labels with GenericLabeling by setting the value to GENERIC.
Port placement now takes the specified port candidates into account. The ports are placed in a post-processing step by the PortPlacementStage. Port candidates can be specified via the properties on the sub-data OrthogonalLayoutData.ports. See also the section Ports in Layout.
Tree Layout
This chapter describes the major API changes to the TreeLayout introduced with yFiles for HTML 3.0 and how to migrate from the older version.
As with all major layout algorithms, the TreeLayout no longer inherits from MultiStageLayout, but instead implements ILayoutAlgorithm directly. The layout stages are now managed by a LayoutStageStack, which can be obtained via the layoutStages property; see the migration chapter Layout Stages and Multi-Stage Layouts for more details.
Renamed, Moved, and Removed Classes and Members
The following table contains the renamed, moved, and removed classes and members of the major classes of the TreeLayout.
yFiles for HTML 2.6 | yFiles for HTML 3.0 | Remarks |
---|---|---|
TreeLayout |
class name unchanged |
|
Properties in class TreeLayout |
||
componentLayoutEnabled |
componentLayout.enabled |
|
considerNodeLabels |
The enum now allows you to choose between considering the node labels and the GenericLabeling algorithm. |
|
defaultLeafPlacer |
removed |
The defaultSubtreePlacer is now used for leaves. Subtree placers for individual nodes can be specified via TreeLayoutData.subtreePlacers property. |
defaultNodePlacer |
||
defaultOutEdgeComparer |
removed |
Use TreeLayoutData.childOrder instead. |
defaultPortAssignment |
||
groupingSupported |
removed |
Groups are always supported now. |
hideGroupsStage |
removed |
The TreeLayout is able to handle group nodes itself. |
hideGroupsStageEnabled |
||
integratedEdgeLabeling |
The enum now allows you to choose between integrated labeling and the GenericLabeling algorithm. |
|
labeling |
removed |
To influence the labeling, use the nodeLabelPlacement and edgeLabelPlacement properties. |
labelingEnabled |
||
multiParentAllowed |
||
orientationLayout |
removed |
Use layoutOrientation to set the desired layout orientation. |
orientationLayoutEnabled |
||
parallelEdgeRouterEnabled |
parallelEdgeRouter.enabled |
|
selfLoopRouterEnabled |
selfLoopRouter.enabled |
|
sourceGroupDataAcceptor |
removed |
|
sourcePortConstraintDataAcceptor |
removed |
|
subgraphLayout |
removed |
If necessary, the SubgraphLayoutStage can be accessed and enabled via method get<T> of property layoutStages, but this may lead to overlaps. |
subgraphLayoutEnabled |
||
targetGroupDataAcceptor |
removed |
|
targetPortConstraintDataAcceptor |
removed |
|
TreeLayoutData |
||
Properties in class TreeLayoutData |
||
abortHandler |
removed |
A LayoutAbortController is exposed by the LayoutExecutor; see Section Layout Duration and Aborting for more details. |
delegatingNodePlacerPrimaryNodes |
||
edgeLabelPreferredPlacement |
||
gridNodePlacerRowIndices |
||
nodeHalos |
||
nodePlacers |
||
outEdgeComparers |
||
portAssignments |
||
sourcePortConstraints |
ports.sourcePortCandidates |
Moved to sub-data ports. See also migration chapter about Ports in Layout. |
targetPortConstraints |
ports.targetPortCandidates |
|
ITreeLayoutNodePlacer |
||
IFromSketchNodePlacer |
||
NodePlacerBase |
removed |
|
RotatableNodePlacerBase |
removed |
|
AspectRatioNodePlacer |
||
AssistantNodePlacer |
||
BusNodePlacer |
||
CompactNodePlacer |
||
DefaultNodePlacer |
||
DelegatingNodePlacer |
||
DendrogramNodePlacer |
||
DoubleLineNodePlacer |
||
FreeNodePlacer |
||
GridNodePlacer |
||
GroupedNodePlacer |
||
LayeredNodePlacer |
||
LeafNodePlacer |
removed |
Use SingleLayerSubtreePlacer instead. |
LeftRightNodePlacer |
||
SimpleNodePlacer |
removed |
Use SingleLayerSubtreePlacer instead. |
RootAlignment |
||
Constants in RootAlignment |
||
CENTER_OVER_CHILDREN |
||
LEADING |
||
LEADING_OFFSET |
||
TRAILING |
||
TRAILING_OFFSET |
||
LayeredRoutingStyle |
||
Constants in enum LevelAlignedSubtreePlacerRoutingStyle |
||
STRAIGHT |
||
MultiParentRoutingStyle |
enum name unchanged |
|
Constants in enum MultiParentRoutingStyle |
||
STRAIGHT |
||
TreeLayoutEdgeRoutingStyle |
||
Constants in enum SingleLayerSubtreePlacerRoutingStyle |
||
FORK |
||
FORK_AT_ROOT |
||
POLYLINE |
||
STRAIGHT |
||
TreeLayoutPortAssignmentMode |
enum name unchanged |
|
Constants in enum MultiParentRoutingStyle |
||
DISTRIBUTED_EAST |
See section Changed Default Values and Behavior Changes. |
|
DISTRIBUTED_NORTH |
||
DISTRIBUTED_SOUTH |
||
DISTRIBUTED_WEST |
||
NONE |
||
portConstraint |
removed |
See section Changed Default Values and Behavior Changes. |
RotatableNodePlacerMatrix |
||
Constants in enum SubtreeTransform |
||
DEFAULT |
||
MIR_HOR |
||
MIR_VERT |
||
ROT90 |
||
ROT180 |
||
ROT270 |
||
MIR_VERT_ROT90 |
||
MIR_HOR_ROT90 |
||
TreeReductionStage |
class name unchanged |
|
Properties in class TreeReductionStage |
||
multiParentAllowed |
||
nonTreeEdgeLabelSelectionKey |
removed |
Transferring the scope between stages is now handled automatically; see section Layout Scope and Affected Items. |
nonTreeEdgeLabelingAlgorithm |
||
nonTreeEdgeSelectionKey |
removed |
Transferring the scope between stages is now handled automatically; see section Layout Scope and Affected Items. |
AspectRatioTreeLayout |
removed |
Use TreeLayout with AspectRatioSubtreePlacer instead. See section Aspect Ratio Tree Layout for more details. |
ClassicTreeLayout |
removed |
Use TreeLayout instead. See section Classic Tree Layout for more details. |
FamilyTreeLayout |
removed |
Use TreeLayout instead. |
Changed Default Values and Behavior Changes
If non-tree graphs are given as input, they are now temporarily reduced to trees by applying the TreeReductionStage before applying the layout algorithm. The non-tree edges are then routed using the router specified via the TreeReductionStage.nonTreeEdgeRouter. The TreeReductionStage that is used by the TreeLayout is available via the property TreeLayout.treeReductionStage.
Node labels are now considered by default. To change this behavior, set the nodeLabelPlacement property to the desired value. It is now also easier to place the node labels with GenericLabeling by setting the value to GENERIC.
Edge labels are now placed using an integrated edge labeling algorithm. To change this behavior, set the edgeLabelPlacement property to the desired value. It is now also easier to place the edge labels with GenericLabeling by setting the value to GENERIC.
The port assignment modes specified via the property TreeLayoutPortAssigner.mode have been
reduced.
Port candidates are now always considered. It is no longer necessary to set it to PORT_CONSTRAINT
.
The distributed values for the four sides of the node have been combined as
DISTRIBUTED. The side can be specified by defining a free port candidate
on the desired side via the properties on TreeLayoutData.ports.
See also section Ports in Layout for more information.
The MultiLayerSubtreePlacer (formerly GridNodePlacer) now automatically considers custom layers defined
via the property multiLayerSubtreePlacerLayerIndices.
It is no longer necessary to set the property automaticRowAssignment
, which has consequently been removed.
Classic Tree Layout
The ClassicTreeLayout has been superseded by the TreeLayout. To obtain similar results within a similar time frame, the following configuration may be used.
const subtreePlacer = new LevelAlignedSubtreePlacer()
subtreePlacer.alignPorts = false // required (default)
subtreePlacer.busAlignment = 0.6 // can be changed freely
subtreePlacer.dendrogramStyle = false // required (default)
subtreePlacer.layerSpacing = layerDistance // can be changed freely
subtreePlacer.polylineLabeling = false // required (default)
subtreePlacer.rootAlignment = SubtreeRootAlignment.CENTER_OF_PORTS // required
subtreePlacer.edgeRoutingStyle =
LevelAlignedSubtreePlacerRoutingStyle.ORTHOGONAL // or StraightLine
subtreePlacer.spacing = nodeDistance // should be at most BusAlignment * LayerSpacing
subtreePlacer.verticalAlignment = 0.5 // required (default)
const treeLayout = new TreeLayout({
defaultSubtreePlacer: subtreePlacer
})
Aspect Ratio Tree Layout
The AspectRatioTreeLayout has been superseded by the TreeLayout with the AspectRatioSubtreePlacer.
To obtain similar results, use the following configuration, which depends on the previous value of the rootPlacement
.
RootPlacement | childArrangement | rootPlacement |
---|---|---|
Corner |
||
CornerTop |
||
CornerSide |
||
Top |
const subtreePlacer = new AspectRatioSubtreePlacer({
childArrangement: childArrangement,
rootPlacement: rootPlacement
})
const treeLayout = new TreeLayout({
defaultSubtreePlacer: subtreePlacer
})
Major Changes to Expert API
Important
|
The changes described in this chapter only affect developers who work directly with the LayoutGraph API, such as those writing custom layout algorithms. |
Several protected methods of the TreeLayout class have been removed. In many case, these protected methods allowed for customizations that are better handled by setting appropriate values through the appropriate TreeLayoutData properties. The remaining methods still allow extensive customization of the layout process.
Radial Tree Layout (formerly: Balloon Layout)
This chapter describes the major API changes to the RadialTreeLayout (formerly called BalloonLayout
)
introduced with yFiles for HTML 3.0 and how to migrate from the older version.
Like all major layout algorithms, the class no longer inherits from MultiStageLayout
, but implements
ILayoutAlgorithm directly.
The layout stages are now managed by a LayoutStageStack, which can be obtained via
the layoutStages property; see the migration chapter Layout Stages and Multi-Stage Layouts for more details.
Renamed, Moved, and Removed Classes and Members
The following table lists the renamed, moved, and removed classes and members of the major classes of the RadialTreeLayout.
yFiles for HTML 2.6 | yFiles for HTML 3.0 | Remarks |
---|---|---|
BalloonLayout |
||
Properties in class RadialTreeLayout |
||
comparer |
removed |
Use childOrder instead |
componentLayoutEnabled |
componentLayout.enabled |
|
considerNodeLabels |
Has been combined with properties IntegratedNodeLabeling and NodeLabelingPolicy. |
|
fromSketchMode |
removed |
Use the new enum value FROM_SKETCH instead. |
hideGroupsStage |
removed |
The GroupHidingStage is enabled by default and can be accessed via the stack layoutStages. |
hideGroupsStageEnabled |
||
integratedEdgeLabeling |
Is now enabled by default (value INTEGRATED). |
|
integratedNodeLabeling |
Has been combined with properties ConsiderNodeLabeling and NodeLabelingPolicy. |
|
interleavedMode |
removed |
Interleaved placement is automatically activated for nodes that are specified via property interleavedNodes. |
labeling |
removed |
To influence the labeling, use the nodeLabelPlacement and edgeLabelPlacement properties. |
labelingEnabled |
||
layoutOrientation |
removed |
Changing the layout orientation does not make sense for an undirected layout algorithm. |
nodeLabelingPolicy |
Has been combined with properties ConsiderNodeLabeling and IntegratedNodeLabeling. |
|
orientationLayout |
removed |
Changing the layout orientation does not make sense for an undirected layout algorithm. |
orientationLayoutEnabled |
||
parallelEdgeRouterEnabled |
removed |
Use property Enabled on parallelEdgeRouter instead. |
preferredChildWedge |
||
preferredRootWedge |
||
rootNodePolicy |
removed |
A custom root is now always used if defined in treeRoot. |
selfLoopRouterEnabled |
removed |
Use property Enabled on selfLoopRouter instead. |
subgraphLayout |
removed |
If necessary, the SubgraphLayoutStage can be accessed and enabled via method get<T> of property layoutStages, but this may lead to overlaps. |
subgraphLayoutEnabled |
||
BalloonLayoutData |
||
Properties in class RadialTreeLayoutData |
||
abortHandler |
removed |
A LayoutAbortController is exposed by the LayoutExecutor; see Section Layout Duration and Aborting for more details. |
edgeLabelPreferredPlacement |
||
nodeHalos |
||
outEdgeComparer |
Changed Default Values and Behavior Changes
If non-tree graphs are provided as input, the layout algorithm now temporarily reduces them to trees by applying the TreeReductionStage. The non-tree edges are then routed using the router specified via the TreeReductionStage.nonTreeEdgeRouter. The TreeReductionStage used by the RadialTreeLayout is accessible via the property RadialTreeLayout.treeReductionStage.
The from-sketch mode (ordering policy FROM_SKETCH) does no longer take precedence over orders specified via layout data properties childOrder or nodeTypes.
Node labels are now considered by default. To change this behavior, set the nodeLabelPlacement property to the desired value. It is now also easier to place the node labels with GenericLabeling by setting the value to GENERIC.
Edge labels are now placed by default using an integrated edge labeling algorithm. To change this behavior set the edgeLabelPlacement property to the desired value. It is now also easier to place the edge labels with GenericLabeling by setting the value to GENERIC.
The default component arrangement style has been changed to PACKED_CIRCLE. The style can be specified via the ComponentLayout.style property. The ComponentLayout used by the RadialTreeLayout is accessible via the componentLayout property.
The compactnessFactor is now interpreted differently. Larger values now produce more compact layouts. The range of the compactness factor has been changed to the interval between 0 and 1.
Major Changes to Expert API
Important
|
The changes described in this chapter only affect users who work directly with the LayoutGraph API, such as when writing custom layout algorithms. |
Several methods for advanced customization of the layout result have been removed from the API, including
calculateChildArrangement
and calculateAngles
. Overriding these methods should not have been necessary.
To customize the preferred sector angles, the
callback method getPreferredChildSectorAngle is still
available.
The helper class BalloonLayoutNodeInfo
has also been removed. It was only necessary and useful during
the layout process and when overriding advanced methods that have now been removed.
Radial Layout
This section describes the major changes to the RadialLayout class.
As with other major layout algorithms, the RadialLayout class no longer inherits from MultiStageLayout, but instead implements ILayoutAlgorithm directly. The layout stages are now managed by a LayoutStageStack, which can be obtained via the layoutStages property; see Layout Stages and Multi-Stage Layouts for more details.
Renamed, Moved, and Removed Classes and Members
The following table contains the renamed, moved, and removed classes and members of the major classes of the RadialLayout.
yFiles for HTML 2.6 | yFiles for HTML 3.0 | Remarks |
---|---|---|
RadialLayout |
class name unchanged |
|
Properties in class RadialLayout |
||
centerNodesDpKey |
removed |
Use RadialLayoutData.centerNodes. |
componentLayoutEnabled |
componentLayout.enabled |
|
considerNodeLabels |
Has been combined with properties IntegratedNodeLabeling and NodeLabelingPolicy. |
|
edgeRoutingStrategy |
||
hideGroupsStage |
removed |
The RadialLayout is able to handle group nodes itself. |
hideGroupsStageEnabled |
||
integratedNodeLabeling |
Has been combined with properties ConsiderNodeLabeling and NodeLabelingPolicy. |
|
labeling |
removed |
To influence the labeling, use the nodeLabelPlacement and edgeLabelPlacement properties. |
labelingEnabled |
||
layoutOrientation |
removed |
Changing the layout orientation does not make sense for an undirected layout algorithm. |
minimumEdgeToEdgeDistance |
||
minimumNodeToNodeDistance |
||
nodeLabelingPolicy |
Has been combined with properties ConsiderNodeLabeling and IntegratedNodeLabeling. |
|
orientationLayout |
removed |
Changing the layout orientation does not make sense for an undirected layout algorithm. |
orientationLayoutEnabled |
||
parallelEdgeRouterEnabled |
parallelEdgeRouter.enabled |
|
selfLoopRouterEnabled |
selfLoopRouter.enabled |
|
subgraphLayout |
removed |
If necessary, the RadialLayout can be wrapped by a SubgraphLayoutStage, but this may lead to overlaps. |
subgraphLayoutEnabled |
||
RadialLayoutData |
||
Properties in class RadialLayoutData |
||
abortHandler |
removed |
A LayoutAbortController is added by the LayoutExecutor; see Section Layout Duration and Aborting for more details. |
nodeComparables |
childOrder.targetNodeComparables |
Moved to sub-data childOrder. |
nodeHalos |
The type of the values was changed to Insets. |
|
nodeInfos |
||
outEdgeComparers |
childOrder.outEdgeComparators |
Moved to sub-data childOrder. |
CenterNodesPolicy |
enum name unchanged |
|
Constants in enum CenterNodesPolicy |
||
custom |
removed |
Custom center nodes defined via the RadialLayoutData.centerNodes are considered automatically. |
RadialLayoutEdgeRoutingStrategy |
||
RadialLayoutLayeringStrategy |
||
Constants in enum RadialLayeringStrategy |
||
USER_DEFINED |
removed |
Custom layers defined via the RadialLayoutData.layerIds are considered automatically. |
RadialLayoutNodeInfo |
Changed Default Values and Behavior Changes
Node labels are now considered by default. To change this behavior, set the nodeLabelPlacement property to the desired value. This property allows switching between all integrated node labeling policies and placing the node labels with GenericLabeling.
Edge labels are now placed by the GenericLabeling algorithm by default. To change this behavior, set the edgeLabelPlacement property to the desired value.
Port placement now takes the specified port candidates into account. Port candidates can be specified via the properties on the sub-data RadialLayoutData.ports. The ports are placed in a post-processing step by the PortPlacementStage.
If custom layers are defined via the RadialLayoutData.layerIds property, these are
considered automatically, and the value of RadialLayout.layeringStrategy is ignored.
It is no longer necessary to set it to RadialLayoutLayeringStrategy.USER_DEFINED
, which consequently has been removed.
If custom center nodes are defined via the RadialLayoutData.centerNodes property, these
are considered automatically, and the value of RadialLayout.centerNodesPolicy is ignored.
It is no longer necessary to set it to CenterNodesPolicy.CUSTOM
, which consequently has been removed.
Radial Group Layout (formerly: Cactus Group Layout)
This section describes the major API changes to the RadialGroupLayout (formerly CactusGroupLayout).
As with all major layout algorithms, the RadialGroupLayout no longer inherits from MultiStageLayout. Instead, it implements ILayoutAlgorithm directly. The layout stages are now managed by a LayoutStageStack, which can be obtained via the layoutStages property. See Layout Stages and Multi-Stage Layouts for more details.
Renamed, Moved, and Removed Classes and Members
The following table lists the renamed, moved, and removed classes and members of the major classes of the RadialGroupLayout.
yFiles for HTML 2.6 | yFiles for HTML 3.0 | Remarks |
---|---|---|
CactusGroupLayout |
||
Properties in class RadialGroupLayout |
||
componentLayoutEnabled |
componentLayout.enabled |
|
considerNodeLabels |
Has been combined with the properties IntegratedNodeLabeling and NodeLabelingPolicy. |
|
defaultNodeComparer |
removed |
|
groupSizingPolicy |
||
hideGroupsStage |
removed |
The RadialGroupLayout is designed to handle grouped graphs. |
hideGroupsStageEnabled |
||
integratedNodeLabeling |
Has been combined with the properties ConsiderNodeLabeling and NodeLabelingPolicy. |
|
labeling |
removed |
To influence the labeling, use the nodeLabelPlacement and edgeLabelPlacement properties. |
labelingEnabled |
||
layoutOrientation |
removed |
Changing the layout orientation is not relevant for an undirected layout algorithm. |
nodeComparer |
RadialGroupLayoutData.childNodeComparator |
|
nodeLabelingPolicy |
Has been combined with the properties ConsiderNodeLabeling and IntegratedNodeLabeling. |
|
orientationLayout |
removed |
Changing the layout orientation is not relevant for an undirected layout algorithm. |
orientationLayoutEnabled |
||
parallelEdgeRouter |
removed |
The RadialGroupLayout handles parallel edges itself. Thus, this stage is not necessary. |
parallelEdgeRouterEnabled |
||
preferredRootWedge |
||
selfLoopRouter |
removed |
The RadialGroupLayout handles self-loops itself. Thus, this stage is not necessary. |
selfLoopRouterEnabled |
||
subgraphLayout |
removed |
If necessary, the SubgraphLayoutStage can be accessed and enabled via the method get<T> of the property layoutStages, but this may lead to overlaps. |
subgraphLayoutEnabled |
||
CactusGroupLayoutData |
||
Properties in class RadialGroupLayoutData |
||
abortHandler |
removed |
A LayoutAbortController is added by the LayoutExecutor; see Section Layout Duration and Aborting for more details. |
nodeComparer |
||
nodeHalos |
The type of the values was changed to Insets. |
|
CactusGroupLayoutGroupSizingPolicy |
Changed Default Values and Behavior Changes
Edge labels are now placed by the GenericLabeling algorithm by default. To change this behavior, set the edgeLabelPlacement property to the desired value.
Port placement now takes the specified port candidates into account. The ports are placed in a post-processing step by the PortPlacementStage. Port candidates can be specified via the properties on the sub-data RadialGroupLayoutData.ports. See also the section Ports in Layout.
The default value of preferredRootSectorAngle has been changed from 180 degrees to 360 degrees.
Circular Layout
This chapter describes the major API changes to the yWorks.Layout.Circular.CircularLayout introduced with yFiles for HTML 3.0 and how to migrate from the older version.
As with all major layout algorithms, the CircularLayout no longer inherits from MultiStageLayout
,
but implements ILayoutAlgorithm directly.
The layout stages are now managed by a LayoutStageStack, which can be obtained via the
layoutStages property; see Layout Stages and Multi-Stage Layouts for more details.
Renamed, Moved, and Removed Classes and Members
The following table lists the renamed, moved, and removed classes and members of the major classes of the CircularLayout. In addition to the changes listed here, the expert API was streamlined by removing some protected methods of CircularLayout.
yFiles for HTML 2.6 | yFiles for HTML 3.0 | Remarks |
---|---|---|
CircularLayout |
class name unchanged |
|
Properties in class CircularLayout |
||
layoutStyle |
||
singleCycleLayout |
See also SingleCycleLayout |
|
defaultEdgeLayoutDescriptor |
||
balloonLayout |
||
componentLayoutEnabled |
removed |
|
considerNodeLabels |
removed |
|
exteriorEdgeLayoutDescriptor |
||
hideGroupsStage |
removed |
|
hideGroupsStageEnabled |
removed |
|
integratedNodeLabeling |
removed |
|
labeling |
removed |
Can be accessed via layoutStages. |
labelingEnabled |
removed |
Can be enabled via layoutStages. |
layoutOrientation |
removed |
|
nodeLabelingPolicy |
removed |
|
orientationLayout |
removed |
Can be accessed via layoutStages. |
orientationLayoutEnabled |
removed |
OrientationStage can be enabled via layoutStages. |
parallelEdgeRouterEnabled |
removed |
Use property Enabled on parallelEdgeRouter instead. |
partitionStyle |
removed |
Partition style can be set via partitionDescriptor |
selfLoopRouterEnabled |
removed |
Use property Enabled on selfLoopRouter instead. |
subgraphLayout |
removed |
If necessary, the SubgraphLayoutStage can be accessed and enabled via method get<T> of property layoutStages, but this may lead to overlaps. |
subgraphLayoutEnabled |
||
CircularLayoutData |
||
Properties in class CircularLayoutData |
||
circleIds |
||
customGroups |
||
nodeHalos |
||
CircularLayoutEdgeLayoutDescriptor |
||
CircularLayoutEdgeRoutingPolicy |
class name unchanged |
|
Properties in class CircularLayoutEdgeRoutingPolicy |
||
markedExterior |
removed |
To manually select which edges should be routed externally, use the exteriorEdges property instead. |
ExteriorEdgeLayoutDescriptor |
||
Properties in class CircularLayoutExteriorEdgeDescriptor |
||
edgeToEdgeDistance |
||
SingleCycleLayout |
removed |
Use partitioningPolicy set to SINGLE_CYCLE instead. |
Properties of former class |
||
nodeSequencer |
CircularLayoutData.nodeComparator |
Replacement for the former INodeSequencer interface. |
Changed Default Values and Behavior Changes
Node labels are now considered by default. To change this behavior, set the nodeLabelPlacement property to the desired value. It is now also easier to place the node labels with GenericLabeling by setting the value to GENERIC.
Edge labels are now considered by default. To change this behavior, set the edgeLabelPlacement property to the desired value. It is now also easier to place the edge labels with GenericLabeling by setting the value to GENERIC.
The default component arrangement style has been changed to PACKED_CIRCLE. The style can be specified via the ComponentLayout.style property. The ComponentLayout that is used by the CircularLayout is available via the componentLayout property.
Port placement now takes the specified port candidates into account. The ports are placed in a post-processing step by the PortPlacementStage. Port candidates can be specified via the properties on the sub-data CircularLayoutData.ports. See also the section Ports in Layout.
SingleCycleLayout
The class SingleCycleLayout
is no longer available as a standalone layout algorithm. To achieve the same style,
apply the CircularLayout and set partitioningPolicy to SINGLE_CYCLE instead.
Consequently, there is no property singleCycleLayout
on the CircularLayout class anymore.
It has been replaced by the new class PartitionDescriptor. This class offers the properties to configure
the single-cycle layout style that were previously available in the removed SingleCycleLayout
class.
Furthermore, the unit of property initialAngle has been changed from radians to degrees.
Compact Disk Layout
This chapter describes the major API changes to the CompactDiskLayout introduced with yFiles for HTML 3.0 and how to migrate from the older version.
As with all major layout algorithms, the CompactDiskLayout no longer inherits from MultiStageLayout
,
but implements ILayoutAlgorithm directly.
The layout stages are now managed by a LayoutStageStack, which can be obtained via the
layoutStages property; see Layout Stages and Multi-Stage Layouts for more details.
Renamed, Moved, and Removed Classes and Members
yFiles for HTML 2.6 | yFiles for HTML 3.0 | Remarks |
---|---|---|
CompactDiskLayout |
class name unchanged |
|
Properties in class CompactDiskLayout |
||
componentLayout |
removed |
The ComponentLayout is disabled by default. It can be accessed using layoutStages.get<T> and enabled if required. |
componentLayoutEnabled |
||
considerNodeLabels |
The properties have been combined into one - the enum allows tchoosing the strategy. |
|
integratedNodeLabeling |
||
nodeLabelingPolicy |
||
hideGroupsStage |
removed |
The GroupHidingStage is enabled by default and can be accessed via layoutStages.get<T>. |
hideGroupsStageEnabled |
||
labeling |
removed |
To influence the labeling, use the nodeLabelPlacement property. |
labelingEnabled |
||
layoutOrientation |
removed |
Changing the layout orientation does not make sense for an undirected layout algorithm. |
orientationLayout |
removed |
Changing the layout orientation does not make sense for an undirected layout algorithm. |
orientationLayoutEnabled |
||
parallelEdgeRouter |
removed |
The ParallelEdgeRouter is enabled by default and can be accessed via layoutStages.get<T>. |
parallelEdgeRouterEnabled |
||
selfLoopRouter |
removed |
The SelfLoopRouter is enabled by default and can be accessed via layoutStages.get<T>. |
selfLoopRouterEnabled |
||
subgraphLayout |
removed |
If necessary, the SubgraphLayoutStage can be wrapped around the CompactDiskLayout, however, this may lead to overlaps. |
subgraphLayoutEnabled |
||
CompactDiskLayoutData |
||
Properties in class CompactDiskLayoutData |
||
nodeHalos |
Changed Default Values and Behavior Changes
Node labels are now considered by default. To change this behavior, set the nodeLabelPlacement property to the desired value. It is now also easier to place the node labels with GenericLabeling by setting the value to GENERIC.
Port placement now takes the specified port candidates into account. The ports are placed in a post-processing step by the PortPlacementStage. Port candidates can be specified via the properties on the sub-data CompactDiskLayoutData.ports. See also the section Ports in Layout.
Tabular Layout
This chapter describes the major API changes to the TabularLayout introduced with yFiles for HTML 3.0 and how to migrate from the older version.
Renamed, Moved, and Removed Classes and Members
The following table lists the renamed, moved, and removed classes and members of the major classes of the TabularLayout.
yFiles for HTML 2.6 | yFiles for HTML 3.0 | Remarks |
---|---|---|
TabularLayout |
class name unchanged |
|
Properties in class TabularLayout |
||
maximumDuration |
The algorithm attempts to stop within the given time, but it is not guaranteed to do so. The property was renamed to better reflect this behavior. |
|
defaultNodeLayoutDescriptor |
||
layoutPolicy |
||
considerNodeLabels |
removed |
Can now be specified with property nodeLabelPlacement. |
nodeComparer |
removed |
Can now be specified with property freeNodeComparator. |
TabularLayoutData |
class name unchanged |
|
Properties in class TabularLayoutData |
||
nodeHalos |
||
nodeLayoutDescriptors |
||
partitionGridData |
||
TabularLayoutPolicy |
||
TabularLayoutNodeLayoutDescriptor |
Changed Default Values and Behavior Changes
Edge labels are now placed using the GenericLabeling algorithm by default. To change this behavior, set the edgeLabelPlacement property to the desired value.
The nodeComparer
property was removed from class TabularLayout. To specify the order of free nodes,
use freeNodeComparator instead.
Series-parallel Layout
This chapter describes the major API changes to the SeriesParallelLayout introduced with yFiles for HTML 3.0 and how to migrate from the older version.
As with all major layout algorithms, the SeriesParallelLayout no longer inherits from MultiStageLayout, but implements ILayoutAlgorithm directly. The layout stages are now managed by a LayoutStageStack, which can be obtained via the layoutStages property; see the migration chapter Layout Stages and Multi-Stage Layouts for more details.
Renamed, Moved, and Removed Classes and Members
The following table contains the renamed, moved, and removed classes and members of the major classes of the SeriesParallelLayout.
yFiles for HTML 2.6 | yFiles for HTML 3.0 | Remarks |
---|---|---|
SeriesParallelLayout |
class name unchanged |
|
Properties in class SeriesParallelLayout |
||
componentLayoutEnabled |
componentLayout.enabled |
|
considerNodeLabels |
The enum now allows you to choose between considering the node labels and the GenericLabeling algorithm. |
|
defaultEdgeLayoutDescriptor |
||
defaultOutEdgeComparer |
removed |
Use SeriesParallelLayoutData.childOrder instead. |
defaultPortAssignment |
||
generalGraphHandling |
removed |
Non-series-parallel graphs are always handled now. |
hideGroupsStage |
removed |
The SeriesParallelLayout is able to handle group nodes itself. |
hideGroupsStageEnabled |
||
integratedEdgeLabeling |
The enum now allows you to choose between integrated labeling and the GenericLabeling algorithm. |
|
labeling |
removed |
To influence the labeling, use the nodeLabelPlacement, edgeLabelPlacement, and nonSeriesParallelEdgeLabelingproperties. |
labelingEnabled |
||
minimumEdgeToEdgeDistance |
||
minimumNodeToNodeDistance |
||
nonSeriesParallelEdgeLabelSelectionKey |
removed |
PLACE_EDGE_LABELS_DATA_KEY is always used now. |
nonSeriesParallelEdgeLabelingAlgorithm |
||
nonSeriesParallelEdgesDpKey |
removed |
ROUTE_EDGES_DATA_KEY is always used now. |
orientationLayout |
removed |
Use layoutOrientation to set the desired layout orientation. |
orientationLayoutEnabled |
||
parallelEdgeRouterEnabled |
parallelEdgeRouter.enabled |
|
routingStyle |
||
selfLoopRouterEnabled |
selfLoopRouter.enabled |
|
subgraphLayout |
removed |
If necessary, the SubgraphLayoutStage can be accessed and enabled via method get<T> of property layoutStages, but this may lead to overlaps. |
subgraphLayoutEnabled |
||
verticalAlignment |
||
SeriesParallelLayoutData |
||
Properties in class SeriesParallelLayoutData |
||
abortHandler |
removed |
A LayoutAbortController is added by the LayoutExecutor; see Section Layout Duration and Aborting for more details. |
edgeLabelPreferredPlacement |
||
edgeLayoutDescriptors |
||
outEdgeComparers |
childOrder.outEdgeComparators |
|
portAssignments |
||
ISeriesParallelLayoutPortAssignment |
||
DefaultSeriesParallelLayoutPortAssignment |
||
Properties in class SeriesParallelLayoutPortAssigner |
||
borderGapToPortGapRatio |
||
forkStyle |
removed |
Has been combined with mode. |
ForkStyle |
removed |
Has been combined with SeriesParallelLayoutPortAssignmentMode. |
SeriesParallelLayoutEdgeLayoutDescriptor |
||
DefaultOutEdgeComparer |
removed |
Changed Default Values and Behavior Changes
Non-series-parallel graphs are now handled by default.
The property generalGraphHandling
is no longer required and has been removed.
Node labels are now considered by default. To change this behavior, set the nodeLabelPlacement property to the desired value. It is now also easier to place the node labels with GenericLabeling by setting the value to GENERIC.
Edge labels are now placed by an integrated edge labeling algorithm. To change this behavior, set the edgeLabelPlacement property to the desired value. It is now also easier to place the edge labels with GenericLabeling by setting the value to GENERIC.
Port placement now takes the specified port candidates into account. The ports are placed in a post-processing step by the PortPlacementStage. Port candidates can be specified via the properties on the sub-data SeriesParallelLayoutData.ports. See also the section Ports in Layout.
Edge Router
This chapter describes the major API changes to the EdgeRouter introduced with yFiles for HTML 3.0 and how to migrate from the older version.
Renamed, Moved, and Removed Classes and Members
The following table contains the renamed, moved, and removed classes and members of the major classes of the EdgeRouter. In addition to the changes listed here, the expert API to customize path search behavior was streamlined as well; see Major Changes to Expert API.
yFiles for HTML 2.6 | yFiles for HTML 3.0 | Remarks |
---|---|---|
EdgeRouter |
class name unchanged |
|
Properties in class EdgeRouter |
||
considerEdgeLabels |
Combined the two properties. The enum now allows you to choose between integrated labeling and the GenericLabeling algorithm. |
|
integratedEdgeLabeling |
||
considerNodeLabels |
The enum now allows you to choose between considering the node labels and the GenericLabeling algorithm. |
|
defaultEdgeLayoutDescriptor |
Settings for individual edges can be specified via the edgeDescriptors property of EdgeRouterData. |
|
edgeComparer |
EdgeRouterData.edgeProcessingComparator |
Moved to layout data. |
grid |
Is now a simple numeric value. Set to zero to disable grid. |
|
ignoreInnerNodeLabels |
removed |
Controlled via nodeLabelPlacement. Inner labels of non-group nodes are only ignored when choosing settings IGNORE; labels of group nodes alone can be ignored when choosing IGNORE_GROUP_LABELS. |
maximumDuration |
The router tries to stop within the given time, but it is not guaranteed to do so. The property was renamed to signal this intent better. |
|
polylineRouting |
removed |
Use routingStyle on the descriptor instead. |
preferredPolylineSegmentLength |
removed |
Use preferredOctilinearSegmentLength on the descriptor instead. |
maximumPolylineSegmentRatio |
removed |
Use maximumOctilinearSegmentRatio on the descriptor instead. |
scope |
removed |
The routed edges can instead be selected using scope |
EdgeRouterData |
||
Properties in class EdgeRouterData |
||
affectedEdges |
scope.edges |
Moved to sub-data scope. See migration chapter about Layout Scope and Affected Items. |
affectedNodes |
scope.incidentNodes |
Moved to sub-data scope. See migration chapter about Layout Scope and Affected Items. |
edgeLabelPreferredPlacement |
||
edgeLayoutDescriptors |
||
nodeHalos |
The type of the values was changed to Insets. |
|
nodePortCandidatesSet |
ports.nodePortCandidates |
Moved to sub-data ports. See also Ports in Layout. |
partitionGridData |
||
sourcePortCandidates |
ports.sourcePortCandidates |
Moved to sub-data ports. PortCandidates and PortConstraints are now combined in one concept; see migration chapter about Ports in Layout. |
sourcePortConstraints |
||
sourcePortGroupIds |
ports.sourcePortGroupIds |
Moved to sub-data ports. |
targetPortCandidates |
ports.targetPortCandidates |
Moved to sub-data ports. PortCandidates and PortConstraints are now combined in one concept; see migration chapter about Ports in Layout. |
targetPortConstraints |
||
targetPortGroupIds |
ports.targetPortGroupIds |
Moved to sub-data ports. |
EdgeRouterEdgeLayoutDescriptor |
||
Properties in class EdgeRouterEdgeDescriptor |
||
penaltySettings |
||
minimumEdgeToEdgeDistance |
||
PenaltySettings |
||
Properties in class EdgeRouterCosts |
||
minimumEdgeToEdgeDistancePenalty |
Changed Default Values and Behavior Changes
With buses and a limited duration, the available time is now split among buses. This means that the algorithm will not get "stuck" on a single bus, which could otherwise negatively affect the quality of the remaining buses and non-bus edge routes.
Node labels are now considered by default. To change this behavior, set the nodeLabelPlacement property to the desired value. It is now also easier to place the node labels with GenericLabeling by setting the value to GENERIC.
Edge labels are now placed by a generic labeling algorithm by default. To change this behavior, set the edgeLabelPlacement property to the desired value.
ChannelEdgeRouter Replacement
The EdgeRouter is the replacement for the removed classes ChannelEdgeRouter
,
OrthogonalPatternEdgeRouter
, and OrthogonalSegmentDistributionStage
.
To configure it to have similar performance and generate similar results as the removed ChannelEdgeRouter
,
set the stopDuration property to zero and use the predefined cost configuration
LOW_QUALITY. However, it is not compatible with advanced features like integrated edge label placement.
const fastEdgeRouter = new EdgeRouter({
stopDuration: TimeSpan.ZERO,
defaultEdgeDescriptor: { edgeRouterCosts: EdgeRouterCosts.LOW_QUALITY }
})
graph.applyLayout(fastEdgeRouter)
Scope
yFiles for HTML 3.0 introduces more powerful options to configure the scope of the edge routing algorithm. The new EdgeRouterScopeData<TNode,TEdge,TNodeLabel,TEdgeLabel> still offers functionality to specify the affected edges directly or based on their incident nodes. In addition, it is now possible to assign one of the more differentiated EdgeRouterScope policies to each individual edge, using the scope's new edgeMapping and incidentNodeMapping properties.
For more information on changes to the Scope API, see Layout Scope and Affected Items.
const edgeRouter = new EdgeRouter()
const routerData = edgeRouter.createLayoutData(graph)
routerData.scope.edgeMapping.mapperFunction = (edge: LayoutEdge) => {
if (edge === edge1) {
// edge1 is always routed
return EdgeRouterScope.PATH
}
if (edge === edge2) {
// edge2 is only routed if necessary
return EdgeRouterScope.PATH_AS_NEEDED
}
if (edge === edge3) {
// only segments of edge3 are routed if necessary
return EdgeRouterScope.SEGMENTS_AS_NEEDED
}
// other edges are not affected
return EdgeRouterScope.IGNORE
}
BusRouter Replacement
The EdgeRouter is the replacement for the removed class BusRouter
.
While it was already able to create bus-style orthogonal edge routes in yFiles for HTML 2.6, the quality
has been improved. Buses are defined very similarly to the old BusRouter
by using a descriptor class
and property buses on class EdgeRouterData.
Major Changes to Expert API
Important
|
The changes described in this section only affect users who directly worked with the LayoutGraph API, such as when writing custom layout algorithms. |
This section provides a broad overview of the changes to the classes that allow advanced customization of the routing and path search algorithm of EdgeRouter. It is not a complete list of all changes.
Note
|
The protected and expert API to customize the routing behavior of EdgeRouter has been simplified considerably. This makes it less powerful in some ways, but also easier to use when required. |
-
Class PathSearchExtension still exists and allows you to influence the search process via various callback methods. You can add extensions to the router with the method addPathSearchExtension.
-
Class
IGraphPartitionExtension
has been removed and replaced by PartitionExtension. You can add custom partition extensions with the method addPartitionExtension. -
Classes/interfaces that have been removed without direct replacement include
PathSearch
,PathSearchResult
,ChannelBasedPathRouting
,IObstaclePartition
,IPartition
,GraphPartition
, andIGraphPartitionExtension
. -
Multiple callback methods on EdgeRouter have been removed because they are now obsolete.
Organic Edge Router
This chapter describes the major API changes to the OrganicEdgeRouter introduced with yFiles for HTML 3.0 and how to migrate from the older version.
Renamed, Moved, and Removed Classes and Members
yFiles for HTML 2.6 | yFiles for HTML 3.0 | Remarks |
---|---|---|
OrganicEdgeRouter |
class name unchanged |
|
Properties in class OrganicEdgeRouter |
||
createNodeEnlargementStage |
Enabling the new property has the same effect as previously appending the stage created by the removed factory method. |
|
edgeNodeOverlapsAllowed |
||
OrganicEdgeRouterData |
||
Properties in class OrganicEdgeRouterData |
||
abortHandler |
removed |
A LayoutAbortController is exposed by the LayoutExecutor; see Section Layout Duration and Aborting for details. |
affectedEdges |
scope.edges |
Moved to sub-data scope. See section below (Scope) and general information about scope migration in Layout Scope and Affected Items. |
Changed Default Values and Behavior Changes
Port placement now considers the specified port candidates. The ports are placed in a post-processing step by the PortPlacementStage. Port candidates can be specified using the properties on the sub-data OrganicEdgeRouterData.ports. See also the section Ports in Layout.
Scope
yFiles for HTML 3.0 introduces more powerful options to configure the scope (the set of edges to route) of the organic router. The new scope property offers functionality to specify the affected edges directly or based on their incident nodes.
For more information on changes to the Scope API, see Layout Scope and Affected Items.
const organicEdgeRouter = new OrganicEdgeRouter()
const organicRouterData = organicEdgeRouter.createLayoutData(graph)
organicRouterData.scope.edges.predicate = (edge: any) => {
if (edge === edge1 || edge === edge2) {
// edge1 and edge2 are routed
return true
}
// all others are not routed
return false
}
// additionally, all edges incident to node1 are routed as well
organicRouterData.scope.incidentNodes.items.add(node)
Generic Labeling
This chapter describes the major API changes to the GenericLabeling introduced with yFiles for HTML 3.0 and explains how to migrate from the older version.
Renamed, Moved, and Removed Classes and Members
yFiles for HTML 2.6 | yFiles for HTML 3.0 | Remarks |
---|---|---|
GenericLabeling |
class name unchanged |
|
Members of class GenericLabeling |
||
affectedLabelsDpKey |
Scope keys are now shared between layout algorithms |
|
autoFlipping |
removed |
Automatically flipping labels right-side up is handled by the view, e.g. SmartEdgeLabelModel.autoRotation |
customProfitModelRatio |
removed |
Custom candidate weights and calculated weights can be combined using nodeLabelCandidateProcessors and edgeLabelCandidateProcessors |
edgeGroupOverlapAllowed |
removed |
|
label |
removed |
Run the GenericLabeling algorithm normally. To specify a subset of labels to place see Scope |
maximumDuration |
||
cptimizationStrategy |
||
placeEdgeLabels |
||
placeNodeLabels |
||
getProfit |
removed |
Specifying custom profits for label candidates has been reworked; see Candidate Positions |
profitModel |
removed |
Specifying custom profits for label candidates has been reworked; see Candidate Positions |
reduceAmbiguity |
removed |
Ambiguity can be penalized using LabelingCosts.ambiguousPlacementCost |
removeEdgeOverlaps |
removed |
|
removeNodeOverlaps |
removed |
|
LabelingData |
||
Properties in class GenericLabelingData |
||
abortHandler |
removed |
The LayoutAbortController is now added by the LayoutExecutor and can be set directly on the LayoutGraphContext |
affectedLabels |
||
edgeLabelModels |
Valid edge label positions are instead specified as EdgeLabelCandidates; see Candidate Positions |
|
nodeLabelModels |
Valid node label positions are instead specified as NodeLabelCandidates; see Candidate Positions |
|
edgeLabelPreferredPlacement |
||
nodeHalos |
||
OptimizationStrategy |
Candidate Positions
yFiles for HTML 3.0 replaces the previous concept of specifying valid label positions using models with the more flexible NodeLabelCandidates and EdgeLabelCandidates. These sets of candidate positions offer convenience methods to create positions corresponding to the previous model implementations, as well as new functionality to add fixed positions. Additionally, weights can be specified for each individual candidate to designate preferred positions.
// specify candidates with different weights (lower weight means that it is less likely chosen by the algorithm)
// creates slider candidates on the left side
const leftSliderCandidates =
new EdgeLabelCandidates().addSliderCandidates({
mode: 'single-side',
distance: 10,
weight: 1
})
// adds slider candidates with lower weight on the right side
const candidates = leftSliderCandidates.addSliderCandidates({
mode: 'single-side',
distance: -5,
weight: 0
})
// apply layout
const labeling = new GenericLabeling()
const labelingData = labeling.createLayoutData(graph)
labelingData.edgeLabelCandidates.constant = candidates
labeling.applyLayout(graph)
Instead of specifying the weights when creating the candidates, the nodeLabelCandidateProcessors and edgeLabelCandidateProcessors also offer the option to adjust the weights during the execution of the generic labeling algorithm. This approach is especially helpful when the priorities of label candidates depend on the result of another layout that has not yet run at the time when candidates are specified. Note that, when the delegate is called, the label candidates already contain the weights calculated by the labeling algorithm.
const weightRatio = 0.8
labelingData.edgeLabelCandidateProcessors.constant = (
candidates: IEnumerable<LabelCandidate>,
label: LayoutEdgeLabel
) => {
for (const labelCandidate of candidates) {
const customWeight = calculateCustomWeight(label, labelCandidate)
// the new weight combines the weight already calculated by the labeling algorithm with a custom weight
labelCandidate.weight =
labelCandidate.weight * (1 - weightRatio) +
customWeight * weightRatio
}
}
Scope
The generic labeling algorithm now offers more convenient ways to specify the labels it should handle. While it is still possible to simply restrict the scope to edge labels or node labels using GenericLabeling.scope, the new scope property of the generic labeling data offers the option to select individual labels, either directly or based on their owners.
For more information on the changed scope API, see Layout Scope and Affected Items.
Optimization Strategy
The labeling algorithm’s optimizationStrategy
property for prioritizing different layout qualities has been removed.
Instead, the optimization strategy can be specified using LabelingCosts and
LabelingOptimizationStrategy for each node label or edge label. Each of the old optimization
strategies corresponds to a LabelingOptimizationStrategy
, which can be used to construct a LabelingCosts
instance that
replicates the old behavior. Costs applying to all node labels and edge labels respectively can be
specified with defaultNodeLabelingCosts and
defaultEdgeLabelingCosts. Individual costs that supersede the default may be
specified using the nodeLabelingCosts
and edgeLabelingCosts properties
of the labeling data.
Note that there is also a new cost preset AMBIGUOUS_PLACEMENTS that replaces the old reduceAmbiguity property of the generic labeling algorithm.
Partial Layout
This chapter describes the major API changes to the PartialLayout introduced with yFiles for HTML 3.0 and how to migrate from the older version.
Renamed, Moved, and Removed Classes and Members
yFiles for HTML 2.6 | yFiles for HTML 3.0 | Remarks |
---|---|---|
PartialLayout |
class name unchanged |
|
Members of class PartialLayout |
||
EdgeRoutingStrategy |
||
MaximumDuration |
The algorithm tries to stop within the given time, but it is not guaranteed to do so. The property was renamed to signal this intent better. |
|
ConfigureEdgeRouter |
removed |
The callback method has been removed. Use property edgeRouter to apply a custom edge routing configuration. |
layoutSubgraph |
removed |
|
PartialLayoutData |
||
Properties in class PartialLayoutData |
||
abortHandler |
removed |
A LayoutAbortController is exposed by the LayoutExecutor; see Section Layout Duration and Aborting for more details. |
affectedEdges |
scope.edges |
All settings related to the scope have been combined into the sub-data scope. |
affectedNodes |
scope.nodes |
All settings related to the scope have been combined into the sub-data scope. |
directedEdges |
Besides the renaming, the type of the ItemMapping was changed. It now assigns to each edge a value from [-1,0,1]. |
|
nodeHalos |
||
partitionGridData |
||
sourcePortCandidates |
ports.sourcePortCandidates |
Moved to sub-data ports. PortCandidates and PortConstraints are now combined in one concept; see migration chapter about Ports in Layout. |
sourcePortConstraints |
||
targetPortCandidates |
ports.targetPortCandidates |
Moved to sub-data ports. PortCandidates and PortConstraints are now combined in one concept; see migration chapter about Ports in Layout. |
targetPortConstraints |
||
PartialLayoutEdgeRoutingStrategy |
The enum that is the return type of property edgeRoutingStyle has been renamed. |
Changed Default Values and Behavior Changes
The CUSTOMIZED
value of the ComponentAssignmentStrategy enum has been removed. Custom components are now automatically
used if they are defined with componentIds.
Clear Area Layout
This chapter describes the major API changes to the ClearAreaLayout introduced with yFiles for HTML 3.0 and how to migrate from the older version.
Renamed, Moved, and Removed Classes and Members
yFiles for HTML 2.6 | yFiles for HTML 3.0 | Remarks |
---|---|---|
ClearAreaLayout |
class name unchanged |
|
Members of class ClearAreaLayout |
||
considerEdgeLabels |
The enum now allows you to choose between considering the edge labels and the GenericLabeling algorithm. |
|
considerNodeLabels |
The enum now allows you to choose between considering the node labels and the GenericLabeling algorithm. |
|
edgeRoutingStrategy |
||
maximumDuration |
The algorithm tries to stop within the given time, but it is not guaranteed to do so. The property was renamed to better reflect this intent. |
|
configureEdgeRouter |
removed |
The callback method has been removed. Use property edgeRouter to apply a custom edge routing configuration. |
ClearAreaLayoutData |
||
Properties in class ClearAreaLayoutData |
||
abortHandler |
removed |
A LayoutAbortController is exposed by the LayoutExecutor; see Section Layout Duration and Aborting for more details. |
nodeHalos |
||
partitionGridData |
||
sourcePortCandidates |
ports.sourcePortCandidates |
Moved to sub-data ports. PortCandidates and PortConstraints are now combined in one concept; see migration chapter about Ports in Layout. |
sourcePortConstraints |
||
sourcePortGroupIds |
ports.sourcePortGroupIds |
Moved to sub-data ports. |
targetPortCandidates |
ports.targetPortCandidates |
Moved to sub-data ports. PortCandidates and PortConstraints are now combined in one concept; see migration chapter about Ports in Layout. |
targetPortConstraints |
||
targetPortGroupIds |
ports.targetPortGroupIds |
Moved to sub-data ports. |
PartialLayoutEdgeRoutingStrategy |
The enum that is the return type of property edgeRoutingStyle has been renamed. |
Changed Default Values and Behavior Changes
The value CUSTOMIZED
of enum ComponentAssignmentStrategy has been removed. Custom components are now automatically
used if defined with componentIds.
Fill Area Layout
This chapter describes the major API changes to the FillAreaLayout introduced with yFiles for HTML 3.0 and how to migrate from the older version.
Renamed, Moved, and Removed Classes and Members
yFiles for HTML 2.6 | yFiles for HTML 3.0 | Remarks |
---|---|---|
FillAreaLayout |
class name unchanged |
|
Properties in class FillAreaLayout |
||
considerEdgeLabels |
The enum now allows you to choose between considering the edge labels and using the GenericLabeling algorithm. |
|
considerNodeLabels |
The enum now allows you to choose between considering the node labels and using the GenericLabeling algorithm. |
|
maximumDuration |
The algorithm tries to stop within the given time, but it is not guaranteed to do so. The property was renamed to better reflect this behavior. |
|
FillAreaLayoutData |
||
Properties in class FillAreaLayoutData |
||
abortHandler |
removed |
A LayoutAbortController is exposed by the LayoutExecutor; see Section Layout Duration and Aborting for more details. |
nodeHalos |
||
partitionGridData |
Changed Default Values and Behavior Changes
The CUSTOMIZED
value of the ComponentAssignmentStrategy enumeration has been removed. Custom components are now automatically
used if they are defined using componentIds.
Multi-Page Layout
This chapter describes the major API changes to the MultiPageLayout introduced with yFiles for HTML 3.0 and how to migrate from the older version.
Renamed, Moved, and Removed Classes and Members
The following table lists the renamed, moved, and removed classes and members of the major classes of the MultiPageLayout.
yFiles for HTML 2.6 | yFiles for HTML 3.0 | Remarks |
---|---|---|
MultiPageLayout |
class name unchanged |
|
Members in class MultiPageLayout |
||
calculateLayout |
removed |
Instead, apply the layout like any other and get the result from the layoutCallback. |
createProxyReferenceNodes |
||
edgeBundleModeMask |
||
groupingMode |
||
labeling |
The new read-only property is of type GenericLabeling |
|
labelingEnabled |
||
name unchanged |
Is no longer an instance of the removed yFiles interface
|
|
maximumDuration |
The algorithm tries to stop within the given time, but it is not guaranteed to do so. The property was renamed to better signal this intent. |
|
MultiPageLayoutData |
||
Properties in class MultiPageLayoutData |
||
abortHandler |
removed |
A LayoutAbortController is added by the LayoutExecutor; see Section Layout Duration and Aborting for more details. |
edgeIds, edgeLabelIds, nodeIds, nodeLabelIds |
removed |
Manually mapping IDs is no longer required. The data class assigns them automatically, and original items can be accessed by new methods like, for example, getOriginalItem. |
edgeBundles |
||
EdgeBundleModes |
||
IElementFactory |
||
DefaultElementFactory |
||
IElementInfoManager |
removed |
Information about items can be queried using methods of MultiPageLayoutContext class which is accessed from property context. |
LayoutContext |
||
ILayoutCallback |
interface removed |
|
GroupingMode |
||
MultiPageLayout.Result |
type name unchanged |
|
Properties in class MultiPageLayoutResult |
||
getPage |
removed |
Replaced by new property pageGraphs. |
pageCount |