documentationfor yFiles for HTML 3.0.0.3

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:

In addition, the ICanvasObject interface and related types have been renamed and slightly adjusted. In particular:

ICanvasObject changes
yFiles for HTML 2.6 yFiles for HTML 3.0

ICanvasObject

IRenderTreeElement

ICanvasObjectGroup

IRenderTreeGroup

ICanvasObjectDescriptor

IObjectRenderer<TRenderTag>

getCanvasObjects

getElements

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 on ICanvasObjectDescriptor in favor of new RenderTree createElement 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 that VisualTemplate was removed from the API. Related resource keys are removed, and usages should be replaced with a renderer 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

addEventListener

Syntax

addEventListener(eventName, callback, options)

Component

Description

Method Name

removeEventListener

Syntax

removeEventListener(eventName, callback)

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 - An AbortController 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

Example 2. Old API
graph.addNodeCreatedListener(callback)
Example 3. New API
graph.addEventListener('node-created', callback)

Migration Steps

  1. Replace specific listener methods with addEventListener.

  2. Convert event names to lowercase and use dashes as separators.

  3. Add an options object when needed.

Callback Signature Changes

Old Signature

New Signature

(sender, eventArgs)

(eventArgs, sender)

Example 4. Example - Old API
graph.addNodeCreatedListener((sender, eventArgs) => {
    // handle node creation
})
Example 5. Example - New API
graph.addEventListener('node-created', (eventArgs) => {
    // handle node creation
})

Important Notes

  • The sender argument has been moved to after the event argument in callbacks.

  • Event handling now focuses directly on event arguments, which can conveniently be destructured, and the sender can be omitted. Typically, the sender 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 old TouchEventArgs.

  • 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

MouseEventArgs

buttons

Use the PointerButtons enum.

MouseEventArgs

changedButtons

Use the PointerButtons enum.

MouseEventArgs

changedModifiers

MouseEventArgs

clickCount

clickCount now also applies for touch taps, pen button clicks, and surface contacts.

MouseEventArgs

defaultPrevented

MouseEventArgs

deltaMode

originalEvent.deltaMode

Check if originalEvent is a WheelEvent first.

MouseEventArgs

eventType

Use the PointerEventType enum. Note the different values.

MouseEventArgs

location

MouseEventArgs

modifiers

Use the ModifierKeys enum.

MouseEventArgs

originalEvent

May be null or undefined.

MouseEventArgs

scrollAmount

Not available

Removed. Use originalEvent (native DOM event) if needed.

MouseEventArgs

wheelDelta

MouseEventArgs

wheelDeltaX

TouchEventArgs

changedModifiers

TouchEventArgs

defaultPrevented

TouchEventArgs

device

pointerId, isPrimary

TouchEventArgs

eventType

Use the PointerEventType enum. Note the different values.

TouchEventArgs

location

TouchEventArgs

modifiers

TouchEventArgs

originalEvent

May be null or undefined.

TouchEventArgs

tapCount

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

MOUSE_LEFT

The left mouse button.

Remains the same.

MOUSE_MIDDLE

The middle mouse button.

Remains the same.

MOUSE_RIGHT

The right mouse button.

Remains the same.

MOUSE_X1

Extra mouse button 1.

Remains the same.

MOUSE_X2

Extra mouse button 2.

Remains the same.

NONE

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

Example 6. Example: Old (yFiles for HTML 2.6) API
graphComponent.addMouseMoveListener((sender, evt: MouseEventArgs) => {
  const worldLocation = evt.location
  console.log(`Mouse moved to: ${worldLocation.x}, ${worldLocation.y}`)
})
Example 7. Example: New (yFiles for HTML 3.0) API
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

Example 8. Example: Old (yFiles for HTML 2.6) API
graphComponent.addTouchTapListener((sender, evt: TouchEventArgs) => {
  const worldLocation = evt.location
  console.log(`Touch tapped at: ${worldLocation.x}, ${worldLocation.y}`)
})
Example 9. Example: New (yFiles for HTML 3.0) API
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: The scrollAmount property from MouseEventArgs 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:

Example 10. Example - Old API
graphComponent.addMouseDownListener((sender, mouseEventArgs) => {
    // handle mouse down
})
Example 11. Example - New API
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 their addEventListener 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.

Example 12. Example: Changing Edge Creation to Work Like in yFiles for HTML 2.6
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 to Control where appropriate.

  • Arrow Keys Constant Names: The simple direction keys (Up, Down, Left, Right) have been replaced with ArrowUp, ArrowDown, ArrowLeft, and ArrowRight.

  • 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 to UpdateContentBounds.

  • Stripe Insets Key Renamed: The keys SetStripeInsets.RedoName and SetStripeInsets.UndoName have been renamed to SetStripePadding.RedoName and SetStripePadding.UndoName.

The names of the shortcut modifiers have been adjusted. If you have customized them, replace Ctrl with Control.

Changed Shortcuts
Key Old Value New Value

RedoKey

Control+Y;Command+Shift+Z

Action+Y;Action+Shift+Z

ExpandGroupKey

Action+Add

Alt+ArrowRight

CollapseGroupKey

Control+Subtract

Alt+ArrowLeft

ToggleExpansionStateKey

Action+Multiply

Alt+Shift+ArrowLeft;Alt+Shift+ArrowRight

EnterGroupKey

Action+Enter

Alt+ArrowDown

ExitGroupKey

Action+Backspace

Alt+ArrowUp

EditLabelKey

F2

F2;Enter

To revert to the original shortcut, set the property to the "old value."

Example: Using a Different Keyboard shortcut
yfiles.resources["invariant"]["ExtendSelectionUpKey"] = "Control+ArrowUp"
Added Shortcuts
Key Value

DecreaseZoomKey

Action+Subtract

ExtendSelectionHierarchyDownKey

Shift+Control+PageDown

ExtendSelectionHierarchyUpKey

Shift+Control+PageUp

IncreaseZoomKey

Action+Add

MoveFocusLeftKey

Action+ArrowLeft

MoveFocusRightKey

Action+ArrowRight

MoveFocusHierarchyDownKey

Control+PageDown

MoveFocusHierarchyUpKey

Control+PageUp

MoveHierarchyDownKey

Alt+PageDown

MoveHierarchyUpKey

Alt+PageUp

ZoomKey

Action+0;Alt+0

FitGraphBoundsKey

Alt+1

ZoomToCurrentItemKey

Alt+3

ZoomToSelectionKey

Alt+2

Example 13. Example: Disabling a Keyboard Shortcut
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

primaryColor

--yfiles-theme-primary

#000000

secondaryColor

--yfiles-theme-secondary

#3399ff

backgroundColor

--yfiles-theme-background

#ffffff

variant

--yfiles-theme-variant

round-hatched

Possible values: round, round-hatched, square, square-hatched

scale

--yfiles-theme-scale

1

hatchRectangle

n/a

Removed. Set --yfiles-theme-variant to round-hatched or square-hatched.

hatchStroke

n/a

Removed. Set --yfiles-theme-variant to round-hatched or square-hatched.

n/a

--yfiles-theme-handle-offset

2

New. This offset prevents handles from overlapping ports.

n/a

--yfiles-theme-indicator-offset

2

New

ThemeVariant.CLASSIC has been removed and has no CSS replacement.

Migration Example

Example 14. Old API
graphComponent.theme = new Theme({ scale: 2 })
Example 15. New CSS
<div id="graphComponent" style="--yfiles-theme-scale: 2"></div>
Example 16. Or programmatically
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.

Migration Steps
  1. Remove any special handling for WebGL styles.

  2. Use standard style interfaces when specifying styles during:

    • Node creation

    • Edge creation

    • Label creation

  3. Apply WebGL style instances directly in or during:

    • Element creation

    • Factories

    • Defaults

  4. 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.

Example: Specifying WebGL2 Style instances
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.

Example: Specifying a WebGL2 Style and an SVG Style for Level of Detail Rendering
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

WebGL2Animation

WebGL2AnimationDirection

WebGL2AnimationEasing

WebGL2AnimationTiming

WebGL2ArcEdgeStyle

WebGL2ArrowType

WebGL2BeaconAnimationType

WebGL2BeaconNodeIndicatorStyle

WebGL2BridgeEdgeStyle

WebGL2DashStyle

WebGL2DefaultLabelStyle

WebGL2EdgeIndicatorStyle

WebGL2Effect

WebGL2FadeAnimationType

WebGL2FocusIndicatorManager

WebGL2GraphModelManager

WebGL2GraphModelManagerRenderMode

WebGL2GroupNodeStyle

WebGL2HighlightIndicatorManager

WebGL2IconLabelStyle

WebGL2IconNodeStyle.icon

WebGL2IconNodeStyle.iconColor

WebGL2IndicatorType

WebGL2LabelIndicatorShape

WebGL2LabelIndicatorStyle

WebGL2LabelShape

WebGL2LineCap

WebGL2NodeIndicatorShape

WebGL2NodeIndicatorStyle

WebGL2PolylineEdgeStyle

WebGL2PulseAnimationType

WebGL2ScaleAnimationType

WebGL2SelectionIndicatorManager

WebGL2ShakeAnimationType

WebGL2ShapeNodeShape

WebGL2ShapeNodeShape.Hexagon2

WebGL2ShapeNodeStyle

WebGL2Stroke

WebGL2TextureRendering

WebGL2Transition

WebGL2TransitionProperties

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:

  • Renamed methods:

  • Changes to method signatures:

    • cut and copy no longer return an object. If you need to pass information between cut/copy and paste, store that information in your implementing class (on this).

    • 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:

  • 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

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:

Note

To respect the isExpanded predicate, create the group node in the master graph instead of the folding view graph.

GraphML

Core Changes

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 and writeXMLSchema: These are now always enabled.

  • Method addInputHandlerFactory and the interface IGenericInputHandlerFactory: This functionality should now be implemented as part of the application logic.

  • Method addInputMapperFuture and the class Future: This functionality should now be implemented as part of the application logic.

  • Methods addRegistryInputMapper and addRegistryOutputMapper: 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, and configureOutputHandlers have been removed. All protected handle*Serialization, handle*Deserialization, register*InputHandler, and register*OutputHandler methods have been removed as well. Use the corresponding handle-deserialization, handle-serialization, query-input-handlers, and query-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 provided SerializationProperties 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 and GraphMLWriter and their creation and configuration methods on GraphMLIOHandler have been removed. All I/O configuration should now happen through class GraphMLIOHandler.

  • Enums GraphMLSharingPolicy and SharingState and the interfaces IReferenceHandle and IReferenceHandler have been removed. All reference handling is now performed by the framework.

  • Interfaces IGraphElementIdAcceptor and IGraphElementIdProvider 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 enum StorageLocation have been removed. This functionality should now be implemented as part of the application logic.

Changes to the file format

Note

The graphml-compatibility source code sample enables parsing of GraphML files written by yFiles for HTML 2.x:

import { configureGraphMLCompatibility } from 'graphml-compatibility/GraphMLCompatibility'
configureGraphMLCompatibility(graphMLIOHandler)

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).
Renamed layout algorithms and stages
yFiles for HTML 2.6 yFiles for HTML 3.0

BalloonLayout

RadialTreeLayout

BendConverter

BendSubstitutionStage

CactusGroupLayout

RadialGroupLayout

EdgeBundlingStage

BundledEdgeRouter

FixNodeLayoutStage

LayoutAnchoringStage

GivenCoordinatesStage

GivenCoordinatesLayout

GraphLayoutLineWrapper

LineWrappingStage

HideGroupsStage

GroupHidingStage

HierarchicLayout

HierarchicalLayout

OrientationLayout

OrientationStage

PolylineLayoutStage

OctilinearRoutingStage

SubgraphLayout

SubgraphLayoutStage

TemporaryGroupNodeInsertionStage

TemporaryGroupInsertionStage

Renamings of other important layout API members
yFiles for HTML 2.6 yFiles for HTML 3.0

AbortHandler

LayoutAbortController

*EdgeLayoutDescriptor classes

CircularLayoutEdgeDescriptor

CurveRoutingEdgeDescriptor

CircularLayoutExteriorEdgeDescriptor

EdgeRouterEdgeDescriptor

HierarchicalLayoutEdgeDescriptor

OrthogonalLayoutEdgeDescriptor

SeriesParallelLayoutEdgeDescriptor

maximumDuration properties

Properties are now named stopDuration, e.g., stopDuration

*NodeLayoutDescriptor classes

HierarchicalLayoutNodeDescriptor

TabularLayoutNodeDescriptor

NodeAggregationAlgorithm

LayoutGraphNodeAggregation

NodeHalo

Class removed. Properties are now named NodeMargins and are of type Insets

PartitionGrid

LayoutGrid

ColumnDescriptor

LayoutGridColumn

RowDescriptor

LayoutGridRow

PartitionCellId

LayoutGridCellDescriptor

Changed Default Values

The following table lists the most important changes to default values.

Layout default value changes
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

MULTI_ROWS

PACKED_CIRCLE

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

RecursiveGroupLayout.considerEmptyGroups property

true

false

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!

Removed layout 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

createCopy; see Copying the Graph

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

TreeLayout

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 LayoutStages.

NodeHalo

Halos are now specified as insets in the corresponding layout data (e.g. nodeMargins).

NormalizeGraphElementOrderStage

nodeComparator and edgeComparator

SingleCycleLayout

The CircularLayout with partitioning policy SINGLE_CYCLE can be used instead.

SnapOuterPortsToNodeBorderStage

portAdjustmentPolicies

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

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.

const edgeRouter = new EdgeRouter() // apply the straight line router immediately before the edge router
const edgeRouterData = edgeRouter.createLayoutData()
edgeRouterData.scope.edges.predicate = (e: IEdge) => e.tag === 'routed' // route marked edges

const straightLineRouter = new StraightLineEdgeRouter()
const contextModificationStage = new ContextModificationStage(
  straightLineRouter
) // temporarily change context for StraightLineRouter
contextModificationStage.addReplacementMap(
  LayoutKeys.ROUTE_EDGES_DATA_KEY,
  IMapper.fromHandler<LayoutEdge, boolean>(
    (e: LayoutEdge) => e.tag === 'straight-line'
  )
)

edgeRouter.coreLayout = contextModificationStage

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.

Using class EdgePortCandidates
// 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'))
Using class NodePortCandidates
// 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).

Creating matching port candidates
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:

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

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

Accessing the nodes and edges of a graph
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
Checking graph contents
// 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 and LayoutGraph.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()

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.

Applying a buffered layout
// 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

Adding and retrieving item data using an IMapper
// 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.

Adding data by using a getter function
// 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.

Adding a single value to the LayoutGraph
// 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.

Using the layers of the context
// 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.

Replacing the current grouping
// 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()
Removing the current grouping
// 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.

Renamed, moved, and removed members of classes related to the HierarchicalLayout (classes are bold)
yFiles for HTML 2.6 yFiles for HTML 3.0 Remarks

HierarchicLayout

HierarchicalLayout

Members of class HierarchicalLayout

backLoopRouting

HierarchicalLayoutEdgeDescriptor.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

groupLayeringPolicy

The setting has been combined with RecursiveGroupLayering.

componentLayoutEnabled

removed

The ComponentLayout can be accessed using property componentLayout, and enabled if required.

considerNodeLabels

nodeLabelPlacement

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

defaultEdgeDescriptor

Settings for individual edges can be specified via the edgeDescriptors property of HierarchicalLayoutData.

edgeToEdgeDistance

edgeDistance

fixedElementsLayerer

core.fixedElementsLayerAssigner

Moved to HierarchicalLayoutCore.

fixedElementsSequencer

core.fixedElementsSequencer

Moved to HierarchicalLayoutCore.

fromScratchLayerer

core.fromScratchLayerAssigner

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

core

The core class no longer implements ILayoutAlgorithm.

integratedEdgeLabeling

edgeLabelPlacement

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

fromSketchMode

The type of the property has been changed to boolean. The incremental mode is now called the from-sketch mode.

maximumDuration

stopDuration

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

defaultNodeDescriptor

Settings for individual edges can be specified via nodeDescriptors on HierarchicalLayoutData.

nodePlacer

coordinateAssigner

nodeToNodeDistance

nodeDistance

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

groupLayeringPolicy

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

stopAfterLayering

Moved to HierarchicalLayoutCore.

stopAfterSequencing

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

bfsLayerAssignerCoreNodes

busRootOffsets

gridComponentRootOffsets

buses

gridComponents

constraintIncrementalLayererAdditionalEdgeWeights

removed

Use the ADDITIONAL_EDGE_WEIGHT_DATA_KEY with the GenericLayoutData<TNode,TEdge,TNodeLabel,TEdgeLabel>.

edgeLabelPreferredPlacement

edgeLabelPreferredPlacements

edgeLayoutDescriptors

edgeDescriptors

givenLayersLayererIds

givenLayersIndices

incrementalHints

incrementalNodes

All nodes specified with this property are layered incrementally. To specify more specific hints, see Section Incremental Hints.

incrementalEdges

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

layerIndicesResult

In addition, the resulting indices are now nullable to indicate that no index was defined, e.g., in the case of group nodes.

nodeHalos

nodeMargins

The type of the values was changed to Insets.

nodeLayoutDescriptors

nodeDescriptors

nodePortCandidatesSet

ports.nodePortCandidates

Moved to sub-data ports. See also Ports in Layout.

partitionGridData

layoutGridData

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

LayerConstraintData<TNode>

Available via the layerConstraints property.

Properties in class LayerConstraintData<TNode>

placeAbove

placeInOrder

placeBelow

SequenceConstraintData

SequenceConstraintData<TNode,TEdge,TItem>

Available via the sequenceConstraints property.

Properties in class SequenceConstraintData<TNode,TEdge,TItem>

placeAfter

placeNodeBeforeNode

placeBefore

HierarchicLayoutNodeLayoutDescriptor

HierarchicalLayoutNodeDescriptor

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

borderToPortGapRatio

The ratio is now the same on all four sides of the node and cannot be defined individually.

HierarchicLayoutEdgeLayoutDescriptor

HierarchicalLayoutEdgeDescriptor

Properties in class HierarchicalLayoutEdgeDescriptor

recursiveEdgeStyle

recursiveEdgePolicy

routingStyle

routingStyleDescriptor

sourcePortOptimization

removed

To influence the port placement, use NodePortCandidates or EdgePortCandidates; see also Ports in Layout.

targetPortOptimization

HierarchicLayoutEdgeRoutingStrategy

HierarchicalLayoutRoutingStyle

HierarchicLayoutRoutingStyle

RoutingStyleDescriptor

IHierarchicLayoutNodePlacer

ICoordinateAssigner

SimplexNodePlacer

CoordinateAssigner

Properties in class CoordinateAssigner

barycenterMode

symmetryOptimizationStrategy

The type has been changed to SymmetryOptimizationStrategy. A previous value of true corresponds to WEAK; a previous value of false corresponds to NONE.

groupCompactionPolicy

groupCompaction

The type has been changed to boolean.

maximumDuration

stopDuration

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

layoutGridCrossingWeight

ILayerer

ILayerAssigner

AsIsLayerer

FromSketchLayerAssigner

BFSLayerer

BfsLayerAssigner

ConstraintIncrementalLayerer

ConstraintIncrementalLayerAssigner

GivenLayersLayerer

GivenLayersAssigner

MultiComponentLayerer

MultiComponentLayerAssigner

TopologicalLayerer

TopologicalLayerAssigner

WeightedLayerer

WeightedLayerAssigner

AsIsSequencer

FromSketchSequencer

DefaultLayerSequencer

DefaultSequencer

IPortAllocator

IHierarchicalLayoutPortAssigner

DefaultPortAllocator

HierarchicalLayoutPortAssigner

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.

Defining incremental nodes and edges
// 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.

Defining incremental nodes and edges with specific hints
// 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.

Defining sequence constraints for a 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.

Renamed, moved, and removed members of classes related to the HierarchicalLayout
yFiles for HTML 2.6 yFiles for HTML 3.0 Remarks

IItemFactory

ItemFactory

IEdgeData

HierarchicalLayoutEdgeContext

ILayer

HierarchicalLayoutLayer

ILayers

IListEnumerable<T> of HierarchicalLayoutLayer

Methods to insert and remove layers are available on HierarchicalLayoutContext.

ILayoutDataProvider

HierarchicalLayoutContext

INodeData

HierarchicalLayoutNodeContext

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.

Renamed, moved, and removed members of classes related to the OrganicLayout (classes are bold)
yFiles for HTML 2.6 yFiles for HTML 3.0 Remarks

OrganicLayout

class name unchanged

Members of class OrganicLayout

clusterAsGroupSubstructureAllowed

allowClusterAsGroupSubstructure

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

nodeLabelPlacement

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

edgeLabelPlacement

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

stopDuration

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

defaultMinimumNodeDistance

Settings for individual edges can be specified via the OrganicLayoutData.minimumNodeDistances property.

nodeEdgeOverlapAvoided

avoidNodeEdgeOverlap

nodeOverlapsAllowed

allowNodeOverlaps

orientationLayout

removed

Use layoutOrientation to set the desired layout orientation.

orientationLayoutEnabled

outputRestriction

shapeConstraint

parallelEdgeRouterEnabled

parallelEdgeRouter.enabled

preferredEdgeLength

defaultPreferredEdgeLength

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

OrganicLayoutData<TNode,TEdge,TNodeLabel,TEdgeLabel>

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

edgeLabelPreferredPlacements

edgeOrientations

edgeOrientation

groupNodeModes

scope.groupNodeHandlingPolicies

All settings related to the scope have been combined into the sub-data scope. See also section Scope.

nodeHalos

nodeMargins

The type of the values was changed to Insets.

partitionGridData

layoutGridData

sourceGroupIds

substructureSourceGroupIds

targetGroupIds

substructureTargetGroupIds

zCoordinates

zCoordinatesResult

OrganicLayoutScope

removed

Now a scope mode is set per node; see section Scope.

GroupNodeMode

GroupNodeHandlingPolicy

Constants in enum GroupNodeHandlingPolicy

NORMAL

FREE

OutputRestriction

ShapeConstraint

Methods in class ShapeConstraint

createAspectRatioRestriction

createAspectRatioConstraint

createCircularCageRestriction

createCircularConstraint

createEllipticalCageRestriction

createEllipticalConstraint

createRectangularCageRestriction

createRectangularConstraint

OrganicLayoutTreeSubstructureStyle

enum name unchanged

Constants in enum OrthogonalLayoutTreeSubstructureStyle

BALLOON

RADIAL_TREE

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.

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.

Defining node placement constraints for a LayoutGraph
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.

Renamed, moved, and removed members of the InteractiveOrganicLayout
yFiles for HTML 2.6 yFiles for HTML 3.0 Remarks

addStructureUpdate

removed

getCenter

InteractiveOrganicNodeHandle.getCenter

The handles are available via InteractiveOrganicLayoutData.nodeHandles.

getCenterX

getCenterY

setCenter

InteractiveOrganicNodeHandle.setCenter

setCenterX

setCenterY

commitPositions

InteractiveOrganicLayoutData.updateNodeCenters

commitPositionsSmoothly

disableAllStages

removed

getInertia

InteractiveOrganicNodeHandle.inertia

The handles are available via InteractiveOrganicLayoutData.nodeHandles.

setInertia

maximumDuration

stopDuration

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

shapeConstraint

preferredEdgeLength

defaultPreferredEdgeLength

Settings for individual edges can be specified via the InteractiveOrganicLayoutData.preferredEdgeLengths property.

setPreferredEdgeLength

InteractiveOrganicEdgeHandle.preferredEdgeLength

The handles are available via InteractiveOrganicLayoutData.edgeHandles.

setRadius

InteractiveOrganicNodeHandle.radius

The handles are available via InteractiveOrganicLayoutData.nodeHandles.

setStress

InteractiveOrganicNodeHandle.stress

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.

Renamed, moved, and removed members of classes related to the OrthogonalLayout (classes are bold)
yFiles for HTML 2.6 yFiles for HTML 3.0 Remarks

OrthogonalLayout

class name unchanged

Properties in class OrthogonalLayout

chainSize

chainSubstructureSize

chainStyle

chainSubstructureStyle

componentLayoutEnabled

componentLayout.enabled

crossingReduction

removed

Crossing reduction is implicitly controlled by the property qualityTimeRatio.

cycleStyle

cycleSubstructureStyle

cycleSize

cycleSubstructureSize

defaultEdgeLayoutDescriptor

defaultEdgeDescriptor

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

layoutMode

maximumDuration

stopDuration

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

treeSubstructureOrientation

treeSize

treeSubstructureSize

treeStyle

treeSubstructureStyle

OrthogonalLayoutData

OrthogonalLayoutData<TNode,TEdge,TNodeLabel,TEdgeLabel>

Properties in class OrthogonalLayoutData

nodeHalos

nodeMargins

directedEdges

edgeOrientation

ItemMapping that assigns to each edge a value from [-1,0,1].

edgeLayoutDescriptors

edgeDescriptors

edgeLabelPreferredPlacement

edgeLabelPreferredPlacements

ChainLayoutStyle

OrthogonalLayoutChainSubstructureStyle

CompactOrthogonalLayout

removed

CycleLayoutStyle

OrthogonalLayoutCycleSubstructureStyle

OrthogonalLayoutEdgeLayoutDescriptor

OrthogonalLayoutEdgeDescriptor

OrthogonalLayoutStyle

OrthogonalLayoutMode

TreeLayoutStyle

OrthogonalLayoutTreeSubstructureStyle

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.

Renamed, moved, and removed members of classes related to the TreeLayout (classes are bold)
yFiles for HTML 2.6 yFiles for HTML 3.0 Remarks

TreeLayout

class name unchanged

Properties in class TreeLayout

componentLayoutEnabled

componentLayout.enabled

considerNodeLabels

nodeLabelPlacement

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

defaultSubtreePlacer

defaultOutEdgeComparer

removed

Use TreeLayoutData.childOrder instead.

defaultPortAssignment

defaultPortAssigner

groupingSupported

removed

Groups are always supported now.

hideGroupsStage

removed

The TreeLayout is able to handle group nodes itself.

hideGroupsStageEnabled

integratedEdgeLabeling

edgeLabelPlacement

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

allowMultiParent

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

TreeLayoutData<TNode,TEdge,TNodeLabel,TEdgeLabel>

Properties in class TreeLayoutData

abortHandler

removed

A LayoutAbortController is exposed by the LayoutExecutor; see Section Layout Duration and Aborting for more details.

delegatingNodePlacerPrimaryNodes

singleSplitSubtreePlacerPrimaryNodes

edgeLabelPreferredPlacement

edgeLabelPreferredPlacements

gridNodePlacerRowIndices

multiLayerSubtreePlacerLayerIndices

nodeHalos

nodeMargins

nodePlacers

subtreePlacers

outEdgeComparers

childOrder

portAssignments

portAssigners

sourcePortConstraints

ports.sourcePortCandidates

Moved to sub-data ports. See also migration chapter about Ports in Layout.

targetPortConstraints

ports.targetPortCandidates

ITreeLayoutNodePlacer

ISubtreePlacer

IFromSketchNodePlacer

IFromSketchSubtreePlacer

NodePlacerBase

removed

RotatableNodePlacerBase

removed

AspectRatioNodePlacer

AspectRatioSubtreePlacer

AssistantNodePlacer

AssistantSubtreePlacer

BusNodePlacer

BusSubtreePlacer

CompactNodePlacer

CompactSubtreePlacer

DefaultNodePlacer

SingleLayerSubtreePlacer

DelegatingNodePlacer

SingleSplitSubtreePlacer

DendrogramNodePlacer

DendrogramSubtreePlacer

DoubleLineNodePlacer

DoubleLayerSubtreePlacer

FreeNodePlacer

FixedSubtreePlacer

GridNodePlacer

MultiLayerSubtreePlacer

GroupedNodePlacer

MultiSplitSubtreePlacer

LayeredNodePlacer

LevelAlignedSubtreePlacer

LeafNodePlacer

removed

Use SingleLayerSubtreePlacer instead.

LeftRightNodePlacer

LeftRightSubtreePlacer

SimpleNodePlacer

removed

Use SingleLayerSubtreePlacer instead.

RootAlignment

MultiLayerSubtreePlacerRootAlignment

For MultiLayerSubtreePlacer.

SingleLayerSubtreePlacerRootAlignment

For SingleLayerSubtreePlacer.

SubtreeRootAlignment

For DoubleLayerSubtreePlacer and LevelAlignedSubtreePlacer.

Constants in RootAlignment

CENTER_OVER_CHILDREN

CENTER_OF_CHILDREN

LEADING

LEFT

LEADING_OFFSET

LEADING

TRAILING

RIGHT

TRAILING_OFFSET

TRAILING

LayeredRoutingStyle

LevelAlignedSubtreePlacerRoutingStyle

Constants in enum LevelAlignedSubtreePlacerRoutingStyle

STRAIGHT

STRAIGHT_LINE

MultiParentRoutingStyle

enum name unchanged

Constants in enum MultiParentRoutingStyle

STRAIGHT

STRAIGHT_LINE

TreeLayoutEdgeRoutingStyle

SingleLayerSubtreePlacerRoutingStyle

Constants in enum SingleLayerSubtreePlacerRoutingStyle

FORK

ORTHOGONAL

FORK_AT_ROOT

ORTHOGONAL_AT_ROOT

POLYLINE

STRAIGHT_LINE_TO_CHILD_CONNECTOR

STRAIGHT

STRAIGHT_LINE

TreeLayoutPortAssignmentMode

enum name unchanged

Constants in enum MultiParentRoutingStyle

DISTRIBUTED_EAST

DISTRIBUTED

See section Changed Default Values and Behavior Changes.

DISTRIBUTED_NORTH

DISTRIBUTED_SOUTH

DISTRIBUTED_WEST

NONE

CENTER

portConstraint

removed

See section Changed Default Values and Behavior Changes.

RotatableNodePlacerMatrix

SubtreeTransform

Constants in enum SubtreeTransform

DEFAULT

NONE

MIR_HOR

FLIP_Y

MIR_VERT

FLIP_X

ROT90

ROTATE_LEFT

ROT180

ROTATE_180

ROT270

ROTATE_RIGHT

MIR_VERT_ROT90

ROTATE_RIGHT_FLIP_Y

MIR_HOR_ROT90

ROTATE_LEFT_FLIP_Y

TreeReductionStage

class name unchanged

Properties in class TreeReductionStage

multiParentAllowed

allowMultiParent

nonTreeEdgeLabelSelectionKey

removed

Transferring the scope between stages is now handled automatically; see section Layout Scope and Affected Items.

nonTreeEdgeLabelingAlgorithm

nonTreeEdgeLabeling

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.

Fast setting for TreeLayout that emulates the ClassicTreeLayout
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

AUTOMATIC

CORNER_COMPACT

CornerTop

HORIZONTAL

CORNER_COMPACT

CornerSide

VERTICAL

CORNER_COMPACT

Top

HORIZONTAL

CENTER

Setting for TreeLayout that emulates the AspectRatioTreeLayout
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.

Renamed, moved, and removed members of classes related to the RadialTreeLayout (classes are bold)
yFiles for HTML 2.6 yFiles for HTML 3.0 Remarks

BalloonLayout

RadialTreeLayout

Properties in class RadialTreeLayout

comparer

removed

Use childOrder instead

componentLayoutEnabled

componentLayout.enabled

considerNodeLabels

nodeLabelPlacement

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

edgeLabelPlacement

Is now enabled by default (value INTEGRATED).

integratedNodeLabeling

nodeLabelPlacement

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

nodeLabelPlacement

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

preferredChildSectorAngle

preferredRootWedge

preferredRootSectorAngle

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

RadialTreeLayoutData<TNode,TEdge,TNodeLabel,TEdgeLabel>

Properties in class RadialTreeLayoutData

abortHandler

removed

A LayoutAbortController is exposed by the LayoutExecutor; see Section Layout Duration and Aborting for more details.

edgeLabelPreferredPlacement

edgeLabelPreferredPlacements

nodeHalos

nodeMargins

outEdgeComparer

childOrder

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.

Renamed, moved, and removed members of classes related to the RadialLayout (classes are bold)
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

nodeLabelPlacement

Has been combined with properties IntegratedNodeLabeling and NodeLabelingPolicy.

edgeRoutingStrategy

edgeRoutingStyle

hideGroupsStage

removed

The RadialLayout is able to handle group nodes itself.

hideGroupsStageEnabled

integratedNodeLabeling

nodeLabelPlacement

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

minimumEdgeDistance

minimumNodeToNodeDistance

minimumNodeDistance

nodeLabelingPolicy

nodeLabelPlacement

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

RadialLayoutData<TNode,TEdge,TNodeLabel,TEdgeLabel>

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

nodeMargins

The type of the values was changed to Insets.

nodeInfos

nodePlacementsResult

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

RadialLayoutRoutingStyle

RadialLayoutLayeringStrategy

RadialLayeringStrategy

Constants in enum RadialLayeringStrategy

USER_DEFINED

removed

Custom layers defined via the RadialLayoutData.layerIds are considered automatically.

RadialLayoutNodeInfo

RadialLayoutNodePlacementResult

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.

Renamed, moved, and removed members of classes related to the RadialGroupLayout (classes are bold)
yFiles for HTML 2.6 yFiles for HTML 3.0 Remarks

CactusGroupLayout

RadialGroupLayout

Properties in class RadialGroupLayout

componentLayoutEnabled

componentLayout.enabled

considerNodeLabels

nodeLabelPlacement

Has been combined with the properties IntegratedNodeLabeling and NodeLabelingPolicy.

defaultNodeComparer

removed

groupSizingPolicy

groupSizePolicy

hideGroupsStage

removed

The RadialGroupLayout is designed to handle grouped graphs.

hideGroupsStageEnabled

integratedNodeLabeling

nodeLabelPlacement

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

nodeLabelPlacement

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

preferredRootSectorAngle

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

RadialGroupLayoutData<TNode,TEdge,TNodeLabel,TEdgeLabel>

Properties in class RadialGroupLayoutData

abortHandler

removed

A LayoutAbortController is added by the LayoutExecutor; see Section Layout Duration and Aborting for more details.

nodeComparer

childNodeComparator

nodeHalos

nodeMargins

The type of the values was changed to Insets.

CactusGroupLayoutGroupSizingPolicy

GroupSizePolicy

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.

Renamed, moved, and removed members of classes related to CircularLayout (classes are bold)
yFiles for HTML 2.6 yFiles for HTML 3.0 Remarks

CircularLayout

class name unchanged

Properties in class CircularLayout

layoutStyle

partitioningPolicy

singleCycleLayout

partitionDescriptor

See also SingleCycleLayout

defaultEdgeLayoutDescriptor

edgeDescriptor

balloonLayout

backboneLayout

componentLayoutEnabled

removed

considerNodeLabels

removed

exteriorEdgeLayoutDescriptor

exteriorEdgeDescriptor

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

CircularLayoutData<TNode,TEdge,TNodeLabel,TEdgeLabel>

Properties in class CircularLayoutData

circleIds

circleIdsResult

customGroups

partitions

nodeHalos

nodeMargins

CircularLayoutEdgeLayoutDescriptor

CircularLayoutEdgeDescriptor

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

CircularLayoutExteriorEdgeDescriptor

Properties in class CircularLayoutExteriorEdgeDescriptor

edgeToEdgeDistance

edgeDistance

SingleCycleLayout

removed

Use partitioningPolicy set to SINGLE_CYCLE instead.

Properties of former class SingleCycleLayout

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

Renamed, moved, and removed API members related to CompactDiskLayout (classes are bold)
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

nodeLabelPlacement

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

CompactDiskLayoutData<TNode,TEdge,TNodeLabel,TEdgeLabel>

Properties in class CompactDiskLayoutData

nodeHalos

nodeMargins

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.

Renamed, moved, and removed members of classes related to the TabularLayout (classes are bold)
yFiles for HTML 2.6 yFiles for HTML 3.0 Remarks

TabularLayout

class name unchanged

Properties in class TabularLayout

maximumDuration

stopDuration

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

defaultNodeDescriptor

layoutPolicy

layoutMode

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

nodeMargins

nodeLayoutDescriptors

nodeDescriptors

partitionGridData

layoutGridData

TabularLayoutPolicy

TabularLayoutMode

TabularLayoutNodeLayoutDescriptor

TabularLayoutNodeDescriptor

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.

Renamed, moved, and removed members of classes related to the SeriesParallelLayout (classes are bold)
yFiles for HTML 2.6 yFiles for HTML 3.0 Remarks

SeriesParallelLayout

class name unchanged

Properties in class SeriesParallelLayout

componentLayoutEnabled

componentLayout.enabled

considerNodeLabels

nodeLabelPlacement

The enum now allows you to choose between considering the node labels and the GenericLabeling algorithm.

defaultEdgeLayoutDescriptor

defaultEdgeDescriptor

defaultOutEdgeComparer

removed

Use SeriesParallelLayoutData.childOrder instead.

defaultPortAssignment

defaultPortAssigner

generalGraphHandling

removed

Non-series-parallel graphs are always handled now.

hideGroupsStage

removed

The SeriesParallelLayout is able to handle group nodes itself.

hideGroupsStageEnabled

integratedEdgeLabeling

edgeLabelPlacement

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

minimumEdgeDistance

minimumNodeToNodeDistance

minimumNodeDistance

nonSeriesParallelEdgeLabelSelectionKey

removed

PLACE_EDGE_LABELS_DATA_KEY is always used now.

nonSeriesParallelEdgeLabelingAlgorithm

nonSeriesParallelEdgeLabeling

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

edgeRoutingStyle

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

parallelSubgraphAlignment

SeriesParallelLayoutData

SeriesParallelLayoutData<TNode,TEdge,TNodeLabel,TEdgeLabel>

Properties in class SeriesParallelLayoutData

abortHandler

removed

A LayoutAbortController is added by the LayoutExecutor; see Section Layout Duration and Aborting for more details.

edgeLabelPreferredPlacement

edgeLabelPreferredPlacements

edgeLayoutDescriptors

edgeDescriptors

outEdgeComparers

childOrder.outEdgeComparators

portAssignments

portAssigners

ISeriesParallelLayoutPortAssignment

ISeriesParallelLayoutPortAssigner

DefaultSeriesParallelLayoutPortAssignment

SeriesParallelLayoutPortAssigner

Properties in class SeriesParallelLayoutPortAssigner

borderGapToPortGapRatio

borderToPortGapRatio

forkStyle

removed

Has been combined with mode.

ForkStyle

removed

Has been combined with SeriesParallelLayoutPortAssignmentMode.

SeriesParallelLayoutEdgeLayoutDescriptor

SeriesParallelLayoutEdgeDescriptor

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.

Renamed, moved, and removed members of classes related to the EdgeRouter (classes are bold)
yFiles for HTML 2.6 yFiles for HTML 3.0 Remarks

EdgeRouter

class name unchanged

Properties in class EdgeRouter

considerEdgeLabels

edgeLabelPlacement

Combined the two properties. The enum now allows you to choose between integrated labeling and the GenericLabeling algorithm.

integratedEdgeLabeling

considerNodeLabels

nodeLabelPlacement

The enum now allows you to choose between considering the node labels and the GenericLabeling algorithm.

defaultEdgeLayoutDescriptor

defaultEdgeDescriptor

Settings for individual edges can be specified via the edgeDescriptors property of EdgeRouterData.

edgeComparer

EdgeRouterData.edgeProcessingComparator

Moved to layout data.

grid

gridSpacing

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

stopDuration

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

EdgeRouterData<TNode,TEdge,TNodeLabel,TEdgeLabel>

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

edgeLabelPreferredPlacements

edgeLayoutDescriptors

edgeDescriptors

nodeHalos

nodeMargins

The type of the values was changed to Insets.

nodePortCandidatesSet

ports.nodePortCandidates

Moved to sub-data ports. See also Ports in Layout.

partitionGridData

layoutGridData

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

EdgeRouterEdgeDescriptor

Properties in class EdgeRouterEdgeDescriptor

penaltySettings

edgeRouterCosts

minimumEdgeToEdgeDistance

minimumEdgeDistance

PenaltySettings

EdgeRouterCosts

Properties in class EdgeRouterCosts

minimumEdgeToEdgeDistancePenalty

minimumEdgeDistanceCost

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.

Creating an EdgeRouter instance that behaves similarly to the removed ChannelEdgeRouter
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, and IGraphPartitionExtension.

  • 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

Renamed, moved, and removed members of classes related to the OrganicEdgeRouter (classes are bold)
yFiles for HTML 2.6 yFiles for HTML 3.0 Remarks

OrganicEdgeRouter

class name unchanged

Properties in class OrganicEdgeRouter

createNodeEnlargementStage

allowMovingNodes

Enabling the new property has the same effect as previously appending the stage created by the removed factory method.

edgeNodeOverlapsAllowed

allowEdgeNodeOverlaps

OrganicEdgeRouterData

OrganicEdgeRouterData<TNode,TEdge,TNodeLabel,TEdgeLabel>

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.

Running OrganicEdgeRouter with a restricted scope
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

Renamed, moved, and removed members of classes related to the GenericLabeling (classes are bold)
yFiles for HTML 2.6 yFiles for HTML 3.0 Remarks

GenericLabeling

class name unchanged

Members of class GenericLabeling

affectedLabelsDpKey

PLACE_EDGE_LABELS_DATA_KEY, PLACE_NODE_LABELS_DATA_KEY

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

stopDuration

cptimizationStrategy

defaultNodeLabelingCosts, defaultEdgeLabelingCosts

placeEdgeLabels

scope

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

GenericLabelingData<TNode,TEdge,TNodeLabel,TEdgeLabel>

Properties in class GenericLabelingData

abortHandler

removed

The LayoutAbortController is now added by the LayoutExecutor and can be set directly on the LayoutGraphContext

affectedLabels

scope

edgeLabelModels

edgeLabelCandidates

Valid edge label positions are instead specified as EdgeLabelCandidates; see Candidate Positions

nodeLabelModels

nodeLabelCandidates

Valid node label positions are instead specified as NodeLabelCandidates; see Candidate Positions

edgeLabelPreferredPlacement

edgeLabelPreferredPlacements

nodeHalos

nodeMargins

OptimizationStrategy

LabelingCosts, LabelingOptimizationStrategy

see Optimization Strategy

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

Renamed, moved, and removed API members related to PartialLayout (classes are bold)
yFiles for HTML 2.6 yFiles for HTML 3.0 Remarks

PartialLayout

class name unchanged

Members of class PartialLayout

EdgeRoutingStrategy

edgeRoutingStyle

MaximumDuration

stopDuration

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

PartialLayoutData<TNode,TEdge,TNodeLabel,TEdgeLabel>

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

edgeOrientation

Besides the renaming, the type of the ItemMapping was changed. It now assigns to each edge a value from [-1,0,1].

nodeHalos

nodeMargins

partitionGridData

layoutGridData

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

PartialLayoutRoutingStyle

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

Renamed, moved, and removed API members related to ClearAreaLayout (classes are bold)
yFiles for HTML 2.6 yFiles for HTML 3.0 Remarks

ClearAreaLayout

class name unchanged

Members of class ClearAreaLayout

considerEdgeLabels

edgeLabelPlacement

The enum now allows you to choose between considering the edge labels and the GenericLabeling algorithm.

considerNodeLabels

nodeLabelPlacement

The enum now allows you to choose between considering the node labels and the GenericLabeling algorithm.

edgeRoutingStrategy

edgeRoutingStyle

maximumDuration

stopDuration

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

ClearAreaLayoutData<TNode,TEdge,TNodeLabel,TEdgeLabel>

Properties in class ClearAreaLayoutData

abortHandler

removed

A LayoutAbortController is exposed by the LayoutExecutor; see Section Layout Duration and Aborting for more details.

nodeHalos

nodeMargins

partitionGridData

layoutGridData

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

PartialLayoutRoutingStyle

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

Renamed, moved, and removed API members related to FillAreaLayout (classes are bold)
yFiles for HTML 2.6 yFiles for HTML 3.0 Remarks

FillAreaLayout

class name unchanged

Properties in class FillAreaLayout

considerEdgeLabels

edgeLabelPlacement

The enum now allows you to choose between considering the edge labels and using the GenericLabeling algorithm.

considerNodeLabels

nodeLabelPlacement

The enum now allows you to choose between considering the node labels and using the GenericLabeling algorithm.

maximumDuration

stopDuration

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

FillAreaLayoutData<TNode,TEdge,TNodeLabel,TEdgeLabel>

Properties in class FillAreaLayoutData

abortHandler

removed

A LayoutAbortController is exposed by the LayoutExecutor; see Section Layout Duration and Aborting for more details.

nodeHalos

nodeMargins

partitionGridData

layoutGridData

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.

Renamed, moved, and removed members of classes related to the MultiPageLayout (classes are bold)
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

useProxyReferenceNodes

edgeBundleModeMask

multiEdgeConnectorPolicy

groupingMode

groupingPolicy

labeling

genericLabeling

The new read-only property is of type GenericLabeling

labelingEnabled

layoutCallback

name unchanged

Is no longer an instance of the removed yFiles interface ILayoutCallback, but a callback function with a MultiPageLayoutResult as parameter

maximumDuration

stopDuration

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

MultiPageLayoutData<TNode,TEdge,TNodeLabel,TEdgeLabel>

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

multiEdgeConnectorIds

EdgeBundleModes

MultiEdgeConnectorPolicy

IElementFactory

MultiPageElementFactory

DefaultElementFactory

MultiPageElementFactory

IElementInfoManager

removed

Information about items can be queried using methods of MultiPageLayoutContext class which is accessed from property context.

LayoutContext

MultiPageLayoutContext

ILayoutCallback

interface removed

GroupingMode

MultiPageGroupingPolicy

MultiPageLayout.Result

type name unchanged

Properties in class MultiPageLayoutResult

getPage

removed

Replaced by new property pageGraphs.

pageCount